text_to_binary.extension_test.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909
  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 "Extension Instruction" section
  15. // of the SPIR-V spec.
  16. #include <string>
  17. #include <tuple>
  18. #include <vector>
  19. #include "gmock/gmock.h"
  20. #include "source/latest_version_glsl_std_450_header.h"
  21. #include "source/latest_version_opencl_std_header.h"
  22. #include "source/util/string_utils.h"
  23. #include "test/test_fixture.h"
  24. #include "test/unit_spirv.h"
  25. namespace spvtools {
  26. namespace {
  27. using spvtest::Concatenate;
  28. using spvtest::MakeInstruction;
  29. using utils::MakeVector;
  30. using spvtest::TextToBinaryTest;
  31. using ::testing::Combine;
  32. using ::testing::Eq;
  33. using ::testing::Values;
  34. using ::testing::ValuesIn;
  35. // Returns a generator of common Vulkan environment values to be tested.
  36. std::vector<spv_target_env> CommonVulkanEnvs() {
  37. return {SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, SPV_ENV_UNIVERSAL_1_2,
  38. SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1};
  39. }
  40. TEST_F(TextToBinaryTest, InvalidExtInstImportName) {
  41. EXPECT_THAT(CompileFailure("%1 = OpExtInstImport \"Haskell.std\""),
  42. Eq("Invalid extended instruction import 'Haskell.std'"));
  43. }
  44. TEST_F(TextToBinaryTest, InvalidImportId) {
  45. EXPECT_THAT(CompileFailure("%1 = OpTypeVoid\n"
  46. "%2 = OpExtInst %1 %1"),
  47. Eq("Invalid extended instruction import Id 2"));
  48. }
  49. TEST_F(TextToBinaryTest, InvalidImportInstruction) {
  50. const std::string input = R"(%1 = OpTypeVoid
  51. %2 = OpExtInstImport "OpenCL.std"
  52. %3 = OpExtInst %1 %2 not_in_the_opencl)";
  53. EXPECT_THAT(CompileFailure(input),
  54. Eq("Invalid extended instruction name 'not_in_the_opencl'."));
  55. }
  56. TEST_F(TextToBinaryTest, MultiImport) {
  57. const std::string input = R"(%2 = OpExtInstImport "OpenCL.std"
  58. %2 = OpExtInstImport "OpenCL.std")";
  59. EXPECT_THAT(CompileFailure(input),
  60. Eq("Import Id is being defined a second time"));
  61. }
  62. TEST_F(TextToBinaryTest, TooManyArguments) {
  63. const std::string input = R"(%opencl = OpExtInstImport "OpenCL.std"
  64. %2 = OpExtInst %float %opencl cos %x %oops")";
  65. EXPECT_THAT(CompileFailure(input), Eq("Expected '=', found end of stream."));
  66. }
  67. TEST_F(TextToBinaryTest, ExtInstFromTwoDifferentImports) {
  68. const std::string input = R"(%1 = OpExtInstImport "OpenCL.std"
  69. %2 = OpExtInstImport "GLSL.std.450"
  70. %4 = OpExtInst %3 %1 native_sqrt %5
  71. %7 = OpExtInst %6 %2 MatrixInverse %8
  72. )";
  73. // Make sure it assembles correctly.
  74. EXPECT_THAT(
  75. CompiledInstructions(input),
  76. Eq(Concatenate({
  77. MakeInstruction(SpvOpExtInstImport, {1}, MakeVector("OpenCL.std")),
  78. MakeInstruction(SpvOpExtInstImport, {2}, MakeVector("GLSL.std.450")),
  79. MakeInstruction(
  80. SpvOpExtInst,
  81. {3, 4, 1, uint32_t(OpenCLLIB::Entrypoints::Native_sqrt), 5}),
  82. MakeInstruction(SpvOpExtInst,
  83. {6, 7, 2, uint32_t(GLSLstd450MatrixInverse), 8}),
  84. })));
  85. // Make sure it disassembles correctly.
  86. EXPECT_THAT(EncodeAndDecodeSuccessfully(input), Eq(input));
  87. }
  88. // A test case for assembling into words in an instruction.
  89. struct AssemblyCase {
  90. std::string input;
  91. std::vector<uint32_t> expected;
  92. };
  93. using ExtensionAssemblyTest = spvtest::TextToBinaryTestBase<
  94. ::testing::TestWithParam<std::tuple<spv_target_env, AssemblyCase>>>;
  95. TEST_P(ExtensionAssemblyTest, Samples) {
  96. const spv_target_env& env = std::get<0>(GetParam());
  97. const AssemblyCase& ac = std::get<1>(GetParam());
  98. // Check that it assembles correctly.
  99. EXPECT_THAT(CompiledInstructions(ac.input, env), Eq(ac.expected));
  100. }
  101. using ExtensionRoundTripTest = spvtest::TextToBinaryTestBase<
  102. ::testing::TestWithParam<std::tuple<spv_target_env, AssemblyCase>>>;
  103. TEST_P(ExtensionRoundTripTest, Samples) {
  104. const spv_target_env& env = std::get<0>(GetParam());
  105. const AssemblyCase& ac = std::get<1>(GetParam());
  106. // Check that it assembles correctly.
  107. EXPECT_THAT(CompiledInstructions(ac.input, env), Eq(ac.expected));
  108. // Check round trip through the disassembler.
  109. EXPECT_THAT(EncodeAndDecodeSuccessfully(ac.input,
  110. SPV_BINARY_TO_TEXT_OPTION_NONE, env),
  111. Eq(ac.input))
  112. << "target env: " << spvTargetEnvDescription(env) << "\n";
  113. }
  114. // SPV_KHR_shader_ballot
  115. INSTANTIATE_TEST_SUITE_P(
  116. SPV_KHR_shader_ballot, ExtensionRoundTripTest,
  117. // We'll get coverage over operand tables by trying the universal
  118. // environments, and at least one specific environment.
  119. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  120. SPV_ENV_VULKAN_1_0),
  121. ValuesIn(std::vector<AssemblyCase>{
  122. {"OpCapability SubgroupBallotKHR\n",
  123. MakeInstruction(SpvOpCapability,
  124. {SpvCapabilitySubgroupBallotKHR})},
  125. {"%2 = OpSubgroupBallotKHR %1 %3\n",
  126. MakeInstruction(SpvOpSubgroupBallotKHR, {1, 2, 3})},
  127. {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n",
  128. MakeInstruction(SpvOpSubgroupFirstInvocationKHR, {1, 2, 3})},
  129. {"OpDecorate %1 BuiltIn SubgroupEqMask\n",
  130. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  131. SpvBuiltInSubgroupEqMaskKHR})},
  132. {"OpDecorate %1 BuiltIn SubgroupGeMask\n",
  133. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  134. SpvBuiltInSubgroupGeMaskKHR})},
  135. {"OpDecorate %1 BuiltIn SubgroupGtMask\n",
  136. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  137. SpvBuiltInSubgroupGtMaskKHR})},
  138. {"OpDecorate %1 BuiltIn SubgroupLeMask\n",
  139. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  140. SpvBuiltInSubgroupLeMaskKHR})},
  141. {"OpDecorate %1 BuiltIn SubgroupLtMask\n",
  142. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  143. SpvBuiltInSubgroupLtMaskKHR})},
  144. })));
  145. INSTANTIATE_TEST_SUITE_P(
  146. SPV_KHR_shader_ballot_vulkan_1_1, ExtensionRoundTripTest,
  147. // In SPIR-V 1.3 and Vulkan 1.1 we can drop the KHR suffix on the
  148. // builtin enums.
  149. Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1),
  150. ValuesIn(std::vector<AssemblyCase>{
  151. {"OpCapability SubgroupBallotKHR\n",
  152. MakeInstruction(SpvOpCapability,
  153. {SpvCapabilitySubgroupBallotKHR})},
  154. {"%2 = OpSubgroupBallotKHR %1 %3\n",
  155. MakeInstruction(SpvOpSubgroupBallotKHR, {1, 2, 3})},
  156. {"%2 = OpSubgroupFirstInvocationKHR %1 %3\n",
  157. MakeInstruction(SpvOpSubgroupFirstInvocationKHR, {1, 2, 3})},
  158. {"OpDecorate %1 BuiltIn SubgroupEqMask\n",
  159. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  160. SpvBuiltInSubgroupEqMask})},
  161. {"OpDecorate %1 BuiltIn SubgroupGeMask\n",
  162. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  163. SpvBuiltInSubgroupGeMask})},
  164. {"OpDecorate %1 BuiltIn SubgroupGtMask\n",
  165. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  166. SpvBuiltInSubgroupGtMask})},
  167. {"OpDecorate %1 BuiltIn SubgroupLeMask\n",
  168. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  169. SpvBuiltInSubgroupLeMask})},
  170. {"OpDecorate %1 BuiltIn SubgroupLtMask\n",
  171. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  172. SpvBuiltInSubgroupLtMask})},
  173. })));
  174. // The old builtin names (with KHR suffix) still work in the assmebler, and
  175. // map to the enums without the KHR.
  176. INSTANTIATE_TEST_SUITE_P(
  177. SPV_KHR_shader_ballot_vulkan_1_1_alias_check, ExtensionAssemblyTest,
  178. // In SPIR-V 1.3 and Vulkan 1.1 we can drop the KHR suffix on the
  179. // builtin enums.
  180. Combine(Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1),
  181. ValuesIn(std::vector<AssemblyCase>{
  182. {"OpDecorate %1 BuiltIn SubgroupEqMaskKHR\n",
  183. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  184. SpvBuiltInSubgroupEqMask})},
  185. {"OpDecorate %1 BuiltIn SubgroupGeMaskKHR\n",
  186. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  187. SpvBuiltInSubgroupGeMask})},
  188. {"OpDecorate %1 BuiltIn SubgroupGtMaskKHR\n",
  189. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  190. SpvBuiltInSubgroupGtMask})},
  191. {"OpDecorate %1 BuiltIn SubgroupLeMaskKHR\n",
  192. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  193. SpvBuiltInSubgroupLeMask})},
  194. {"OpDecorate %1 BuiltIn SubgroupLtMaskKHR\n",
  195. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  196. SpvBuiltInSubgroupLtMask})},
  197. })));
  198. // SPV_KHR_shader_draw_parameters
  199. INSTANTIATE_TEST_SUITE_P(
  200. SPV_KHR_shader_draw_parameters, ExtensionRoundTripTest,
  201. // We'll get coverage over operand tables by trying the universal
  202. // environments, and at least one specific environment.
  203. Combine(
  204. ValuesIn(CommonVulkanEnvs()),
  205. ValuesIn(std::vector<AssemblyCase>{
  206. {"OpCapability DrawParameters\n",
  207. MakeInstruction(SpvOpCapability, {SpvCapabilityDrawParameters})},
  208. {"OpDecorate %1 BuiltIn BaseVertex\n",
  209. MakeInstruction(SpvOpDecorate,
  210. {1, SpvDecorationBuiltIn, SpvBuiltInBaseVertex})},
  211. {"OpDecorate %1 BuiltIn BaseInstance\n",
  212. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  213. SpvBuiltInBaseInstance})},
  214. {"OpDecorate %1 BuiltIn DrawIndex\n",
  215. MakeInstruction(SpvOpDecorate,
  216. {1, SpvDecorationBuiltIn, SpvBuiltInDrawIndex})},
  217. })));
  218. // SPV_KHR_subgroup_vote
  219. INSTANTIATE_TEST_SUITE_P(
  220. SPV_KHR_subgroup_vote, ExtensionRoundTripTest,
  221. // We'll get coverage over operand tables by trying the universal
  222. // environments, and at least one specific environment.
  223. Combine(ValuesIn(CommonVulkanEnvs()),
  224. ValuesIn(std::vector<AssemblyCase>{
  225. {"OpCapability SubgroupVoteKHR\n",
  226. MakeInstruction(SpvOpCapability,
  227. {SpvCapabilitySubgroupVoteKHR})},
  228. {"%2 = OpSubgroupAnyKHR %1 %3\n",
  229. MakeInstruction(SpvOpSubgroupAnyKHR, {1, 2, 3})},
  230. {"%2 = OpSubgroupAllKHR %1 %3\n",
  231. MakeInstruction(SpvOpSubgroupAllKHR, {1, 2, 3})},
  232. {"%2 = OpSubgroupAllEqualKHR %1 %3\n",
  233. MakeInstruction(SpvOpSubgroupAllEqualKHR, {1, 2, 3})},
  234. })));
  235. // SPV_KHR_16bit_storage
  236. INSTANTIATE_TEST_SUITE_P(
  237. SPV_KHR_16bit_storage, ExtensionRoundTripTest,
  238. // We'll get coverage over operand tables by trying the universal
  239. // environments, and at least one specific environment.
  240. Combine(ValuesIn(CommonVulkanEnvs()),
  241. ValuesIn(std::vector<AssemblyCase>{
  242. {"OpCapability StorageBuffer16BitAccess\n",
  243. MakeInstruction(SpvOpCapability,
  244. {SpvCapabilityStorageUniformBufferBlock16})},
  245. {"OpCapability StorageBuffer16BitAccess\n",
  246. MakeInstruction(SpvOpCapability,
  247. {SpvCapabilityStorageBuffer16BitAccess})},
  248. {"OpCapability UniformAndStorageBuffer16BitAccess\n",
  249. MakeInstruction(
  250. SpvOpCapability,
  251. {SpvCapabilityUniformAndStorageBuffer16BitAccess})},
  252. {"OpCapability UniformAndStorageBuffer16BitAccess\n",
  253. MakeInstruction(SpvOpCapability,
  254. {SpvCapabilityStorageUniform16})},
  255. {"OpCapability StoragePushConstant16\n",
  256. MakeInstruction(SpvOpCapability,
  257. {SpvCapabilityStoragePushConstant16})},
  258. {"OpCapability StorageInputOutput16\n",
  259. MakeInstruction(SpvOpCapability,
  260. {SpvCapabilityStorageInputOutput16})},
  261. })));
  262. INSTANTIATE_TEST_SUITE_P(
  263. SPV_KHR_16bit_storage_alias_check, ExtensionAssemblyTest,
  264. Combine(ValuesIn(CommonVulkanEnvs()),
  265. ValuesIn(std::vector<AssemblyCase>{
  266. // The old name maps to the new enum.
  267. {"OpCapability StorageUniformBufferBlock16\n",
  268. MakeInstruction(SpvOpCapability,
  269. {SpvCapabilityStorageBuffer16BitAccess})},
  270. // The new name maps to the old enum.
  271. {"OpCapability UniformAndStorageBuffer16BitAccess\n",
  272. MakeInstruction(SpvOpCapability,
  273. {SpvCapabilityStorageUniform16})},
  274. })));
  275. // SPV_KHR_device_group
  276. INSTANTIATE_TEST_SUITE_P(
  277. SPV_KHR_device_group, ExtensionRoundTripTest,
  278. // We'll get coverage over operand tables by trying the universal
  279. // environments, and at least one specific environment.
  280. Combine(ValuesIn(CommonVulkanEnvs()),
  281. ValuesIn(std::vector<AssemblyCase>{
  282. {"OpCapability DeviceGroup\n",
  283. MakeInstruction(SpvOpCapability, {SpvCapabilityDeviceGroup})},
  284. {"OpDecorate %1 BuiltIn DeviceIndex\n",
  285. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  286. SpvBuiltInDeviceIndex})},
  287. })));
  288. // SPV_KHR_8bit_storage
  289. INSTANTIATE_TEST_SUITE_P(
  290. SPV_KHR_8bit_storage, ExtensionRoundTripTest,
  291. // We'll get coverage over operand tables by trying the universal
  292. // environments, and at least one specific environment.
  293. Combine(
  294. ValuesIn(CommonVulkanEnvs()),
  295. ValuesIn(std::vector<AssemblyCase>{
  296. {"OpCapability StorageBuffer8BitAccess\n",
  297. MakeInstruction(SpvOpCapability,
  298. {SpvCapabilityStorageBuffer8BitAccess})},
  299. {"OpCapability UniformAndStorageBuffer8BitAccess\n",
  300. MakeInstruction(SpvOpCapability,
  301. {SpvCapabilityUniformAndStorageBuffer8BitAccess})},
  302. {"OpCapability StoragePushConstant8\n",
  303. MakeInstruction(SpvOpCapability,
  304. {SpvCapabilityStoragePushConstant8})},
  305. })));
  306. // SPV_KHR_multiview
  307. INSTANTIATE_TEST_SUITE_P(
  308. SPV_KHR_multiview, ExtensionRoundTripTest,
  309. // We'll get coverage over operand tables by trying the universal
  310. // environments, and at least one specific environment.
  311. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  312. SPV_ENV_VULKAN_1_0),
  313. ValuesIn(std::vector<AssemblyCase>{
  314. {"OpCapability MultiView\n",
  315. MakeInstruction(SpvOpCapability, {SpvCapabilityMultiView})},
  316. {"OpDecorate %1 BuiltIn ViewIndex\n",
  317. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  318. SpvBuiltInViewIndex})},
  319. })));
  320. // SPV_AMD_shader_explicit_vertex_parameter
  321. #define PREAMBLE \
  322. "%1 = OpExtInstImport \"SPV_AMD_shader_explicit_vertex_parameter\"\n"
  323. INSTANTIATE_TEST_SUITE_P(
  324. SPV_AMD_shader_explicit_vertex_parameter, ExtensionRoundTripTest,
  325. // We'll get coverage over operand tables by trying the universal
  326. // environments, and at least one specific environment.
  327. Combine(
  328. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  329. SPV_ENV_VULKAN_1_0),
  330. ValuesIn(std::vector<AssemblyCase>{
  331. {PREAMBLE "%3 = OpExtInst %2 %1 InterpolateAtVertexAMD %4 %5\n",
  332. Concatenate(
  333. {MakeInstruction(
  334. SpvOpExtInstImport, {1},
  335. MakeVector("SPV_AMD_shader_explicit_vertex_parameter")),
  336. MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5})})},
  337. })));
  338. #undef PREAMBLE
  339. // SPV_AMD_shader_trinary_minmax
  340. #define PREAMBLE "%1 = OpExtInstImport \"SPV_AMD_shader_trinary_minmax\"\n"
  341. INSTANTIATE_TEST_SUITE_P(
  342. SPV_AMD_shader_trinary_minmax, ExtensionRoundTripTest,
  343. // We'll get coverage over operand tables by trying the universal
  344. // environments, and at least one specific environment.
  345. Combine(
  346. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  347. SPV_ENV_VULKAN_1_0),
  348. ValuesIn(std::vector<AssemblyCase>{
  349. {PREAMBLE "%3 = OpExtInst %2 %1 FMin3AMD %4 %5 %6\n",
  350. Concatenate(
  351. {MakeInstruction(SpvOpExtInstImport, {1},
  352. MakeVector("SPV_AMD_shader_trinary_minmax")),
  353. MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5, 6})})},
  354. {PREAMBLE "%3 = OpExtInst %2 %1 UMin3AMD %4 %5 %6\n",
  355. Concatenate(
  356. {MakeInstruction(SpvOpExtInstImport, {1},
  357. MakeVector("SPV_AMD_shader_trinary_minmax")),
  358. MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4, 5, 6})})},
  359. {PREAMBLE "%3 = OpExtInst %2 %1 SMin3AMD %4 %5 %6\n",
  360. Concatenate(
  361. {MakeInstruction(SpvOpExtInstImport, {1},
  362. MakeVector("SPV_AMD_shader_trinary_minmax")),
  363. MakeInstruction(SpvOpExtInst, {2, 3, 1, 3, 4, 5, 6})})},
  364. {PREAMBLE "%3 = OpExtInst %2 %1 FMax3AMD %4 %5 %6\n",
  365. Concatenate(
  366. {MakeInstruction(SpvOpExtInstImport, {1},
  367. MakeVector("SPV_AMD_shader_trinary_minmax")),
  368. MakeInstruction(SpvOpExtInst, {2, 3, 1, 4, 4, 5, 6})})},
  369. {PREAMBLE "%3 = OpExtInst %2 %1 UMax3AMD %4 %5 %6\n",
  370. Concatenate(
  371. {MakeInstruction(SpvOpExtInstImport, {1},
  372. MakeVector("SPV_AMD_shader_trinary_minmax")),
  373. MakeInstruction(SpvOpExtInst, {2, 3, 1, 5, 4, 5, 6})})},
  374. {PREAMBLE "%3 = OpExtInst %2 %1 SMax3AMD %4 %5 %6\n",
  375. Concatenate(
  376. {MakeInstruction(SpvOpExtInstImport, {1},
  377. MakeVector("SPV_AMD_shader_trinary_minmax")),
  378. MakeInstruction(SpvOpExtInst, {2, 3, 1, 6, 4, 5, 6})})},
  379. {PREAMBLE "%3 = OpExtInst %2 %1 FMid3AMD %4 %5 %6\n",
  380. Concatenate(
  381. {MakeInstruction(SpvOpExtInstImport, {1},
  382. MakeVector("SPV_AMD_shader_trinary_minmax")),
  383. MakeInstruction(SpvOpExtInst, {2, 3, 1, 7, 4, 5, 6})})},
  384. {PREAMBLE "%3 = OpExtInst %2 %1 UMid3AMD %4 %5 %6\n",
  385. Concatenate(
  386. {MakeInstruction(SpvOpExtInstImport, {1},
  387. MakeVector("SPV_AMD_shader_trinary_minmax")),
  388. MakeInstruction(SpvOpExtInst, {2, 3, 1, 8, 4, 5, 6})})},
  389. {PREAMBLE "%3 = OpExtInst %2 %1 SMid3AMD %4 %5 %6\n",
  390. Concatenate(
  391. {MakeInstruction(SpvOpExtInstImport, {1},
  392. MakeVector("SPV_AMD_shader_trinary_minmax")),
  393. MakeInstruction(SpvOpExtInst, {2, 3, 1, 9, 4, 5, 6})})},
  394. })));
  395. #undef PREAMBLE
  396. // SPV_AMD_gcn_shader
  397. #define PREAMBLE "%1 = OpExtInstImport \"SPV_AMD_gcn_shader\"\n"
  398. INSTANTIATE_TEST_SUITE_P(
  399. SPV_AMD_gcn_shader, ExtensionRoundTripTest,
  400. // We'll get coverage over operand tables by trying the universal
  401. // environments, and at least one specific environment.
  402. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  403. SPV_ENV_VULKAN_1_0),
  404. ValuesIn(std::vector<AssemblyCase>{
  405. {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceIndexAMD %4\n",
  406. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  407. MakeVector("SPV_AMD_gcn_shader")),
  408. MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4})})},
  409. {PREAMBLE "%3 = OpExtInst %2 %1 CubeFaceCoordAMD %4\n",
  410. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  411. MakeVector("SPV_AMD_gcn_shader")),
  412. MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4})})},
  413. {PREAMBLE "%3 = OpExtInst %2 %1 TimeAMD\n",
  414. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  415. MakeVector("SPV_AMD_gcn_shader")),
  416. MakeInstruction(SpvOpExtInst, {2, 3, 1, 3})})},
  417. })));
  418. #undef PREAMBLE
  419. // SPV_AMD_shader_ballot
  420. #define PREAMBLE "%1 = OpExtInstImport \"SPV_AMD_shader_ballot\"\n"
  421. INSTANTIATE_TEST_SUITE_P(
  422. SPV_AMD_shader_ballot, ExtensionRoundTripTest,
  423. // We'll get coverage over operand tables by trying the universal
  424. // environments, and at least one specific environment.
  425. Combine(
  426. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  427. SPV_ENV_VULKAN_1_0),
  428. ValuesIn(std::vector<AssemblyCase>{
  429. {PREAMBLE "%3 = OpExtInst %2 %1 SwizzleInvocationsAMD %4 %5\n",
  430. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  431. MakeVector("SPV_AMD_shader_ballot")),
  432. MakeInstruction(SpvOpExtInst, {2, 3, 1, 1, 4, 5})})},
  433. {PREAMBLE
  434. "%3 = OpExtInst %2 %1 SwizzleInvocationsMaskedAMD %4 %5\n",
  435. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  436. MakeVector("SPV_AMD_shader_ballot")),
  437. MakeInstruction(SpvOpExtInst, {2, 3, 1, 2, 4, 5})})},
  438. {PREAMBLE "%3 = OpExtInst %2 %1 WriteInvocationAMD %4 %5 %6\n",
  439. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  440. MakeVector("SPV_AMD_shader_ballot")),
  441. MakeInstruction(SpvOpExtInst,
  442. {2, 3, 1, 3, 4, 5, 6})})},
  443. {PREAMBLE "%3 = OpExtInst %2 %1 MbcntAMD %4\n",
  444. Concatenate({MakeInstruction(SpvOpExtInstImport, {1},
  445. MakeVector("SPV_AMD_shader_ballot")),
  446. MakeInstruction(SpvOpExtInst, {2, 3, 1, 4, 4})})},
  447. })));
  448. #undef PREAMBLE
  449. // SPV_KHR_variable_pointers
  450. INSTANTIATE_TEST_SUITE_P(
  451. SPV_KHR_variable_pointers, ExtensionRoundTripTest,
  452. // We'll get coverage over operand tables by trying the universal
  453. // environments, and at least one specific environment.
  454. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  455. SPV_ENV_VULKAN_1_0),
  456. ValuesIn(std::vector<AssemblyCase>{
  457. {"OpCapability VariablePointers\n",
  458. MakeInstruction(SpvOpCapability,
  459. {SpvCapabilityVariablePointers})},
  460. {"OpCapability VariablePointersStorageBuffer\n",
  461. MakeInstruction(SpvOpCapability,
  462. {SpvCapabilityVariablePointersStorageBuffer})},
  463. })));
  464. // SPV_KHR_vulkan_memory_model
  465. INSTANTIATE_TEST_SUITE_P(
  466. SPV_KHR_vulkan_memory_model, ExtensionRoundTripTest,
  467. // We'll get coverage over operand tables by trying the universal
  468. // environments, and at least one specific environment.
  469. //
  470. // Note: SPV_KHR_vulkan_memory_model adds scope enum value QueueFamilyKHR.
  471. // Scope enums are used in ID definitions elsewhere, that don't know they
  472. // are using particular enums. So the assembler doesn't support assembling
  473. // those enums names into the corresponding values. So there is no asm/dis
  474. // tests for those enums.
  475. Combine(
  476. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  477. SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1),
  478. ValuesIn(std::vector<AssemblyCase>{
  479. {"OpCapability VulkanMemoryModel\n",
  480. MakeInstruction(SpvOpCapability,
  481. {SpvCapabilityVulkanMemoryModelKHR})},
  482. {"OpCapability VulkanMemoryModelDeviceScope\n",
  483. MakeInstruction(SpvOpCapability,
  484. {SpvCapabilityVulkanMemoryModelDeviceScopeKHR})},
  485. {"OpMemoryModel Logical Vulkan\n",
  486. MakeInstruction(SpvOpMemoryModel, {SpvAddressingModelLogical,
  487. SpvMemoryModelVulkanKHR})},
  488. {"OpStore %1 %2 MakePointerAvailable %3\n",
  489. MakeInstruction(SpvOpStore,
  490. {1, 2, SpvMemoryAccessMakePointerAvailableKHRMask,
  491. 3})},
  492. {"OpStore %1 %2 Volatile|MakePointerAvailable %3\n",
  493. MakeInstruction(SpvOpStore,
  494. {1, 2,
  495. int(SpvMemoryAccessMakePointerAvailableKHRMask) |
  496. int(SpvMemoryAccessVolatileMask),
  497. 3})},
  498. {"OpStore %1 %2 Aligned|MakePointerAvailable 4 %3\n",
  499. MakeInstruction(SpvOpStore,
  500. {1, 2,
  501. int(SpvMemoryAccessMakePointerAvailableKHRMask) |
  502. int(SpvMemoryAccessAlignedMask),
  503. 4, 3})},
  504. {"OpStore %1 %2 MakePointerAvailable|NonPrivatePointer %3\n",
  505. MakeInstruction(SpvOpStore,
  506. {1, 2,
  507. int(SpvMemoryAccessMakePointerAvailableKHRMask) |
  508. int(SpvMemoryAccessNonPrivatePointerKHRMask),
  509. 3})},
  510. {"%2 = OpLoad %1 %3 MakePointerVisible %4\n",
  511. MakeInstruction(SpvOpLoad,
  512. {1, 2, 3, SpvMemoryAccessMakePointerVisibleKHRMask,
  513. 4})},
  514. {"%2 = OpLoad %1 %3 Volatile|MakePointerVisible %4\n",
  515. MakeInstruction(SpvOpLoad,
  516. {1, 2, 3,
  517. int(SpvMemoryAccessMakePointerVisibleKHRMask) |
  518. int(SpvMemoryAccessVolatileMask),
  519. 4})},
  520. {"%2 = OpLoad %1 %3 Aligned|MakePointerVisible 8 %4\n",
  521. MakeInstruction(SpvOpLoad,
  522. {1, 2, 3,
  523. int(SpvMemoryAccessMakePointerVisibleKHRMask) |
  524. int(SpvMemoryAccessAlignedMask),
  525. 8, 4})},
  526. {"%2 = OpLoad %1 %3 MakePointerVisible|NonPrivatePointer "
  527. "%4\n",
  528. MakeInstruction(SpvOpLoad,
  529. {1, 2, 3,
  530. int(SpvMemoryAccessMakePointerVisibleKHRMask) |
  531. int(SpvMemoryAccessNonPrivatePointerKHRMask),
  532. 4})},
  533. {"OpCopyMemory %1 %2 "
  534. "MakePointerAvailable|"
  535. "MakePointerVisible|"
  536. "NonPrivatePointer "
  537. "%3 %4\n",
  538. MakeInstruction(SpvOpCopyMemory,
  539. {1, 2,
  540. (int(SpvMemoryAccessMakePointerVisibleKHRMask) |
  541. int(SpvMemoryAccessMakePointerAvailableKHRMask) |
  542. int(SpvMemoryAccessNonPrivatePointerKHRMask)),
  543. 3, 4})},
  544. {"OpCopyMemorySized %1 %2 %3 "
  545. "MakePointerAvailable|"
  546. "MakePointerVisible|"
  547. "NonPrivatePointer "
  548. "%4 %5\n",
  549. MakeInstruction(SpvOpCopyMemorySized,
  550. {1, 2, 3,
  551. (int(SpvMemoryAccessMakePointerVisibleKHRMask) |
  552. int(SpvMemoryAccessMakePointerAvailableKHRMask) |
  553. int(SpvMemoryAccessNonPrivatePointerKHRMask)),
  554. 4, 5})},
  555. // Image operands
  556. {"OpImageWrite %1 %2 %3 MakeTexelAvailable "
  557. "%4\n",
  558. MakeInstruction(
  559. SpvOpImageWrite,
  560. {1, 2, 3, int(SpvImageOperandsMakeTexelAvailableKHRMask), 4})},
  561. {"OpImageWrite %1 %2 %3 MakeTexelAvailable|NonPrivateTexel "
  562. "%4\n",
  563. MakeInstruction(SpvOpImageWrite,
  564. {1, 2, 3,
  565. int(SpvImageOperandsMakeTexelAvailableKHRMask) |
  566. int(SpvImageOperandsNonPrivateTexelKHRMask),
  567. 4})},
  568. {"OpImageWrite %1 %2 %3 "
  569. "MakeTexelAvailable|NonPrivateTexel|VolatileTexel "
  570. "%4\n",
  571. MakeInstruction(SpvOpImageWrite,
  572. {1, 2, 3,
  573. int(SpvImageOperandsMakeTexelAvailableKHRMask) |
  574. int(SpvImageOperandsNonPrivateTexelKHRMask) |
  575. int(SpvImageOperandsVolatileTexelKHRMask),
  576. 4})},
  577. {"%2 = OpImageRead %1 %3 %4 MakeTexelVisible "
  578. "%5\n",
  579. MakeInstruction(SpvOpImageRead,
  580. {1, 2, 3, 4,
  581. int(SpvImageOperandsMakeTexelVisibleKHRMask),
  582. 5})},
  583. {"%2 = OpImageRead %1 %3 %4 "
  584. "MakeTexelVisible|NonPrivateTexel "
  585. "%5\n",
  586. MakeInstruction(SpvOpImageRead,
  587. {1, 2, 3, 4,
  588. int(SpvImageOperandsMakeTexelVisibleKHRMask) |
  589. int(SpvImageOperandsNonPrivateTexelKHRMask),
  590. 5})},
  591. {"%2 = OpImageRead %1 %3 %4 "
  592. "MakeTexelVisible|NonPrivateTexel|VolatileTexel "
  593. "%5\n",
  594. MakeInstruction(SpvOpImageRead,
  595. {1, 2, 3, 4,
  596. int(SpvImageOperandsMakeTexelVisibleKHRMask) |
  597. int(SpvImageOperandsNonPrivateTexelKHRMask) |
  598. int(SpvImageOperandsVolatileTexelKHRMask),
  599. 5})},
  600. // Memory semantics ID values are numbers put into a SPIR-V
  601. // constant integer referenced by Id. There is no token for
  602. // them, and so no assembler or disassembler support required.
  603. // Similar for Scope ID.
  604. })));
  605. // SPV_GOOGLE_decorate_string
  606. // Now that OpDecorateString is the preferred spelling for
  607. // OpDecorateStringGOOGLE use that name in round trip tests, and the GOOGLE
  608. // name in an assembly-only test.
  609. INSTANTIATE_TEST_SUITE_P(
  610. SPV_GOOGLE_decorate_string, ExtensionRoundTripTest,
  611. Combine(
  612. // We'll get coverage over operand tables by trying the universal
  613. // environments, and at least one specific environment.
  614. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  615. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0),
  616. ValuesIn(std::vector<AssemblyCase>{
  617. {"OpDecorateString %1 UserSemantic \"ABC\"\n",
  618. MakeInstruction(SpvOpDecorateStringGOOGLE,
  619. {1, SpvDecorationHlslSemanticGOOGLE},
  620. MakeVector("ABC"))},
  621. {"OpDecorateString %1 UserSemantic \"ABC\"\n",
  622. MakeInstruction(SpvOpDecorateString,
  623. {1, SpvDecorationUserSemantic},
  624. MakeVector("ABC"))},
  625. {"OpMemberDecorateString %1 3 UserSemantic \"DEF\"\n",
  626. MakeInstruction(SpvOpMemberDecorateStringGOOGLE,
  627. {1, 3, SpvDecorationUserSemantic},
  628. MakeVector("DEF"))},
  629. {"OpMemberDecorateString %1 3 UserSemantic \"DEF\"\n",
  630. MakeInstruction(SpvOpMemberDecorateString,
  631. {1, 3, SpvDecorationUserSemantic},
  632. MakeVector("DEF"))},
  633. })));
  634. INSTANTIATE_TEST_SUITE_P(
  635. SPV_GOOGLE_decorate_string, ExtensionAssemblyTest,
  636. Combine(
  637. // We'll get coverage over operand tables by trying the universal
  638. // environments, and at least one specific environment.
  639. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  640. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0),
  641. ValuesIn(std::vector<AssemblyCase>{
  642. {"OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE \"ABC\"\n",
  643. MakeInstruction(SpvOpDecorateStringGOOGLE,
  644. {1, SpvDecorationHlslSemanticGOOGLE},
  645. MakeVector("ABC"))},
  646. {"OpMemberDecorateStringGOOGLE %1 3 HlslSemanticGOOGLE \"DEF\"\n",
  647. MakeInstruction(SpvOpMemberDecorateStringGOOGLE,
  648. {1, 3, SpvDecorationHlslSemanticGOOGLE},
  649. MakeVector("DEF"))},
  650. })));
  651. // SPV_GOOGLE_hlsl_functionality1
  652. // Now that CounterBuffer is the preferred spelling for HlslCounterBufferGOOGLE,
  653. // use that name in round trip tests, and the GOOGLE name in an assembly-only
  654. // test.
  655. INSTANTIATE_TEST_SUITE_P(
  656. SPV_GOOGLE_hlsl_functionality1, ExtensionRoundTripTest,
  657. Combine(
  658. // We'll get coverage over operand tables by trying the universal
  659. // environments, and at least one specific environment.
  660. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  661. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0),
  662. // HlslSemanticGOOGLE is tested in SPV_GOOGLE_decorate_string, since
  663. // they are coupled together.
  664. ValuesIn(std::vector<AssemblyCase>{
  665. {"OpDecorateId %1 CounterBuffer %2\n",
  666. MakeInstruction(SpvOpDecorateId,
  667. {1, SpvDecorationHlslCounterBufferGOOGLE, 2})},
  668. {"OpDecorateId %1 CounterBuffer %2\n",
  669. MakeInstruction(SpvOpDecorateId,
  670. {1, SpvDecorationCounterBuffer, 2})},
  671. })));
  672. INSTANTIATE_TEST_SUITE_P(
  673. SPV_GOOGLE_hlsl_functionality1, ExtensionAssemblyTest,
  674. Combine(
  675. // We'll get coverage over operand tables by trying the universal
  676. // environments, and at least one specific environment.
  677. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  678. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0),
  679. // HlslSemanticGOOGLE is tested in SPV_GOOGLE_decorate_string, since
  680. // they are coupled together.
  681. ValuesIn(std::vector<AssemblyCase>{
  682. {"OpDecorateId %1 HlslCounterBufferGOOGLE %2\n",
  683. MakeInstruction(SpvOpDecorateId,
  684. {1, SpvDecorationHlslCounterBufferGOOGLE, 2})},
  685. })));
  686. // SPV_NV_viewport_array2
  687. INSTANTIATE_TEST_SUITE_P(
  688. SPV_NV_viewport_array2, ExtensionRoundTripTest,
  689. Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  690. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3,
  691. SPV_ENV_VULKAN_1_0, SPV_ENV_VULKAN_1_1),
  692. ValuesIn(std::vector<AssemblyCase>{
  693. {"OpExtension \"SPV_NV_viewport_array2\"\n",
  694. MakeInstruction(SpvOpExtension,
  695. MakeVector("SPV_NV_viewport_array2"))},
  696. // The EXT and NV extensions have the same token number for this
  697. // capability.
  698. {"OpCapability ShaderViewportIndexLayerEXT\n",
  699. MakeInstruction(SpvOpCapability,
  700. {SpvCapabilityShaderViewportIndexLayerNV})},
  701. // Check the new capability's token number
  702. {"OpCapability ShaderViewportIndexLayerEXT\n",
  703. MakeInstruction(SpvOpCapability, {5254})},
  704. // Decorations
  705. {"OpDecorate %1 ViewportRelativeNV\n",
  706. MakeInstruction(SpvOpDecorate,
  707. {1, SpvDecorationViewportRelativeNV})},
  708. {"OpDecorate %1 BuiltIn ViewportMaskNV\n",
  709. MakeInstruction(SpvOpDecorate, {1, SpvDecorationBuiltIn,
  710. SpvBuiltInViewportMaskNV})},
  711. })));
  712. // SPV_NV_shader_subgroup_partitioned
  713. INSTANTIATE_TEST_SUITE_P(
  714. SPV_NV_shader_subgroup_partitioned, ExtensionRoundTripTest,
  715. Combine(
  716. Values(SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_1),
  717. ValuesIn(std::vector<AssemblyCase>{
  718. {"OpExtension \"SPV_NV_shader_subgroup_partitioned\"\n",
  719. MakeInstruction(SpvOpExtension,
  720. MakeVector("SPV_NV_shader_subgroup_partitioned"))},
  721. {"OpCapability GroupNonUniformPartitionedNV\n",
  722. MakeInstruction(SpvOpCapability,
  723. {SpvCapabilityGroupNonUniformPartitionedNV})},
  724. // Check the new capability's token number
  725. {"OpCapability GroupNonUniformPartitionedNV\n",
  726. MakeInstruction(SpvOpCapability, {5297})},
  727. {"%2 = OpGroupNonUniformPartitionNV %1 %3\n",
  728. MakeInstruction(SpvOpGroupNonUniformPartitionNV, {1, 2, 3})},
  729. // Check the new instruction's token number
  730. {"%2 = OpGroupNonUniformPartitionNV %1 %3\n",
  731. MakeInstruction(static_cast<SpvOp>(5296), {1, 2, 3})},
  732. // Check the new group operations
  733. {"%2 = OpGroupIAdd %1 %3 PartitionedReduceNV %4\n",
  734. MakeInstruction(SpvOpGroupIAdd,
  735. {1, 2, 3, SpvGroupOperationPartitionedReduceNV,
  736. 4})},
  737. {"%2 = OpGroupIAdd %1 %3 PartitionedReduceNV %4\n",
  738. MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 6, 4})},
  739. {"%2 = OpGroupIAdd %1 %3 PartitionedInclusiveScanNV %4\n",
  740. MakeInstruction(SpvOpGroupIAdd,
  741. {1, 2, 3,
  742. SpvGroupOperationPartitionedInclusiveScanNV, 4})},
  743. {"%2 = OpGroupIAdd %1 %3 PartitionedInclusiveScanNV %4\n",
  744. MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 7, 4})},
  745. {"%2 = OpGroupIAdd %1 %3 PartitionedExclusiveScanNV %4\n",
  746. MakeInstruction(SpvOpGroupIAdd,
  747. {1, 2, 3,
  748. SpvGroupOperationPartitionedExclusiveScanNV, 4})},
  749. {"%2 = OpGroupIAdd %1 %3 PartitionedExclusiveScanNV %4\n",
  750. MakeInstruction(SpvOpGroupIAdd, {1, 2, 3, 8, 4})},
  751. })));
  752. // SPV_EXT_descriptor_indexing
  753. INSTANTIATE_TEST_SUITE_P(
  754. SPV_EXT_descriptor_indexing, ExtensionRoundTripTest,
  755. Combine(
  756. Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1,
  757. SPV_ENV_UNIVERSAL_1_2, SPV_ENV_UNIVERSAL_1_3, SPV_ENV_VULKAN_1_0,
  758. SPV_ENV_VULKAN_1_1),
  759. ValuesIn(std::vector<AssemblyCase>{
  760. {"OpExtension \"SPV_EXT_descriptor_indexing\"\n",
  761. MakeInstruction(SpvOpExtension,
  762. MakeVector("SPV_EXT_descriptor_indexing"))},
  763. // Check capabilities, by name
  764. {"OpCapability ShaderNonUniform\n",
  765. MakeInstruction(SpvOpCapability,
  766. {SpvCapabilityShaderNonUniformEXT})},
  767. {"OpCapability RuntimeDescriptorArray\n",
  768. MakeInstruction(SpvOpCapability,
  769. {SpvCapabilityRuntimeDescriptorArrayEXT})},
  770. {"OpCapability InputAttachmentArrayDynamicIndexing\n",
  771. MakeInstruction(
  772. SpvOpCapability,
  773. {SpvCapabilityInputAttachmentArrayDynamicIndexingEXT})},
  774. {"OpCapability UniformTexelBufferArrayDynamicIndexing\n",
  775. MakeInstruction(
  776. SpvOpCapability,
  777. {SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT})},
  778. {"OpCapability StorageTexelBufferArrayDynamicIndexing\n",
  779. MakeInstruction(
  780. SpvOpCapability,
  781. {SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT})},
  782. {"OpCapability UniformBufferArrayNonUniformIndexing\n",
  783. MakeInstruction(
  784. SpvOpCapability,
  785. {SpvCapabilityUniformBufferArrayNonUniformIndexingEXT})},
  786. {"OpCapability SampledImageArrayNonUniformIndexing\n",
  787. MakeInstruction(
  788. SpvOpCapability,
  789. {SpvCapabilitySampledImageArrayNonUniformIndexingEXT})},
  790. {"OpCapability StorageBufferArrayNonUniformIndexing\n",
  791. MakeInstruction(
  792. SpvOpCapability,
  793. {SpvCapabilityStorageBufferArrayNonUniformIndexingEXT})},
  794. {"OpCapability StorageImageArrayNonUniformIndexing\n",
  795. MakeInstruction(
  796. SpvOpCapability,
  797. {SpvCapabilityStorageImageArrayNonUniformIndexingEXT})},
  798. {"OpCapability InputAttachmentArrayNonUniformIndexing\n",
  799. MakeInstruction(
  800. SpvOpCapability,
  801. {SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT})},
  802. {"OpCapability UniformTexelBufferArrayNonUniformIndexing\n",
  803. MakeInstruction(
  804. SpvOpCapability,
  805. {SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT})},
  806. {"OpCapability StorageTexelBufferArrayNonUniformIndexing\n",
  807. MakeInstruction(
  808. SpvOpCapability,
  809. {SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT})},
  810. // Check capabilities, by number
  811. {"OpCapability ShaderNonUniform\n",
  812. MakeInstruction(SpvOpCapability, {5301})},
  813. {"OpCapability RuntimeDescriptorArray\n",
  814. MakeInstruction(SpvOpCapability, {5302})},
  815. {"OpCapability InputAttachmentArrayDynamicIndexing\n",
  816. MakeInstruction(SpvOpCapability, {5303})},
  817. {"OpCapability UniformTexelBufferArrayDynamicIndexing\n",
  818. MakeInstruction(SpvOpCapability, {5304})},
  819. {"OpCapability StorageTexelBufferArrayDynamicIndexing\n",
  820. MakeInstruction(SpvOpCapability, {5305})},
  821. {"OpCapability UniformBufferArrayNonUniformIndexing\n",
  822. MakeInstruction(SpvOpCapability, {5306})},
  823. {"OpCapability SampledImageArrayNonUniformIndexing\n",
  824. MakeInstruction(SpvOpCapability, {5307})},
  825. {"OpCapability StorageBufferArrayNonUniformIndexing\n",
  826. MakeInstruction(SpvOpCapability, {5308})},
  827. {"OpCapability StorageImageArrayNonUniformIndexing\n",
  828. MakeInstruction(SpvOpCapability, {5309})},
  829. {"OpCapability InputAttachmentArrayNonUniformIndexing\n",
  830. MakeInstruction(SpvOpCapability, {5310})},
  831. {"OpCapability UniformTexelBufferArrayNonUniformIndexing\n",
  832. MakeInstruction(SpvOpCapability, {5311})},
  833. {"OpCapability StorageTexelBufferArrayNonUniformIndexing\n",
  834. MakeInstruction(SpvOpCapability, {5312})},
  835. // Check the decoration token
  836. {"OpDecorate %1 NonUniform\n",
  837. MakeInstruction(SpvOpDecorate, {1, SpvDecorationNonUniformEXT})},
  838. {"OpDecorate %1 NonUniform\n",
  839. MakeInstruction(SpvOpDecorate, {1, 5300})},
  840. })));
  841. } // namespace
  842. } // namespace spvtools