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