instruction_test.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570
  1. // Copyright (c) 2016 Google 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. #include "source/opt/instruction.h"
  15. #include <memory>
  16. #include <utility>
  17. #include <vector>
  18. #include "gmock/gmock.h"
  19. #include "source/opt/ir_context.h"
  20. #include "spirv-tools/libspirv.h"
  21. #include "test/opt/pass_fixture.h"
  22. #include "test/opt/pass_utils.h"
  23. #include "test/unit_spirv.h"
  24. namespace spvtools {
  25. namespace opt {
  26. namespace {
  27. using ::testing::Eq;
  28. using spvtest::MakeInstruction;
  29. using DescriptorTypeTest = PassTest<::testing::Test>;
  30. using OpaqueTypeTest = PassTest<::testing::Test>;
  31. using GetBaseTest = PassTest<::testing::Test>;
  32. using ValidBasePointerTest = PassTest<::testing::Test>;
  33. using VulkanBufferTest = PassTest<::testing::Test>;
  34. TEST(InstructionTest, CreateTrivial) {
  35. Instruction empty;
  36. EXPECT_EQ(spv::Op::OpNop, empty.opcode());
  37. EXPECT_EQ(0u, empty.type_id());
  38. EXPECT_EQ(0u, empty.result_id());
  39. EXPECT_EQ(0u, empty.NumOperands());
  40. EXPECT_EQ(0u, empty.NumOperandWords());
  41. EXPECT_EQ(0u, empty.NumInOperandWords());
  42. EXPECT_EQ(empty.cend(), empty.cbegin());
  43. EXPECT_EQ(empty.end(), empty.begin());
  44. }
  45. TEST(InstructionTest, CreateWithOpcodeAndNoOperands) {
  46. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  47. Instruction inst(&context, spv::Op::OpReturn);
  48. EXPECT_EQ(spv::Op::OpReturn, inst.opcode());
  49. EXPECT_EQ(0u, inst.type_id());
  50. EXPECT_EQ(0u, inst.result_id());
  51. EXPECT_EQ(0u, inst.NumOperands());
  52. EXPECT_EQ(0u, inst.NumOperandWords());
  53. EXPECT_EQ(0u, inst.NumInOperandWords());
  54. EXPECT_EQ(inst.cend(), inst.cbegin());
  55. EXPECT_EQ(inst.end(), inst.begin());
  56. }
  57. TEST(InstructionTest, OperandAsString) {
  58. Operand::OperandData abcde{0x64636261, 0x65};
  59. Operand operand(SPV_OPERAND_TYPE_LITERAL_STRING, std::move(abcde));
  60. EXPECT_EQ("abcde", operand.AsString());
  61. }
  62. TEST(InstructionTest, OperandAsLiteralUint64_32bits) {
  63. Operand::OperandData words{0x1234};
  64. Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
  65. EXPECT_EQ(uint64_t(0x1234), operand.AsLiteralUint64());
  66. }
  67. TEST(InstructionTest, OperandAsLiteralUint64_64bits) {
  68. Operand::OperandData words{0x1234, 0x89ab};
  69. Operand operand(SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER, std::move(words));
  70. EXPECT_EQ((uint64_t(0x89ab) << 32 | 0x1234), operand.AsLiteralUint64());
  71. }
  72. // The words for an OpTypeInt for 32-bit signed integer resulting in Id 44.
  73. uint32_t kSampleInstructionWords[] = {(4 << 16) | uint32_t(spv::Op::OpTypeInt),
  74. 44, 32, 1};
  75. // The operands that would be parsed from kSampleInstructionWords
  76. spv_parsed_operand_t kSampleParsedOperands[] = {
  77. {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0},
  78. {2, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 32},
  79. {3, 1, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_NUMBER_UNSIGNED_INT, 1},
  80. };
  81. // A valid parse of kSampleParsedOperands.
  82. spv_parsed_instruction_t kSampleParsedInstruction = {
  83. kSampleInstructionWords,
  84. uint16_t(4),
  85. uint16_t(spv::Op::OpTypeInt),
  86. SPV_EXT_INST_TYPE_NONE,
  87. 0, // type id
  88. 44, // result id
  89. kSampleParsedOperands,
  90. 3};
  91. // The words for an OpAccessChain instruction.
  92. uint32_t kSampleAccessChainInstructionWords[] = {
  93. (7 << 16) | uint32_t(spv::Op::OpAccessChain), 100, 101, 102, 103, 104, 105};
  94. // The operands that would be parsed from kSampleAccessChainInstructionWords.
  95. spv_parsed_operand_t kSampleAccessChainOperands[] = {
  96. {1, 1, SPV_OPERAND_TYPE_RESULT_ID, SPV_NUMBER_NONE, 0},
  97. {2, 1, SPV_OPERAND_TYPE_TYPE_ID, SPV_NUMBER_NONE, 0},
  98. {3, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
  99. {4, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
  100. {5, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
  101. {6, 1, SPV_OPERAND_TYPE_ID, SPV_NUMBER_NONE, 0},
  102. };
  103. // A valid parse of kSampleAccessChainInstructionWords
  104. spv_parsed_instruction_t kSampleAccessChainInstruction = {
  105. kSampleAccessChainInstructionWords,
  106. uint16_t(7),
  107. uint16_t(spv::Op::OpAccessChain),
  108. SPV_EXT_INST_TYPE_NONE,
  109. 100, // type id
  110. 101, // result id
  111. kSampleAccessChainOperands,
  112. 6};
  113. // The words for an OpControlBarrier instruction.
  114. uint32_t kSampleControlBarrierInstructionWords[] = {
  115. (4 << 16) | uint32_t(spv::Op::OpControlBarrier), 100, 101, 102};
  116. // The operands that would be parsed from kSampleControlBarrierInstructionWords.
  117. spv_parsed_operand_t kSampleControlBarrierOperands[] = {
  118. {1, 1, SPV_OPERAND_TYPE_SCOPE_ID, SPV_NUMBER_NONE, 0}, // Execution
  119. {2, 1, SPV_OPERAND_TYPE_SCOPE_ID, SPV_NUMBER_NONE, 0}, // Memory
  120. {3, 1, SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID, SPV_NUMBER_NONE,
  121. 0}, // Semantics
  122. };
  123. // A valid parse of kSampleControlBarrierInstructionWords
  124. spv_parsed_instruction_t kSampleControlBarrierInstruction = {
  125. kSampleControlBarrierInstructionWords,
  126. uint16_t(4),
  127. uint16_t(spv::Op::OpControlBarrier),
  128. SPV_EXT_INST_TYPE_NONE,
  129. 0, // type id
  130. 0, // result id
  131. kSampleControlBarrierOperands,
  132. 3};
  133. TEST(InstructionTest, CreateWithOpcodeAndOperands) {
  134. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  135. Instruction inst(&context, kSampleParsedInstruction);
  136. EXPECT_EQ(spv::Op::OpTypeInt, inst.opcode());
  137. EXPECT_EQ(0u, inst.type_id());
  138. EXPECT_EQ(44u, inst.result_id());
  139. EXPECT_EQ(3u, inst.NumOperands());
  140. EXPECT_EQ(3u, inst.NumOperandWords());
  141. EXPECT_EQ(2u, inst.NumInOperandWords());
  142. }
  143. TEST(InstructionTest, GetOperand) {
  144. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  145. Instruction inst(&context, kSampleParsedInstruction);
  146. EXPECT_THAT(inst.GetOperand(0).words, Eq(std::vector<uint32_t>{44}));
  147. EXPECT_THAT(inst.GetOperand(1).words, Eq(std::vector<uint32_t>{32}));
  148. EXPECT_THAT(inst.GetOperand(2).words, Eq(std::vector<uint32_t>{1}));
  149. }
  150. TEST(InstructionTest, GetInOperand) {
  151. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  152. Instruction inst(&context, kSampleParsedInstruction);
  153. EXPECT_THAT(inst.GetInOperand(0).words, Eq(std::vector<uint32_t>{32}));
  154. EXPECT_THAT(inst.GetInOperand(1).words, Eq(std::vector<uint32_t>{1}));
  155. }
  156. TEST(InstructionTest, OperandConstIterators) {
  157. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  158. Instruction inst(&context, kSampleParsedInstruction);
  159. // Spot check iteration across operands.
  160. auto cbegin = inst.cbegin();
  161. auto cend = inst.cend();
  162. EXPECT_NE(cend, inst.cbegin());
  163. auto citer = inst.cbegin();
  164. for (int i = 0; i < 3; ++i, ++citer) {
  165. const auto& operand = *citer;
  166. EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type));
  167. EXPECT_THAT(operand.words,
  168. Eq(std::vector<uint32_t>{kSampleInstructionWords[i + 1]}));
  169. EXPECT_NE(cend, citer);
  170. }
  171. EXPECT_EQ(cend, citer);
  172. // Check that cbegin and cend have not changed.
  173. EXPECT_EQ(cbegin, inst.cbegin());
  174. EXPECT_EQ(cend, inst.cend());
  175. // Check arithmetic.
  176. const Operand& operand2 = *(inst.cbegin() + 2);
  177. EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type);
  178. }
  179. TEST(InstructionTest, OperandIterators) {
  180. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  181. Instruction inst(&context, kSampleParsedInstruction);
  182. // Spot check iteration across operands, with mutable iterators.
  183. auto begin = inst.begin();
  184. auto end = inst.end();
  185. EXPECT_NE(end, inst.begin());
  186. auto iter = inst.begin();
  187. for (int i = 0; i < 3; ++i, ++iter) {
  188. const auto& operand = *iter;
  189. EXPECT_THAT(operand.type, Eq(kSampleParsedOperands[i].type));
  190. EXPECT_THAT(operand.words,
  191. Eq(std::vector<uint32_t>{kSampleInstructionWords[i + 1]}));
  192. EXPECT_NE(end, iter);
  193. }
  194. EXPECT_EQ(end, iter);
  195. // Check that begin and end have not changed.
  196. EXPECT_EQ(begin, inst.begin());
  197. EXPECT_EQ(end, inst.end());
  198. // Check arithmetic.
  199. Operand& operand2 = *(inst.begin() + 2);
  200. EXPECT_EQ(SPV_OPERAND_TYPE_LITERAL_INTEGER, operand2.type);
  201. // Check mutation through an iterator.
  202. operand2.type = SPV_OPERAND_TYPE_TYPE_ID;
  203. EXPECT_EQ(SPV_OPERAND_TYPE_TYPE_ID, (*(inst.cbegin() + 2)).type);
  204. }
  205. TEST(InstructionTest, ForInIdStandardIdTypes) {
  206. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  207. Instruction inst(&context, kSampleAccessChainInstruction);
  208. std::vector<uint32_t> ids;
  209. inst.ForEachInId([&ids](const uint32_t* idptr) { ids.push_back(*idptr); });
  210. EXPECT_THAT(ids, Eq(std::vector<uint32_t>{102, 103, 104, 105}));
  211. ids.clear();
  212. inst.ForEachInId([&ids](uint32_t* idptr) { ids.push_back(*idptr); });
  213. EXPECT_THAT(ids, Eq(std::vector<uint32_t>{102, 103, 104, 105}));
  214. }
  215. TEST(InstructionTest, ForInIdNonstandardIdTypes) {
  216. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  217. Instruction inst(&context, kSampleControlBarrierInstruction);
  218. std::vector<uint32_t> ids;
  219. inst.ForEachInId([&ids](const uint32_t* idptr) { ids.push_back(*idptr); });
  220. EXPECT_THAT(ids, Eq(std::vector<uint32_t>{100, 101, 102}));
  221. ids.clear();
  222. inst.ForEachInId([&ids](uint32_t* idptr) { ids.push_back(*idptr); });
  223. EXPECT_THAT(ids, Eq(std::vector<uint32_t>{100, 101, 102}));
  224. }
  225. TEST(InstructionTest, UniqueIds) {
  226. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  227. Instruction inst1(&context);
  228. Instruction inst2(&context);
  229. EXPECT_NE(inst1.unique_id(), inst2.unique_id());
  230. }
  231. TEST(InstructionTest, CloneUniqueIdDifferent) {
  232. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  233. Instruction inst(&context);
  234. std::unique_ptr<Instruction> clone(inst.Clone(&context));
  235. EXPECT_EQ(inst.context(), clone->context());
  236. EXPECT_NE(inst.unique_id(), clone->unique_id());
  237. }
  238. TEST(InstructionTest, CloneDifferentContext) {
  239. IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
  240. IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
  241. Instruction inst(&c1);
  242. std::unique_ptr<Instruction> clone(inst.Clone(&c2));
  243. EXPECT_EQ(&c1, inst.context());
  244. EXPECT_EQ(&c2, clone->context());
  245. EXPECT_NE(&c1, &c2);
  246. }
  247. TEST(InstructionTest, CloneDifferentContextDifferentUniqueId) {
  248. IRContext c1(SPV_ENV_UNIVERSAL_1_2, nullptr);
  249. IRContext c2(SPV_ENV_UNIVERSAL_1_2, nullptr);
  250. Instruction inst(&c1);
  251. Instruction other(&c2);
  252. std::unique_ptr<Instruction> clone(inst.Clone(&c2));
  253. EXPECT_EQ(&c2, clone->context());
  254. EXPECT_NE(other.unique_id(), clone->unique_id());
  255. }
  256. TEST(InstructionTest, EqualsEqualsOperator) {
  257. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  258. Instruction i1(&context);
  259. Instruction i2(&context);
  260. std::unique_ptr<Instruction> clone(i1.Clone(&context));
  261. EXPECT_TRUE(i1 == i1);
  262. EXPECT_FALSE(i1 == i2);
  263. EXPECT_FALSE(i1 == *clone);
  264. EXPECT_FALSE(i2 == *clone);
  265. }
  266. TEST(InstructionTest, LessThanOperator) {
  267. IRContext context(SPV_ENV_UNIVERSAL_1_2, nullptr);
  268. Instruction i1(&context);
  269. Instruction i2(&context);
  270. std::unique_ptr<Instruction> clone(i1.Clone(&context));
  271. EXPECT_TRUE(i1 < i2);
  272. EXPECT_TRUE(i1 < *clone);
  273. EXPECT_TRUE(i2 < *clone);
  274. }
  275. TEST_F(DescriptorTypeTest, StorageImage) {
  276. const std::string text = R"(
  277. OpCapability Shader
  278. %1 = OpExtInstImport "GLSL.std.450"
  279. OpMemoryModel Logical GLSL450
  280. OpEntryPoint Fragment %2 "main"
  281. OpExecutionMode %2 OriginUpperLeft
  282. OpSource GLSL 430
  283. OpName %3 "myStorageImage"
  284. OpDecorate %3 DescriptorSet 0
  285. OpDecorate %3 Binding 0
  286. %4 = OpTypeVoid
  287. %5 = OpTypeFunction %4
  288. %6 = OpTypeFloat 32
  289. %7 = OpTypeImage %6 2D 0 0 0 2 R32f
  290. %8 = OpTypePointer UniformConstant %7
  291. %3 = OpVariable %8 UniformConstant
  292. %2 = OpFunction %4 None %5
  293. %9 = OpLabel
  294. %10 = OpCopyObject %8 %3
  295. OpReturn
  296. OpFunctionEnd
  297. )";
  298. std::unique_ptr<IRContext> context =
  299. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  300. Instruction* type = context->get_def_use_mgr()->GetDef(8);
  301. EXPECT_TRUE(type->IsVulkanStorageImage());
  302. EXPECT_FALSE(type->IsVulkanSampledImage());
  303. EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
  304. EXPECT_FALSE(type->IsVulkanStorageBuffer());
  305. EXPECT_FALSE(type->IsVulkanUniformBuffer());
  306. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  307. EXPECT_FALSE(variable->IsReadOnlyPointer());
  308. Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
  309. EXPECT_FALSE(object_copy->IsReadOnlyPointer());
  310. }
  311. TEST_F(DescriptorTypeTest, SampledImage) {
  312. const std::string text = R"(
  313. OpCapability Shader
  314. %1 = OpExtInstImport "GLSL.std.450"
  315. OpMemoryModel Logical GLSL450
  316. OpEntryPoint Fragment %2 "main"
  317. OpExecutionMode %2 OriginUpperLeft
  318. OpSource GLSL 430
  319. OpName %3 "myStorageImage"
  320. OpDecorate %3 DescriptorSet 0
  321. OpDecorate %3 Binding 0
  322. %4 = OpTypeVoid
  323. %5 = OpTypeFunction %4
  324. %6 = OpTypeFloat 32
  325. %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
  326. %8 = OpTypePointer UniformConstant %7
  327. %3 = OpVariable %8 UniformConstant
  328. %2 = OpFunction %4 None %5
  329. %9 = OpLabel
  330. %10 = OpCopyObject %8 %3
  331. OpReturn
  332. OpFunctionEnd
  333. )";
  334. std::unique_ptr<IRContext> context =
  335. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  336. Instruction* type = context->get_def_use_mgr()->GetDef(8);
  337. EXPECT_FALSE(type->IsVulkanStorageImage());
  338. EXPECT_TRUE(type->IsVulkanSampledImage());
  339. EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
  340. EXPECT_FALSE(type->IsVulkanStorageBuffer());
  341. EXPECT_FALSE(type->IsVulkanUniformBuffer());
  342. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  343. EXPECT_TRUE(variable->IsReadOnlyPointer());
  344. Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
  345. EXPECT_TRUE(object_copy->IsReadOnlyPointer());
  346. }
  347. TEST_F(DescriptorTypeTest, StorageTexelBuffer) {
  348. const std::string text = R"(
  349. OpCapability Shader
  350. %1 = OpExtInstImport "GLSL.std.450"
  351. OpMemoryModel Logical GLSL450
  352. OpEntryPoint Fragment %2 "main"
  353. OpExecutionMode %2 OriginUpperLeft
  354. OpSource GLSL 430
  355. OpName %3 "myStorageImage"
  356. OpDecorate %3 DescriptorSet 0
  357. OpDecorate %3 Binding 0
  358. %4 = OpTypeVoid
  359. %5 = OpTypeFunction %4
  360. %6 = OpTypeFloat 32
  361. %7 = OpTypeImage %6 Buffer 0 0 0 2 R32f
  362. %8 = OpTypePointer UniformConstant %7
  363. %3 = OpVariable %8 UniformConstant
  364. %2 = OpFunction %4 None %5
  365. %9 = OpLabel
  366. %10 = OpCopyObject %8 %3
  367. OpReturn
  368. OpFunctionEnd
  369. )";
  370. std::unique_ptr<IRContext> context =
  371. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  372. Instruction* type = context->get_def_use_mgr()->GetDef(8);
  373. EXPECT_FALSE(type->IsVulkanStorageImage());
  374. EXPECT_FALSE(type->IsVulkanSampledImage());
  375. EXPECT_TRUE(type->IsVulkanStorageTexelBuffer());
  376. EXPECT_FALSE(type->IsVulkanStorageBuffer());
  377. EXPECT_FALSE(type->IsVulkanUniformBuffer());
  378. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  379. EXPECT_FALSE(variable->IsReadOnlyPointer());
  380. Instruction* object_copy = context->get_def_use_mgr()->GetDef(10);
  381. EXPECT_FALSE(object_copy->IsReadOnlyPointer());
  382. }
  383. TEST_F(DescriptorTypeTest, StorageBuffer) {
  384. const std::string text = R"(
  385. OpCapability Shader
  386. %1 = OpExtInstImport "GLSL.std.450"
  387. OpMemoryModel Logical GLSL450
  388. OpEntryPoint Fragment %2 "main"
  389. OpExecutionMode %2 OriginUpperLeft
  390. OpSource GLSL 430
  391. OpName %3 "myStorageImage"
  392. OpDecorate %3 DescriptorSet 0
  393. OpDecorate %3 Binding 0
  394. OpDecorate %9 BufferBlock
  395. %4 = OpTypeVoid
  396. %5 = OpTypeFunction %4
  397. %6 = OpTypeFloat 32
  398. %7 = OpTypeVector %6 4
  399. %8 = OpTypeRuntimeArray %7
  400. %9 = OpTypeStruct %8
  401. %10 = OpTypePointer Uniform %9
  402. %3 = OpVariable %10 Uniform
  403. %2 = OpFunction %4 None %5
  404. %11 = OpLabel
  405. %12 = OpCopyObject %8 %3
  406. OpReturn
  407. OpFunctionEnd
  408. )";
  409. std::unique_ptr<IRContext> context =
  410. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  411. Instruction* type = context->get_def_use_mgr()->GetDef(10);
  412. EXPECT_FALSE(type->IsVulkanStorageImage());
  413. EXPECT_FALSE(type->IsVulkanSampledImage());
  414. EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
  415. EXPECT_TRUE(type->IsVulkanStorageBuffer());
  416. EXPECT_FALSE(type->IsVulkanUniformBuffer());
  417. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  418. EXPECT_FALSE(variable->IsReadOnlyPointer());
  419. Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
  420. EXPECT_FALSE(object_copy->IsReadOnlyPointer());
  421. }
  422. TEST_F(DescriptorTypeTest, UniformBuffer) {
  423. const std::string text = R"(
  424. OpCapability Shader
  425. %1 = OpExtInstImport "GLSL.std.450"
  426. OpMemoryModel Logical GLSL450
  427. OpEntryPoint Fragment %2 "main"
  428. OpExecutionMode %2 OriginUpperLeft
  429. OpSource GLSL 430
  430. OpName %3 "myStorageImage"
  431. OpDecorate %3 DescriptorSet 0
  432. OpDecorate %3 Binding 0
  433. OpDecorate %9 Block
  434. %4 = OpTypeVoid
  435. %5 = OpTypeFunction %4
  436. %6 = OpTypeFloat 32
  437. %7 = OpTypeVector %6 4
  438. %8 = OpTypeRuntimeArray %7
  439. %9 = OpTypeStruct %8
  440. %10 = OpTypePointer Uniform %9
  441. %3 = OpVariable %10 Uniform
  442. %2 = OpFunction %4 None %5
  443. %11 = OpLabel
  444. %12 = OpCopyObject %10 %3
  445. OpReturn
  446. OpFunctionEnd
  447. )";
  448. std::unique_ptr<IRContext> context =
  449. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  450. Instruction* type = context->get_def_use_mgr()->GetDef(10);
  451. EXPECT_FALSE(type->IsVulkanStorageImage());
  452. EXPECT_FALSE(type->IsVulkanSampledImage());
  453. EXPECT_FALSE(type->IsVulkanStorageTexelBuffer());
  454. EXPECT_FALSE(type->IsVulkanStorageBuffer());
  455. EXPECT_TRUE(type->IsVulkanUniformBuffer());
  456. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  457. EXPECT_TRUE(variable->IsReadOnlyPointer());
  458. Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
  459. EXPECT_TRUE(object_copy->IsReadOnlyPointer());
  460. }
  461. TEST_F(DescriptorTypeTest, NonWritableIsReadOnly) {
  462. const std::string text = R"(
  463. OpCapability Shader
  464. %1 = OpExtInstImport "GLSL.std.450"
  465. OpMemoryModel Logical GLSL450
  466. OpEntryPoint Fragment %2 "main"
  467. OpExecutionMode %2 OriginUpperLeft
  468. OpSource GLSL 430
  469. OpName %3 "myStorageImage"
  470. OpDecorate %3 DescriptorSet 0
  471. OpDecorate %3 Binding 0
  472. OpDecorate %9 BufferBlock
  473. OpDecorate %3 NonWritable
  474. %4 = OpTypeVoid
  475. %5 = OpTypeFunction %4
  476. %6 = OpTypeFloat 32
  477. %7 = OpTypeVector %6 4
  478. %8 = OpTypeRuntimeArray %7
  479. %9 = OpTypeStruct %8
  480. %10 = OpTypePointer Uniform %9
  481. %3 = OpVariable %10 Uniform
  482. %2 = OpFunction %4 None %5
  483. %11 = OpLabel
  484. %12 = OpCopyObject %8 %3
  485. OpReturn
  486. OpFunctionEnd
  487. )";
  488. std::unique_ptr<IRContext> context =
  489. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  490. Instruction* variable = context->get_def_use_mgr()->GetDef(3);
  491. EXPECT_TRUE(variable->IsReadOnlyPointer());
  492. // This demonstrates that the check for whether a pointer is read-only is not
  493. // precise: copying a NonWritable-decorated variable can yield a pointer that
  494. // the check does not regard as read-only.
  495. Instruction* object_copy = context->get_def_use_mgr()->GetDef(12);
  496. EXPECT_FALSE(object_copy->IsReadOnlyPointer());
  497. }
  498. TEST_F(DescriptorTypeTest, AccessChainIntoReadOnlyStructIsReadOnly) {
  499. const std::string text = R"(
  500. OpCapability Shader
  501. %1 = OpExtInstImport "GLSL.std.450"
  502. OpMemoryModel Logical GLSL450
  503. OpEntryPoint Fragment %2 "main"
  504. OpExecutionMode %2 OriginUpperLeft
  505. OpSource ESSL 320
  506. OpMemberDecorate %3 0 Offset 0
  507. OpMemberDecorate %3 1 Offset 4
  508. OpDecorate %3 Block
  509. %4 = OpTypeVoid
  510. %5 = OpTypeFunction %4
  511. %6 = OpTypeInt 32 1
  512. %7 = OpTypePointer Function %6
  513. %8 = OpTypeFloat 32
  514. %3 = OpTypeStruct %6 %8
  515. %9 = OpTypePointer PushConstant %3
  516. %10 = OpVariable %9 PushConstant
  517. %11 = OpConstant %6 0
  518. %12 = OpTypePointer PushConstant %6
  519. %13 = OpConstant %6 1
  520. %14 = OpTypePointer PushConstant %8
  521. %2 = OpFunction %4 None %5
  522. %15 = OpLabel
  523. %16 = OpVariable %7 Function
  524. %17 = OpAccessChain %12 %10 %11
  525. %18 = OpAccessChain %14 %10 %13
  526. OpReturn
  527. OpFunctionEnd
  528. )";
  529. std::unique_ptr<IRContext> context =
  530. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  531. Instruction* push_constant_struct_variable =
  532. context->get_def_use_mgr()->GetDef(10);
  533. EXPECT_TRUE(push_constant_struct_variable->IsReadOnlyPointer());
  534. Instruction* push_constant_struct_field_0 =
  535. context->get_def_use_mgr()->GetDef(17);
  536. EXPECT_TRUE(push_constant_struct_field_0->IsReadOnlyPointer());
  537. Instruction* push_constant_struct_field_1 =
  538. context->get_def_use_mgr()->GetDef(18);
  539. EXPECT_TRUE(push_constant_struct_field_1->IsReadOnlyPointer());
  540. }
  541. TEST_F(DescriptorTypeTest, ReadOnlyPointerParameter) {
  542. const std::string text = R"(
  543. OpCapability Shader
  544. %1 = OpExtInstImport "GLSL.std.450"
  545. OpMemoryModel Logical GLSL450
  546. OpEntryPoint Fragment %2 "main"
  547. OpExecutionMode %2 OriginUpperLeft
  548. OpSource ESSL 320
  549. OpMemberDecorate %3 0 Offset 0
  550. OpMemberDecorate %3 1 Offset 4
  551. OpDecorate %3 Block
  552. %4 = OpTypeVoid
  553. %5 = OpTypeFunction %4
  554. %6 = OpTypeInt 32 1
  555. %7 = OpTypePointer Function %6
  556. %8 = OpTypeFloat 32
  557. %3 = OpTypeStruct %6 %8
  558. %9 = OpTypePointer PushConstant %3
  559. %10 = OpVariable %9 PushConstant
  560. %11 = OpConstant %6 0
  561. %12 = OpTypePointer PushConstant %6
  562. %13 = OpConstant %6 1
  563. %14 = OpTypePointer PushConstant %8
  564. %15 = OpTypeFunction %4 %9
  565. %2 = OpFunction %4 None %5
  566. %16 = OpLabel
  567. %17 = OpVariable %7 Function
  568. %18 = OpAccessChain %12 %10 %11
  569. %19 = OpAccessChain %14 %10 %13
  570. OpReturn
  571. OpFunctionEnd
  572. %20 = OpFunction %4 None %15
  573. %21 = OpFunctionParameter %9
  574. %22 = OpLabel
  575. OpReturn
  576. OpFunctionEnd
  577. )";
  578. std::unique_ptr<IRContext> context =
  579. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  580. Instruction* push_constant_struct_parameter =
  581. context->get_def_use_mgr()->GetDef(21);
  582. EXPECT_TRUE(push_constant_struct_parameter->IsReadOnlyPointer());
  583. }
  584. TEST_F(OpaqueTypeTest, BaseOpaqueTypesShader) {
  585. const std::string text = R"(
  586. OpCapability Shader
  587. %1 = OpExtInstImport "GLSL.std.450"
  588. OpMemoryModel Logical GLSL450
  589. OpEntryPoint Fragment %2 "main"
  590. OpExecutionMode %2 OriginUpperLeft
  591. OpSource GLSL 430
  592. %3 = OpTypeVoid
  593. %4 = OpTypeFunction %3
  594. %5 = OpTypeFloat 32
  595. %6 = OpTypeImage %5 2D 1 0 0 1 Unknown
  596. %7 = OpTypeSampler
  597. %8 = OpTypeSampledImage %6
  598. %9 = OpTypeRuntimeArray %5
  599. %2 = OpFunction %3 None %4
  600. %10 = OpLabel
  601. OpReturn
  602. OpFunctionEnd
  603. )";
  604. std::unique_ptr<IRContext> context =
  605. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  606. Instruction* image_type = context->get_def_use_mgr()->GetDef(6);
  607. EXPECT_TRUE(image_type->IsOpaqueType());
  608. Instruction* sampler_type = context->get_def_use_mgr()->GetDef(7);
  609. EXPECT_TRUE(sampler_type->IsOpaqueType());
  610. Instruction* sampled_image_type = context->get_def_use_mgr()->GetDef(8);
  611. EXPECT_TRUE(sampled_image_type->IsOpaqueType());
  612. Instruction* runtime_array_type = context->get_def_use_mgr()->GetDef(9);
  613. EXPECT_TRUE(runtime_array_type->IsOpaqueType());
  614. Instruction* float_type = context->get_def_use_mgr()->GetDef(5);
  615. EXPECT_FALSE(float_type->IsOpaqueType());
  616. Instruction* void_type = context->get_def_use_mgr()->GetDef(3);
  617. EXPECT_FALSE(void_type->IsOpaqueType());
  618. }
  619. TEST_F(OpaqueTypeTest, OpaqueStructTypes) {
  620. const std::string text = R"(
  621. OpCapability Shader
  622. %1 = OpExtInstImport "GLSL.std.450"
  623. OpMemoryModel Logical GLSL450
  624. OpEntryPoint Fragment %2 "main"
  625. OpExecutionMode %2 OriginUpperLeft
  626. OpSource GLSL 430
  627. %3 = OpTypeVoid
  628. %4 = OpTypeFunction %3
  629. %5 = OpTypeFloat 32
  630. %6 = OpTypeRuntimeArray %5
  631. %7 = OpTypeStruct %6 %6
  632. %8 = OpTypeStruct %5 %6
  633. %9 = OpTypeStruct %6 %5
  634. %10 = OpTypeStruct %7
  635. %2 = OpFunction %3 None %4
  636. %11 = OpLabel
  637. OpReturn
  638. OpFunctionEnd
  639. )";
  640. std::unique_ptr<IRContext> context =
  641. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  642. for (int i = 7; i <= 10; i++) {
  643. Instruction* type = context->get_def_use_mgr()->GetDef(i);
  644. EXPECT_TRUE(type->IsOpaqueType());
  645. }
  646. }
  647. TEST_F(GetBaseTest, SampleImage) {
  648. const std::string text = R"(
  649. OpCapability Shader
  650. %1 = OpExtInstImport "GLSL.std.450"
  651. OpMemoryModel Logical GLSL450
  652. OpEntryPoint Fragment %2 "main"
  653. OpExecutionMode %2 OriginUpperLeft
  654. OpSource GLSL 430
  655. OpName %3 "myStorageImage"
  656. OpDecorate %3 DescriptorSet 0
  657. OpDecorate %3 Binding 0
  658. %4 = OpTypeVoid
  659. %5 = OpTypeFunction %4
  660. %6 = OpTypeFloat 32
  661. %7 = OpTypeVector %6 2
  662. %8 = OpTypeVector %6 4
  663. %9 = OpConstant %6 0
  664. %10 = OpConstantComposite %7 %9 %9
  665. %11 = OpTypeImage %6 2D 0 0 0 1 R32f
  666. %12 = OpTypePointer UniformConstant %11
  667. %3 = OpVariable %12 UniformConstant
  668. %13 = OpTypeSampledImage %11
  669. %14 = OpTypeSampler
  670. %15 = OpTypePointer UniformConstant %14
  671. %16 = OpVariable %15 UniformConstant
  672. %2 = OpFunction %4 None %5
  673. %17 = OpLabel
  674. %18 = OpLoad %11 %3
  675. %19 = OpLoad %14 %16
  676. %20 = OpSampledImage %13 %18 %19
  677. %21 = OpImageSampleImplicitLod %8 %20 %10
  678. OpReturn
  679. OpFunctionEnd
  680. )";
  681. std::unique_ptr<IRContext> context =
  682. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  683. Instruction* load = context->get_def_use_mgr()->GetDef(21);
  684. Instruction* base = context->get_def_use_mgr()->GetDef(20);
  685. EXPECT_TRUE(load->GetBaseAddress() == base);
  686. }
  687. TEST_F(GetBaseTest, PtrAccessChain) {
  688. const std::string text = R"(
  689. OpCapability VariablePointers
  690. OpMemoryModel Logical GLSL450
  691. OpEntryPoint Fragment %1 "PSMain" %2
  692. OpExecutionMode %1 OriginUpperLeft
  693. %void = OpTypeVoid
  694. %4 = OpTypeFunction %void
  695. %float = OpTypeFloat 32
  696. %v4float = OpTypeVector %float 4
  697. %int = OpTypeInt 32 8388353
  698. %int_0 = OpConstant %int 0
  699. %_ptr_Function_v4float = OpTypePointer Function %v4float
  700. %2 = OpVariable %_ptr_Function_v4float Input
  701. %1 = OpFunction %void None %4
  702. %10 = OpLabel
  703. %11 = OpPtrAccessChain %_ptr_Function_v4float %2 %int_0
  704. %12 = OpLoad %v4float %11
  705. OpReturn
  706. OpFunctionEnd
  707. )";
  708. std::unique_ptr<IRContext> context =
  709. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  710. Instruction* load = context->get_def_use_mgr()->GetDef(12);
  711. Instruction* base = context->get_def_use_mgr()->GetDef(2);
  712. EXPECT_TRUE(load->GetBaseAddress() == base);
  713. }
  714. TEST_F(GetBaseTest, ImageRead) {
  715. const std::string text = R"(
  716. OpCapability Shader
  717. %1 = OpExtInstImport "GLSL.std.450"
  718. OpMemoryModel Logical GLSL450
  719. OpEntryPoint Fragment %2 "main"
  720. OpExecutionMode %2 OriginUpperLeft
  721. OpSource GLSL 430
  722. OpName %3 "myStorageImage"
  723. OpDecorate %3 DescriptorSet 0
  724. OpDecorate %3 Binding 0
  725. %4 = OpTypeVoid
  726. %5 = OpTypeFunction %4
  727. %6 = OpTypeInt 32 0
  728. %7 = OpTypeVector %6 2
  729. %8 = OpConstant %6 0
  730. %9 = OpConstantComposite %7 %8 %8
  731. %10 = OpTypeImage %6 2D 0 0 0 2 R32f
  732. %11 = OpTypePointer UniformConstant %10
  733. %3 = OpVariable %11 UniformConstant
  734. %2 = OpFunction %4 None %5
  735. %12 = OpLabel
  736. %13 = OpLoad %10 %3
  737. %14 = OpImageRead %6 %13 %9
  738. OpReturn
  739. OpFunctionEnd
  740. )";
  741. std::unique_ptr<IRContext> context =
  742. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  743. Instruction* load = context->get_def_use_mgr()->GetDef(14);
  744. Instruction* base = context->get_def_use_mgr()->GetDef(13);
  745. EXPECT_TRUE(load->GetBaseAddress() == base);
  746. }
  747. TEST_F(ValidBasePointerTest, OpSelectBadNoVariablePointersStorageBuffer) {
  748. const std::string text = R"(
  749. OpCapability Shader
  750. OpMemoryModel Logical GLSL450
  751. OpEntryPoint Fragment %1 "func"
  752. %2 = OpTypeVoid
  753. %3 = OpTypeInt 32 0
  754. %4 = OpTypePointer StorageBuffer %3
  755. %5 = OpVariable %4 StorageBuffer
  756. %6 = OpTypeFunction %2
  757. %7 = OpTypeBool
  758. %8 = OpConstantTrue %7
  759. %1 = OpFunction %2 None %6
  760. %9 = OpLabel
  761. %10 = OpSelect %4 %8 %5 %5
  762. OpReturn
  763. OpFunctionEnd
  764. )";
  765. std::unique_ptr<IRContext> context =
  766. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  767. EXPECT_NE(context, nullptr);
  768. Instruction* select = context->get_def_use_mgr()->GetDef(10);
  769. EXPECT_NE(select, nullptr);
  770. EXPECT_FALSE(select->IsValidBasePointer());
  771. }
  772. TEST_F(ValidBasePointerTest, OpSelectBadNoVariablePointers) {
  773. const std::string text = R"(
  774. OpCapability Shader
  775. OpCapability VariablePointersStorageBuffer
  776. OpMemoryModel Logical GLSL450
  777. OpEntryPoint Fragment %1 "func"
  778. %2 = OpTypeVoid
  779. %3 = OpTypeInt 32 0
  780. %4 = OpTypePointer Workgroup %3
  781. %5 = OpVariable %4 Workgroup
  782. %6 = OpTypeFunction %2
  783. %7 = OpTypeBool
  784. %8 = OpConstantTrue %7
  785. %1 = OpFunction %2 None %6
  786. %9 = OpLabel
  787. %10 = OpSelect %4 %8 %5 %5
  788. OpReturn
  789. OpFunctionEnd
  790. )";
  791. std::unique_ptr<IRContext> context =
  792. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  793. EXPECT_NE(context, nullptr);
  794. Instruction* select = context->get_def_use_mgr()->GetDef(10);
  795. EXPECT_NE(select, nullptr);
  796. EXPECT_FALSE(select->IsValidBasePointer());
  797. }
  798. TEST_F(ValidBasePointerTest, OpSelectGoodVariablePointersStorageBuffer) {
  799. const std::string text = R"(
  800. OpCapability Shader
  801. OpCapability VariablePointersStorageBuffer
  802. OpMemoryModel Logical GLSL450
  803. OpEntryPoint Fragment %1 "func"
  804. %2 = OpTypeVoid
  805. %3 = OpTypeInt 32 0
  806. %4 = OpTypePointer StorageBuffer %3
  807. %5 = OpVariable %4 StorageBuffer
  808. %6 = OpTypeFunction %2
  809. %7 = OpTypeBool
  810. %8 = OpConstantTrue %7
  811. %1 = OpFunction %2 None %6
  812. %9 = OpLabel
  813. %10 = OpSelect %4 %8 %5 %5
  814. OpReturn
  815. OpFunctionEnd
  816. )";
  817. std::unique_ptr<IRContext> context =
  818. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  819. EXPECT_NE(context, nullptr);
  820. Instruction* select = context->get_def_use_mgr()->GetDef(10);
  821. EXPECT_NE(select, nullptr);
  822. EXPECT_TRUE(select->IsValidBasePointer());
  823. }
  824. TEST_F(ValidBasePointerTest, OpSelectGoodVariablePointers) {
  825. const std::string text = R"(
  826. OpCapability Shader
  827. OpCapability VariablePointers
  828. OpMemoryModel Logical GLSL450
  829. OpEntryPoint Fragment %1 "func"
  830. %2 = OpTypeVoid
  831. %3 = OpTypeInt 32 0
  832. %4 = OpTypePointer Workgroup %3
  833. %5 = OpVariable %4 Workgroup
  834. %6 = OpTypeFunction %2
  835. %7 = OpTypeBool
  836. %8 = OpConstantTrue %7
  837. %1 = OpFunction %2 None %6
  838. %9 = OpLabel
  839. %10 = OpSelect %4 %8 %5 %5
  840. OpReturn
  841. OpFunctionEnd
  842. )";
  843. std::unique_ptr<IRContext> context =
  844. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  845. EXPECT_NE(context, nullptr);
  846. Instruction* select = context->get_def_use_mgr()->GetDef(10);
  847. EXPECT_NE(select, nullptr);
  848. EXPECT_TRUE(select->IsValidBasePointer());
  849. }
  850. TEST_F(ValidBasePointerTest, OpConstantNullBadNoVariablePointersStorageBuffer) {
  851. const std::string text = R"(
  852. OpCapability Shader
  853. OpMemoryModel Logical GLSL450
  854. OpEntryPoint Fragment %1 "func"
  855. %2 = OpTypeVoid
  856. %3 = OpTypeInt 32 0
  857. %4 = OpTypePointer StorageBuffer %3
  858. %5 = OpConstantNull %4
  859. %6 = OpTypeFunction %2
  860. %1 = OpFunction %2 None %6
  861. %7 = OpLabel
  862. OpReturn
  863. OpFunctionEnd
  864. )";
  865. std::unique_ptr<IRContext> context =
  866. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  867. EXPECT_NE(context, nullptr);
  868. Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
  869. EXPECT_NE(null_inst, nullptr);
  870. EXPECT_FALSE(null_inst->IsValidBasePointer());
  871. }
  872. TEST_F(ValidBasePointerTest, OpConstantNullBadNoVariablePointers) {
  873. const std::string text = R"(
  874. OpCapability Shader
  875. OpCapability VariablePointersStorageBuffer
  876. OpMemoryModel Logical GLSL450
  877. OpEntryPoint Fragment %1 "func"
  878. %2 = OpTypeVoid
  879. %3 = OpTypeInt 32 0
  880. %4 = OpTypePointer Workgroup %3
  881. %5 = OpConstantNull %4
  882. %6 = OpTypeFunction %2
  883. %1 = OpFunction %2 None %6
  884. %7 = OpLabel
  885. OpReturn
  886. OpFunctionEnd
  887. )";
  888. std::unique_ptr<IRContext> context =
  889. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  890. EXPECT_NE(context, nullptr);
  891. Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
  892. EXPECT_NE(null_inst, nullptr);
  893. EXPECT_FALSE(null_inst->IsValidBasePointer());
  894. }
  895. TEST_F(ValidBasePointerTest, OpConstantNullGoodVariablePointersStorageBuffer) {
  896. const std::string text = R"(
  897. OpCapability Shader
  898. OpCapability VariablePointersStorageBuffer
  899. OpMemoryModel Logical GLSL450
  900. OpEntryPoint Fragment %1 "func"
  901. %2 = OpTypeVoid
  902. %3 = OpTypeInt 32 0
  903. %4 = OpTypePointer StorageBuffer %3
  904. %5 = OpConstantNull %4
  905. %6 = OpTypeFunction %2
  906. %1 = OpFunction %2 None %6
  907. %9 = OpLabel
  908. OpReturn
  909. OpFunctionEnd
  910. )";
  911. std::unique_ptr<IRContext> context =
  912. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  913. EXPECT_NE(context, nullptr);
  914. Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
  915. EXPECT_NE(null_inst, nullptr);
  916. EXPECT_TRUE(null_inst->IsValidBasePointer());
  917. }
  918. TEST_F(ValidBasePointerTest, OpConstantNullGoodVariablePointers) {
  919. const std::string text = R"(
  920. OpCapability Shader
  921. OpCapability VariablePointers
  922. OpMemoryModel Logical GLSL450
  923. OpEntryPoint Fragment %1 "func"
  924. %2 = OpTypeVoid
  925. %3 = OpTypeInt 32 0
  926. %4 = OpTypePointer Workgroup %3
  927. %5 = OpConstantNull %4
  928. %6 = OpTypeFunction %2
  929. %1 = OpFunction %2 None %6
  930. %7 = OpLabel
  931. OpReturn
  932. OpFunctionEnd
  933. )";
  934. std::unique_ptr<IRContext> context =
  935. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  936. EXPECT_NE(context, nullptr);
  937. Instruction* null_inst = context->get_def_use_mgr()->GetDef(5);
  938. EXPECT_NE(null_inst, nullptr);
  939. EXPECT_TRUE(null_inst->IsValidBasePointer());
  940. }
  941. TEST_F(ValidBasePointerTest, OpPhiBadNoVariablePointersStorageBuffer) {
  942. const std::string text = R"(
  943. OpCapability Shader
  944. OpMemoryModel Logical GLSL450
  945. OpEntryPoint Fragment %1 "func"
  946. %2 = OpTypeVoid
  947. %3 = OpTypeInt 32 0
  948. %4 = OpTypePointer StorageBuffer %3
  949. %5 = OpVariable %4 StorageBuffer
  950. %6 = OpTypeFunction %2
  951. %1 = OpFunction %2 None %6
  952. %7 = OpLabel
  953. OpBranch %8
  954. %8 = OpLabel
  955. %9 = OpPhi %4 %5 %7
  956. OpReturn
  957. OpFunctionEnd
  958. )";
  959. std::unique_ptr<IRContext> context =
  960. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  961. EXPECT_NE(context, nullptr);
  962. Instruction* phi = context->get_def_use_mgr()->GetDef(9);
  963. EXPECT_NE(phi, nullptr);
  964. EXPECT_FALSE(phi->IsValidBasePointer());
  965. }
  966. TEST_F(ValidBasePointerTest, OpPhiBadNoVariablePointers) {
  967. const std::string text = R"(
  968. OpCapability Shader
  969. OpCapability VariablePointersStorageBuffer
  970. OpMemoryModel Logical GLSL450
  971. OpEntryPoint Fragment %1 "func"
  972. %2 = OpTypeVoid
  973. %3 = OpTypeInt 32 0
  974. %4 = OpTypePointer Workgroup %3
  975. %5 = OpVariable %4 Workgroup
  976. %6 = OpTypeFunction %2
  977. %1 = OpFunction %2 None %6
  978. %7 = OpLabel
  979. OpBranch %8
  980. %8 = OpLabel
  981. %9 = OpPhi %4 %5 %7
  982. OpReturn
  983. OpFunctionEnd
  984. )";
  985. std::unique_ptr<IRContext> context =
  986. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  987. EXPECT_NE(context, nullptr);
  988. Instruction* phi = context->get_def_use_mgr()->GetDef(9);
  989. EXPECT_NE(phi, nullptr);
  990. EXPECT_FALSE(phi->IsValidBasePointer());
  991. }
  992. TEST_F(ValidBasePointerTest, OpPhiGoodVariablePointersStorageBuffer) {
  993. const std::string text = R"(
  994. OpCapability Shader
  995. OpCapability VariablePointersStorageBuffer
  996. OpMemoryModel Logical GLSL450
  997. OpEntryPoint Fragment %1 "func"
  998. %2 = OpTypeVoid
  999. %3 = OpTypeInt 32 0
  1000. %4 = OpTypePointer StorageBuffer %3
  1001. %5 = OpVariable %4 StorageBuffer
  1002. %6 = OpTypeFunction %2
  1003. %1 = OpFunction %2 None %6
  1004. %7 = OpLabel
  1005. OpBranch %8
  1006. %8 = OpLabel
  1007. %9 = OpPhi %4 %5 %7
  1008. OpReturn
  1009. OpFunctionEnd
  1010. )";
  1011. std::unique_ptr<IRContext> context =
  1012. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1013. EXPECT_NE(context, nullptr);
  1014. Instruction* phi = context->get_def_use_mgr()->GetDef(9);
  1015. EXPECT_NE(phi, nullptr);
  1016. EXPECT_TRUE(phi->IsValidBasePointer());
  1017. }
  1018. TEST_F(ValidBasePointerTest, OpPhiGoodVariablePointers) {
  1019. const std::string text = R"(
  1020. OpCapability Shader
  1021. OpCapability VariablePointers
  1022. OpMemoryModel Logical GLSL450
  1023. OpEntryPoint Fragment %1 "func"
  1024. %2 = OpTypeVoid
  1025. %3 = OpTypeInt 32 0
  1026. %4 = OpTypePointer Workgroup %3
  1027. %5 = OpVariable %4 Workgroup
  1028. %6 = OpTypeFunction %2
  1029. %1 = OpFunction %2 None %6
  1030. %7 = OpLabel
  1031. OpBranch %8
  1032. %8 = OpLabel
  1033. %9 = OpPhi %4 %5 %7
  1034. OpReturn
  1035. OpFunctionEnd
  1036. )";
  1037. std::unique_ptr<IRContext> context =
  1038. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1039. EXPECT_NE(context, nullptr);
  1040. Instruction* phi = context->get_def_use_mgr()->GetDef(9);
  1041. EXPECT_NE(phi, nullptr);
  1042. EXPECT_TRUE(phi->IsValidBasePointer());
  1043. }
  1044. TEST_F(ValidBasePointerTest, OpFunctionCallBadNoVariablePointersStorageBuffer) {
  1045. const std::string text = R"(
  1046. OpCapability Shader
  1047. OpMemoryModel Logical GLSL450
  1048. OpEntryPoint Fragment %1 "func"
  1049. %2 = OpTypeVoid
  1050. %3 = OpTypeInt 32 0
  1051. %4 = OpTypePointer StorageBuffer %3
  1052. %5 = OpConstantNull %4
  1053. %6 = OpTypeFunction %2
  1054. %7 = OpTypeFunction %4
  1055. %1 = OpFunction %2 None %6
  1056. %8 = OpLabel
  1057. %9 = OpFunctionCall %4 %10
  1058. OpReturn
  1059. OpFunctionEnd
  1060. %10 = OpFunction %4 None %7
  1061. %11 = OpLabel
  1062. OpReturnValue %5
  1063. OpFunctionEnd
  1064. )";
  1065. std::unique_ptr<IRContext> context =
  1066. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1067. EXPECT_NE(context, nullptr);
  1068. Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
  1069. EXPECT_NE(null_inst, nullptr);
  1070. EXPECT_FALSE(null_inst->IsValidBasePointer());
  1071. }
  1072. TEST_F(ValidBasePointerTest, OpFunctionCallBadNoVariablePointers) {
  1073. const std::string text = R"(
  1074. OpCapability Shader
  1075. OpCapability VariablePointersStorageBuffer
  1076. OpMemoryModel Logical GLSL450
  1077. OpEntryPoint Fragment %1 "func"
  1078. %2 = OpTypeVoid
  1079. %3 = OpTypeInt 32 0
  1080. %4 = OpTypePointer Workgroup %3
  1081. %5 = OpConstantNull %4
  1082. %6 = OpTypeFunction %2
  1083. %7 = OpTypeFunction %4
  1084. %1 = OpFunction %2 None %6
  1085. %8 = OpLabel
  1086. %9 = OpFunctionCall %4 %10
  1087. OpReturn
  1088. OpFunctionEnd
  1089. %10 = OpFunction %4 None %7
  1090. %11 = OpLabel
  1091. OpReturnValue %5
  1092. OpFunctionEnd
  1093. )";
  1094. std::unique_ptr<IRContext> context =
  1095. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1096. EXPECT_NE(context, nullptr);
  1097. Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
  1098. EXPECT_NE(null_inst, nullptr);
  1099. EXPECT_FALSE(null_inst->IsValidBasePointer());
  1100. }
  1101. TEST_F(ValidBasePointerTest, OpFunctionCallGoodVariablePointersStorageBuffer) {
  1102. const std::string text = R"(
  1103. OpCapability Shader
  1104. OpCapability VariablePointersStorageBuffer
  1105. OpMemoryModel Logical GLSL450
  1106. OpEntryPoint Fragment %1 "func"
  1107. %2 = OpTypeVoid
  1108. %3 = OpTypeInt 32 0
  1109. %4 = OpTypePointer StorageBuffer %3
  1110. %5 = OpConstantNull %4
  1111. %6 = OpTypeFunction %2
  1112. %7 = OpTypeFunction %4
  1113. %1 = OpFunction %2 None %6
  1114. %8 = OpLabel
  1115. %9 = OpFunctionCall %4 %10
  1116. OpReturn
  1117. OpFunctionEnd
  1118. %10 = OpFunction %4 None %7
  1119. %11 = OpLabel
  1120. OpReturnValue %5
  1121. OpFunctionEnd
  1122. )";
  1123. std::unique_ptr<IRContext> context =
  1124. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1125. EXPECT_NE(context, nullptr);
  1126. Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
  1127. EXPECT_NE(null_inst, nullptr);
  1128. EXPECT_TRUE(null_inst->IsValidBasePointer());
  1129. }
  1130. TEST_F(ValidBasePointerTest, OpFunctionCallGoodVariablePointers) {
  1131. const std::string text = R"(
  1132. OpCapability Shader
  1133. OpCapability VariablePointers
  1134. OpMemoryModel Logical GLSL450
  1135. OpEntryPoint Fragment %1 "func"
  1136. %2 = OpTypeVoid
  1137. %3 = OpTypeInt 32 0
  1138. %4 = OpTypePointer Workgroup %3
  1139. %5 = OpConstantNull %4
  1140. %6 = OpTypeFunction %2
  1141. %7 = OpTypeFunction %4
  1142. %1 = OpFunction %2 None %6
  1143. %8 = OpLabel
  1144. %9 = OpFunctionCall %4 %10
  1145. OpReturn
  1146. OpFunctionEnd
  1147. %10 = OpFunction %4 None %7
  1148. %11 = OpLabel
  1149. OpReturnValue %5
  1150. OpFunctionEnd
  1151. )";
  1152. std::unique_ptr<IRContext> context =
  1153. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1154. EXPECT_NE(context, nullptr);
  1155. Instruction* null_inst = context->get_def_use_mgr()->GetDef(9);
  1156. EXPECT_NE(null_inst, nullptr);
  1157. EXPECT_TRUE(null_inst->IsValidBasePointer());
  1158. }
  1159. TEST_F(VulkanBufferTest, VulkanStorageBuffer) {
  1160. const std::string text = R"(
  1161. OpCapability Shader
  1162. OpCapability RuntimeDescriptorArray
  1163. OpMemoryModel Logical GLSL450
  1164. OpEntryPoint GLCompute %1 "main"
  1165. OpExecutionMode %1 LocalSize 1 1 1
  1166. OpDecorate %2 Block
  1167. OpMemberDecorate %2 0 Offset 0
  1168. OpDecorate %3 BufferBlock
  1169. OpMemberDecorate %3 0 Offset 0
  1170. %4 = OpTypeVoid
  1171. %5 = OpTypeInt 32 0
  1172. %2 = OpTypeStruct %5
  1173. %3 = OpTypeStruct %5
  1174. %6 = OpTypePointer StorageBuffer %2
  1175. %7 = OpTypePointer Uniform %2
  1176. %8 = OpTypePointer Uniform %3
  1177. %9 = OpConstant %5 1
  1178. %10 = OpTypeArray %2 %9
  1179. %11 = OpTypeArray %3 %9
  1180. %12 = OpTypePointer StorageBuffer %10
  1181. %13 = OpTypePointer Uniform %10
  1182. %14 = OpTypePointer Uniform %11
  1183. %15 = OpTypeRuntimeArray %2
  1184. %16 = OpTypeRuntimeArray %3
  1185. %17 = OpTypePointer StorageBuffer %15
  1186. %18 = OpTypePointer Uniform %15
  1187. %19 = OpTypePointer Uniform %16
  1188. %50 = OpTypeFunction %4
  1189. %1 = OpFunction %4 None %50
  1190. %51 = OpLabel
  1191. OpReturn
  1192. OpFunctionEnd
  1193. )";
  1194. std::unique_ptr<IRContext> context =
  1195. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1196. EXPECT_NE(context, nullptr);
  1197. // Standard SSBO and UBO
  1198. Instruction* inst = context->get_def_use_mgr()->GetDef(6);
  1199. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1200. inst = context->get_def_use_mgr()->GetDef(7);
  1201. EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
  1202. inst = context->get_def_use_mgr()->GetDef(8);
  1203. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1204. // Arrayed SSBO and UBO
  1205. inst = context->get_def_use_mgr()->GetDef(12);
  1206. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1207. inst = context->get_def_use_mgr()->GetDef(13);
  1208. EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
  1209. inst = context->get_def_use_mgr()->GetDef(14);
  1210. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1211. // Runtime arrayed SSBO and UBO
  1212. inst = context->get_def_use_mgr()->GetDef(17);
  1213. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1214. inst = context->get_def_use_mgr()->GetDef(18);
  1215. EXPECT_EQ(false, inst->IsVulkanStorageBuffer());
  1216. inst = context->get_def_use_mgr()->GetDef(19);
  1217. EXPECT_EQ(true, inst->IsVulkanStorageBuffer());
  1218. }
  1219. TEST_F(VulkanBufferTest, VulkanUniformBuffer) {
  1220. const std::string text = R"(
  1221. OpCapability Shader
  1222. OpCapability RuntimeDescriptorArray
  1223. OpMemoryModel Logical GLSL450
  1224. OpEntryPoint GLCompute %1 "main"
  1225. OpExecutionMode %1 LocalSize 1 1 1
  1226. OpDecorate %2 Block
  1227. OpMemberDecorate %2 0 Offset 0
  1228. OpDecorate %3 BufferBlock
  1229. OpMemberDecorate %3 0 Offset 0
  1230. %4 = OpTypeVoid
  1231. %5 = OpTypeInt 32 0
  1232. %2 = OpTypeStruct %5
  1233. %3 = OpTypeStruct %5
  1234. %6 = OpTypePointer StorageBuffer %2
  1235. %7 = OpTypePointer Uniform %2
  1236. %8 = OpTypePointer Uniform %3
  1237. %9 = OpConstant %5 1
  1238. %10 = OpTypeArray %2 %9
  1239. %11 = OpTypeArray %3 %9
  1240. %12 = OpTypePointer StorageBuffer %10
  1241. %13 = OpTypePointer Uniform %10
  1242. %14 = OpTypePointer Uniform %11
  1243. %15 = OpTypeRuntimeArray %2
  1244. %16 = OpTypeRuntimeArray %3
  1245. %17 = OpTypePointer StorageBuffer %15
  1246. %18 = OpTypePointer Uniform %15
  1247. %19 = OpTypePointer Uniform %16
  1248. %50 = OpTypeFunction %4
  1249. %1 = OpFunction %4 None %50
  1250. %51 = OpLabel
  1251. OpReturn
  1252. OpFunctionEnd
  1253. )";
  1254. std::unique_ptr<IRContext> context =
  1255. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1256. EXPECT_NE(context, nullptr);
  1257. // Standard SSBO and UBO
  1258. Instruction* inst = context->get_def_use_mgr()->GetDef(6);
  1259. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1260. inst = context->get_def_use_mgr()->GetDef(7);
  1261. EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
  1262. inst = context->get_def_use_mgr()->GetDef(8);
  1263. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1264. // Arrayed SSBO and UBO
  1265. inst = context->get_def_use_mgr()->GetDef(12);
  1266. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1267. inst = context->get_def_use_mgr()->GetDef(13);
  1268. EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
  1269. inst = context->get_def_use_mgr()->GetDef(14);
  1270. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1271. // Runtime arrayed SSBO and UBO
  1272. inst = context->get_def_use_mgr()->GetDef(17);
  1273. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1274. inst = context->get_def_use_mgr()->GetDef(18);
  1275. EXPECT_EQ(true, inst->IsVulkanUniformBuffer());
  1276. inst = context->get_def_use_mgr()->GetDef(19);
  1277. EXPECT_EQ(false, inst->IsVulkanUniformBuffer());
  1278. }
  1279. TEST_F(VulkanBufferTest, ImageQueries) {
  1280. const std::string text = R"(
  1281. OpCapability Shader
  1282. OpCapability ImageBuffer
  1283. OpCapability RuntimeDescriptorArray
  1284. OpMemoryModel Logical GLSL450
  1285. OpEntryPoint GLCompute %1 "main"
  1286. OpExecutionMode %1 LocalSize 1 1 1
  1287. %2 = OpTypeVoid
  1288. %3 = OpTypeFloat 32
  1289. %4 = OpTypeImage %3 Buffer 0 0 0 1 Rgba32f
  1290. %5 = OpTypeImage %3 Buffer 0 0 0 2 Rgba32f
  1291. %6 = OpTypeImage %3 2D 0 0 0 1 Rgba32f
  1292. %7 = OpTypeImage %3 2D 0 0 0 2 Rgba32f
  1293. %8 = OpTypePointer UniformConstant %4
  1294. %9 = OpTypePointer UniformConstant %5
  1295. %10 = OpTypePointer UniformConstant %6
  1296. %11 = OpTypePointer UniformConstant %7
  1297. %12 = OpTypeInt 32 0
  1298. %13 = OpConstant %12 1
  1299. %14 = OpTypeArray %4 %13
  1300. %15 = OpTypeArray %5 %13
  1301. %16 = OpTypeArray %6 %13
  1302. %17 = OpTypeArray %7 %13
  1303. %18 = OpTypePointer UniformConstant %14
  1304. %19 = OpTypePointer UniformConstant %15
  1305. %20 = OpTypePointer UniformConstant %16
  1306. %21 = OpTypePointer UniformConstant %17
  1307. %22 = OpTypeRuntimeArray %4
  1308. %23 = OpTypeRuntimeArray %5
  1309. %24 = OpTypeRuntimeArray %6
  1310. %25 = OpTypeRuntimeArray %7
  1311. %26 = OpTypePointer UniformConstant %22
  1312. %27 = OpTypePointer UniformConstant %23
  1313. %28 = OpTypePointer UniformConstant %24
  1314. %29 = OpTypePointer UniformConstant %25
  1315. %50 = OpTypeFunction %4
  1316. %1 = OpFunction %4 None %50
  1317. %51 = OpLabel
  1318. OpReturn
  1319. OpFunctionEnd
  1320. )";
  1321. std::unique_ptr<IRContext> context =
  1322. BuildModule(SPV_ENV_UNIVERSAL_1_3, nullptr, text);
  1323. EXPECT_NE(context, nullptr);
  1324. // Bare pointers
  1325. Instruction* inst = context->get_def_use_mgr()->GetDef(8);
  1326. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1327. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1328. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1329. inst = context->get_def_use_mgr()->GetDef(9);
  1330. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1331. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1332. EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
  1333. inst = context->get_def_use_mgr()->GetDef(10);
  1334. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1335. EXPECT_EQ(true, inst->IsVulkanSampledImage());
  1336. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1337. inst = context->get_def_use_mgr()->GetDef(11);
  1338. EXPECT_EQ(true, inst->IsVulkanStorageImage());
  1339. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1340. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1341. // Array pointers
  1342. inst = context->get_def_use_mgr()->GetDef(18);
  1343. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1344. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1345. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1346. inst = context->get_def_use_mgr()->GetDef(19);
  1347. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1348. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1349. EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
  1350. inst = context->get_def_use_mgr()->GetDef(20);
  1351. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1352. EXPECT_EQ(true, inst->IsVulkanSampledImage());
  1353. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1354. inst = context->get_def_use_mgr()->GetDef(21);
  1355. EXPECT_EQ(true, inst->IsVulkanStorageImage());
  1356. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1357. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1358. // Runtime array pointers
  1359. inst = context->get_def_use_mgr()->GetDef(26);
  1360. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1361. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1362. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1363. inst = context->get_def_use_mgr()->GetDef(27);
  1364. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1365. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1366. EXPECT_EQ(true, inst->IsVulkanStorageTexelBuffer());
  1367. inst = context->get_def_use_mgr()->GetDef(28);
  1368. EXPECT_EQ(false, inst->IsVulkanStorageImage());
  1369. EXPECT_EQ(true, inst->IsVulkanSampledImage());
  1370. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1371. inst = context->get_def_use_mgr()->GetDef(29);
  1372. EXPECT_EQ(true, inst->IsVulkanStorageImage());
  1373. EXPECT_EQ(false, inst->IsVulkanSampledImage());
  1374. EXPECT_EQ(false, inst->IsVulkanStorageTexelBuffer());
  1375. }
  1376. TEST_F(DescriptorTypeTest, GetShader100DebugOpcode) {
  1377. const std::string text = R"(
  1378. OpCapability Shader
  1379. %1 = OpExtInstImport "NonSemantic.Shader.DebugInfo.100"
  1380. %2 = OpString "ps.hlsl"
  1381. %3 = OpString "#line 1 \"ps.hlsl\""
  1382. %void = OpTypeVoid
  1383. %5 = OpExtInst %void %1 DebugExpression
  1384. %6 = OpExtInst %void %1 DebugSource %2 %3
  1385. )";
  1386. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1387. std::unique_ptr<IRContext> context =
  1388. BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
  1389. Instruction* debug_expression = context->get_def_use_mgr()->GetDef(5);
  1390. EXPECT_EQ(debug_expression->GetShader100DebugOpcode(),
  1391. NonSemanticShaderDebugInfo100DebugExpression);
  1392. Instruction* debug_source = context->get_def_use_mgr()->GetDef(6);
  1393. EXPECT_EQ(debug_source->GetShader100DebugOpcode(),
  1394. NonSemanticShaderDebugInfo100DebugSource);
  1395. // Test that an opcode larger than the max will return Max. This instruction
  1396. // cannot be in the assembly above because the assembler expects the string
  1397. // for the opcode, so we cannot use an arbitrary number. However, a binary
  1398. // file could have an arbitrary number.
  1399. std::unique_ptr<Instruction> past_max(debug_expression->Clone(context.get()));
  1400. const uint32_t kExtInstOpcodeInIndex = 1;
  1401. uint32_t large_opcode = NonSemanticShaderDebugInfo100InstructionsMax + 2;
  1402. past_max->SetInOperand(kExtInstOpcodeInIndex, {large_opcode});
  1403. EXPECT_EQ(past_max->GetShader100DebugOpcode(),
  1404. NonSemanticShaderDebugInfo100InstructionsMax);
  1405. // Test that an opcode without a value in the enum, but less than Max returns
  1406. // the same value.
  1407. uint32_t opcode = NonSemanticShaderDebugInfo100InstructionsMax - 2;
  1408. past_max->SetInOperand(kExtInstOpcodeInIndex, {opcode});
  1409. EXPECT_EQ(past_max->GetShader100DebugOpcode(), opcode);
  1410. }
  1411. } // namespace
  1412. } // namespace opt
  1413. } // namespace spvtools