val_annotation_test.cpp 28 KB

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