val_annotation_test.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  1. // Copyright (c) 2021 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. // Validation tests for decorations
  15. #include <string>
  16. #include <vector>
  17. #include "gmock/gmock.h"
  18. #include "test/unit_spirv.h"
  19. #include "test/val/val_code_generator.h"
  20. #include "test/val/val_fixtures.h"
  21. namespace spvtools {
  22. namespace val {
  23. namespace {
  24. using ::testing::Combine;
  25. using ::testing::Eq;
  26. using ::testing::HasSubstr;
  27. using ::testing::Values;
  28. using DecorationTest = spvtest::ValidateBase<bool>;
  29. TEST_F(DecorationTest, WorkgroupSizeShader) {
  30. const std::string text = R"(
  31. OpCapability Shader
  32. OpCapability Linkage
  33. OpMemoryModel Logical GLSL450
  34. OpDecorate %ones BuiltIn WorkgroupSize
  35. %int = OpTypeInt 32 0
  36. %int3 = OpTypeVector %int 3
  37. %int_1 = OpConstant %int 1
  38. %ones = OpConstantComposite %int3 %int_1 %int_1 %int_1
  39. )";
  40. CompileSuccessfully(text);
  41. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  42. }
  43. TEST_F(DecorationTest, WorkgroupSizeKernel) {
  44. const std::string text = R"(
  45. OpCapability Kernel
  46. OpCapability Linkage
  47. OpMemoryModel Logical OpenCL
  48. OpDecorate %var BuiltIn WorkgroupSize
  49. %int = OpTypeInt 32 0
  50. %int3 = OpTypeVector %int 3
  51. %ptr = OpTypePointer Input %int3
  52. %var = OpVariable %ptr Input
  53. )";
  54. CompileSuccessfully(text);
  55. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  56. }
  57. TEST_F(DecorationTest, FPFastMathModeInvalidMask) {
  58. const std::string text = R"(
  59. OpCapability Shader
  60. OpCapability FloatControls2
  61. OpExtension "SPV_KHR_float_controls2"
  62. OpMemoryModel Logical GLSL450
  63. OpEntryPoint GLCompute %main "main"
  64. OpExecutionMode %main LocalSize 1 1 1
  65. OpDecorate %add FPFastMathMode !524288
  66. %void = OpTypeVoid
  67. %float = OpTypeFloat 32
  68. %undef = OpUndef %float
  69. %void_fn = OpTypeFunction %void
  70. %main = OpFunction %void None %void_fn
  71. %entry = OpLabel
  72. %add = OpFAdd %float %undef %undef
  73. OpReturn
  74. OpFunctionEnd
  75. )";
  76. CompileSuccessfully(text);
  77. EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
  78. EXPECT_THAT(getDiagnosticString(),
  79. HasSubstr("Invalid floating-point fast math mode operand"));
  80. }
  81. TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingAllowContract) {
  82. const std::string text = R"(
  83. OpCapability Shader
  84. OpCapability FloatControls2
  85. OpExtension "SPV_KHR_float_controls2"
  86. OpMemoryModel Logical GLSL450
  87. OpEntryPoint GLCompute %main "main"
  88. OpExecutionMode %main LocalSize 1 1 1
  89. OpDecorate %add FPFastMathMode AllowTransform|AllowReassoc
  90. %void = OpTypeVoid
  91. %float = OpTypeFloat 32
  92. %undef = OpUndef %float
  93. %void_fn = OpTypeFunction %void
  94. %main = OpFunction %void None %void_fn
  95. %entry = OpLabel
  96. %add = OpFAdd %float %undef %undef
  97. OpReturn
  98. OpFunctionEnd
  99. )";
  100. CompileSuccessfully(text);
  101. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  102. EXPECT_THAT(getDiagnosticString(),
  103. HasSubstr("AllowReassoc and AllowContract must be specified when "
  104. "AllowTransform is specified"));
  105. }
  106. TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingAllowReassoc) {
  107. const std::string text = R"(
  108. OpCapability Shader
  109. OpCapability FloatControls2
  110. OpExtension "SPV_KHR_float_controls2"
  111. OpMemoryModel Logical GLSL450
  112. OpEntryPoint GLCompute %main "main"
  113. OpExecutionMode %main LocalSize 1 1 1
  114. OpDecorate %add FPFastMathMode AllowTransform|AllowContract
  115. %void = OpTypeVoid
  116. %float = OpTypeFloat 32
  117. %undef = OpUndef %float
  118. %void_fn = OpTypeFunction %void
  119. %main = OpFunction %void None %void_fn
  120. %entry = OpLabel
  121. %add = OpFAdd %float %undef %undef
  122. OpReturn
  123. OpFunctionEnd
  124. )";
  125. CompileSuccessfully(text);
  126. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  127. EXPECT_THAT(getDiagnosticString(),
  128. HasSubstr("AllowReassoc and AllowContract must be specified when "
  129. "AllowTransform is specified"));
  130. }
  131. TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingContractAndReassoc) {
  132. const std::string text = R"(
  133. OpCapability Shader
  134. OpCapability FloatControls2
  135. OpExtension "SPV_KHR_float_controls2"
  136. OpMemoryModel Logical GLSL450
  137. OpEntryPoint GLCompute %main "main"
  138. OpExecutionMode %main LocalSize 1 1 1
  139. OpDecorate %add FPFastMathMode AllowTransform
  140. %void = OpTypeVoid
  141. %float = OpTypeFloat 32
  142. %undef = OpUndef %float
  143. %void_fn = OpTypeFunction %void
  144. %main = OpFunction %void None %void_fn
  145. %entry = OpLabel
  146. %add = OpFAdd %float %undef %undef
  147. OpReturn
  148. OpFunctionEnd
  149. )";
  150. CompileSuccessfully(text);
  151. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  152. EXPECT_THAT(getDiagnosticString(),
  153. HasSubstr("AllowReassoc and AllowContract must be specified when "
  154. "AllowTransform is specified"));
  155. }
  156. TEST_F(DecorationTest, FPFastMathModeAndNoContraction) {
  157. const std::string text = R"(
  158. OpCapability Shader
  159. OpCapability FloatControls2
  160. OpExtension "SPV_KHR_float_controls2"
  161. OpMemoryModel Logical GLSL450
  162. OpEntryPoint GLCompute %main "main"
  163. OpExecutionMode %main LocalSize 1 1 1
  164. OpDecorate %add FPFastMathMode None
  165. OpDecorate %add NoContraction
  166. %void = OpTypeVoid
  167. %float = OpTypeFloat 32
  168. %undef = OpUndef %float
  169. %void_fn = OpTypeFunction %void
  170. %main = OpFunction %void None %void_fn
  171. %entry = OpLabel
  172. %add = OpFAdd %float %undef %undef
  173. OpReturn
  174. OpFunctionEnd
  175. )";
  176. CompileSuccessfully(text);
  177. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  178. EXPECT_THAT(
  179. getDiagnosticString(),
  180. HasSubstr(
  181. "FPFastMathMode and NoContraction cannot decorate the same target"));
  182. }
  183. TEST_F(DecorationTest, FPFastMathModeAndNoContraction2) {
  184. const std::string text = R"(
  185. OpCapability Shader
  186. OpCapability FloatControls2
  187. OpExtension "SPV_KHR_float_controls2"
  188. OpMemoryModel Logical GLSL450
  189. OpEntryPoint GLCompute %main "main"
  190. OpExecutionMode %main LocalSize 1 1 1
  191. OpDecorate %add NoContraction
  192. OpDecorate %add FPFastMathMode None
  193. %void = OpTypeVoid
  194. %float = OpTypeFloat 32
  195. %undef = OpUndef %float
  196. %void_fn = OpTypeFunction %void
  197. %main = OpFunction %void None %void_fn
  198. %entry = OpLabel
  199. %add = OpFAdd %float %undef %undef
  200. OpReturn
  201. OpFunctionEnd
  202. )";
  203. CompileSuccessfully(text);
  204. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  205. EXPECT_THAT(
  206. getDiagnosticString(),
  207. HasSubstr(
  208. "FPFastMathMode and NoContraction cannot decorate the same target"));
  209. }
  210. TEST_F(DecorationTest, RestrictOnUntypedPointer) {
  211. const std::string text = R"(
  212. OpCapability Shader
  213. OpCapability Linkage
  214. OpCapability UntypedPointersKHR
  215. OpCapability SampleRateShading
  216. OpCapability TransformFeedback
  217. OpCapability GeometryStreams
  218. OpCapability Tessellation
  219. OpExtension "SPV_KHR_untyped_pointers"
  220. OpExtension "SPV_KHR_storage_buffer_storage_class"
  221. OpMemoryModel Logical GLSL450
  222. OpDecorate %param Restrict
  223. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  224. %void = OpTypeVoid
  225. %f_ty = OpTypeFunction %void %ptr
  226. %f = OpFunction %void None %f_ty
  227. %param = OpFunctionParameter %ptr
  228. %entry = OpLabel
  229. OpReturn
  230. OpFunctionEnd
  231. )";
  232. CompileSuccessfully(text);
  233. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  234. }
  235. TEST_F(DecorationTest, ArrayStrideUntypedPointerKHR) {
  236. const std::string text = R"(
  237. OpCapability Shader
  238. OpCapability Linkage
  239. OpCapability UntypedPointersKHR
  240. OpExtension "SPV_KHR_untyped_pointers"
  241. OpExtension "SPV_KHR_storage_buffer_storage_class"
  242. OpMemoryModel Logical GLSL450
  243. OpDecorate %ptr ArrayStride 4
  244. %ptr = OpTypeUntypedPointerKHR StorageBuffer
  245. )";
  246. CompileSuccessfully(text);
  247. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  248. }
  249. using MemberOnlyDecorations = spvtest::ValidateBase<std::string>;
  250. TEST_P(MemberOnlyDecorations, MemberDecoration) {
  251. const auto deco = GetParam();
  252. const std::string text = R"(
  253. OpCapability Shader
  254. OpCapability Linkage
  255. OpMemoryModel Logical GLSL450
  256. OpMemberDecorate %struct 0 )" +
  257. deco + R"(
  258. %float = OpTypeFloat 32
  259. %float2 = OpTypeVector %float 2
  260. %float2x2 = OpTypeMatrix %float2 2
  261. %struct = OpTypeStruct %float2x2
  262. )";
  263. CompileSuccessfully(text);
  264. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  265. }
  266. TEST_P(MemberOnlyDecorations, Decoration) {
  267. const auto deco = GetParam();
  268. const std::string text = R"(
  269. OpCapability Shader
  270. OpCapability Linkage
  271. OpMemoryModel Logical GLSL450
  272. OpDecorate %struct )" + deco +
  273. R"(
  274. %float = OpTypeFloat 32
  275. %float2 = OpTypeVector %float 2
  276. %float2x2 = OpTypeMatrix %float2 2
  277. %struct = OpTypeStruct %float2x2
  278. )";
  279. CompileSuccessfully(text);
  280. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  281. EXPECT_THAT(getDiagnosticString(),
  282. HasSubstr("can only be applied to structure members"));
  283. }
  284. INSTANTIATE_TEST_SUITE_P(ValidateMemberOnlyDecorations, MemberOnlyDecorations,
  285. Values("RowMajor", "ColMajor", "MatrixStride 16"
  286. // SPIR-V spec bug?
  287. /*,"Offset 0"*/));
  288. using NonMemberOnlyDecorations = spvtest::ValidateBase<std::string>;
  289. TEST_P(NonMemberOnlyDecorations, MemberDecoration) {
  290. const auto deco = GetParam();
  291. const auto text = R"(
  292. OpCapability Shader
  293. OpCapability Kernel
  294. OpCapability Linkage
  295. OpCapability InputAttachment
  296. OpCapability Addresses
  297. OpCapability PhysicalStorageBufferAddresses
  298. OpCapability ShaderNonUniform
  299. OpExtension "SPV_KHR_no_integer_wrap_decoration"
  300. OpExtension "SPV_KHR_physical_storage_buffer"
  301. OpExtension "SPV_GOOGLE_hlsl_functionality1"
  302. OpExtension "SPV_EXT_descriptor_indexing"
  303. OpMemoryModel Logical GLSL450
  304. OpMemberDecorate %struct 0 )" +
  305. deco + R"(
  306. %float = OpTypeFloat 32
  307. %float2 = OpTypeVector %float 2
  308. %float2x2 = OpTypeMatrix %float2 2
  309. %struct = OpTypeStruct %float2x2
  310. )";
  311. CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
  312. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  313. EXPECT_THAT(getDiagnosticString(),
  314. HasSubstr("cannot be applied to structure members"));
  315. }
  316. INSTANTIATE_TEST_SUITE_P(
  317. ValidateNonMemberOnlyDecorations, NonMemberOnlyDecorations,
  318. Values("SpecId 1", "Block", "BufferBlock", "ArrayStride 4", "GLSLShared",
  319. "GLSLPacked", "CPacked",
  320. // TODO: https://github.com/KhronosGroup/glslang/issues/703:
  321. // glslang applies Restrict to structure members.
  322. //"Restrict",
  323. "Aliased", "Constant", "Uniform", "SaturatedConversion", "Index 0",
  324. "Binding 0", "DescriptorSet 0", "FuncParamAttr Zext",
  325. "FPRoundingMode RTE", "FPFastMathMode None",
  326. "LinkageAttributes \"ext\" Import", "NoContraction",
  327. "InputAttachmentIndex 0", "Alignment 4", "MaxByteOffset 4",
  328. "AlignmentId %float", "MaxByteOffsetId %float", "NoSignedWrap",
  329. "NoUnsignedWrap", "NonUniform", "RestrictPointer", "AliasedPointer",
  330. "CounterBuffer %float"));
  331. using StructDecorations = spvtest::ValidateBase<std::string>;
  332. TEST_P(StructDecorations, Struct) {
  333. const std::string deco = GetParam();
  334. const std::string text = R"(
  335. OpCapability Shader
  336. OpCapability Kernel
  337. OpCapability Linkage
  338. OpMemoryModel Logical GLSL450
  339. OpDecorate %struct )" + deco +
  340. R"(
  341. %struct = OpTypeStruct
  342. )";
  343. CompileSuccessfully(text);
  344. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  345. }
  346. TEST_P(StructDecorations, OtherType) {
  347. const std::string deco = GetParam();
  348. const std::string text = R"(
  349. OpCapability Shader
  350. OpCapability Kernel
  351. OpCapability Linkage
  352. OpMemoryModel Logical GLSL450
  353. OpDecorate %int )" + deco + R"(
  354. %int = OpTypeInt 32 0
  355. )";
  356. CompileSuccessfully(text);
  357. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  358. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  359. }
  360. TEST_P(StructDecorations, Variable) {
  361. const std::string deco = GetParam();
  362. const std::string text = R"(
  363. OpCapability Shader
  364. OpCapability Kernel
  365. OpCapability Linkage
  366. OpMemoryModel Logical GLSL450
  367. OpDecorate %var )" + deco + R"(
  368. %int = OpTypeInt 32 0
  369. %ptr = OpTypePointer Private %int
  370. %var = OpVariable %ptr Private
  371. )";
  372. CompileSuccessfully(text);
  373. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  374. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  375. }
  376. TEST_P(StructDecorations, FunctionParameter) {
  377. const auto deco = GetParam();
  378. const std::string text = R"(
  379. OpCapability Shader
  380. OpCapability Kernel
  381. OpCapability Linkage
  382. OpMemoryModel Logical GLSL450
  383. OpDecorate %func LinkageAttributes "import" Import
  384. OpDecorate %param )" + deco +
  385. R"(
  386. %int = OpTypeInt 32 0
  387. %void = OpTypeVoid
  388. %fn = OpTypeFunction %void %int
  389. %func = OpFunction %void None %fn
  390. %param = OpFunctionParameter %int
  391. OpFunctionEnd
  392. )";
  393. CompileSuccessfully(text);
  394. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  395. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  396. }
  397. TEST_P(StructDecorations, Constant) {
  398. const std::string deco = GetParam();
  399. const std::string text = R"(
  400. OpCapability Shader
  401. OpCapability Kernel
  402. OpCapability Linkage
  403. OpMemoryModel Logical GLSL450
  404. OpDecorate %int_0 )" + deco +
  405. R"(
  406. %int = OpTypeInt 32 0
  407. %int_0 = OpConstant %int 0
  408. )";
  409. CompileSuccessfully(text);
  410. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  411. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a structure type"));
  412. }
  413. INSTANTIATE_TEST_SUITE_P(ValidateStructDecorations, StructDecorations,
  414. Values("Block", "BufferBlock", "GLSLShared",
  415. "GLSLPacked", "CPacked"));
  416. using ArrayDecorations = spvtest::ValidateBase<std::string>;
  417. TEST_P(ArrayDecorations, Array) {
  418. const auto deco = GetParam();
  419. const std::string text = R"(
  420. OpCapability Shader
  421. OpCapability Linkage
  422. OpMemoryModel Logical GLSL450
  423. OpDecorate %array )" + deco +
  424. R"(
  425. %int = OpTypeInt 32 0
  426. %int_4 = OpConstant %int 4
  427. %array = OpTypeArray %int %int_4
  428. )";
  429. CompileSuccessfully(text);
  430. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  431. }
  432. TEST_P(ArrayDecorations, RuntimeArray) {
  433. const auto deco = GetParam();
  434. const std::string text = R"(
  435. OpCapability Shader
  436. OpCapability Linkage
  437. OpMemoryModel Logical GLSL450
  438. OpDecorate %array )" + deco +
  439. R"(
  440. %int = OpTypeInt 32 0
  441. %array = OpTypeRuntimeArray %int
  442. )";
  443. CompileSuccessfully(text);
  444. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  445. }
  446. TEST_P(ArrayDecorations, Pointer) {
  447. const auto deco = GetParam();
  448. const std::string text = R"(
  449. OpCapability Shader
  450. OpCapability Linkage
  451. OpMemoryModel Logical GLSL450
  452. OpDecorate %ptr )" + deco + R"(
  453. %int = OpTypeInt 32 0
  454. %ptr = OpTypePointer Workgroup %int
  455. )";
  456. CompileSuccessfully(text);
  457. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  458. }
  459. TEST_P(ArrayDecorations, Struct) {
  460. const auto deco = GetParam();
  461. const std::string text = R"(
  462. OpCapability Shader
  463. OpCapability Linkage
  464. OpMemoryModel Logical GLSL450
  465. OpDecorate %struct )" + deco +
  466. R"(
  467. %int = OpTypeInt 32 0
  468. %struct = OpTypeStruct %int
  469. )";
  470. CompileSuccessfully(text);
  471. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  472. EXPECT_THAT(getDiagnosticString(),
  473. HasSubstr("must be an array or pointer type"));
  474. }
  475. TEST_P(ArrayDecorations, Variable) {
  476. const auto deco = GetParam();
  477. const std::string text = R"(
  478. OpCapability Shader
  479. OpCapability Linkage
  480. OpMemoryModel Logical GLSL450
  481. OpDecorate %var )" + deco + R"(
  482. %int = OpTypeInt 32 0
  483. %ptr = OpTypePointer Private %int
  484. %var = OpVariable %ptr Private
  485. )";
  486. CompileSuccessfully(text);
  487. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  488. EXPECT_THAT(getDiagnosticString(),
  489. HasSubstr("must be an array or pointer type"));
  490. }
  491. TEST_P(ArrayDecorations, FunctionParameter) {
  492. const auto deco = GetParam();
  493. const std::string text = R"(
  494. OpCapability Shader
  495. OpCapability Linkage
  496. OpMemoryModel Logical GLSL450
  497. OpDecorate %func LinkageAttributes "import" Import
  498. OpDecorate %param )" + deco +
  499. R"(
  500. %int = OpTypeInt 32 0
  501. %void = OpTypeVoid
  502. %fn = OpTypeFunction %void %int
  503. %func = OpFunction %void None %fn
  504. %param = OpFunctionParameter %int
  505. OpFunctionEnd
  506. )";
  507. CompileSuccessfully(text);
  508. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  509. EXPECT_THAT(getDiagnosticString(),
  510. HasSubstr("must be an array or pointer type"));
  511. }
  512. TEST_P(ArrayDecorations, Constant) {
  513. const auto deco = GetParam();
  514. const std::string text = R"(
  515. OpCapability Shader
  516. OpCapability Linkage
  517. OpMemoryModel Logical GLSL450
  518. OpDecorate %null )" + deco +
  519. R"(
  520. %int = OpTypeInt 32 0
  521. %int_4 = OpConstant %int 4
  522. %array = OpTypeArray %int %int_4
  523. %null = OpConstantNull %array
  524. )";
  525. CompileSuccessfully(text);
  526. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  527. EXPECT_THAT(getDiagnosticString(),
  528. HasSubstr("must be an array or pointer type"));
  529. }
  530. INSTANTIATE_TEST_SUITE_P(ValidateArrayDecorations, ArrayDecorations,
  531. Values("ArrayStride 4"));
  532. using BuiltInDecorations = spvtest::ValidateBase<std::string>;
  533. TEST_P(BuiltInDecorations, Variable) {
  534. const auto deco = GetParam();
  535. const std::string text = R"(
  536. OpCapability Shader
  537. OpCapability Linkage
  538. OpMemoryModel Logical GLSL450
  539. OpDecorate %var BuiltIn )" +
  540. deco + R"(
  541. %int = OpTypeInt 32 0
  542. %ptr = OpTypePointer Input %int
  543. %var = OpVariable %ptr Input
  544. )";
  545. CompileSuccessfully(text);
  546. if (deco != "WorkgroupSize") {
  547. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  548. } else {
  549. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  550. EXPECT_THAT(getDiagnosticString(),
  551. HasSubstr("must be a constant for WorkgroupSize"));
  552. }
  553. }
  554. TEST_P(BuiltInDecorations, IntegerType) {
  555. const auto deco = GetParam();
  556. const std::string text = R"(
  557. OpCapability Shader
  558. OpCapability Linkage
  559. OpMemoryModel Logical GLSL450
  560. OpDecorate %int BuiltIn )" +
  561. deco + R"(
  562. %int = OpTypeInt 32 0
  563. )";
  564. CompileSuccessfully(text);
  565. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  566. EXPECT_THAT(getDiagnosticString(),
  567. HasSubstr("BuiltIns can only target variables, structure members "
  568. "or constants"));
  569. }
  570. TEST_P(BuiltInDecorations, FunctionParameter) {
  571. const auto deco = GetParam();
  572. const std::string text = R"(
  573. OpCapability Shader
  574. OpCapability Linkage
  575. OpMemoryModel Logical GLSL450
  576. OpDecorate %func LinkageAttributes "import" Import
  577. OpDecorate %param BuiltIn )" +
  578. deco + R"(
  579. %int = OpTypeInt 32 0
  580. %void = OpTypeVoid
  581. %fn = OpTypeFunction %void %int
  582. %func = OpFunction %void None %fn
  583. %param = OpFunctionParameter %int
  584. OpFunctionEnd
  585. )";
  586. CompileSuccessfully(text);
  587. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  588. EXPECT_THAT(getDiagnosticString(),
  589. HasSubstr("BuiltIns can only target variables, structure members "
  590. "or constants"));
  591. }
  592. TEST_P(BuiltInDecorations, Constant) {
  593. const auto deco = GetParam();
  594. const std::string text = R"(
  595. OpCapability Shader
  596. OpCapability Linkage
  597. OpMemoryModel Logical GLSL450
  598. OpDecorate %const BuiltIn )" +
  599. deco + R"(
  600. %int = OpTypeInt 32 0
  601. %int3 = OpTypeVector %int 3
  602. %int_1 = OpConstant %int 1
  603. %const = OpConstantComposite %int3 %int_1 %int_1 %int_1
  604. )";
  605. CompileSuccessfully(text);
  606. if (deco == "WorkgroupSize") {
  607. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  608. } else {
  609. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  610. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  611. }
  612. }
  613. TEST_P(BuiltInDecorations, SpecConstant) {
  614. const auto deco = GetParam();
  615. const std::string text = R"(
  616. OpCapability Shader
  617. OpCapability Linkage
  618. OpMemoryModel Logical GLSL450
  619. OpDecorate %const BuiltIn )" +
  620. deco + R"(
  621. %int = OpTypeInt 32 0
  622. %int3 = OpTypeVector %int 3
  623. %int_1 = OpConstant %int 1
  624. %const = OpSpecConstantComposite %int3 %int_1 %int_1 %int_1
  625. )";
  626. CompileSuccessfully(text);
  627. if (deco == "WorkgroupSize") {
  628. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  629. } else {
  630. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  631. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  632. }
  633. }
  634. INSTANTIATE_TEST_SUITE_P(ValidateBuiltInDecorations, BuiltInDecorations,
  635. Values("Position", "PointSize", "VertexId",
  636. "InstanceId", "FragCoord", "FrontFacing",
  637. "NumWorkgroups", "WorkgroupSize",
  638. "LocalInvocationId", "GlobalInvocationId"));
  639. using MemoryObjectDecorations = spvtest::ValidateBase<std::string>;
  640. TEST_P(MemoryObjectDecorations, Variable) {
  641. const auto deco = GetParam();
  642. const std::string text = R"(
  643. OpCapability Shader
  644. OpCapability Linkage
  645. OpCapability SampleRateShading
  646. OpCapability TransformFeedback
  647. OpCapability GeometryStreams
  648. OpCapability Tessellation
  649. OpCapability PhysicalStorageBufferAddresses
  650. OpExtension "SPV_KHR_physical_storage_buffer"
  651. OpMemoryModel Logical GLSL450
  652. OpDecorate %var )" + deco + R"(
  653. %float = OpTypeFloat 32
  654. %ptr = OpTypePointer Input %float
  655. %var = OpVariable %ptr Input
  656. )";
  657. CompileSuccessfully(text);
  658. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  659. }
  660. TEST_P(MemoryObjectDecorations, FunctionParameterGood) {
  661. const auto deco = GetParam();
  662. const std::string text = R"(
  663. OpCapability Shader
  664. OpCapability Linkage
  665. OpCapability SampleRateShading
  666. OpCapability TransformFeedback
  667. OpCapability GeometryStreams
  668. OpCapability Tessellation
  669. OpCapability PhysicalStorageBufferAddresses
  670. OpExtension "SPV_KHR_physical_storage_buffer"
  671. OpMemoryModel Logical GLSL450
  672. OpDecorate %func LinkageAttributes "import" Import
  673. OpDecorate %param )" + deco +
  674. R"(
  675. %float = OpTypeFloat 32
  676. %ptr = OpTypePointer Input %float
  677. %void = OpTypeVoid
  678. %fn = OpTypeFunction %void %ptr
  679. %func = OpFunction %void None %fn
  680. %param = OpFunctionParameter %ptr
  681. OpFunctionEnd
  682. )";
  683. CompileSuccessfully(text);
  684. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  685. }
  686. TEST_P(MemoryObjectDecorations, FunctionParameterNotAPointer) {
  687. const auto deco = GetParam();
  688. const std::string text = R"(
  689. OpCapability Shader
  690. OpCapability Linkage
  691. OpCapability SampleRateShading
  692. OpCapability TransformFeedback
  693. OpCapability GeometryStreams
  694. OpCapability Tessellation
  695. OpCapability PhysicalStorageBufferAddresses
  696. OpExtension "SPV_KHR_physical_storage_buffer"
  697. OpMemoryModel Logical GLSL450
  698. OpDecorate %func LinkageAttributes "import" Import
  699. OpDecorate %param )" + deco +
  700. R"(
  701. %float = OpTypeFloat 32
  702. %void = OpTypeVoid
  703. %fn = OpTypeFunction %void %float
  704. %func = OpFunction %void None %fn
  705. %param = OpFunctionParameter %float
  706. OpFunctionEnd
  707. )";
  708. CompileSuccessfully(text);
  709. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  710. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a pointer type"));
  711. }
  712. TEST_P(MemoryObjectDecorations, FloatType) {
  713. const auto deco = GetParam();
  714. const std::string text = R"(
  715. OpCapability Shader
  716. OpCapability Linkage
  717. OpCapability SampleRateShading
  718. OpCapability TransformFeedback
  719. OpCapability GeometryStreams
  720. OpCapability Tessellation
  721. OpCapability PhysicalStorageBufferAddresses
  722. OpExtension "SPV_KHR_physical_storage_buffer"
  723. OpMemoryModel Logical GLSL450
  724. OpDecorate %float )" + deco +
  725. R"(
  726. %float = OpTypeFloat 32
  727. )";
  728. CompileSuccessfully(text);
  729. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  730. EXPECT_THAT(getDiagnosticString(),
  731. HasSubstr("must be a memory object declaration"));
  732. }
  733. TEST_P(MemoryObjectDecorations, Constant) {
  734. const auto deco = GetParam();
  735. const std::string text = R"(
  736. OpCapability Shader
  737. OpCapability Linkage
  738. OpCapability SampleRateShading
  739. OpCapability TransformFeedback
  740. OpCapability GeometryStreams
  741. OpCapability Tessellation
  742. OpCapability PhysicalStorageBufferAddresses
  743. OpExtension "SPV_KHR_physical_storage_buffer"
  744. OpMemoryModel Logical GLSL450
  745. OpDecorate %const )" + deco +
  746. R"(
  747. %float = OpTypeFloat 32
  748. %const = OpConstant %float 0
  749. )";
  750. CompileSuccessfully(text);
  751. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  752. EXPECT_THAT(getDiagnosticString(),
  753. HasSubstr("must be a memory object declaration"));
  754. }
  755. // NonWritable and NonReadable are covered by other tests.
  756. INSTANTIATE_TEST_SUITE_P(
  757. ValidateMemoryObjectDecorations, MemoryObjectDecorations,
  758. Values("NoPerspective", "Flat", "Patch", "Centroid", "Component 0",
  759. "Sample", "Restrict", "Aliased", "Volatile", "Coherent", "Stream 0",
  760. "XfbBuffer 1", "XfbStride 1", "AliasedPointer", "RestrictPointer"));
  761. using VariableDecorations = spvtest::ValidateBase<std::string>;
  762. TEST_P(VariableDecorations, Variable) {
  763. const auto deco = GetParam();
  764. const std::string text = R"(
  765. OpCapability Shader
  766. OpCapability Kernel
  767. OpCapability Linkage
  768. OpCapability InputAttachment
  769. OpMemoryModel Logical GLSL450
  770. OpDecorate %var )" + deco + R"(
  771. %float = OpTypeFloat 32
  772. %ptr = OpTypePointer Input %float
  773. %var = OpVariable %ptr Input
  774. )";
  775. CompileSuccessfully(text);
  776. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  777. }
  778. TEST_P(VariableDecorations, FunctionParameter) {
  779. const auto deco = GetParam();
  780. const std::string text = R"(
  781. OpCapability Shader
  782. OpCapability Kernel
  783. OpCapability Linkage
  784. OpCapability InputAttachment
  785. OpMemoryModel Logical GLSL450
  786. OpDecorate %func LinkageAttributes "import" Import
  787. OpDecorate %param )" + deco +
  788. R"(
  789. %float = OpTypeFloat 32
  790. %void = OpTypeVoid
  791. %fn = OpTypeFunction %void %float
  792. %func = OpFunction %void None %fn
  793. %param = OpFunctionParameter %float
  794. OpFunctionEnd
  795. )";
  796. CompileSuccessfully(text);
  797. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  798. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  799. }
  800. TEST_P(VariableDecorations, FloatType) {
  801. const auto deco = GetParam();
  802. const std::string text = R"(
  803. OpCapability Shader
  804. OpCapability Kernel
  805. OpCapability Linkage
  806. OpCapability InputAttachment
  807. OpMemoryModel Logical GLSL450
  808. OpDecorate %float )" + deco +
  809. R"(
  810. %float = OpTypeFloat 32
  811. )";
  812. CompileSuccessfully(text);
  813. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  814. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  815. }
  816. TEST_P(VariableDecorations, Constant) {
  817. const auto deco = GetParam();
  818. const std::string text = R"(
  819. OpCapability Shader
  820. OpCapability Kernel
  821. OpCapability Linkage
  822. OpCapability InputAttachment
  823. OpMemoryModel Logical GLSL450
  824. OpDecorate %const )" + deco +
  825. R"(
  826. %float = OpTypeFloat 32
  827. %const = OpConstant %float 0
  828. )";
  829. CompileSuccessfully(text);
  830. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  831. EXPECT_THAT(getDiagnosticString(), HasSubstr("must be a variable"));
  832. }
  833. INSTANTIATE_TEST_SUITE_P(ValidateVariableDecorations, VariableDecorations,
  834. Values("Invariant", "Constant", "Location 0",
  835. "Index 0", "Binding 0", "DescriptorSet 0"));
  836. using VulkanIOStorageClass =
  837. spvtest::ValidateBase<std::tuple<std::string, std::string>>;
  838. TEST_P(VulkanIOStorageClass, Invalid) {
  839. const auto deco = std::get<0>(GetParam());
  840. const auto sc = std::get<1>(GetParam());
  841. const std::string text = R"(
  842. OpCapability Shader
  843. OpExtension "SPV_KHR_storage_buffer_storage_class"
  844. OpMemoryModel Logical GLSL450
  845. OpEntryPoint Fragment %main "main"
  846. OpExecutionMode %main OriginUpperLeft
  847. OpDecorate %var )" + deco + R"( 0
  848. %void = OpTypeVoid
  849. %float = OpTypeFloat 32
  850. %ptr = OpTypePointer )" +
  851. sc +
  852. R"( %float
  853. %var = OpVariable %ptr )" + sc +
  854. R"(
  855. %void_fn = OpTypeFunction %void
  856. %main = OpFunction %void None %void_fn
  857. %entry = OpLabel
  858. OpReturn
  859. OpFunctionEnd
  860. )";
  861. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  862. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  863. EXPECT_THAT(getDiagnosticString(),
  864. AnyVUID("VUID-StandaloneSpirv-Location-06672"));
  865. EXPECT_THAT(
  866. getDiagnosticString(),
  867. HasSubstr("decoration must not be applied to this storage class"));
  868. }
  869. INSTANTIATE_TEST_SUITE_P(ValidateVulkanIOStorageClass, VulkanIOStorageClass,
  870. Combine(Values("Location", "Component"),
  871. Values("StorageBuffer", "Uniform",
  872. "UniformConstant", "Workgroup",
  873. "Private")));
  874. using VulkanResourceStorageClass =
  875. spvtest::ValidateBase<std::tuple<std::string, std::string>>;
  876. TEST_P(VulkanResourceStorageClass, Invalid) {
  877. const auto deco = std::get<0>(GetParam());
  878. const auto sc = std::get<1>(GetParam());
  879. const std::string text = R"(
  880. OpCapability Shader
  881. OpMemoryModel Logical GLSL450
  882. OpEntryPoint Fragment %main "main"
  883. OpExecutionMode %main OriginUpperLeft
  884. OpDecorate %var )" + deco + R"( 0
  885. %void = OpTypeVoid
  886. %float = OpTypeFloat 32
  887. %ptr = OpTypePointer )" +
  888. sc +
  889. R"( %float
  890. %var = OpVariable %ptr )" + sc +
  891. R"(
  892. %void_fn = OpTypeFunction %void
  893. %main = OpFunction %void None %void_fn
  894. %entry = OpLabel
  895. OpReturn
  896. OpFunctionEnd
  897. )";
  898. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  899. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  900. EXPECT_THAT(getDiagnosticString(),
  901. HasSubstr("VUID-StandaloneSpirv-DescriptorSet-06491"));
  902. EXPECT_THAT(getDiagnosticString(),
  903. HasSubstr("must be in the StorageBuffer, Uniform, or "
  904. "UniformConstant storage class"));
  905. }
  906. INSTANTIATE_TEST_SUITE_P(ValidateVulkanResourceStorageClass,
  907. VulkanResourceStorageClass,
  908. Combine(Values("DescriptorSet", "Binding"),
  909. Values("Private", "Input", "Output",
  910. "Workgroup")));
  911. using VulkanInterpolationStorageClass = spvtest::ValidateBase<std::string>;
  912. TEST_P(VulkanInterpolationStorageClass, Input) {
  913. const auto deco = GetParam();
  914. const std::string text = R"(
  915. OpCapability Shader
  916. OpCapability SampleRateShading
  917. OpMemoryModel Logical GLSL450
  918. OpEntryPoint Fragment %main "main"
  919. OpExecutionMode %main OriginUpperLeft
  920. OpDecorate %var )" + deco + R"(
  921. %void = OpTypeVoid
  922. %float = OpTypeFloat 32
  923. %void_fn = OpTypeFunction %void
  924. %ptr = OpTypePointer Input %float
  925. %var = OpVariable %ptr 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_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  933. }
  934. TEST_P(VulkanInterpolationStorageClass, Output) {
  935. const auto deco = GetParam();
  936. const std::string text = R"(
  937. OpCapability Shader
  938. OpCapability SampleRateShading
  939. OpMemoryModel Logical GLSL450
  940. OpEntryPoint Vertex %main "main"
  941. OpDecorate %var )" + deco + R"(
  942. %void = OpTypeVoid
  943. %float = OpTypeFloat 32
  944. %void_fn = OpTypeFunction %void
  945. %ptr = OpTypePointer Output %float
  946. %var = OpVariable %ptr Output
  947. %main = OpFunction %void None %void_fn
  948. %entry = OpLabel
  949. OpReturn
  950. OpFunctionEnd
  951. )";
  952. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  953. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  954. }
  955. TEST_P(VulkanInterpolationStorageClass, Private) {
  956. const auto deco = GetParam();
  957. const std::string text = R"(
  958. OpCapability Shader
  959. OpCapability SampleRateShading
  960. OpMemoryModel Logical GLSL450
  961. OpEntryPoint Fragment %main "main"
  962. OpExecutionMode %main OriginUpperLeft
  963. OpDecorate %var )" + deco + R"(
  964. %void = OpTypeVoid
  965. %float = OpTypeFloat 32
  966. %void_fn = OpTypeFunction %void
  967. %ptr = OpTypePointer Private %float
  968. %var = OpVariable %ptr Private
  969. %main = OpFunction %void None %void_fn
  970. %entry = OpLabel
  971. OpReturn
  972. OpFunctionEnd
  973. )";
  974. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  975. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  976. EXPECT_THAT(getDiagnosticString(),
  977. HasSubstr("storage class must be Input or Output"));
  978. EXPECT_THAT(getDiagnosticString(),
  979. HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
  980. }
  981. TEST_P(VulkanInterpolationStorageClass, Uniform) {
  982. const auto deco = GetParam();
  983. const std::string text = R"(
  984. OpCapability Shader
  985. OpCapability SampleRateShading
  986. OpMemoryModel Logical GLSL450
  987. OpEntryPoint Fragment %main "main"
  988. OpExecutionMode %main OriginUpperLeft
  989. OpDecorate %var )" + deco + R"(
  990. OpDecorate %var Binding 0
  991. OpDecorate %var DescriptorSet 0
  992. %void = OpTypeVoid
  993. %float = OpTypeFloat 32
  994. %void_fn = OpTypeFunction %void
  995. %ptr = OpTypePointer Uniform %float
  996. %var = OpVariable %ptr Uniform
  997. %main = OpFunction %void None %void_fn
  998. %entry = OpLabel
  999. OpReturn
  1000. OpFunctionEnd
  1001. )";
  1002. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1003. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1004. EXPECT_THAT(getDiagnosticString(),
  1005. HasSubstr("storage class must be Input or Output"));
  1006. EXPECT_THAT(getDiagnosticString(),
  1007. HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
  1008. }
  1009. TEST_P(VulkanInterpolationStorageClass, StorageBuffer) {
  1010. const auto deco = GetParam();
  1011. const std::string text = R"(
  1012. OpCapability Shader
  1013. OpCapability SampleRateShading
  1014. OpExtension "SPV_KHR_storage_buffer_storage_class"
  1015. OpMemoryModel Logical GLSL450
  1016. OpEntryPoint Fragment %main "main"
  1017. OpExecutionMode %main OriginUpperLeft
  1018. OpDecorate %var )" + deco + R"(
  1019. OpDecorate %var Binding 0
  1020. OpDecorate %var DescriptorSet 0
  1021. %void = OpTypeVoid
  1022. %float = OpTypeFloat 32
  1023. %void_fn = OpTypeFunction %void
  1024. %ptr = OpTypePointer StorageBuffer %float
  1025. %var = OpVariable %ptr StorageBuffer
  1026. %main = OpFunction %void None %void_fn
  1027. %entry = OpLabel
  1028. OpReturn
  1029. OpFunctionEnd
  1030. )";
  1031. CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
  1032. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
  1033. EXPECT_THAT(getDiagnosticString(),
  1034. HasSubstr("storage class must be Input or Output"));
  1035. EXPECT_THAT(getDiagnosticString(),
  1036. HasSubstr("[VUID-StandaloneSpirv-Flat-04670"));
  1037. }
  1038. INSTANTIATE_TEST_SUITE_P(ValidateVulkanInterpolationStorageClass,
  1039. VulkanInterpolationStorageClass,
  1040. Values("Flat", "NoPerspective", "Centroid", "Sample"));
  1041. } // namespace
  1042. } // namespace val
  1043. } // namespace spvtools