text_to_binary.annotation_test.cpp 22 KB

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