instruction_test.cpp 49 KB

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