val_constants_test.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. // Copyright (c) 2019 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. // Test validation of constants.
  15. //
  16. // This file contains newer tests. Older tests may be in other files such as
  17. // val_id_test.cpp.
  18. #include <string>
  19. #include <vector>
  20. #include "gmock/gmock.h"
  21. #include "test/unit_spirv.h"
  22. #include "test/val/val_code_generator.h"
  23. #include "test/val/val_fixtures.h"
  24. namespace spvtools {
  25. namespace val {
  26. namespace {
  27. using ::testing::Combine;
  28. using ::testing::Eq;
  29. using ::testing::HasSubstr;
  30. using ::testing::Values;
  31. using ::testing::ValuesIn;
  32. using ValidateConstant = spvtest::ValidateBase<bool>;
  33. #define kBasicTypes \
  34. "%bool = OpTypeBool " \
  35. "%uint = OpTypeInt 32 0 " \
  36. "%uint2 = OpTypeVector %uint 2 " \
  37. "%float = OpTypeFloat 32 " \
  38. "%_ptr_uint = OpTypePointer Workgroup %uint " \
  39. "%uint_0 = OpConstantNull %uint " \
  40. "%uint2_0 = OpConstantNull %uint " \
  41. "%float_0 = OpConstantNull %float " \
  42. "%false = OpConstantFalse %bool " \
  43. "%true = OpConstantTrue %bool " \
  44. "%null = OpConstantNull %_ptr_uint "
  45. #define kShaderPreamble \
  46. "OpCapability Shader\n" \
  47. "OpCapability Linkage\n" \
  48. "OpMemoryModel Logical Simple\n"
  49. #define kKernelPreamble \
  50. "OpCapability Kernel\n" \
  51. "OpCapability Linkage\n" \
  52. "OpCapability Addresses\n" \
  53. "OpMemoryModel Physical32 OpenCL\n"
  54. struct ConstantOpCase {
  55. spv_target_env env;
  56. std::string assembly;
  57. bool expect_success;
  58. std::string expect_err;
  59. };
  60. using ValidateConstantOp = spvtest::ValidateBase<ConstantOpCase>;
  61. TEST_P(ValidateConstantOp, Samples) {
  62. const auto env = GetParam().env;
  63. CompileSuccessfully(GetParam().assembly, env);
  64. const auto result = ValidateInstructions(env);
  65. if (GetParam().expect_success) {
  66. EXPECT_EQ(SPV_SUCCESS, result);
  67. EXPECT_THAT(getDiagnosticString(), Eq(""));
  68. } else {
  69. EXPECT_EQ(SPV_ERROR_INVALID_ID, result);
  70. EXPECT_THAT(getDiagnosticString(), HasSubstr(GetParam().expect_err));
  71. }
  72. }
  73. #define GOOD_SHADER_10(STR) \
  74. { SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, true, "" }
  75. #define GOOD_KERNEL_10(STR) \
  76. { SPV_ENV_UNIVERSAL_1_0, kKernelPreamble kBasicTypes STR, true, "" }
  77. INSTANTIATE_TEST_SUITE_P(
  78. UniversalInShader, ValidateConstantOp,
  79. ValuesIn(std::vector<ConstantOpCase>{
  80. // TODO(dneto): Conversions must change width.
  81. GOOD_SHADER_10("%v = OpSpecConstantOp %uint SConvert %uint_0"),
  82. GOOD_SHADER_10("%v = OpSpecConstantOp %float FConvert %float_0"),
  83. GOOD_SHADER_10("%v = OpSpecConstantOp %uint SNegate %uint_0"),
  84. GOOD_SHADER_10("%v = OpSpecConstantOp %uint Not %uint_0"),
  85. GOOD_SHADER_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"),
  86. GOOD_SHADER_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"),
  87. GOOD_SHADER_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"),
  88. GOOD_SHADER_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"),
  89. GOOD_SHADER_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"),
  90. GOOD_SHADER_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"),
  91. GOOD_SHADER_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"),
  92. GOOD_SHADER_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"),
  93. GOOD_SHADER_10(
  94. "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"),
  95. GOOD_SHADER_10(
  96. "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"),
  97. GOOD_SHADER_10(
  98. "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"),
  99. GOOD_SHADER_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"),
  100. GOOD_SHADER_10(
  101. "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"),
  102. GOOD_SHADER_10(
  103. "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"),
  104. GOOD_SHADER_10(
  105. "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"),
  106. GOOD_SHADER_10(
  107. "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"),
  108. GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"),
  109. GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalNot %true"),
  110. GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"),
  111. GOOD_SHADER_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"),
  112. GOOD_SHADER_10(
  113. "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"),
  114. GOOD_SHADER_10(
  115. "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"),
  116. GOOD_SHADER_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"),
  117. GOOD_SHADER_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"),
  118. GOOD_SHADER_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"),
  119. GOOD_SHADER_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"),
  120. GOOD_SHADER_10(
  121. "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"),
  122. GOOD_SHADER_10(
  123. "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"),
  124. GOOD_SHADER_10(
  125. "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"),
  126. GOOD_SHADER_10(
  127. "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"),
  128. GOOD_SHADER_10(
  129. "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"),
  130. GOOD_SHADER_10(
  131. "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"),
  132. }));
  133. INSTANTIATE_TEST_SUITE_P(
  134. UniversalInKernel, ValidateConstantOp,
  135. ValuesIn(std::vector<ConstantOpCase>{
  136. // TODO(dneto): Conversions must change width.
  137. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SConvert %uint_0"),
  138. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FConvert %float_0"),
  139. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SNegate %uint_0"),
  140. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Not %uint_0"),
  141. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IAdd %uint_0 %uint_0"),
  142. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ISub %uint_0 %uint_0"),
  143. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint IMul %uint_0 %uint_0"),
  144. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UDiv %uint_0 %uint_0"),
  145. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SDiv %uint_0 %uint_0"),
  146. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UMod %uint_0 %uint_0"),
  147. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SRem %uint_0 %uint_0"),
  148. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint SMod %uint_0 %uint_0"),
  149. GOOD_KERNEL_10(
  150. "%v = OpSpecConstantOp %uint ShiftRightLogical %uint_0 %uint_0"),
  151. GOOD_KERNEL_10(
  152. "%v = OpSpecConstantOp %uint ShiftRightArithmetic %uint_0 %uint_0"),
  153. GOOD_KERNEL_10(
  154. "%v = OpSpecConstantOp %uint ShiftLeftLogical %uint_0 %uint_0"),
  155. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint BitwiseOr %uint_0 %uint_0"),
  156. GOOD_KERNEL_10(
  157. "%v = OpSpecConstantOp %uint BitwiseXor %uint_0 %uint_0"),
  158. GOOD_KERNEL_10(
  159. "%v = OpSpecConstantOp %uint2 VectorShuffle %uint2_0 %uint2_0 1 3"),
  160. GOOD_KERNEL_10(
  161. "%v = OpSpecConstantOp %uint CompositeExtract %uint2_0 1"),
  162. GOOD_KERNEL_10(
  163. "%v = OpSpecConstantOp %uint2 CompositeInsert %uint_0 %uint2_0 1"),
  164. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalOr %true %false"),
  165. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalNot %true"),
  166. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalAnd %true %false"),
  167. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool LogicalEqual %true %false"),
  168. GOOD_KERNEL_10(
  169. "%v = OpSpecConstantOp %bool LogicalNotEqual %true %false"),
  170. GOOD_KERNEL_10(
  171. "%v = OpSpecConstantOp %uint Select %true %uint_0 %uint_0"),
  172. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool IEqual %uint_0 %uint_0"),
  173. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool INotEqual %uint_0 %uint_0"),
  174. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool ULessThan %uint_0 %uint_0"),
  175. GOOD_KERNEL_10("%v = OpSpecConstantOp %bool SLessThan %uint_0 %uint_0"),
  176. GOOD_KERNEL_10(
  177. "%v = OpSpecConstantOp %bool ULessThanEqual %uint_0 %uint_0"),
  178. GOOD_KERNEL_10(
  179. "%v = OpSpecConstantOp %bool SLessThanEqual %uint_0 %uint_0"),
  180. GOOD_KERNEL_10(
  181. "%v = OpSpecConstantOp %bool UGreaterThan %uint_0 %uint_0"),
  182. GOOD_KERNEL_10(
  183. "%v = OpSpecConstantOp %bool UGreaterThanEqual %uint_0 %uint_0"),
  184. GOOD_KERNEL_10(
  185. "%v = OpSpecConstantOp %bool SGreaterThan %uint_0 %uint_0"),
  186. GOOD_KERNEL_10(
  187. "%v = OpSpecConstantOp %bool SGreaterThanEqual %uint_0 %uint_0"),
  188. }));
  189. INSTANTIATE_TEST_SUITE_P(
  190. UConvert, ValidateConstantOp,
  191. ValuesIn(std::vector<ConstantOpCase>{
  192. // TODO(dneto): Conversions must change width.
  193. {SPV_ENV_UNIVERSAL_1_0,
  194. kKernelPreamble kBasicTypes
  195. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  196. true, ""},
  197. {SPV_ENV_UNIVERSAL_1_1,
  198. kKernelPreamble kBasicTypes
  199. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  200. true, ""},
  201. {SPV_ENV_UNIVERSAL_1_3,
  202. kKernelPreamble kBasicTypes
  203. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  204. true, ""},
  205. {SPV_ENV_UNIVERSAL_1_3,
  206. kKernelPreamble kBasicTypes
  207. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  208. true, ""},
  209. {SPV_ENV_UNIVERSAL_1_4,
  210. kKernelPreamble kBasicTypes
  211. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  212. true, ""},
  213. {SPV_ENV_UNIVERSAL_1_0,
  214. kShaderPreamble kBasicTypes
  215. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  216. false,
  217. "Prior to SPIR-V 1.4, specialization constant operation "
  218. "UConvert requires Kernel capability"},
  219. {SPV_ENV_UNIVERSAL_1_1,
  220. kShaderPreamble kBasicTypes
  221. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  222. false,
  223. "Prior to SPIR-V 1.4, specialization constant operation "
  224. "UConvert requires Kernel capability"},
  225. {SPV_ENV_UNIVERSAL_1_3,
  226. kShaderPreamble kBasicTypes
  227. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  228. false,
  229. "Prior to SPIR-V 1.4, specialization constant operation "
  230. "UConvert requires Kernel capability"},
  231. {SPV_ENV_UNIVERSAL_1_3,
  232. kShaderPreamble kBasicTypes
  233. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  234. false,
  235. "Prior to SPIR-V 1.4, specialization constant operation "
  236. "UConvert requires Kernel capability"},
  237. {SPV_ENV_UNIVERSAL_1_4,
  238. kShaderPreamble kBasicTypes
  239. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  240. true, ""},
  241. }));
  242. INSTANTIATE_TEST_SUITE_P(
  243. KernelInKernel, ValidateConstantOp,
  244. ValuesIn(std::vector<ConstantOpCase>{
  245. // TODO(dneto): Conversions must change width.
  246. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0"),
  247. GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0"),
  248. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0"),
  249. GOOD_KERNEL_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0"),
  250. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint UConvert %uint_0"),
  251. GOOD_KERNEL_10(
  252. "%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null"),
  253. GOOD_KERNEL_10(
  254. "%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null"),
  255. GOOD_KERNEL_10("%v = OpSpecConstantOp %uint Bitcast %uint_0"),
  256. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FNegate %float_0"),
  257. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0"),
  258. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0"),
  259. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0"),
  260. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0"),
  261. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0"),
  262. GOOD_KERNEL_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0"),
  263. GOOD_KERNEL_10(
  264. "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0"),
  265. GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain "
  266. "%null %uint_0"),
  267. GOOD_KERNEL_10(
  268. "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0"),
  269. GOOD_KERNEL_10("%v = OpSpecConstantOp %_ptr_uint "
  270. "InBoundsPtrAccessChain %null %uint_0"),
  271. }));
  272. #define BAD_SHADER_10(STR, NAME) \
  273. { \
  274. SPV_ENV_UNIVERSAL_1_0, kShaderPreamble kBasicTypes STR, false, \
  275. "Specialization constant operation " NAME \
  276. " requires Kernel capability" \
  277. }
  278. INSTANTIATE_TEST_SUITE_P(
  279. KernelInShader, ValidateConstantOp,
  280. ValuesIn(std::vector<ConstantOpCase>{
  281. // TODO(dneto): Conversions must change width.
  282. BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToS %float_0",
  283. "ConvertFToS"),
  284. BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertSToF %uint_0",
  285. "ConvertSToF"),
  286. BAD_SHADER_10("%v = OpSpecConstantOp %uint ConvertFToU %float_0",
  287. "ConvertFToU"),
  288. BAD_SHADER_10("%v = OpSpecConstantOp %float ConvertUToF %uint_0",
  289. "ConvertUToF"),
  290. BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint GenericCastToPtr %null",
  291. "GenericCastToPtr"),
  292. BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint PtrCastToGeneric %null",
  293. "PtrCastToGeneric"),
  294. BAD_SHADER_10("%v = OpSpecConstantOp %uint Bitcast %uint_0", "Bitcast"),
  295. BAD_SHADER_10("%v = OpSpecConstantOp %float FNegate %float_0",
  296. "FNegate"),
  297. BAD_SHADER_10("%v = OpSpecConstantOp %float FAdd %float_0 %float_0",
  298. "FAdd"),
  299. BAD_SHADER_10("%v = OpSpecConstantOp %float FSub %float_0 %float_0",
  300. "FSub"),
  301. BAD_SHADER_10("%v = OpSpecConstantOp %float FMul %float_0 %float_0",
  302. "FMul"),
  303. BAD_SHADER_10("%v = OpSpecConstantOp %float FDiv %float_0 %float_0",
  304. "FDiv"),
  305. BAD_SHADER_10("%v = OpSpecConstantOp %float FRem %float_0 %float_0",
  306. "FRem"),
  307. BAD_SHADER_10("%v = OpSpecConstantOp %float FMod %float_0 %float_0",
  308. "FMod"),
  309. BAD_SHADER_10(
  310. "%v = OpSpecConstantOp %_ptr_uint AccessChain %null %uint_0",
  311. "AccessChain"),
  312. BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint InBoundsAccessChain "
  313. "%null %uint_0",
  314. "InBoundsAccessChain"),
  315. BAD_SHADER_10(
  316. "%v = OpSpecConstantOp %_ptr_uint PtrAccessChain %null %uint_0",
  317. "PtrAccessChain"),
  318. BAD_SHADER_10("%v = OpSpecConstantOp %_ptr_uint "
  319. "InBoundsPtrAccessChain %null %uint_0",
  320. "InBoundsPtrAccessChain"),
  321. }));
  322. INSTANTIATE_TEST_SUITE_P(
  323. UConvertInAMD_gpu_shader_int16, ValidateConstantOp,
  324. ValuesIn(std::vector<ConstantOpCase>{
  325. // SPV_AMD_gpu_shader_int16 should enable UConvert for OpSpecConstantOp
  326. // https://github.com/KhronosGroup/glslang/issues/848
  327. {SPV_ENV_UNIVERSAL_1_0,
  328. "OpCapability Shader "
  329. "OpCapability Linkage ; So we don't need to define a function\n"
  330. "OpExtension \"SPV_AMD_gpu_shader_int16\" "
  331. "OpMemoryModel Logical Simple " kBasicTypes
  332. "%v = OpSpecConstantOp %uint UConvert %uint_0",
  333. true, ""},
  334. }));
  335. TEST_F(ValidateConstant, SpecConstantUConvert1p3Binary1p4EnvBad) {
  336. const std::string spirv = R"(
  337. OpCapability Shader
  338. OpCapability Linkage
  339. OpMemoryModel Logical GLSL450
  340. %int = OpTypeInt 32 0
  341. %int0 = OpConstant %int 0
  342. %const = OpSpecConstantOp %int UConvert %int0
  343. )";
  344. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  345. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  346. EXPECT_THAT(
  347. getDiagnosticString(),
  348. HasSubstr(
  349. "Prior to SPIR-V 1.4, specialization constant operation UConvert "
  350. "requires Kernel capability or extension SPV_AMD_gpu_shader_int16"));
  351. }
  352. using SmallStorageConstants = spvtest::ValidateBase<std::string>;
  353. CodeGenerator GetSmallStorageCodeGenerator() {
  354. CodeGenerator generator;
  355. generator.capabilities_ = R"(
  356. OpCapability Shader
  357. OpCapability Linkage
  358. OpCapability UniformAndStorageBuffer16BitAccess
  359. OpCapability StoragePushConstant16
  360. OpCapability StorageInputOutput16
  361. OpCapability UniformAndStorageBuffer8BitAccess
  362. OpCapability StoragePushConstant8
  363. )";
  364. generator.extensions_ = R"(
  365. OpExtension "SPV_KHR_16bit_storage"
  366. OpExtension "SPV_KHR_8bit_storage"
  367. )";
  368. generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
  369. generator.types_ = R"(
  370. %short = OpTypeInt 16 0
  371. %short2 = OpTypeVector %short 2
  372. %char = OpTypeInt 8 0
  373. %char2 = OpTypeVector %char 2
  374. %half = OpTypeFloat 16
  375. %half2 = OpTypeVector %half 2
  376. %int = OpTypeInt 32 0
  377. %int_0 = OpConstant %int 0
  378. %float = OpTypeFloat 32
  379. %float_0 = OpConstant %float 0
  380. )";
  381. return generator;
  382. }
  383. TEST_P(SmallStorageConstants, SmallConstant) {
  384. std::string constant = GetParam();
  385. CodeGenerator generator = GetSmallStorageCodeGenerator();
  386. generator.after_types_ += constant + "\n";
  387. CompileSuccessfully(generator.Build(), SPV_ENV_UNIVERSAL_1_3);
  388. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  389. EXPECT_THAT(getDiagnosticString(),
  390. HasSubstr("Cannot form constants of 8- or 16-bit types"));
  391. }
  392. // Constant composites would be caught through scalar constants.
  393. INSTANTIATE_TEST_SUITE_P(
  394. SmallConstants, SmallStorageConstants,
  395. Values("%c = OpConstant %char 0", "%c = OpConstantNull %char2",
  396. "%c = OpConstant %short 0", "%c = OpConstantNull %short",
  397. "%c = OpConstant %half 0", "%c = OpConstantNull %half",
  398. "%c = OpSpecConstant %char 0", "%c = OpSpecConstant %short 0",
  399. "%c = OpSpecConstant %half 0",
  400. "%c = OpSpecConstantOp %char SConvert %int_0",
  401. "%c = OpSpecConstantOp %short SConvert %int_0",
  402. "%c = OpSpecConstantOp %half FConvert %float_0"));
  403. TEST_F(ValidateConstant, NullPointerTo16BitStorageOk) {
  404. std::string spirv = R"(
  405. OpCapability Shader
  406. OpCapability VariablePointersStorageBuffer
  407. OpCapability UniformAndStorageBuffer16BitAccess
  408. OpCapability Linkage
  409. OpExtension "SPV_KHR_16bit_storage"
  410. OpMemoryModel Logical GLSL450
  411. %half = OpTypeFloat 16
  412. %ptr_ssbo_half = OpTypePointer StorageBuffer %half
  413. %null_ptr = OpConstantNull %ptr_ssbo_half
  414. )";
  415. CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
  416. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
  417. }
  418. TEST_F(ValidateConstant, NullMatrix) {
  419. std::string spirv = R"(
  420. OpCapability Shader
  421. OpCapability Linkage
  422. OpMemoryModel Logical GLSL450
  423. %float = OpTypeFloat 32
  424. %v2float = OpTypeVector %float 2
  425. %mat2x2 = OpTypeMatrix %v2float 2
  426. %null_vector = OpConstantNull %v2float
  427. %null_matrix = OpConstantComposite %mat2x2 %null_vector %null_vector
  428. )";
  429. CompileSuccessfully(spirv);
  430. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  431. }
  432. TEST_F(ValidateConstant, NullPhysicalStorageBuffer) {
  433. std::string spirv = R"(
  434. OpCapability Shader
  435. OpCapability PhysicalStorageBufferAddresses
  436. OpCapability Linkage
  437. OpExtension "SPV_KHR_physical_storage_buffer"
  438. OpMemoryModel PhysicalStorageBuffer64 GLSL450
  439. OpName %ptr "ptr"
  440. %int = OpTypeInt 32 0
  441. %ptr = OpTypePointer PhysicalStorageBuffer %int
  442. %null = OpConstantNull %ptr
  443. )";
  444. CompileSuccessfully(spirv);
  445. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  446. EXPECT_THAT(getDiagnosticString(),
  447. HasSubstr("OpConstantNull Result Type <id> '1[%ptr]' cannot have "
  448. "a null value"));
  449. }
  450. TEST_F(ValidateConstant, VectorMismatchedConstituents) {
  451. std::string spirv = kShaderPreamble kBasicTypes R"(
  452. %int = OpTypeInt 32 1
  453. %int_0 = OpConstantNull %int
  454. %const_vector = OpConstantComposite %uint2 %uint_0 %int_0
  455. )";
  456. CompileSuccessfully(spirv);
  457. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  458. EXPECT_THAT(
  459. getDiagnosticString(),
  460. HasSubstr(
  461. "OpConstantComposite Constituent <id> '13[%13]'s type "
  462. "does not match Result Type <id> '3[%v2uint]'s vector element type"));
  463. }
  464. } // namespace
  465. } // namespace val
  466. } // namespace spvtools