val_interfaces_test.cpp 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959
  1. // Copyright (c) 2018 Google LLC.
  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 <string>
  15. #include "gmock/gmock.h"
  16. #include "test/unit_spirv.h"
  17. #include "test/val/val_fixtures.h"
  18. namespace spvtools {
  19. namespace val {
  20. namespace {
  21. using ::testing::HasSubstr;
  22. using ValidateInterfacesTest = spvtest::ValidateBase<bool>;
  23. TEST_F(ValidateInterfacesTest, EntryPointMissingInput) {
  24. std::string text = R"(
  25. OpCapability Shader
  26. OpMemoryModel Logical GLSL450
  27. OpEntryPoint Fragment %1 "func"
  28. OpExecutionMode %1 OriginUpperLeft
  29. %2 = OpTypeVoid
  30. %3 = OpTypeInt 32 0
  31. %4 = OpTypePointer Input %3
  32. %5 = OpVariable %4 Input
  33. %6 = OpTypeFunction %2
  34. %1 = OpFunction %2 None %6
  35. %7 = OpLabel
  36. %8 = OpLoad %3 %5
  37. OpReturn
  38. OpFunctionEnd
  39. )";
  40. CompileSuccessfully(text);
  41. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  42. EXPECT_THAT(
  43. getDiagnosticString(),
  44. HasSubstr(
  45. "Interface variable id <5> is used by entry point 'func' id <1>, "
  46. "but is not listed as an interface"));
  47. }
  48. TEST_F(ValidateInterfacesTest, EntryPointMissingOutput) {
  49. std::string text = R"(
  50. OpCapability Shader
  51. OpMemoryModel Logical GLSL450
  52. OpEntryPoint Fragment %1 "func"
  53. OpExecutionMode %1 OriginUpperLeft
  54. %2 = OpTypeVoid
  55. %3 = OpTypeInt 32 0
  56. %4 = OpTypePointer Output %3
  57. %5 = OpVariable %4 Output
  58. %6 = OpTypeFunction %2
  59. %1 = OpFunction %2 None %6
  60. %7 = OpLabel
  61. %8 = OpLoad %3 %5
  62. OpReturn
  63. OpFunctionEnd
  64. )";
  65. CompileSuccessfully(text);
  66. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  67. EXPECT_THAT(
  68. getDiagnosticString(),
  69. HasSubstr(
  70. "Interface variable id <5> is used by entry point 'func' id <1>, "
  71. "but is not listed as an interface"));
  72. }
  73. TEST_F(ValidateInterfacesTest, InterfaceMissingUseInSubfunction) {
  74. std::string text = R"(
  75. OpCapability Shader
  76. OpMemoryModel Logical GLSL450
  77. OpEntryPoint Fragment %1 "func"
  78. OpExecutionMode %1 OriginUpperLeft
  79. %2 = OpTypeVoid
  80. %3 = OpTypeInt 32 0
  81. %4 = OpTypePointer Input %3
  82. %5 = OpVariable %4 Input
  83. %6 = OpTypeFunction %2
  84. %1 = OpFunction %2 None %6
  85. %7 = OpLabel
  86. %8 = OpFunctionCall %2 %9
  87. OpReturn
  88. OpFunctionEnd
  89. %9 = OpFunction %2 None %6
  90. %10 = OpLabel
  91. %11 = OpLoad %3 %5
  92. OpReturn
  93. OpFunctionEnd
  94. )";
  95. CompileSuccessfully(text);
  96. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  97. EXPECT_THAT(
  98. getDiagnosticString(),
  99. HasSubstr(
  100. "Interface variable id <5> is used by entry point 'func' id <1>, "
  101. "but is not listed as an interface"));
  102. }
  103. TEST_F(ValidateInterfacesTest, TwoEntryPointsOneFunction) {
  104. std::string text = R"(
  105. OpCapability Shader
  106. OpMemoryModel Logical GLSL450
  107. OpEntryPoint Fragment %1 "func" %2
  108. OpEntryPoint Fragment %1 "func2"
  109. OpExecutionMode %1 OriginUpperLeft
  110. %3 = OpTypeVoid
  111. %4 = OpTypeInt 32 0
  112. %5 = OpTypePointer Input %4
  113. %2 = OpVariable %5 Input
  114. %6 = OpTypeFunction %3
  115. %1 = OpFunction %3 None %6
  116. %7 = OpLabel
  117. %8 = OpLoad %4 %2
  118. OpReturn
  119. OpFunctionEnd
  120. )";
  121. CompileSuccessfully(text);
  122. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  123. EXPECT_THAT(
  124. getDiagnosticString(),
  125. HasSubstr(
  126. "Interface variable id <2> is used by entry point 'func2' id <1>, "
  127. "but is not listed as an interface"));
  128. }
  129. TEST_F(ValidateInterfacesTest, MissingInterfaceThroughInitializer) {
  130. const std::string text = R"(
  131. OpCapability Shader
  132. OpCapability VariablePointers
  133. OpMemoryModel Logical GLSL450
  134. OpEntryPoint Fragment %1 "func"
  135. OpExecutionMode %1 OriginUpperLeft
  136. %2 = OpTypeVoid
  137. %3 = OpTypeInt 32 0
  138. %4 = OpTypePointer Input %3
  139. %5 = OpTypePointer Function %4
  140. %6 = OpVariable %4 Input
  141. %7 = OpTypeFunction %2
  142. %1 = OpFunction %2 None %7
  143. %8 = OpLabel
  144. %9 = OpVariable %5 Function %6
  145. OpReturn
  146. OpFunctionEnd
  147. )";
  148. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  149. ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  150. EXPECT_THAT(
  151. getDiagnosticString(),
  152. HasSubstr(
  153. "Interface variable id <6> is used by entry point 'func' id <1>, "
  154. "but is not listed as an interface"));
  155. }
  156. TEST_F(ValidateInterfacesTest, NonUniqueInterfacesSPV1p3) {
  157. const std::string text = R"(
  158. OpCapability Shader
  159. OpMemoryModel Logical GLSL450
  160. OpEntryPoint GLCompute %main "main" %var %var
  161. OpExecutionMode %main LocalSize 1 1 1
  162. %void = OpTypeVoid
  163. %uint = OpTypeInt 32 0
  164. %uint3 = OpTypeVector %uint 3
  165. %struct = OpTypeStruct %uint3
  166. %ptr_struct = OpTypePointer Input %struct
  167. %var = OpVariable %ptr_struct Input
  168. %func_ty = OpTypeFunction %void
  169. %main = OpFunction %void None %func_ty
  170. %1 = OpLabel
  171. OpReturn
  172. OpFunctionEnd
  173. )";
  174. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  175. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  176. }
  177. TEST_F(ValidateInterfacesTest, NonUniqueInterfacesSPV1p4) {
  178. const std::string text = R"(
  179. OpCapability Shader
  180. OpMemoryModel Logical GLSL450
  181. OpEntryPoint GLCompute %main "main" %var %var
  182. OpExecutionMode %main LocalSize 1 1 1
  183. OpName %main "main"
  184. OpName %var "var"
  185. %void = OpTypeVoid
  186. %uint = OpTypeInt 32 0
  187. %uint3 = OpTypeVector %uint 3
  188. %struct = OpTypeStruct %uint3
  189. %ptr_struct = OpTypePointer Input %struct
  190. %var = OpVariable %ptr_struct Input
  191. %func_ty = OpTypeFunction %void
  192. %main = OpFunction %void None %func_ty
  193. %1 = OpLabel
  194. OpReturn
  195. OpFunctionEnd
  196. )";
  197. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  198. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  199. EXPECT_THAT(
  200. getDiagnosticString(),
  201. HasSubstr("Non-unique OpEntryPoint interface '2[%var]' is disallowed"));
  202. }
  203. TEST_F(ValidateInterfacesTest, MissingGlobalVarSPV1p3) {
  204. const std::string text = R"(
  205. OpCapability Shader
  206. OpMemoryModel Logical GLSL450
  207. OpEntryPoint GLCompute %main "main"
  208. OpExecutionMode %main LocalSize 1 1 1
  209. %void = OpTypeVoid
  210. %uint = OpTypeInt 32 0
  211. %uint3 = OpTypeVector %uint 3
  212. %struct = OpTypeStruct %uint3
  213. %ptr_struct = OpTypePointer StorageBuffer %struct
  214. %var = OpVariable %ptr_struct StorageBuffer
  215. %func_ty = OpTypeFunction %void
  216. %main = OpFunction %void None %func_ty
  217. %1 = OpLabel
  218. %ld = OpLoad %struct %var
  219. OpReturn
  220. OpFunctionEnd
  221. )";
  222. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  223. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  224. }
  225. TEST_F(ValidateInterfacesTest, MissingGlobalVarSPV1p4) {
  226. const std::string text = R"(
  227. OpCapability Shader
  228. OpMemoryModel Logical GLSL450
  229. OpEntryPoint GLCompute %main "main"
  230. OpExecutionMode %main LocalSize 1 1 1
  231. OpName %var "var"
  232. %void = OpTypeVoid
  233. %uint = OpTypeInt 32 0
  234. %uint3 = OpTypeVector %uint 3
  235. %struct = OpTypeStruct %uint3
  236. %ptr_struct = OpTypePointer StorageBuffer %struct
  237. %var = OpVariable %ptr_struct StorageBuffer
  238. %func_ty = OpTypeFunction %void
  239. %main = OpFunction %void None %func_ty
  240. %1 = OpLabel
  241. %ld = OpLoad %struct %var
  242. OpReturn
  243. OpFunctionEnd
  244. )";
  245. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  246. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  247. EXPECT_THAT(getDiagnosticString(),
  248. HasSubstr("Interface variable id <2> is used by entry point "
  249. "'main' id <1>, but is not listed as an interface"));
  250. }
  251. TEST_F(ValidateInterfacesTest, FunctionInterfaceVarSPV1p3) {
  252. const std::string text = R"(
  253. OpCapability Shader
  254. OpMemoryModel Logical GLSL450
  255. OpEntryPoint GLCompute %main "main" %var
  256. OpExecutionMode %main LocalSize 1 1 1
  257. OpName %var "var"
  258. %void = OpTypeVoid
  259. %uint = OpTypeInt 32 0
  260. %uint3 = OpTypeVector %uint 3
  261. %struct = OpTypeStruct %uint3
  262. %ptr_struct = OpTypePointer Function %struct
  263. %func_ty = OpTypeFunction %void
  264. %main = OpFunction %void None %func_ty
  265. %1 = OpLabel
  266. %var = OpVariable %ptr_struct Function
  267. OpReturn
  268. OpFunctionEnd
  269. )";
  270. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  271. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  272. EXPECT_THAT(getDiagnosticString(),
  273. HasSubstr("OpEntryPoint interfaces must be OpVariables with "
  274. "Storage Class of Input(1) or Output(3). Found Storage "
  275. "Class 7 for Entry Point id 1."));
  276. }
  277. TEST_F(ValidateInterfacesTest, FunctionInterfaceVarSPV1p4) {
  278. const std::string text = R"(
  279. OpCapability Shader
  280. OpMemoryModel Logical GLSL450
  281. OpEntryPoint GLCompute %main "main" %var
  282. OpExecutionMode %main LocalSize 1 1 1
  283. OpName %var "var"
  284. %void = OpTypeVoid
  285. %uint = OpTypeInt 32 0
  286. %uint3 = OpTypeVector %uint 3
  287. %struct = OpTypeStruct %uint3
  288. %ptr_struct = OpTypePointer Function %struct
  289. %func_ty = OpTypeFunction %void
  290. %main = OpFunction %void None %func_ty
  291. %1 = OpLabel
  292. %var = OpVariable %ptr_struct Function
  293. OpReturn
  294. OpFunctionEnd
  295. )";
  296. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  297. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  298. EXPECT_THAT(
  299. getDiagnosticString(),
  300. HasSubstr("OpEntryPoint interfaces should only list global variables"));
  301. }
  302. TEST_F(ValidateInterfacesTest, ModuleSPV1p3ValidateSPV1p4_NotAllUsedGlobals) {
  303. const std::string text = R"(
  304. OpCapability Shader
  305. OpMemoryModel Logical GLSL450
  306. OpEntryPoint GLCompute %main "main"
  307. OpExecutionMode %main LocalSize 1 1 1
  308. OpName %var "var"
  309. %void = OpTypeVoid
  310. %uint = OpTypeInt 32 0
  311. %uint3 = OpTypeVector %uint 3
  312. %struct = OpTypeStruct %uint3
  313. %ptr_struct = OpTypePointer StorageBuffer %struct
  314. %var = OpVariable %ptr_struct StorageBuffer
  315. %func_ty = OpTypeFunction %void
  316. %main = OpFunction %void None %func_ty
  317. %1 = OpLabel
  318. %ld = OpLoad %struct %var
  319. OpReturn
  320. OpFunctionEnd
  321. )";
  322. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  323. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  324. }
  325. TEST_F(ValidateInterfacesTest, ModuleSPV1p3ValidateSPV1p4_DuplicateInterface) {
  326. const std::string text = R"(
  327. OpCapability Shader
  328. OpMemoryModel Logical GLSL450
  329. OpEntryPoint GLCompute %main "main" %gid %gid
  330. OpExecutionMode %main LocalSize 1 1 1
  331. OpDecorate %gid BuiltIn GlobalInvocationId
  332. %void = OpTypeVoid
  333. %int = OpTypeInt 32 0
  334. %int3 = OpTypeVector %int 3
  335. %ptr_input_int3 = OpTypePointer Input %int3
  336. %gid = OpVariable %ptr_input_int3 Input
  337. %void_fn = OpTypeFunction %void
  338. %main = OpFunction %void None %void_fn
  339. %entry = OpLabel
  340. OpReturn
  341. OpFunctionEnd
  342. )";
  343. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  344. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  345. }
  346. TEST_F(ValidateInterfacesTest, SPV14MultipleEntryPointsSameFunction) {
  347. const std::string text = R"(
  348. OpCapability Shader
  349. OpMemoryModel Logical GLSL450
  350. OpEntryPoint GLCompute %main "main1" %gid
  351. OpEntryPoint GLCompute %main "main2" %gid
  352. OpExecutionMode %main LocalSize 1 1 1
  353. OpDecorate %gid BuiltIn GlobalInvocationId
  354. %void = OpTypeVoid
  355. %int = OpTypeInt 32 0
  356. %int3 = OpTypeVector %int 3
  357. %ptr_input_int3 = OpTypePointer Input %int3
  358. %gid = OpVariable %ptr_input_int3 Input
  359. %void_fn = OpTypeFunction %void
  360. %main = OpFunction %void None %void_fn
  361. %entry = OpLabel
  362. OpReturn
  363. OpFunctionEnd
  364. )";
  365. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  366. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  367. }
  368. TEST_F(ValidateInterfacesTest, VulkanLocationsDoubleAssignmentVariable) {
  369. const std::string text = R"(
  370. OpCapability Shader
  371. OpMemoryModel Logical GLSL450
  372. OpEntryPoint Fragment %main "main" %var
  373. OpExecutionMode %main OriginUpperLeft
  374. OpDecorate %var Location 0
  375. OpDecorate %var Location 1
  376. %void = OpTypeVoid
  377. %void_fn = OpTypeFunction %void
  378. %float = OpTypeFloat 32
  379. %ptr_input_float = OpTypePointer Input %float
  380. %var = OpVariable %ptr_input_float Input
  381. %main = OpFunction %void None %void_fn
  382. %entry = OpLabel
  383. OpReturn
  384. OpFunctionEnd
  385. )";
  386. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  387. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  388. EXPECT_THAT(
  389. getDiagnosticString(),
  390. HasSubstr("decorated with Location multiple times is not allowed"));
  391. }
  392. TEST_F(ValidateInterfacesTest, VulkanLocationsVariableAndMemberAssigned) {
  393. const std::string text = R"(
  394. OpCapability Shader
  395. OpMemoryModel Logical GLSL450
  396. OpEntryPoint Fragment %main "main" %var
  397. OpExecutionMode %main OriginUpperLeft
  398. OpDecorate %var Location 0
  399. OpDecorate %struct Block
  400. OpMemberDecorate %struct 0 Location 0
  401. %void = OpTypeVoid
  402. %void_fn = OpTypeFunction %void
  403. %float = OpTypeFloat 32
  404. %struct = OpTypeStruct %float
  405. %ptr_input_struct = OpTypePointer Input %struct
  406. %var = OpVariable %ptr_input_struct Input
  407. %main = OpFunction %void None %void_fn
  408. %entry = OpLabel
  409. OpReturn
  410. OpFunctionEnd
  411. )";
  412. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  413. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  414. EXPECT_THAT(getDiagnosticString(),
  415. AnyVUID("VUID-StandaloneSpirv-Location-04918"));
  416. EXPECT_THAT(getDiagnosticString(),
  417. HasSubstr("Members cannot be assigned a location"));
  418. }
  419. TEST_F(ValidateInterfacesTest, VulkanLocationsMemberAndSubMemberAssigned) {
  420. const std::string text = R"(
  421. OpCapability Shader
  422. OpMemoryModel Logical GLSL450
  423. OpEntryPoint Fragment %main "main" %var
  424. OpExecutionMode %main OriginUpperLeft
  425. OpDecorate %outer Block
  426. OpMemberDecorate %outer 0 Location 0
  427. OpMemberDecorate %struct 0 Location 0
  428. %void = OpTypeVoid
  429. %void_fn = OpTypeFunction %void
  430. %float = OpTypeFloat 32
  431. %struct = OpTypeStruct %float
  432. %outer = OpTypeStruct %struct
  433. %ptr_input_outer = OpTypePointer Input %outer
  434. %var = OpVariable %ptr_input_outer Input
  435. %main = OpFunction %void None %void_fn
  436. %entry = OpLabel
  437. OpReturn
  438. OpFunctionEnd
  439. )";
  440. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  441. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  442. EXPECT_THAT(getDiagnosticString(),
  443. AnyVUID("VUID-StandaloneSpirv-Location-04918"));
  444. EXPECT_THAT(getDiagnosticString(),
  445. HasSubstr("Members cannot be assigned a location"));
  446. }
  447. TEST_F(ValidateInterfacesTest, VulkanLocationsDoubleAssignmentStructMember) {
  448. const std::string text = R"(
  449. OpCapability Shader
  450. OpMemoryModel Logical GLSL450
  451. OpEntryPoint Fragment %main "main" %var
  452. OpExecutionMode %main OriginUpperLeft
  453. OpDecorate %struct Block
  454. OpMemberDecorate %struct 1 Location 0
  455. OpMemberDecorate %struct 1 Location 1
  456. %void = OpTypeVoid
  457. %void_fn = OpTypeFunction %void
  458. %float = OpTypeFloat 32
  459. %struct = OpTypeStruct %float %float
  460. %ptr_input_struct = OpTypePointer Input %struct
  461. %var = OpVariable %ptr_input_struct Input
  462. %main = OpFunction %void None %void_fn
  463. %entry = OpLabel
  464. OpReturn
  465. OpFunctionEnd
  466. )";
  467. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  468. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  469. EXPECT_THAT(
  470. getDiagnosticString(),
  471. HasSubstr("decorated with Location multiple times is not allowed"));
  472. }
  473. TEST_F(ValidateInterfacesTest, VulkanLocationsMissingAssignmentStructMember) {
  474. const std::string text = R"(
  475. OpCapability Shader
  476. OpMemoryModel Logical GLSL450
  477. OpEntryPoint Fragment %main "main" %var
  478. OpExecutionMode %main OriginUpperLeft
  479. OpDecorate %struct Block
  480. OpMemberDecorate %struct 1 Location 1
  481. %void = OpTypeVoid
  482. %void_fn = OpTypeFunction %void
  483. %float = OpTypeFloat 32
  484. %struct = OpTypeStruct %float %float
  485. %ptr_input_struct = OpTypePointer Input %struct
  486. %var = OpVariable %ptr_input_struct Input
  487. %main = OpFunction %void None %void_fn
  488. %entry = OpLabel
  489. OpReturn
  490. OpFunctionEnd
  491. )";
  492. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  493. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  494. EXPECT_THAT(getDiagnosticString(),
  495. HasSubstr("Member index 0 is missing a location assignment"));
  496. }
  497. TEST_F(ValidateInterfacesTest, VulkanLocationsMissingAssignmentNonBlockStruct) {
  498. const std::string text = R"(
  499. OpCapability Shader
  500. OpMemoryModel Logical GLSL450
  501. OpEntryPoint Fragment %main "main" %var
  502. OpExecutionMode %main OriginUpperLeft
  503. %void = OpTypeVoid
  504. %void_fn = OpTypeFunction %void
  505. %float = OpTypeFloat 32
  506. %struct = OpTypeStruct %float %float
  507. %ptr_input_struct = OpTypePointer Input %struct
  508. %var = OpVariable %ptr_input_struct Input
  509. %main = OpFunction %void None %void_fn
  510. %entry = OpLabel
  511. OpReturn
  512. OpFunctionEnd
  513. )";
  514. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  515. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  516. EXPECT_THAT(getDiagnosticString(),
  517. HasSubstr("Variable must be decorated with a location"));
  518. }
  519. TEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictInput) {
  520. const std::string text = R"(
  521. OpCapability Shader
  522. OpMemoryModel Logical GLSL450
  523. OpEntryPoint Fragment %main "main" %var1 %var2
  524. OpExecutionMode %main OriginUpperLeft
  525. OpDecorate %var1 Location 0
  526. OpDecorate %var2 Location 0
  527. %void = OpTypeVoid
  528. %void_fn = OpTypeFunction %void
  529. %float = OpTypeFloat 32
  530. %struct = OpTypeStruct %float %float
  531. %ptr_input_struct = OpTypePointer Input %struct
  532. %var1 = OpVariable %ptr_input_struct Input
  533. %var2 = OpVariable %ptr_input_struct Input
  534. %main = OpFunction %void None %void_fn
  535. %entry = OpLabel
  536. OpReturn
  537. OpFunctionEnd
  538. )";
  539. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  540. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  541. EXPECT_THAT(getDiagnosticString(),
  542. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  543. EXPECT_THAT(getDiagnosticString(),
  544. HasSubstr("Entry-point has conflicting input location assignment "
  545. "at location 0"));
  546. }
  547. TEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictOutput) {
  548. const std::string text = R"(
  549. OpCapability Shader
  550. OpMemoryModel Logical GLSL450
  551. OpEntryPoint Fragment %main "main" %var1 %var2
  552. OpExecutionMode %main OriginUpperLeft
  553. OpDecorate %var1 Location 1
  554. OpDecorate %var2 Location 1
  555. %void = OpTypeVoid
  556. %void_fn = OpTypeFunction %void
  557. %float = OpTypeFloat 32
  558. %struct = OpTypeStruct %float %float
  559. %ptr_output_struct = OpTypePointer Output %struct
  560. %var1 = OpVariable %ptr_output_struct Output
  561. %var2 = OpVariable %ptr_output_struct Output
  562. %main = OpFunction %void None %void_fn
  563. %entry = OpLabel
  564. OpReturn
  565. OpFunctionEnd
  566. )";
  567. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  568. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  569. EXPECT_THAT(getDiagnosticString(),
  570. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
  571. EXPECT_THAT(
  572. getDiagnosticString(),
  573. HasSubstr("Entry-point has conflicting output location assignment "
  574. "at location 1"));
  575. }
  576. TEST_F(ValidateInterfacesTest, VulkanPatchAndNonPatchOverlap) {
  577. const std::string text = R"(
  578. OpCapability Tessellation
  579. OpMemoryModel Logical GLSL450
  580. OpEntryPoint TessellationControl %main "main" %a %b
  581. OpExecutionMode %main OutputVertices 4
  582. OpDecorate %a Location 0
  583. OpDecorate %b Patch
  584. OpDecorate %b Location 0
  585. %void = OpTypeVoid
  586. %3 = OpTypeFunction %void
  587. %float = OpTypeFloat 32
  588. %uint = OpTypeInt 32 0
  589. %uint_4 = OpConstant %uint 4
  590. %_arr_float_uint_4 = OpTypeArray %float %uint_4
  591. %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
  592. %a = OpVariable %_ptr_Output__arr_float_uint_4 Output
  593. %_ptr_Output_float = OpTypePointer Output %float
  594. %b = OpVariable %_ptr_Output_float Output
  595. %main = OpFunction %void None %3
  596. %5 = OpLabel
  597. OpReturn
  598. OpFunctionEnd
  599. )";
  600. CompileSuccessfully(text, SPV_ENV_VULKAN_1_2);
  601. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  602. }
  603. TEST_F(ValidateInterfacesTest, VulkanPatchOverlap) {
  604. const std::string text = R"(
  605. OpCapability Tessellation
  606. OpMemoryModel Logical GLSL450
  607. OpEntryPoint TessellationControl %main "main" %a %b %c
  608. OpExecutionMode %main OutputVertices 4
  609. OpDecorate %a Location 0
  610. OpDecorate %b Patch
  611. OpDecorate %b Location 6
  612. OpDecorate %c Patch
  613. OpDecorate %c Location 6
  614. %void = OpTypeVoid
  615. %3 = OpTypeFunction %void
  616. %float = OpTypeFloat 32
  617. %uint = OpTypeInt 32 0
  618. %uint_4 = OpConstant %uint 4
  619. %_arr_float_uint_4 = OpTypeArray %float %uint_4
  620. %_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
  621. %a = OpVariable %_ptr_Output__arr_float_uint_4 Output
  622. %_ptr_Output_float = OpTypePointer Output %float
  623. %b = OpVariable %_ptr_Output_float Output
  624. %c = OpVariable %_ptr_Output_float Output
  625. %main = OpFunction %void None %3
  626. %5 = OpLabel
  627. OpReturn
  628. OpFunctionEnd
  629. )";
  630. CompileSuccessfully(text, SPV_ENV_VULKAN_1_2);
  631. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  632. EXPECT_THAT(getDiagnosticString(),
  633. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
  634. EXPECT_THAT(getDiagnosticString(),
  635. HasSubstr("Entry-point has conflicting output location "
  636. "assignment at location 6, component 0"));
  637. }
  638. TEST_F(ValidateInterfacesTest,
  639. VulkanLocationsSameLocationInputAndOutputNoConflict) {
  640. const std::string text = R"(
  641. OpCapability Shader
  642. OpMemoryModel Logical GLSL450
  643. OpEntryPoint Fragment %main "main" %var1 %var2
  644. OpExecutionMode %main OriginUpperLeft
  645. OpDecorate %var1 Location 1
  646. OpDecorate %var2 Location 1
  647. %void = OpTypeVoid
  648. %void_fn = OpTypeFunction %void
  649. %float = OpTypeFloat 32
  650. %struct = OpTypeStruct %float %float
  651. %ptr_input_struct = OpTypePointer Input %struct
  652. %ptr_output_struct = OpTypePointer Output %struct
  653. %var1 = OpVariable %ptr_input_struct Input
  654. %var2 = OpVariable %ptr_output_struct Output
  655. %main = OpFunction %void None %void_fn
  656. %entry = OpLabel
  657. OpReturn
  658. OpFunctionEnd
  659. )";
  660. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  661. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  662. }
  663. TEST_F(ValidateInterfacesTest, VulkanLocationsVariableInGap) {
  664. const std::string text = R"(
  665. OpCapability Shader
  666. OpMemoryModel Logical GLSL450
  667. OpEntryPoint Fragment %main "main" %var1 %var2
  668. OpExecutionMode %main OriginUpperLeft
  669. OpDecorate %struct Block
  670. OpMemberDecorate %struct 0 Location 0
  671. OpMemberDecorate %struct 1 Location 2
  672. OpDecorate %var2 Location 1
  673. %void = OpTypeVoid
  674. %void_fn = OpTypeFunction %void
  675. %float = OpTypeFloat 32
  676. %struct = OpTypeStruct %float %float
  677. %ptr_input_struct = OpTypePointer Input %struct
  678. %ptr_input_float = OpTypePointer Input %float
  679. %var1 = OpVariable %ptr_input_struct Input
  680. %var2 = OpVariable %ptr_input_float Input
  681. %main = OpFunction %void None %void_fn
  682. %entry = OpLabel
  683. OpReturn
  684. OpFunctionEnd
  685. )";
  686. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  687. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  688. }
  689. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeFloatVectorConflict) {
  690. const std::string text = R"(
  691. OpCapability Shader
  692. OpCapability Float64
  693. OpMemoryModel Logical GLSL450
  694. OpEntryPoint Fragment %main "main" %var1 %var2
  695. OpExecutionMode %main OriginUpperLeft
  696. OpDecorate %var1 Location 0
  697. OpDecorate %var2 Location 1
  698. %void = OpTypeVoid
  699. %void_fn = OpTypeFunction %void
  700. %float = OpTypeFloat 32
  701. %double = OpTypeFloat 64
  702. %vector = OpTypeVector %double 3
  703. %ptr_input_float = OpTypePointer Input %float
  704. %ptr_input_vector = OpTypePointer Input %vector
  705. %var1 = OpVariable %ptr_input_vector Input
  706. %var2 = OpVariable %ptr_input_float Input
  707. %main = OpFunction %void None %void_fn
  708. %entry = OpLabel
  709. OpReturn
  710. OpFunctionEnd
  711. )";
  712. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  713. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  714. EXPECT_THAT(getDiagnosticString(),
  715. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  716. EXPECT_THAT(getDiagnosticString(),
  717. HasSubstr("Entry-point has conflicting input location assignment "
  718. "at location 1"));
  719. }
  720. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeIntVectorConflict) {
  721. const std::string text = R"(
  722. OpCapability Shader
  723. OpCapability Int64
  724. OpMemoryModel Logical GLSL450
  725. OpEntryPoint Fragment %main "main" %var1 %var2
  726. OpExecutionMode %main OriginUpperLeft
  727. OpDecorate %var1 Location 0
  728. OpDecorate %var1 Flat
  729. OpDecorate %var2 Location 1
  730. OpDecorate %var2 Flat
  731. %void = OpTypeVoid
  732. %void_fn = OpTypeFunction %void
  733. %float = OpTypeFloat 32
  734. %long = OpTypeInt 64 0
  735. %vector = OpTypeVector %long 4
  736. %ptr_input_float = OpTypePointer Input %float
  737. %ptr_input_vector = OpTypePointer Input %vector
  738. %var1 = OpVariable %ptr_input_vector Input
  739. %var2 = OpVariable %ptr_input_float Input
  740. %main = OpFunction %void None %void_fn
  741. %entry = OpLabel
  742. OpReturn
  743. OpFunctionEnd
  744. )";
  745. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  746. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  747. EXPECT_THAT(getDiagnosticString(),
  748. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  749. EXPECT_THAT(getDiagnosticString(),
  750. HasSubstr("Entry-point has conflicting input location assignment "
  751. "at location 1"));
  752. }
  753. TEST_F(ValidateInterfacesTest, VulkanLocationsMatrix2x2Conflict) {
  754. const std::string text = R"(
  755. OpCapability Shader
  756. OpMemoryModel Logical GLSL450
  757. OpEntryPoint Fragment %main "main" %var1 %var2
  758. OpExecutionMode %main OriginUpperLeft
  759. OpDecorate %var1 Location 0
  760. OpDecorate %var2 Location 1
  761. %void = OpTypeVoid
  762. %void_fn = OpTypeFunction %void
  763. %float = OpTypeFloat 32
  764. %vector = OpTypeVector %float 2
  765. %matrix = OpTypeMatrix %vector 2
  766. %ptr_input_float = OpTypePointer Input %float
  767. %ptr_input_matrix = OpTypePointer Input %matrix
  768. %var1 = OpVariable %ptr_input_matrix Input
  769. %var2 = OpVariable %ptr_input_float Input
  770. %main = OpFunction %void None %void_fn
  771. %entry = OpLabel
  772. OpReturn
  773. OpFunctionEnd
  774. )";
  775. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  776. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  777. EXPECT_THAT(getDiagnosticString(),
  778. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  779. EXPECT_THAT(getDiagnosticString(),
  780. HasSubstr("Entry-point has conflicting input location assignment "
  781. "at location 1"));
  782. }
  783. TEST_F(ValidateInterfacesTest, VulkanLocationsMatrix3x3Conflict) {
  784. const std::string text = R"(
  785. OpCapability Shader
  786. OpMemoryModel Logical GLSL450
  787. OpEntryPoint Fragment %main "main" %var1 %var2
  788. OpExecutionMode %main OriginUpperLeft
  789. OpDecorate %var1 Location 0
  790. OpDecorate %var2 Location 2
  791. %void = OpTypeVoid
  792. %void_fn = OpTypeFunction %void
  793. %float = OpTypeFloat 32
  794. %vector = OpTypeVector %float 3
  795. %matrix = OpTypeMatrix %vector 3
  796. %ptr_input_float = OpTypePointer Input %float
  797. %ptr_input_matrix = OpTypePointer Input %matrix
  798. %var1 = OpVariable %ptr_input_matrix Input
  799. %var2 = OpVariable %ptr_input_float Input
  800. %main = OpFunction %void None %void_fn
  801. %entry = OpLabel
  802. OpReturn
  803. OpFunctionEnd
  804. )";
  805. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  806. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  807. EXPECT_THAT(getDiagnosticString(),
  808. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  809. EXPECT_THAT(getDiagnosticString(),
  810. HasSubstr("Entry-point has conflicting input location assignment "
  811. "at location 2"));
  812. }
  813. TEST_F(ValidateInterfacesTest, VulkanLocationsMatrix4x4Conflict) {
  814. const std::string text = R"(
  815. OpCapability Shader
  816. OpMemoryModel Logical GLSL450
  817. OpEntryPoint Fragment %main "main" %var1 %var2
  818. OpExecutionMode %main OriginUpperLeft
  819. OpDecorate %var1 Location 0
  820. OpDecorate %var2 Location 3
  821. %void = OpTypeVoid
  822. %void_fn = OpTypeFunction %void
  823. %float = OpTypeFloat 32
  824. %vector = OpTypeVector %float 4
  825. %matrix = OpTypeMatrix %vector 4
  826. %ptr_input_float = OpTypePointer Input %float
  827. %ptr_input_matrix = OpTypePointer Input %matrix
  828. %var1 = OpVariable %ptr_input_matrix Input
  829. %var2 = OpVariable %ptr_input_float Input
  830. %main = OpFunction %void None %void_fn
  831. %entry = OpLabel
  832. OpReturn
  833. OpFunctionEnd
  834. )";
  835. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  836. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  837. EXPECT_THAT(getDiagnosticString(),
  838. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  839. EXPECT_THAT(getDiagnosticString(),
  840. HasSubstr("Entry-point has conflicting input location assignment "
  841. "at location 3"));
  842. }
  843. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix2x2Conflict) {
  844. const std::string text = R"(
  845. OpCapability Shader
  846. OpCapability Float64
  847. OpMemoryModel Logical GLSL450
  848. OpEntryPoint Fragment %main "main" %var1 %var2
  849. OpExecutionMode %main OriginUpperLeft
  850. OpDecorate %var1 Location 0
  851. OpDecorate %var2 Location 1
  852. %void = OpTypeVoid
  853. %void_fn = OpTypeFunction %void
  854. %float = OpTypeFloat 32
  855. %double = OpTypeFloat 64
  856. %vector = OpTypeVector %double 2
  857. %matrix = OpTypeMatrix %vector 2
  858. %ptr_input_float = OpTypePointer Input %float
  859. %ptr_input_matrix = OpTypePointer Input %matrix
  860. %var1 = OpVariable %ptr_input_matrix Input
  861. %var2 = OpVariable %ptr_input_float Input
  862. %main = OpFunction %void None %void_fn
  863. %entry = OpLabel
  864. OpReturn
  865. OpFunctionEnd
  866. )";
  867. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  868. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  869. EXPECT_THAT(getDiagnosticString(),
  870. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  871. EXPECT_THAT(getDiagnosticString(),
  872. HasSubstr("Entry-point has conflicting input location assignment "
  873. "at location 1"));
  874. }
  875. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix3x3Conflict) {
  876. const std::string text = R"(
  877. OpCapability Shader
  878. OpCapability Float64
  879. OpMemoryModel Logical GLSL450
  880. OpEntryPoint Fragment %main "main" %var1 %var2
  881. OpExecutionMode %main OriginUpperLeft
  882. OpDecorate %var1 Location 0
  883. OpDecorate %var2 Location 5
  884. %void = OpTypeVoid
  885. %void_fn = OpTypeFunction %void
  886. %float = OpTypeFloat 32
  887. %double = OpTypeFloat 64
  888. %vector = OpTypeVector %double 3
  889. %matrix = OpTypeMatrix %vector 3
  890. %ptr_input_float = OpTypePointer Input %float
  891. %ptr_input_matrix = OpTypePointer Input %matrix
  892. %var1 = OpVariable %ptr_input_matrix Input
  893. %var2 = OpVariable %ptr_input_float Input
  894. %main = OpFunction %void None %void_fn
  895. %entry = OpLabel
  896. OpReturn
  897. OpFunctionEnd
  898. )";
  899. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  900. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  901. EXPECT_THAT(getDiagnosticString(),
  902. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  903. EXPECT_THAT(getDiagnosticString(),
  904. HasSubstr("Entry-point has conflicting input location assignment "
  905. "at location 5"));
  906. }
  907. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeMatrix4x4Conflict) {
  908. const std::string text = R"(
  909. OpCapability Shader
  910. OpCapability Float64
  911. OpMemoryModel Logical GLSL450
  912. OpEntryPoint Fragment %main "main" %var1 %var2
  913. OpExecutionMode %main OriginUpperLeft
  914. OpDecorate %var1 Location 0
  915. OpDecorate %var2 Location 7
  916. %void = OpTypeVoid
  917. %void_fn = OpTypeFunction %void
  918. %float = OpTypeFloat 32
  919. %double = OpTypeFloat 64
  920. %vector = OpTypeVector %double 4
  921. %matrix = OpTypeMatrix %vector 4
  922. %ptr_input_float = OpTypePointer Input %float
  923. %ptr_input_matrix = OpTypePointer Input %matrix
  924. %var1 = OpVariable %ptr_input_matrix Input
  925. %var2 = OpVariable %ptr_input_float Input
  926. %main = OpFunction %void None %void_fn
  927. %entry = OpLabel
  928. OpReturn
  929. OpFunctionEnd
  930. )";
  931. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  932. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  933. EXPECT_THAT(getDiagnosticString(),
  934. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  935. EXPECT_THAT(getDiagnosticString(),
  936. HasSubstr("Entry-point has conflicting input location assignment "
  937. "at location 7"));
  938. }
  939. TEST_F(ValidateInterfacesTest, VulkanLocationsArray2Conflict) {
  940. const std::string text = R"(
  941. OpCapability Shader
  942. OpMemoryModel Logical GLSL450
  943. OpEntryPoint Fragment %main "main" %var1 %var2
  944. OpExecutionMode %main OriginUpperLeft
  945. OpDecorate %var1 Location 0
  946. OpDecorate %var2 Location 1
  947. %void = OpTypeVoid
  948. %void_fn = OpTypeFunction %void
  949. %float = OpTypeFloat 32
  950. %int = OpTypeInt 32 0
  951. %int_2 = OpConstant %int 2
  952. %array = OpTypeArray %int %int_2
  953. %struct = OpTypeStruct %array
  954. %ptr_input_float = OpTypePointer Input %float
  955. %ptr_input_struct = OpTypePointer Input %struct
  956. %var1 = OpVariable %ptr_input_struct Input
  957. %var2 = OpVariable %ptr_input_float Input
  958. %main = OpFunction %void None %void_fn
  959. %entry = OpLabel
  960. OpReturn
  961. OpFunctionEnd
  962. )";
  963. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  964. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  965. EXPECT_THAT(getDiagnosticString(),
  966. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  967. EXPECT_THAT(getDiagnosticString(),
  968. HasSubstr("Entry-point has conflicting input location assignment "
  969. "at location 1"));
  970. }
  971. TEST_F(ValidateInterfacesTest, VulkanLocationsArray4Conflict) {
  972. const std::string text = R"(
  973. OpCapability Shader
  974. OpMemoryModel Logical GLSL450
  975. OpEntryPoint Fragment %main "main" %var1 %var2
  976. OpExecutionMode %main OriginUpperLeft
  977. OpDecorate %var1 Location 0
  978. OpDecorate %var2 Location 3
  979. %void = OpTypeVoid
  980. %void_fn = OpTypeFunction %void
  981. %float = OpTypeFloat 32
  982. %int = OpTypeInt 32 0
  983. %int_4 = OpConstant %int 4
  984. %array = OpTypeArray %int %int_4
  985. %struct = OpTypeStruct %array
  986. %ptr_input_float = OpTypePointer Input %float
  987. %ptr_input_struct = OpTypePointer Input %struct
  988. %var1 = OpVariable %ptr_input_struct Input
  989. %var2 = OpVariable %ptr_input_float Input
  990. %main = OpFunction %void None %void_fn
  991. %entry = OpLabel
  992. OpReturn
  993. OpFunctionEnd
  994. )";
  995. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  996. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  997. EXPECT_THAT(getDiagnosticString(),
  998. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  999. EXPECT_THAT(getDiagnosticString(),
  1000. HasSubstr("Entry-point has conflicting input location assignment "
  1001. "at location 3"));
  1002. }
  1003. TEST_F(ValidateInterfacesTest, VulkanLocationsMatrix4x4Array4Conflict) {
  1004. const std::string text = R"(
  1005. OpCapability Shader
  1006. OpMemoryModel Logical GLSL450
  1007. OpEntryPoint Fragment %main "main" %var1 %var2
  1008. OpExecutionMode %main OriginUpperLeft
  1009. OpDecorate %var1 Location 0
  1010. OpDecorate %var2 Location 15
  1011. %void = OpTypeVoid
  1012. %void_fn = OpTypeFunction %void
  1013. %float = OpTypeFloat 32
  1014. %int = OpTypeInt 32 0
  1015. %int_4 = OpConstant %int 4
  1016. %vector = OpTypeVector %float 4
  1017. %matrix = OpTypeMatrix %vector 4
  1018. %array = OpTypeArray %matrix %int_4
  1019. %struct = OpTypeStruct %array
  1020. %ptr_input_float = OpTypePointer Input %float
  1021. %ptr_input_struct = OpTypePointer Input %struct
  1022. %var1 = OpVariable %ptr_input_struct Input
  1023. %var2 = OpVariable %ptr_input_float Input
  1024. %main = OpFunction %void None %void_fn
  1025. %entry = OpLabel
  1026. OpReturn
  1027. OpFunctionEnd
  1028. )";
  1029. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1030. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1031. EXPECT_THAT(getDiagnosticString(),
  1032. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  1033. EXPECT_THAT(getDiagnosticString(),
  1034. HasSubstr("Entry-point has conflicting input location assignment "
  1035. "at location 15"));
  1036. }
  1037. TEST_F(ValidateInterfacesTest, VulkanLocationsComponentDisambiguates) {
  1038. const std::string text = R"(
  1039. OpCapability Shader
  1040. OpMemoryModel Logical GLSL450
  1041. OpEntryPoint Fragment %main "main" %var1
  1042. OpExecutionMode %main OriginUpperLeft
  1043. OpDecorate %struct Block
  1044. OpMemberDecorate %struct 0 Location 0
  1045. OpMemberDecorate %struct 0 Component 0
  1046. OpMemberDecorate %struct 1 Location 0
  1047. OpMemberDecorate %struct 1 Component 1
  1048. %void = OpTypeVoid
  1049. %void_fn = OpTypeFunction %void
  1050. %float = OpTypeFloat 32
  1051. %struct = OpTypeStruct %float %float
  1052. %ptr_input_struct = OpTypePointer Input %struct
  1053. %var1 = OpVariable %ptr_input_struct Input
  1054. %main = OpFunction %void None %void_fn
  1055. %entry = OpLabel
  1056. OpReturn
  1057. OpFunctionEnd
  1058. )";
  1059. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1060. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1061. }
  1062. TEST_F(ValidateInterfacesTest, VulkanLocationsComponentIn64BitVec3) {
  1063. const std::string text = R"(
  1064. OpCapability Shader
  1065. OpCapability Float64
  1066. OpMemoryModel Logical GLSL450
  1067. OpEntryPoint Fragment %main "main" %var
  1068. OpExecutionMode %main OriginUpperLeft
  1069. OpDecorate %struct Block
  1070. OpMemberDecorate %struct 0 Location 0
  1071. OpMemberDecorate %struct 1 Location 1
  1072. OpMemberDecorate %struct 1 Component 1
  1073. %void = OpTypeVoid
  1074. %void_fn = OpTypeFunction %void
  1075. %float = OpTypeFloat 32
  1076. %double = OpTypeFloat 64
  1077. %double3 = OpTypeVector %double 3
  1078. %struct = OpTypeStruct %double3 %float
  1079. %ptr_input_struct = OpTypePointer Input %struct
  1080. %var = OpVariable %ptr_input_struct Input
  1081. %main = OpFunction %void None %void_fn
  1082. %entry = OpLabel
  1083. OpReturn
  1084. OpFunctionEnd
  1085. )";
  1086. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1087. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1088. EXPECT_THAT(getDiagnosticString(),
  1089. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  1090. EXPECT_THAT(getDiagnosticString(),
  1091. HasSubstr("Entry-point has conflicting input location assignment "
  1092. "at location 1, component 1"));
  1093. }
  1094. TEST_F(ValidateInterfacesTest, VulkanLocationsComponentAfter64BitVec3) {
  1095. const std::string text = R"(
  1096. OpCapability Shader
  1097. OpCapability Float64
  1098. OpMemoryModel Logical GLSL450
  1099. OpEntryPoint Fragment %main "main" %var
  1100. OpExecutionMode %main OriginUpperLeft
  1101. OpDecorate %struct Block
  1102. OpMemberDecorate %struct 0 Location 0
  1103. OpMemberDecorate %struct 1 Location 1
  1104. OpMemberDecorate %struct 1 Component 2
  1105. %void = OpTypeVoid
  1106. %void_fn = OpTypeFunction %void
  1107. %float = OpTypeFloat 32
  1108. %double = OpTypeFloat 64
  1109. %double3 = OpTypeVector %double 3
  1110. %struct = OpTypeStruct %double3 %float
  1111. %ptr_input_struct = OpTypePointer Input %struct
  1112. %var = OpVariable %ptr_input_struct Input
  1113. %main = OpFunction %void None %void_fn
  1114. %entry = OpLabel
  1115. OpReturn
  1116. OpFunctionEnd
  1117. )";
  1118. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1119. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1120. }
  1121. TEST_F(ValidateInterfacesTest, VulkanLocationsConflictingComponentVariable) {
  1122. const std::string text = R"(
  1123. OpCapability Shader
  1124. OpMemoryModel Logical GLSL450
  1125. OpEntryPoint Fragment %main "main" %var
  1126. OpExecutionMode %main OriginUpperLeft
  1127. OpDecorate %var Location 0
  1128. OpDecorate %var Component 0
  1129. OpDecorate %var Component 1
  1130. %void = OpTypeVoid
  1131. %void_fn = OpTypeFunction %void
  1132. %float = OpTypeFloat 32
  1133. %ptr_input_float = OpTypePointer Input %float
  1134. %var = OpVariable %ptr_input_float Input
  1135. %main = OpFunction %void None %void_fn
  1136. %entry = OpLabel
  1137. OpReturn
  1138. OpFunctionEnd
  1139. )";
  1140. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1141. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1142. EXPECT_THAT(
  1143. getDiagnosticString(),
  1144. HasSubstr("decorated with Component multiple times is not allowed"));
  1145. }
  1146. TEST_F(ValidateInterfacesTest,
  1147. VulkanLocationsConflictingComponentStructMember) {
  1148. const std::string text = R"(
  1149. OpCapability Shader
  1150. OpMemoryModel Logical GLSL450
  1151. OpEntryPoint Fragment %main "main" %var
  1152. OpExecutionMode %main OriginUpperLeft
  1153. OpDecorate %struct Block
  1154. OpMemberDecorate %struct 0 Location 0
  1155. OpMemberDecorate %struct 0 Component 0
  1156. OpMemberDecorate %struct 0 Component 1
  1157. %void = OpTypeVoid
  1158. %void_fn = OpTypeFunction %void
  1159. %float = OpTypeFloat 32
  1160. %struct = OpTypeStruct %float
  1161. %ptr_input_struct = OpTypePointer Input %struct
  1162. %var = OpVariable %ptr_input_struct Input
  1163. %main = OpFunction %void None %void_fn
  1164. %entry = OpLabel
  1165. OpReturn
  1166. OpFunctionEnd
  1167. )";
  1168. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1169. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1170. EXPECT_THAT(
  1171. getDiagnosticString(),
  1172. HasSubstr("decorated with Component multiple times is not allowed"));
  1173. }
  1174. TEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictOutputIndex1) {
  1175. const std::string text = R"(
  1176. OpCapability Shader
  1177. OpMemoryModel Logical GLSL450
  1178. OpEntryPoint Fragment %main "main" %var1 %var2
  1179. OpExecutionMode %main OriginUpperLeft
  1180. OpDecorate %var1 Location 1
  1181. OpDecorate %var1 Index 1
  1182. OpDecorate %var2 Location 1
  1183. OpDecorate %var2 Index 1
  1184. %void = OpTypeVoid
  1185. %void_fn = OpTypeFunction %void
  1186. %float = OpTypeFloat 32
  1187. %struct = OpTypeStruct %float %float
  1188. %ptr_output_struct = OpTypePointer Output %struct
  1189. %var1 = OpVariable %ptr_output_struct Output
  1190. %var2 = OpVariable %ptr_output_struct Output
  1191. %main = OpFunction %void None %void_fn
  1192. %entry = OpLabel
  1193. OpReturn
  1194. OpFunctionEnd
  1195. )";
  1196. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1197. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1198. EXPECT_THAT(getDiagnosticString(),
  1199. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
  1200. EXPECT_THAT(
  1201. getDiagnosticString(),
  1202. HasSubstr("Entry-point has conflicting output location assignment "
  1203. "at location 1"));
  1204. }
  1205. TEST_F(ValidateInterfacesTest,
  1206. VulkanLocationsVariableNoConflictDifferentIndex) {
  1207. const std::string text = R"(
  1208. OpCapability Shader
  1209. OpMemoryModel Logical GLSL450
  1210. OpEntryPoint Fragment %main "main" %var1 %var2
  1211. OpExecutionMode %main OriginUpperLeft
  1212. OpDecorate %var1 Location 1
  1213. OpDecorate %var1 Index 0
  1214. OpDecorate %var2 Location 1
  1215. OpDecorate %var2 Index 1
  1216. %void = OpTypeVoid
  1217. %void_fn = OpTypeFunction %void
  1218. %float = OpTypeFloat 32
  1219. %struct = OpTypeStruct %float %float
  1220. %ptr_output_struct = OpTypePointer Output %struct
  1221. %var1 = OpVariable %ptr_output_struct Output
  1222. %var2 = OpVariable %ptr_output_struct Output
  1223. %main = OpFunction %void None %void_fn
  1224. %entry = OpLabel
  1225. OpReturn
  1226. OpFunctionEnd
  1227. )";
  1228. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1229. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1230. }
  1231. TEST_F(ValidateInterfacesTest, VulkanLocationsIndexGLCompute) {
  1232. const std::string text = R"(
  1233. OpCapability Shader
  1234. OpCapability Geometry
  1235. OpMemoryModel Logical GLSL450
  1236. OpEntryPoint Geometry %main "main" %var1
  1237. OpExecutionMode %main Triangles
  1238. OpExecutionMode %main OutputPoints
  1239. OpDecorate %var1 Location 1
  1240. OpDecorate %var1 Index 1
  1241. %void = OpTypeVoid
  1242. %void_fn = OpTypeFunction %void
  1243. %float = OpTypeFloat 32
  1244. %struct = OpTypeStruct %float %float
  1245. %ptr_output_struct = OpTypePointer Output %struct
  1246. %var1 = OpVariable %ptr_output_struct Output
  1247. %main = OpFunction %void None %void_fn
  1248. %entry = OpLabel
  1249. OpReturn
  1250. OpFunctionEnd
  1251. )";
  1252. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1253. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1254. EXPECT_THAT(
  1255. getDiagnosticString(),
  1256. HasSubstr("Index can only be applied to Fragment output variables"));
  1257. }
  1258. TEST_F(ValidateInterfacesTest, VulkanLocationsIndexInput) {
  1259. const std::string text = R"(
  1260. OpCapability Shader
  1261. OpMemoryModel Logical GLSL450
  1262. OpEntryPoint Fragment %main "main" %var1
  1263. OpExecutionMode %main OriginUpperLeft
  1264. OpDecorate %var1 Location 1
  1265. OpDecorate %var1 Index 1
  1266. %void = OpTypeVoid
  1267. %void_fn = OpTypeFunction %void
  1268. %float = OpTypeFloat 32
  1269. %struct = OpTypeStruct %float %float
  1270. %ptr_input_struct = OpTypePointer Input %struct
  1271. %var1 = OpVariable %ptr_input_struct Input
  1272. %main = OpFunction %void None %void_fn
  1273. %entry = OpLabel
  1274. OpReturn
  1275. OpFunctionEnd
  1276. )";
  1277. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1278. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1279. EXPECT_THAT(getDiagnosticString(),
  1280. HasSubstr("must be in the Output storage class"));
  1281. }
  1282. TEST_F(ValidateInterfacesTest, VulkanLocationsArrayWithComponent) {
  1283. const std::string text = R"(
  1284. OpCapability Shader
  1285. OpMemoryModel Logical GLSL450
  1286. OpEntryPoint Fragment %4 "main" %11 %18 %28 %36 %40
  1287. OpExecutionMode %4 OriginUpperLeft
  1288. OpDecorate %11 Location 0
  1289. OpDecorate %18 Component 0
  1290. OpDecorate %18 Location 0
  1291. OpDecorate %28 Component 1
  1292. OpDecorate %28 Location 0
  1293. OpDecorate %36 Location 1
  1294. OpDecorate %40 Component 0
  1295. OpDecorate %40 Location 1
  1296. %void = OpTypeVoid
  1297. %3 = OpTypeFunction %void
  1298. %float = OpTypeFloat 32
  1299. %v4float = OpTypeVector %float 4
  1300. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1301. %11 = OpVariable %_ptr_Input_v4float Input
  1302. %_ptr_Output_float = OpTypePointer Output %float
  1303. %18 = OpVariable %_ptr_Output_float Output
  1304. %uint = OpTypeInt 32 0
  1305. %v3float = OpTypeVector %float 3
  1306. %uint_2 = OpConstant %uint 2
  1307. %_arr_v3float_uint_2 = OpTypeArray %v3float %uint_2
  1308. %_ptr_Output__arr_v3float_uint_2 = OpTypePointer Output %_arr_v3float_uint_2
  1309. %28 = OpVariable %_ptr_Output__arr_v3float_uint_2 Output
  1310. %_ptr_Output_v3float = OpTypePointer Output %v3float
  1311. %36 = OpVariable %_ptr_Input_v4float Input
  1312. %40 = OpVariable %_ptr_Output_float Output
  1313. %4 = OpFunction %void None %3
  1314. %5 = OpLabel
  1315. OpReturn
  1316. OpFunctionEnd
  1317. )";
  1318. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1319. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1320. EXPECT_THAT(getDiagnosticString(),
  1321. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
  1322. EXPECT_THAT(getDiagnosticString(),
  1323. HasSubstr("Entry-point has conflicting output location "
  1324. "assignment at location 0, component 0"));
  1325. }
  1326. TEST_F(ValidateInterfacesTest, VulkanLocationsArrayWithComponentBad) {
  1327. const std::string text = R"(
  1328. OpCapability Shader
  1329. OpMemoryModel Logical GLSL450
  1330. OpEntryPoint Fragment %4 "main" %11 %18 %28 %36 %40
  1331. OpExecutionMode %4 OriginUpperLeft
  1332. OpDecorate %11 Location 0
  1333. OpDecorate %18 Component 0
  1334. OpDecorate %18 Location 0
  1335. OpDecorate %28 Component 1
  1336. OpDecorate %28 Location 1
  1337. OpDecorate %36 Location 1
  1338. OpDecorate %40 Component 1
  1339. OpDecorate %40 Location 1
  1340. %void = OpTypeVoid
  1341. %3 = OpTypeFunction %void
  1342. %float = OpTypeFloat 32
  1343. %v4float = OpTypeVector %float 4
  1344. %_ptr_Input_v4float = OpTypePointer Input %v4float
  1345. %11 = OpVariable %_ptr_Input_v4float Input
  1346. %_ptr_Output_float = OpTypePointer Output %float
  1347. %18 = OpVariable %_ptr_Output_float Output
  1348. %uint = OpTypeInt 32 0
  1349. %v3float = OpTypeVector %float 3
  1350. %uint_2 = OpConstant %uint 2
  1351. %_arr_v3float_uint_2 = OpTypeArray %v3float %uint_2
  1352. %_ptr_Output__arr_v3float_uint_2 = OpTypePointer Output %_arr_v3float_uint_2
  1353. %28 = OpVariable %_ptr_Output__arr_v3float_uint_2 Output
  1354. %_ptr_Output_v3float = OpTypePointer Output %v3float
  1355. %36 = OpVariable %_ptr_Input_v4float Input
  1356. %40 = OpVariable %_ptr_Output_float Output
  1357. %4 = OpFunction %void None %3
  1358. %5 = OpLabel
  1359. OpReturn
  1360. OpFunctionEnd
  1361. )";
  1362. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1363. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1364. EXPECT_THAT(getDiagnosticString(),
  1365. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
  1366. EXPECT_THAT(getDiagnosticString(),
  1367. HasSubstr("Entry-point has conflicting output location "
  1368. "assignment at location 1, component 1"));
  1369. }
  1370. TEST_F(ValidateInterfacesTest, VulkanLocationsLargeLocation) {
  1371. const std::string text = R"(
  1372. OpCapability Shader
  1373. OpMemoryModel Logical GLSL450
  1374. OpEntryPoint Fragment %4 "????????" %17
  1375. OpExecutionMode %4 OriginUpperLeft
  1376. OpDecorate %17 Location 4227868160
  1377. %void = OpTypeVoid
  1378. %3 = OpTypeFunction %void
  1379. %float = OpTypeFloat 32
  1380. %v3float = OpTypeVector %float 3
  1381. %_ptr_Input_v3float = OpTypePointer Input %v3float
  1382. %17 = OpVariable %_ptr_Input_v3float Input
  1383. %4 = OpFunction %void None %3
  1384. %5 = OpLabel
  1385. OpUnreachable
  1386. OpFunctionEnd
  1387. )";
  1388. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1389. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1390. }
  1391. TEST_F(ValidateInterfacesTest, VulkanLocationMeshShader) {
  1392. const std::string text = R"(
  1393. OpCapability Shader
  1394. OpCapability MeshShadingNV
  1395. OpExtension "SPV_NV_mesh_shader"
  1396. OpMemoryModel Logical GLSL450
  1397. OpEntryPoint MeshNV %foo "foo" %in
  1398. OpExecutionMode %foo LocalSize 1 1 1
  1399. OpDecorate %block Block
  1400. OpMemberDecorate %block 0 PerTaskNV
  1401. OpMemberDecorate %block 0 Offset 0
  1402. %void = OpTypeVoid
  1403. %int = OpTypeInt 32 0
  1404. %int_32 = OpConstant %int 32
  1405. %array = OpTypeArray %int %int_32
  1406. %block = OpTypeStruct %array
  1407. %ptr_input_block = OpTypePointer Input %block
  1408. %in = OpVariable %ptr_input_block Input
  1409. %void_fn = OpTypeFunction %void
  1410. %foo = OpFunction %void None %void_fn
  1411. %entry = OpLabel
  1412. OpReturn
  1413. OpFunctionEnd
  1414. )";
  1415. CompileSuccessfully(text, SPV_ENV_VULKAN_1_2);
  1416. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  1417. }
  1418. TEST_F(ValidateInterfacesTest, VulkanLocationArrayWithComponent1) {
  1419. const std::string text = R"(
  1420. OpCapability Shader
  1421. OpMemoryModel Logical GLSL450
  1422. OpEntryPoint Fragment %main "main" %in
  1423. OpExecutionMode %main OriginUpperLeft
  1424. OpDecorate %struct Block
  1425. OpMemberDecorate %struct 0 Location 0
  1426. OpMemberDecorate %struct 0 Component 0
  1427. OpMemberDecorate %struct 1 Location 0
  1428. OpMemberDecorate %struct 1 Component 1
  1429. %void = OpTypeVoid
  1430. %void_fn = OpTypeFunction %void
  1431. %float = OpTypeFloat 32
  1432. %int = OpTypeInt 32 0
  1433. %int_2 = OpConstant %int 2
  1434. %float_arr = OpTypeArray %float %int_2
  1435. %struct = OpTypeStruct %float_arr %float_arr
  1436. %ptr = OpTypePointer Input %struct
  1437. %in = OpVariable %ptr Input
  1438. %main = OpFunction %void None %void_fn
  1439. %entry = OpLabel
  1440. OpReturn
  1441. OpFunctionEnd
  1442. )";
  1443. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1444. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1445. EXPECT_THAT(getDiagnosticString(),
  1446. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  1447. EXPECT_THAT(getDiagnosticString(),
  1448. HasSubstr("Entry-point has conflicting input location "
  1449. "assignment at location 0, component 0"));
  1450. }
  1451. TEST_F(ValidateInterfacesTest, VulkanLocationArrayWithComponent2) {
  1452. const std::string text = R"(
  1453. OpCapability Shader
  1454. OpCapability Float64
  1455. OpMemoryModel Logical GLSL450
  1456. OpEntryPoint Fragment %main "main" %in
  1457. OpExecutionMode %main OriginUpperLeft
  1458. OpDecorate %struct Block
  1459. OpMemberDecorate %struct 0 Location 0
  1460. OpMemberDecorate %struct 0 Component 0
  1461. OpMemberDecorate %struct 1 Location 0
  1462. OpMemberDecorate %struct 1 Component 2
  1463. %void = OpTypeVoid
  1464. %void_fn = OpTypeFunction %void
  1465. %float = OpTypeFloat 32
  1466. %double = OpTypeFloat 64
  1467. %int = OpTypeInt 32 0
  1468. %int_2 = OpConstant %int 2
  1469. %double_arr = OpTypeArray %double %int_2
  1470. %struct = OpTypeStruct %float %double_arr
  1471. %ptr = OpTypePointer Input %struct
  1472. %in = OpVariable %ptr Input
  1473. %main = OpFunction %void None %void_fn
  1474. %entry = OpLabel
  1475. OpReturn
  1476. OpFunctionEnd
  1477. )";
  1478. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1479. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1480. EXPECT_THAT(getDiagnosticString(),
  1481. AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
  1482. EXPECT_THAT(getDiagnosticString(),
  1483. HasSubstr("Entry-point has conflicting input location "
  1484. "assignment at location 0, component 0"));
  1485. }
  1486. TEST_F(ValidateInterfacesTest, DuplicateInterfaceVariableSuccess) {
  1487. const std::string text = R"(
  1488. OpCapability Shader
  1489. OpMemoryModel Logical GLSL450
  1490. OpEntryPoint Fragment %main "main" %in %out %in
  1491. OpExecutionMode %main OriginUpperLeft
  1492. OpDecorate %in Location 0
  1493. OpDecorate %out Location 0
  1494. %void = OpTypeVoid
  1495. %float = OpTypeFloat 32
  1496. %in_ptr = OpTypePointer Input %float
  1497. %out_ptr = OpTypePointer Output %float
  1498. %in = OpVariable %in_ptr Input
  1499. %out = OpVariable %out_ptr Output
  1500. %void_fn = OpTypeFunction %void
  1501. %main = OpFunction %void None %void_fn
  1502. %entry = OpLabel
  1503. OpReturn
  1504. OpFunctionEnd
  1505. )";
  1506. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1507. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1508. }
  1509. TEST_F(ValidateInterfacesTest, StructWithBuiltinsMissingBlock_Bad) {
  1510. // See https://github.com/KhronosGroup/SPIRV-Registry/issues/134
  1511. //
  1512. // When a shader input or output is a struct that does not have Block,
  1513. // then it must have a Location.
  1514. // But BuiltIns must not have locations.
  1515. const std::string text = R"(
  1516. OpCapability Shader
  1517. OpMemoryModel Logical GLSL450
  1518. OpEntryPoint Fragment %main "main" %in
  1519. OpExecutionMode %main OriginUpperLeft
  1520. ; %struct needs a Block decoration
  1521. OpMemberDecorate %struct 0 BuiltIn Position
  1522. %void = OpTypeVoid
  1523. %float = OpTypeFloat 32
  1524. %v4float = OpTypeVector %float 4
  1525. %struct = OpTypeStruct %v4float
  1526. %in_ptr = OpTypePointer Input %struct
  1527. %in = OpVariable %in_ptr Input
  1528. %void_fn = OpTypeFunction %void
  1529. %main = OpFunction %void None %void_fn
  1530. %entry = OpLabel
  1531. OpReturn
  1532. OpFunctionEnd
  1533. )";
  1534. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1535. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1536. EXPECT_THAT(getDiagnosticString(),
  1537. AnyVUID("VUID-StandaloneSpirv-Location-04919"));
  1538. EXPECT_THAT(
  1539. getDiagnosticString(),
  1540. HasSubstr(
  1541. "Interface struct has no Block decoration but has BuiltIn members."));
  1542. }
  1543. TEST_F(ValidateInterfacesTest, InvalidLocationTypePointer) {
  1544. const std::string text = R"(
  1545. OpCapability Shader
  1546. OpMemoryModel Logical Simple
  1547. OpEntryPoint Vertex %1 "Aiqn0" %2 %3
  1548. OpDecorate %2 Location 0
  1549. %void = OpTypeVoid
  1550. %5 = OpTypeFunction %void
  1551. %float = OpTypeFloat 32
  1552. %_ptr_Private_void = OpTypePointer Private %void
  1553. %uint = OpTypeInt 32 0
  1554. %uint_4278132784 = OpConstant %uint 4278132784
  1555. %_arr__ptr_Private_void_uint_4278132784 = OpTypeArray %_ptr_Private_void %uint_4278132784
  1556. %_ptr_Output__arr__ptr_Private_void_uint_4278132784 = OpTypePointer Output %_arr__ptr_Private_void_uint_4278132784
  1557. %2 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output
  1558. %_ptr_Output__ptr_Private_void = OpTypePointer Output %_ptr_Private_void
  1559. %3 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output
  1560. %1 = OpFunction %void None %5
  1561. %15 = OpLabel
  1562. OpReturn
  1563. OpFunctionEnd
  1564. )";
  1565. CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
  1566. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
  1567. EXPECT_THAT(getDiagnosticString(),
  1568. HasSubstr("Invalid type to assign a location"));
  1569. }
  1570. TEST_F(ValidateInterfacesTest, PhysicalStorageBufferPointer) {
  1571. const std::string text = R"(
  1572. OpCapability Shader
  1573. OpCapability PhysicalStorageBufferAddresses
  1574. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1575. OpEntryPoint Vertex %main "main" %var
  1576. OpDecorate %var Location 0
  1577. OpDecorate %var RestrictPointer
  1578. %void = OpTypeVoid
  1579. %uint = OpTypeInt 32 0
  1580. %psb_ptr = OpTypePointer PhysicalStorageBuffer %uint
  1581. %in_ptr = OpTypePointer Input %psb_ptr
  1582. %var = OpVariable %in_ptr Input
  1583. %void_fn = OpTypeFunction %void
  1584. %main = OpFunction %void None %void_fn
  1585. %entry = OpLabel
  1586. OpReturn
  1587. OpFunctionEnd
  1588. )";
  1589. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1590. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1591. EXPECT_THAT(getDiagnosticString(),
  1592. AnyVUID("VUID-StandaloneSpirv-Input-09557"));
  1593. EXPECT_THAT(getDiagnosticString(),
  1594. HasSubstr("Input/Output interface variable id <2> contains a "
  1595. "PhysicalStorageBuffer pointer, which is not allowed"));
  1596. }
  1597. TEST_F(ValidateInterfacesTest, PhysicalStorageBufferPointerArray) {
  1598. const std::string text = R"(
  1599. OpCapability Shader
  1600. OpCapability PhysicalStorageBufferAddresses
  1601. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1602. OpEntryPoint Vertex %main "main" %var
  1603. OpDecorate %var Location 0
  1604. OpDecorate %var RestrictPointer
  1605. %void = OpTypeVoid
  1606. %uint = OpTypeInt 32 0
  1607. %uint_3 = OpConstant %uint 3
  1608. %psb_ptr = OpTypePointer PhysicalStorageBuffer %uint
  1609. %array = OpTypeArray %psb_ptr %uint_3
  1610. %in_ptr = OpTypePointer Input %array
  1611. %var = OpVariable %in_ptr Input
  1612. %void_fn = OpTypeFunction %void
  1613. %main = OpFunction %void None %void_fn
  1614. %entry = OpLabel
  1615. OpReturn
  1616. OpFunctionEnd
  1617. )";
  1618. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1619. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1620. EXPECT_THAT(getDiagnosticString(),
  1621. AnyVUID("VUID-StandaloneSpirv-Input-09557"));
  1622. EXPECT_THAT(getDiagnosticString(),
  1623. HasSubstr("Input/Output interface variable id <2> contains a "
  1624. "PhysicalStorageBuffer pointer, which is not allowed"));
  1625. }
  1626. TEST_F(ValidateInterfacesTest, PhysicalStorageBufferPointerStruct) {
  1627. const std::string text = R"(
  1628. OpCapability Shader
  1629. OpCapability PhysicalStorageBufferAddresses
  1630. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1631. OpEntryPoint Vertex %main "main" %var
  1632. OpDecorate %var Location 0
  1633. OpDecorate %var RestrictPointer
  1634. %void = OpTypeVoid
  1635. %int = OpTypeInt 32 1
  1636. OpTypeForwardPointer %psb_ptr PhysicalStorageBuffer
  1637. %struct_0 = OpTypeStruct %int %psb_ptr
  1638. %struct_1 = OpTypeStruct %int %int
  1639. %psb_ptr = OpTypePointer PhysicalStorageBuffer %struct_1
  1640. %in_ptr = OpTypePointer Input %struct_0
  1641. %var = OpVariable %in_ptr Input
  1642. %void_fn = OpTypeFunction %void
  1643. %main = OpFunction %void None %void_fn
  1644. %entry = OpLabel
  1645. OpReturn
  1646. OpFunctionEnd
  1647. )";
  1648. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1649. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1650. EXPECT_THAT(getDiagnosticString(),
  1651. AnyVUID("VUID-StandaloneSpirv-Input-09557"));
  1652. EXPECT_THAT(getDiagnosticString(),
  1653. HasSubstr("Input/Output interface variable id <2> contains a "
  1654. "PhysicalStorageBuffer pointer, which is not allowed"));
  1655. }
  1656. TEST_F(ValidateInterfacesTest, PhysicalStorageBufferPointerArrayOfStruct) {
  1657. const std::string text = R"(
  1658. OpCapability Shader
  1659. OpCapability PhysicalStorageBufferAddresses
  1660. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1661. OpEntryPoint Vertex %main "main" %var
  1662. OpDecorate %var Location 0
  1663. OpDecorate %var RestrictPointer
  1664. %void = OpTypeVoid
  1665. %int = OpTypeInt 32 1
  1666. %uint = OpTypeInt 32 0
  1667. %uint_3 = OpConstant %uint 3
  1668. OpTypeForwardPointer %psb_ptr PhysicalStorageBuffer
  1669. %array_1 = OpTypeArray %psb_ptr %uint_3
  1670. %struct_0 = OpTypeStruct %int %array_1
  1671. %struct_1 = OpTypeStruct %int %int
  1672. %psb_ptr = OpTypePointer PhysicalStorageBuffer %struct_1
  1673. %array_0 = OpTypeArray %struct_0 %uint_3
  1674. %in_ptr = OpTypePointer Input %array_0
  1675. %var = OpVariable %in_ptr Input
  1676. %void_fn = OpTypeFunction %void
  1677. %main = OpFunction %void None %void_fn
  1678. %entry = OpLabel
  1679. OpReturn
  1680. OpFunctionEnd
  1681. )";
  1682. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1683. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1684. EXPECT_THAT(getDiagnosticString(),
  1685. AnyVUID("VUID-StandaloneSpirv-Input-09557"));
  1686. EXPECT_THAT(getDiagnosticString(),
  1687. HasSubstr("Input/Output interface variable id <2> contains a "
  1688. "PhysicalStorageBuffer pointer, which is not allowed"));
  1689. }
  1690. TEST_F(ValidateInterfacesTest, PhysicalStorageBufferPointerNestedStruct) {
  1691. const std::string text = R"(
  1692. OpCapability Shader
  1693. OpCapability PhysicalStorageBufferAddresses
  1694. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  1695. OpEntryPoint Vertex %main "main" %var
  1696. OpDecorate %var Location 0
  1697. OpDecorate %var RestrictPointer
  1698. %void = OpTypeVoid
  1699. %int = OpTypeInt 32 1
  1700. OpTypeForwardPointer %psb_ptr PhysicalStorageBuffer
  1701. %struct_0 = OpTypeStruct %int %psb_ptr
  1702. %struct_1 = OpTypeStruct %int %int
  1703. %psb_ptr = OpTypePointer PhysicalStorageBuffer %struct_1
  1704. %struct_2 = OpTypeStruct %int %struct_0
  1705. %in_ptr = OpTypePointer Input %struct_2
  1706. %var = OpVariable %in_ptr Input
  1707. %void_fn = OpTypeFunction %void
  1708. %main = OpFunction %void None %void_fn
  1709. %entry = OpLabel
  1710. OpReturn
  1711. OpFunctionEnd
  1712. )";
  1713. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1714. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1715. EXPECT_THAT(getDiagnosticString(),
  1716. AnyVUID("VUID-StandaloneSpirv-Input-09557"));
  1717. EXPECT_THAT(getDiagnosticString(),
  1718. HasSubstr("Input/Output interface variable id <2> contains a "
  1719. "PhysicalStorageBuffer pointer, which is not allowed"));
  1720. }
  1721. TEST_F(ValidateInterfacesTest, UntypedVariableInputMissing) {
  1722. const std::string text = R"(
  1723. OpCapability Kernel
  1724. OpCapability UntypedPointersKHR
  1725. OpExtension "SPV_KHR_untyped_pointers"
  1726. OpMemoryModel Logical OpenCL
  1727. OpEntryPoint Kernel %main "main"
  1728. OpExecutionMode %main LocalSize 1 1 1
  1729. OpName %var "var"
  1730. OpDecorate %var BuiltIn LocalInvocationId
  1731. %void = OpTypeVoid
  1732. %int = OpTypeInt 32 0
  1733. %int3 = OpTypeVector %int 3
  1734. %ptr = OpTypeUntypedPointerKHR Input
  1735. %var = OpUntypedVariableKHR %ptr Input %int3
  1736. %void_fn = OpTypeFunction %void
  1737. %main = OpFunction %void None %void_fn
  1738. %entry = OpLabel
  1739. %load = OpLoad %int3 %var
  1740. OpReturn
  1741. OpFunctionEnd
  1742. )";
  1743. CompileSuccessfully(text);
  1744. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  1745. EXPECT_THAT(getDiagnosticString(),
  1746. HasSubstr("Interface variable id <2> is used by entry point "
  1747. "'main' id <1>, but is not listed as an interface"));
  1748. }
  1749. TEST_F(ValidateInterfacesTest, UntypedVariableWorkgroupMissingSpv1p4) {
  1750. const std::string text = R"(
  1751. OpCapability Shader
  1752. OpCapability UntypedPointersKHR
  1753. OpCapability WorkgroupMemoryExplicitLayoutKHR
  1754. OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
  1755. OpExtension "SPV_KHR_untyped_pointers"
  1756. OpMemoryModel Logical GLSL450
  1757. OpEntryPoint GLCompute %main "main"
  1758. OpName %var "var"
  1759. %void = OpTypeVoid
  1760. %int = OpTypeInt 32 0
  1761. %ptr = OpTypeUntypedPointerKHR Workgroup
  1762. %var = OpUntypedVariableKHR %ptr Workgroup %int
  1763. %void_fn = OpTypeFunction %void
  1764. %main = OpFunction %void None %void_fn
  1765. %entry = OpLabel
  1766. %load = OpLoad %int %var
  1767. OpReturn
  1768. OpFunctionEnd
  1769. )";
  1770. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
  1771. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  1772. EXPECT_THAT(getDiagnosticString(),
  1773. HasSubstr("Interface variable id <2> is used by entry point "
  1774. "'main' id <1>, but is not listed as an interface"));
  1775. }
  1776. TEST_F(ValidateInterfacesTest, UntypedIdMatchesInputVulkan1p3) {
  1777. const std::string text = R"(
  1778. OpCapability Shader
  1779. OpCapability UntypedPointersKHR
  1780. OpExtension "SPV_KHR_untyped_pointers"
  1781. OpMemoryModel Logical GLSL450
  1782. OpEntryPoint Fragment %main "main" %var
  1783. OpExecutionMode %main OriginUpperLeft
  1784. OpDecorate %var DescriptorSet 0
  1785. OpDecorate %var Binding 0
  1786. OpDecorate %1 Block
  1787. OpMemberDecorate %1 0 Offset 0
  1788. %void = OpTypeVoid
  1789. %float = OpTypeFloat 32
  1790. %1 = OpTypeStruct %float ; this id matches Input storage class
  1791. %ptr = OpTypeUntypedPointerKHR Uniform
  1792. %var = OpUntypedVariableKHR %ptr Uniform %1
  1793. %void_fn = OpTypeFunction %void
  1794. %main = OpFunction %void None %void_fn
  1795. %entry = OpLabel
  1796. OpReturn
  1797. OpFunctionEnd
  1798. )";
  1799. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1800. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1801. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1802. }
  1803. TEST_F(ValidateInterfacesTest, UntypedIdMatchesPushConstantVulkan1p3) {
  1804. const std::string text = R"(
  1805. OpCapability Shader
  1806. OpCapability UntypedPointersKHR
  1807. OpExtension "SPV_KHR_untyped_pointers"
  1808. OpMemoryModel Logical GLSL450
  1809. OpEntryPoint Fragment %main "main" %var
  1810. OpExecutionMode %main OriginUpperLeft
  1811. OpDecorate %var DescriptorSet 0
  1812. OpDecorate %var Binding 0
  1813. OpDecorate %9 Block
  1814. OpMemberDecorate %9 0 Offset 0
  1815. %void = OpTypeVoid
  1816. %float = OpTypeFloat 32
  1817. %9 = OpTypeStruct %float ; this id matches PushConstant storage class
  1818. %ptr = OpTypeUntypedPointerKHR Uniform
  1819. %var = OpUntypedVariableKHR %ptr Uniform %9
  1820. %void_fn = OpTypeFunction %void
  1821. %main = OpFunction %void None %void_fn
  1822. %entry = OpLabel
  1823. OpReturn
  1824. OpFunctionEnd
  1825. )";
  1826. SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  1827. CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
  1828. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
  1829. }
  1830. } // namespace
  1831. } // namespace val
  1832. } // namespace spvtools