1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 // Assembler tests for instructions in the "Annotation" section of the
16 // SPIR-V spec.
17
18 #include <sstream>
19 #include <string>
20 #include <tuple>
21 #include <vector>
22
23 #include "gmock/gmock.h"
24 #include "source/util/string_utils.h"
25 #include "test/test_fixture.h"
26 #include "test/unit_spirv.h"
27
28 namespace spvtools {
29 namespace {
30
31 using spvtest::EnumCase;
32 using spvtest::MakeInstruction;
33 using utils::MakeVector;
34 using spvtest::TextToBinaryTest;
35 using ::testing::Combine;
36 using ::testing::Eq;
37 using ::testing::Values;
38 using ::testing::ValuesIn;
39
40 // Test OpDecorate
41
42 using OpDecorateSimpleTest =
43 spvtest::TextToBinaryTestBase<::testing::TestWithParam<
44 std::tuple<spv_target_env, EnumCase<SpvDecoration>>>>;
45
TEST_P(OpDecorateSimpleTest,AnySimpleDecoration)46 TEST_P(OpDecorateSimpleTest, AnySimpleDecoration) {
47 // This string should assemble, but should not validate.
48 std::stringstream input;
49 input << "OpDecorate %1 " << std::get<1>(GetParam()).name();
50 for (auto operand : std::get<1>(GetParam()).operands())
51 input << " " << operand;
52 input << std::endl;
53 EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())),
54 Eq(MakeInstruction(SpvOpDecorate,
55 {1, uint32_t(std::get<1>(GetParam()).value())},
56 std::get<1>(GetParam()).operands())));
57 // Also check disassembly.
58 EXPECT_THAT(
59 EncodeAndDecodeSuccessfully(input.str(), SPV_BINARY_TO_TEXT_OPTION_NONE,
60 std::get<0>(GetParam())),
61 Eq(input.str()));
62 }
63
64 // Like above, but parameters to the decoration are IDs.
65 using OpDecorateSimpleIdTest =
66 spvtest::TextToBinaryTestBase<::testing::TestWithParam<
67 std::tuple<spv_target_env, EnumCase<SpvDecoration>>>>;
68
TEST_P(OpDecorateSimpleIdTest,AnySimpleDecoration)69 TEST_P(OpDecorateSimpleIdTest, AnySimpleDecoration) {
70 // This string should assemble, but should not validate.
71 std::stringstream input;
72 input << "OpDecorateId %1 " << std::get<1>(GetParam()).name();
73 for (auto operand : std::get<1>(GetParam()).operands())
74 input << " %" << operand;
75 input << std::endl;
76 EXPECT_THAT(CompiledInstructions(input.str(), std::get<0>(GetParam())),
77 Eq(MakeInstruction(SpvOpDecorateId,
78 {1, uint32_t(std::get<1>(GetParam()).value())},
79 std::get<1>(GetParam()).operands())));
80 // Also check disassembly.
81 EXPECT_THAT(
82 EncodeAndDecodeSuccessfully(input.str(), SPV_BINARY_TO_TEXT_OPTION_NONE,
83 std::get<0>(GetParam())),
84 Eq(input.str()));
85 }
86
87 #define CASE(NAME) SpvDecoration##NAME, #NAME
88 INSTANTIATE_TEST_SUITE_P(
89 TextToBinaryDecorateSimple, OpDecorateSimpleTest,
90 Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
91 ValuesIn(std::vector<EnumCase<SpvDecoration>>{
92 // The operand literal values are arbitrarily chosen,
93 // but there are the right number of them.
94 {CASE(RelaxedPrecision), {}},
95 {CASE(SpecId), {100}},
96 {CASE(Block), {}},
97 {CASE(BufferBlock), {}},
98 {CASE(RowMajor), {}},
99 {CASE(ColMajor), {}},
100 {CASE(ArrayStride), {4}},
101 {CASE(MatrixStride), {16}},
102 {CASE(GLSLShared), {}},
103 {CASE(GLSLPacked), {}},
104 {CASE(CPacked), {}},
105 // Placeholder line for enum value 12
106 {CASE(NoPerspective), {}},
107 {CASE(Flat), {}},
108 {CASE(Patch), {}},
109 {CASE(Centroid), {}},
110 {CASE(Sample), {}},
111 {CASE(Invariant), {}},
112 {CASE(Restrict), {}},
113 {CASE(Aliased), {}},
114 {CASE(Volatile), {}},
115 {CASE(Constant), {}},
116 {CASE(Coherent), {}},
117 {CASE(NonWritable), {}},
118 {CASE(NonReadable), {}},
119 {CASE(Uniform), {}},
120 {CASE(SaturatedConversion), {}},
121 {CASE(Stream), {2}},
122 {CASE(Location), {6}},
123 {CASE(Component), {3}},
124 {CASE(Index), {14}},
125 {CASE(Binding), {19}},
126 {CASE(DescriptorSet), {7}},
127 {CASE(Offset), {12}},
128 {CASE(XfbBuffer), {1}},
129 {CASE(XfbStride), {8}},
130 {CASE(NoContraction), {}},
131 {CASE(InputAttachmentIndex), {102}},
132 {CASE(Alignment), {16}},
133 })));
134
135 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleV11, OpDecorateSimpleTest,
136 Combine(Values(SPV_ENV_UNIVERSAL_1_1),
137 Values(EnumCase<SpvDecoration>{
138 CASE(MaxByteOffset), {128}})));
139
140 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleV14, OpDecorateSimpleTest,
141 Combine(Values(SPV_ENV_UNIVERSAL_1_4),
142 ValuesIn(std::vector<EnumCase<SpvDecoration>>{
143 {CASE(Uniform), {}},
144 })));
145
146 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateSimpleIdV14,
147 OpDecorateSimpleIdTest,
148 Combine(Values(SPV_ENV_UNIVERSAL_1_4),
149 ValuesIn(std::vector<EnumCase<SpvDecoration>>{
150 // In 1.4, UniformId decoration takes a
151 // scope Id.
152 {CASE(UniformId), {1}},
153 })));
154 #undef CASE
155
TEST_F(OpDecorateSimpleTest,WrongDecoration)156 TEST_F(OpDecorateSimpleTest, WrongDecoration) {
157 EXPECT_THAT(CompileFailure("OpDecorate %1 xxyyzz"),
158 Eq("Invalid decoration 'xxyyzz'."));
159 }
160
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingNone)161 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingNone) {
162 EXPECT_THAT(CompileFailure("OpDecorate %1 RelaxedPrecision 99"),
163 Eq("Expected <opcode> or <result-id> at the beginning of an "
164 "instruction, found '99'."));
165 }
166
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingOne)167 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingOne) {
168 EXPECT_THAT(CompileFailure("OpDecorate %1 SpecId 99 100"),
169 Eq("Expected <opcode> or <result-id> at the beginning of an "
170 "instruction, found '100'."));
171 }
172
TEST_F(OpDecorateSimpleTest,ExtraOperandsOnDecorationExpectingTwo)173 TEST_F(OpDecorateSimpleTest, ExtraOperandsOnDecorationExpectingTwo) {
174 EXPECT_THAT(
175 CompileFailure("OpDecorate %1 LinkageAttributes \"abc\" Import 42"),
176 Eq("Expected <opcode> or <result-id> at the beginning of an "
177 "instruction, found '42'."));
178 }
179
180 // A single test case for an enum decoration.
181 struct DecorateEnumCase {
182 // Place the enum value first, so it's easier to read the binary dumps when
183 // the test fails.
184 uint32_t value; // The value within the enum, e.g. Position
185 std::string name;
186 uint32_t enum_value; // Which enum, e.g. BuiltIn
187 std::string enum_name;
188 };
189
190 using OpDecorateEnumTest =
191 spvtest::TextToBinaryTestBase<::testing::TestWithParam<DecorateEnumCase>>;
192
TEST_P(OpDecorateEnumTest,AnyEnumDecoration)193 TEST_P(OpDecorateEnumTest, AnyEnumDecoration) {
194 // This string should assemble, but should not validate.
195 const std::string input =
196 "OpDecorate %1 " + GetParam().enum_name + " " + GetParam().name;
197 EXPECT_THAT(CompiledInstructions(input),
198 Eq(MakeInstruction(SpvOpDecorate, {1, GetParam().enum_value,
199 GetParam().value})));
200 }
201
202 // Test OpDecorate BuiltIn.
203 // clang-format off
204 #define CASE(NAME) \
205 { SpvBuiltIn##NAME, #NAME, SpvDecorationBuiltIn, "BuiltIn" }
206 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateBuiltIn, OpDecorateEnumTest,
207 ::testing::ValuesIn(std::vector<DecorateEnumCase>{
208 CASE(Position),
209 CASE(PointSize),
210 CASE(ClipDistance),
211 CASE(CullDistance),
212 CASE(VertexId),
213 CASE(InstanceId),
214 CASE(PrimitiveId),
215 CASE(InvocationId),
216 CASE(Layer),
217 CASE(ViewportIndex),
218 CASE(TessLevelOuter),
219 CASE(TessLevelInner),
220 CASE(TessCoord),
221 CASE(PatchVertices),
222 CASE(FragCoord),
223 CASE(PointCoord),
224 CASE(FrontFacing),
225 CASE(SampleId),
226 CASE(SamplePosition),
227 CASE(SampleMask),
228 // Value 21 intentionally missing.
229 CASE(FragDepth),
230 CASE(HelperInvocation),
231 CASE(NumWorkgroups),
232 CASE(WorkgroupSize),
233 CASE(WorkgroupId),
234 CASE(LocalInvocationId),
235 CASE(GlobalInvocationId),
236 CASE(LocalInvocationIndex),
237 CASE(WorkDim),
238 CASE(GlobalSize),
239 CASE(EnqueuedWorkgroupSize),
240 CASE(GlobalOffset),
241 CASE(GlobalLinearId),
242 // Value 35 intentionally missing.
243 CASE(SubgroupSize),
244 CASE(SubgroupMaxSize),
245 CASE(NumSubgroups),
246 CASE(NumEnqueuedSubgroups),
247 CASE(SubgroupId),
248 CASE(SubgroupLocalInvocationId),
249 CASE(VertexIndex),
250 CASE(InstanceIndex),
251 }));
252 #undef CASE
253 // clang-format on
254
TEST_F(OpDecorateEnumTest,WrongBuiltIn)255 TEST_F(OpDecorateEnumTest, WrongBuiltIn) {
256 EXPECT_THAT(CompileFailure("OpDecorate %1 BuiltIn xxyyzz"),
257 Eq("Invalid built-in 'xxyyzz'."));
258 }
259
260 // Test OpDecorate FuncParamAttr
261 // clang-format off
262 #define CASE(NAME) \
263 { SpvFunctionParameterAttribute##NAME, #NAME, SpvDecorationFuncParamAttr, "FuncParamAttr" }
264 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFuncParamAttr, OpDecorateEnumTest,
265 ::testing::ValuesIn(std::vector<DecorateEnumCase>{
266 CASE(Zext),
267 CASE(Sext),
268 CASE(ByVal),
269 CASE(Sret),
270 CASE(NoAlias),
271 CASE(NoCapture),
272 CASE(NoWrite),
273 CASE(NoReadWrite),
274 }));
275 #undef CASE
276 // clang-format on
277
TEST_F(OpDecorateEnumTest,WrongFuncParamAttr)278 TEST_F(OpDecorateEnumTest, WrongFuncParamAttr) {
279 EXPECT_THAT(CompileFailure("OpDecorate %1 FuncParamAttr xxyyzz"),
280 Eq("Invalid function parameter attribute 'xxyyzz'."));
281 }
282
283 // Test OpDecorate FPRoundingMode
284 // clang-format off
285 #define CASE(NAME) \
286 { SpvFPRoundingMode##NAME, #NAME, SpvDecorationFPRoundingMode, "FPRoundingMode" }
287 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFPRoundingMode, OpDecorateEnumTest,
288 ::testing::ValuesIn(std::vector<DecorateEnumCase>{
289 CASE(RTE),
290 CASE(RTZ),
291 CASE(RTP),
292 CASE(RTN),
293 }));
294 #undef CASE
295 // clang-format on
296
TEST_F(OpDecorateEnumTest,WrongFPRoundingMode)297 TEST_F(OpDecorateEnumTest, WrongFPRoundingMode) {
298 EXPECT_THAT(CompileFailure("OpDecorate %1 FPRoundingMode xxyyzz"),
299 Eq("Invalid floating-point rounding mode 'xxyyzz'."));
300 }
301
302 // Test OpDecorate FPFastMathMode.
303 // These can by named enums for the single-bit masks. However, we don't support
304 // symbolic combinations of the masks. Rather, they can use !<immediate>
305 // syntax, e.g. !0x3
306
307 // clang-format off
308 #define CASE(ENUM,NAME) \
309 { SpvFPFastMathMode##ENUM, #NAME, SpvDecorationFPFastMathMode, "FPFastMathMode" }
310 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateFPFastMathMode, OpDecorateEnumTest,
311 ::testing::ValuesIn(std::vector<DecorateEnumCase>{
312 CASE(MaskNone, None),
313 CASE(NotNaNMask, NotNaN),
314 CASE(NotInfMask, NotInf),
315 CASE(NSZMask, NSZ),
316 CASE(AllowRecipMask, AllowRecip),
317 CASE(FastMask, Fast),
318 }));
319 #undef CASE
320 // clang-format on
321
TEST_F(OpDecorateEnumTest,CombinedFPFastMathMask)322 TEST_F(OpDecorateEnumTest, CombinedFPFastMathMask) {
323 // Sample a single combination. This ensures we've integrated
324 // the instruction parsing logic with spvTextParseMask.
325 const std::string input = "OpDecorate %1 FPFastMathMode NotNaN|NotInf|NSZ";
326 const uint32_t expected_enum = SpvDecorationFPFastMathMode;
327 const uint32_t expected_mask = SpvFPFastMathModeNotNaNMask |
328 SpvFPFastMathModeNotInfMask |
329 SpvFPFastMathModeNSZMask;
330 EXPECT_THAT(
331 CompiledInstructions(input),
332 Eq(MakeInstruction(SpvOpDecorate, {1, expected_enum, expected_mask})));
333 }
334
TEST_F(OpDecorateEnumTest,WrongFPFastMathMode)335 TEST_F(OpDecorateEnumTest, WrongFPFastMathMode) {
336 EXPECT_THAT(
337 CompileFailure("OpDecorate %1 FPFastMathMode NotNaN|xxyyzz"),
338 Eq("Invalid floating-point fast math mode operand 'NotNaN|xxyyzz'."));
339 }
340
341 // Test OpDecorate Linkage
342
343 // A single test case for a linkage
344 struct DecorateLinkageCase {
345 uint32_t linkage_type_value;
346 std::string linkage_type_name;
347 std::string external_name;
348 };
349
350 using OpDecorateLinkageTest = spvtest::TextToBinaryTestBase<
351 ::testing::TestWithParam<DecorateLinkageCase>>;
352
TEST_P(OpDecorateLinkageTest,AnyLinkageDecoration)353 TEST_P(OpDecorateLinkageTest, AnyLinkageDecoration) {
354 // This string should assemble, but should not validate.
355 const std::string input = "OpDecorate %1 LinkageAttributes \"" +
356 GetParam().external_name + "\" " +
357 GetParam().linkage_type_name;
358 std::vector<uint32_t> expected_operands{1, SpvDecorationLinkageAttributes};
359 std::vector<uint32_t> encoded_external_name =
360 MakeVector(GetParam().external_name);
361 expected_operands.insert(expected_operands.end(),
362 encoded_external_name.begin(),
363 encoded_external_name.end());
364 expected_operands.push_back(GetParam().linkage_type_value);
365 EXPECT_THAT(CompiledInstructions(input),
366 Eq(MakeInstruction(SpvOpDecorate, expected_operands)));
367 }
368
369 // clang-format off
370 #define CASE(ENUM) SpvLinkageType##ENUM, #ENUM
371 INSTANTIATE_TEST_SUITE_P(TextToBinaryDecorateLinkage, OpDecorateLinkageTest,
372 ::testing::ValuesIn(std::vector<DecorateLinkageCase>{
373 { CASE(Import), "a" },
374 { CASE(Export), "foo" },
375 { CASE(Import), "some kind of long name with spaces etc." },
376 // TODO(dneto): utf-8, escaping, quoting cases.
377 }));
378 #undef CASE
379 // clang-format on
380
TEST_F(OpDecorateLinkageTest,WrongType)381 TEST_F(OpDecorateLinkageTest, WrongType) {
382 EXPECT_THAT(CompileFailure("OpDecorate %1 LinkageAttributes \"foo\" xxyyzz"),
383 Eq("Invalid linkage type 'xxyyzz'."));
384 }
385
386 // Test OpGroupMemberDecorate
387
TEST_F(TextToBinaryTest,GroupMemberDecorateGoodOneTarget)388 TEST_F(TextToBinaryTest, GroupMemberDecorateGoodOneTarget) {
389 EXPECT_THAT(CompiledInstructions("OpGroupMemberDecorate %group %id0 42"),
390 Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 42})));
391 }
392
TEST_F(TextToBinaryTest,GroupMemberDecorateGoodTwoTargets)393 TEST_F(TextToBinaryTest, GroupMemberDecorateGoodTwoTargets) {
394 EXPECT_THAT(
395 CompiledInstructions("OpGroupMemberDecorate %group %id0 96 %id1 42"),
396 Eq(MakeInstruction(SpvOpGroupMemberDecorate, {1, 2, 96, 3, 42})));
397 }
398
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingGroupId)399 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingGroupId) {
400 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate"),
401 Eq("Expected operand for OpGroupMemberDecorate instruction, but "
402 "found the end of the stream."));
403 }
404
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidGroupId)405 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidGroupId) {
406 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate 16"),
407 Eq("Expected id to start with %."));
408 }
409
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidTargetId)410 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidTargetId) {
411 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group 12"),
412 Eq("Expected id to start with %."));
413 }
414
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingTargetMemberNumber)415 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingTargetMemberNumber) {
416 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0"),
417 Eq("Expected operand for OpGroupMemberDecorate instruction, but "
418 "found the end of the stream."));
419 }
420
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidTargetMemberNumber)421 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidTargetMemberNumber) {
422 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 %id1"),
423 Eq("Invalid unsigned integer literal: %id1"));
424 }
425
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidSecondTargetId)426 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidSecondTargetId) {
427 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id1 42 12"),
428 Eq("Expected id to start with %."));
429 }
430
TEST_F(TextToBinaryTest,GroupMemberDecorateMissingSecondTargetMemberNumber)431 TEST_F(TextToBinaryTest, GroupMemberDecorateMissingSecondTargetMemberNumber) {
432 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 42 %id1"),
433 Eq("Expected operand for OpGroupMemberDecorate instruction, but "
434 "found the end of the stream."));
435 }
436
TEST_F(TextToBinaryTest,GroupMemberDecorateInvalidSecondTargetMemberNumber)437 TEST_F(TextToBinaryTest, GroupMemberDecorateInvalidSecondTargetMemberNumber) {
438 EXPECT_THAT(CompileFailure("OpGroupMemberDecorate %group %id0 42 %id1 %id2"),
439 Eq("Invalid unsigned integer literal: %id2"));
440 }
441
442 // Test OpMemberDecorate
443
444 using OpMemberDecorateSimpleTest =
445 spvtest::TextToBinaryTestBase<::testing::TestWithParam<
446 std::tuple<spv_target_env, EnumCase<SpvDecoration>>>>;
447
TEST_P(OpMemberDecorateSimpleTest,AnySimpleDecoration)448 TEST_P(OpMemberDecorateSimpleTest, AnySimpleDecoration) {
449 // This string should assemble, but should not validate.
450 std::stringstream input;
451 input << "OpMemberDecorate %1 42 " << std::get<1>(GetParam()).name();
452 for (auto operand : std::get<1>(GetParam()).operands())
453 input << " " << operand;
454 input << std::endl;
455 EXPECT_THAT(
456 CompiledInstructions(input.str(), std::get<0>(GetParam())),
457 Eq(MakeInstruction(SpvOpMemberDecorate,
458 {1, 42, uint32_t(std::get<1>(GetParam()).value())},
459 std::get<1>(GetParam()).operands())));
460 // Also check disassembly.
461 EXPECT_THAT(
462 EncodeAndDecodeSuccessfully(input.str(), SPV_BINARY_TO_TEXT_OPTION_NONE,
463 std::get<0>(GetParam())),
464 Eq(input.str()));
465 }
466
467 #define CASE(NAME) SpvDecoration##NAME, #NAME
468 INSTANTIATE_TEST_SUITE_P(
469 TextToBinaryDecorateSimple, OpMemberDecorateSimpleTest,
470 Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
471 ValuesIn(std::vector<EnumCase<SpvDecoration>>{
472 // The operand literal values are arbitrarily chosen,
473 // but there are the right number of them.
474 {CASE(RelaxedPrecision), {}},
475 {CASE(SpecId), {100}},
476 {CASE(Block), {}},
477 {CASE(BufferBlock), {}},
478 {CASE(RowMajor), {}},
479 {CASE(ColMajor), {}},
480 {CASE(ArrayStride), {4}},
481 {CASE(MatrixStride), {16}},
482 {CASE(GLSLShared), {}},
483 {CASE(GLSLPacked), {}},
484 {CASE(CPacked), {}},
485 // Placeholder line for enum value 12
486 {CASE(NoPerspective), {}},
487 {CASE(Flat), {}},
488 {CASE(Patch), {}},
489 {CASE(Centroid), {}},
490 {CASE(Sample), {}},
491 {CASE(Invariant), {}},
492 {CASE(Restrict), {}},
493 {CASE(Aliased), {}},
494 {CASE(Volatile), {}},
495 {CASE(Constant), {}},
496 {CASE(Coherent), {}},
497 {CASE(NonWritable), {}},
498 {CASE(NonReadable), {}},
499 {CASE(Uniform), {}},
500 {CASE(SaturatedConversion), {}},
501 {CASE(Stream), {2}},
502 {CASE(Location), {6}},
503 {CASE(Component), {3}},
504 {CASE(Index), {14}},
505 {CASE(Binding), {19}},
506 {CASE(DescriptorSet), {7}},
507 {CASE(Offset), {12}},
508 {CASE(XfbBuffer), {1}},
509 {CASE(XfbStride), {8}},
510 {CASE(NoContraction), {}},
511 {CASE(InputAttachmentIndex), {102}},
512 {CASE(Alignment), {16}},
513 })));
514
515 INSTANTIATE_TEST_SUITE_P(
516 TextToBinaryDecorateSimpleV11, OpMemberDecorateSimpleTest,
517 Combine(Values(SPV_ENV_UNIVERSAL_1_1),
518 Values(EnumCase<SpvDecoration>{CASE(MaxByteOffset), {128}})));
519 #undef CASE
520
TEST_F(OpMemberDecorateSimpleTest,WrongDecoration)521 TEST_F(OpMemberDecorateSimpleTest, WrongDecoration) {
522 EXPECT_THAT(CompileFailure("OpMemberDecorate %1 9 xxyyzz"),
523 Eq("Invalid decoration 'xxyyzz'."));
524 }
525
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingNone)526 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingNone) {
527 EXPECT_THAT(CompileFailure("OpMemberDecorate %1 12 RelaxedPrecision 99"),
528 Eq("Expected <opcode> or <result-id> at the beginning of an "
529 "instruction, found '99'."));
530 }
531
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingOne)532 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingOne) {
533 EXPECT_THAT(CompileFailure("OpMemberDecorate %1 0 SpecId 99 100"),
534 Eq("Expected <opcode> or <result-id> at the beginning of an "
535 "instruction, found '100'."));
536 }
537
TEST_F(OpMemberDecorateSimpleTest,ExtraOperandsOnDecorationExpectingTwo)538 TEST_F(OpMemberDecorateSimpleTest, ExtraOperandsOnDecorationExpectingTwo) {
539 EXPECT_THAT(CompileFailure(
540 "OpMemberDecorate %1 1 LinkageAttributes \"abc\" Import 42"),
541 Eq("Expected <opcode> or <result-id> at the beginning of an "
542 "instruction, found '42'."));
543 }
544
545 // TODO(dneto): OpMemberDecorate cases for decorations with parameters which
546 // are: not just lists of literal numbers.
547
548 // TODO(dneto): OpDecorationGroup
549 // TODO(dneto): OpGroupDecorate
550
551 } // namespace
552 } // namespace spvtools
553