val_opencl_test.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. // Copyright (c) 2019 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Validation tests for OpenCL env specific checks
  15. #include <string>
  16. #include "gmock/gmock.h"
  17. #include "test/val/val_fixtures.h"
  18. namespace spvtools {
  19. namespace val {
  20. namespace {
  21. using testing::Eq;
  22. using testing::HasSubstr;
  23. using ValidateOpenCL = spvtest::ValidateBase<bool>;
  24. TEST_F(ValidateOpenCL, NonPhysicalAddressingModelBad) {
  25. std::string spirv = R"(
  26. OpCapability Kernel
  27. OpMemoryModel Logical OpenCL
  28. )";
  29. CompileSuccessfully(spirv);
  30. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  31. EXPECT_THAT(getDiagnosticString(),
  32. HasSubstr("Addressing model must be Physical32 or Physical64 "
  33. "in the OpenCL environment.\n OpMemoryModel Logical "
  34. "OpenCL\n"));
  35. }
  36. TEST_F(ValidateOpenCL, NonOpenCLMemoryModelBad) {
  37. std::string spirv = R"(
  38. OpCapability Kernel
  39. OpCapability Addresses
  40. OpCapability VulkanMemoryModelKHR
  41. OpExtension "SPV_KHR_vulkan_memory_model"
  42. OpMemoryModel Physical32 VulkanKHR
  43. )";
  44. CompileSuccessfully(spirv);
  45. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  46. EXPECT_THAT(
  47. getDiagnosticString(),
  48. HasSubstr("Memory model must be OpenCL in the OpenCL environment."));
  49. }
  50. TEST_F(ValidateOpenCL, NonVoidSampledTypeImageBad) {
  51. std::string spirv = R"(
  52. OpCapability Addresses
  53. OpCapability Kernel
  54. OpMemoryModel Physical32 OpenCL
  55. %1 = OpTypeInt 32 0
  56. %2 = OpTypeImage %1 2D 0 0 0 0 Unknown ReadOnly
  57. )";
  58. CompileSuccessfully(spirv);
  59. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  60. EXPECT_THAT(
  61. getDiagnosticString(),
  62. HasSubstr("Sampled Type must be OpTypeVoid in the OpenCL environment."
  63. "\n %2 = OpTypeImage %uint 2D 0 0 0 0 Unknown ReadOnly\n"));
  64. }
  65. TEST_F(ValidateOpenCL, NonZeroMSImageBad) {
  66. std::string spirv = R"(
  67. OpCapability Addresses
  68. OpCapability Kernel
  69. OpMemoryModel Physical32 OpenCL
  70. %1 = OpTypeVoid
  71. %2 = OpTypeImage %1 2D 0 0 1 0 Unknown ReadOnly
  72. )";
  73. CompileSuccessfully(spirv);
  74. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  75. EXPECT_THAT(
  76. getDiagnosticString(),
  77. HasSubstr("MS must be 0 in the OpenCL environment."
  78. "\n %2 = OpTypeImage %void 2D 0 0 1 0 Unknown ReadOnly\n"));
  79. }
  80. TEST_F(ValidateOpenCL, Non1D2DArrayedImageBad) {
  81. std::string spirv = R"(
  82. OpCapability Addresses
  83. OpCapability Kernel
  84. OpMemoryModel Physical32 OpenCL
  85. %1 = OpTypeVoid
  86. %2 = OpTypeImage %1 3D 0 1 0 0 Unknown ReadOnly
  87. )";
  88. CompileSuccessfully(spirv);
  89. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  90. EXPECT_THAT(
  91. getDiagnosticString(),
  92. HasSubstr("In the OpenCL environment, Arrayed may only be set to 1 "
  93. "when Dim is either 1D or 2D."
  94. "\n %2 = OpTypeImage %void 3D 0 1 0 0 Unknown ReadOnly\n"));
  95. }
  96. TEST_F(ValidateOpenCL, NonZeroSampledImageBad) {
  97. std::string spirv = R"(
  98. OpCapability Addresses
  99. OpCapability Kernel
  100. OpMemoryModel Physical32 OpenCL
  101. %1 = OpTypeVoid
  102. %2 = OpTypeImage %1 3D 0 0 0 1 Unknown ReadOnly
  103. )";
  104. CompileSuccessfully(spirv);
  105. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  106. EXPECT_THAT(
  107. getDiagnosticString(),
  108. HasSubstr("Sampled must be 0 in the OpenCL environment."
  109. "\n %2 = OpTypeImage %void 3D 0 0 0 1 Unknown ReadOnly\n"));
  110. }
  111. TEST_F(ValidateOpenCL, NoAccessQualifierImageBad) {
  112. std::string spirv = R"(
  113. OpCapability Addresses
  114. OpCapability Kernel
  115. OpMemoryModel Physical32 OpenCL
  116. %1 = OpTypeVoid
  117. %2 = OpTypeImage %1 3D 0 0 0 0 Unknown
  118. )";
  119. CompileSuccessfully(spirv);
  120. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  121. EXPECT_THAT(getDiagnosticString(),
  122. HasSubstr("In the OpenCL environment, the optional "
  123. "Access Qualifier must be present."
  124. "\n %2 = OpTypeImage %void 3D 0 0 0 0 Unknown\n"));
  125. }
  126. TEST_F(ValidateOpenCL, ImageWriteWithOptionalImageOperandsBad) {
  127. std::string spirv = R"(
  128. OpCapability Addresses
  129. OpCapability Kernel
  130. OpCapability ImageBasic
  131. OpMemoryModel Physical64 OpenCL
  132. OpEntryPoint Kernel %5 "test"
  133. %uint = OpTypeInt 32 0
  134. %uint_7 = OpConstant %uint 7
  135. %uint_3 = OpConstant %uint 3
  136. %uint_1 = OpConstant %uint 1
  137. %uint_2 = OpConstant %uint 2
  138. %uint_4 = OpConstant %uint 4
  139. %void = OpTypeVoid
  140. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown WriteOnly
  141. %4 = OpTypeFunction %void %3
  142. %v2uint = OpTypeVector %uint 2
  143. %v4uint = OpTypeVector %uint 4
  144. %12 = OpConstantComposite %v2uint %uint_7 %uint_3
  145. %17 = OpConstantComposite %v4uint %uint_1 %uint_2 %uint_3 %uint_4
  146. %5 = OpFunction %void None %4
  147. %img = OpFunctionParameter %3
  148. %entry = OpLabel
  149. OpImageWrite %img %12 %17 ConstOffset %12
  150. OpReturn
  151. OpFunctionEnd
  152. )";
  153. CompileSuccessfully(spirv);
  154. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  155. EXPECT_THAT(getDiagnosticString(),
  156. HasSubstr("Optional Image Operands are not allowed in the "
  157. "OpenCL environment."
  158. "\n OpImageWrite %15 %13 %14 ConstOffset %13\n"));
  159. }
  160. TEST_F(ValidateOpenCL, ImageReadWithConstOffsetBad) {
  161. std::string spirv = R"(
  162. OpCapability Addresses
  163. OpCapability Kernel
  164. OpCapability ImageBasic
  165. OpMemoryModel Physical64 OpenCL
  166. OpEntryPoint Kernel %5 "image_kernel"
  167. OpName %img "img"
  168. OpName %coord "coord"
  169. OpName %call "call"
  170. %uint = OpTypeInt 32 0
  171. %uint_7 = OpConstant %uint 7
  172. %uint_3 = OpConstant %uint 3
  173. %void = OpTypeVoid
  174. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  175. %4 = OpTypeFunction %void %3
  176. %v4uint = OpTypeVector %uint 4
  177. %v2uint = OpTypeVector %uint 2
  178. %coord = OpConstantComposite %v2uint %uint_7 %uint_3
  179. %5 = OpFunction %void None %4
  180. %img = OpFunctionParameter %3
  181. %entry = OpLabel
  182. %call = OpImageRead %v4uint %img %coord ConstOffset %coord
  183. OpReturn
  184. OpFunctionEnd
  185. )";
  186. CompileSuccessfully(spirv);
  187. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  188. EXPECT_THAT(
  189. getDiagnosticString(),
  190. HasSubstr(
  191. "ConstOffset image operand not allowed in the OpenCL environment."
  192. "\n %call = OpImageRead %v4uint %img %coord ConstOffset %coord\n"));
  193. }
  194. TEST_F(ValidateOpenCL, ImageRead_NonDepthScalarFloatResult_Bad) {
  195. std::string spirv = R"(
  196. OpCapability Addresses
  197. OpCapability Kernel
  198. OpCapability ImageBasic
  199. OpMemoryModel Physical64 OpenCL
  200. OpEntryPoint Kernel %5 "image_kernel"
  201. OpName %img "img"
  202. OpName %coord "coord"
  203. OpName %call "call"
  204. %uint = OpTypeInt 32 0
  205. %v2uint = OpTypeVector %uint 2
  206. %coord = OpConstantNull %v2uint
  207. %void = OpTypeVoid
  208. %float = OpTypeFloat 32
  209. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  210. %4 = OpTypeFunction %void %3
  211. %5 = OpFunction %void None %4
  212. %img = OpFunctionParameter %3
  213. %entry = OpLabel
  214. %call = OpImageRead %float %img %coord
  215. OpReturn
  216. OpFunctionEnd
  217. )";
  218. CompileSuccessfully(spirv);
  219. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  220. EXPECT_THAT(getDiagnosticString(),
  221. HasSubstr("Expected Result Type to have 4 components"));
  222. }
  223. TEST_F(ValidateOpenCL, ImageRead_NonDepthScalarIntResult_Bad) {
  224. std::string spirv = R"(
  225. OpCapability Addresses
  226. OpCapability Kernel
  227. OpCapability ImageBasic
  228. OpMemoryModel Physical64 OpenCL
  229. OpEntryPoint Kernel %5 "image_kernel"
  230. OpName %img "img"
  231. OpName %coord "coord"
  232. OpName %call "call"
  233. %uint = OpTypeInt 32 0
  234. %v2uint = OpTypeVector %uint 2
  235. %coord = OpConstantNull %v2uint
  236. %void = OpTypeVoid
  237. %float = OpTypeFloat 32
  238. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  239. %4 = OpTypeFunction %void %3
  240. %5 = OpFunction %void None %4
  241. %img = OpFunctionParameter %3
  242. %entry = OpLabel
  243. %call = OpImageRead %uint %img %coord
  244. OpReturn
  245. OpFunctionEnd
  246. )";
  247. CompileSuccessfully(spirv);
  248. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  249. EXPECT_THAT(getDiagnosticString(),
  250. HasSubstr("Expected Result Type to have 4 components"));
  251. }
  252. TEST_F(ValidateOpenCL, ImageRead_NonDepthVector3FloatResult_Bad) {
  253. std::string spirv = R"(
  254. OpCapability Addresses
  255. OpCapability Kernel
  256. OpCapability ImageBasic
  257. OpMemoryModel Physical64 OpenCL
  258. OpEntryPoint Kernel %5 "image_kernel"
  259. OpName %img "img"
  260. OpName %coord "coord"
  261. OpName %call "call"
  262. %uint = OpTypeInt 32 0
  263. %v2uint = OpTypeVector %uint 2
  264. %coord = OpConstantNull %v2uint
  265. %void = OpTypeVoid
  266. %float = OpTypeFloat 32
  267. %v3float = OpTypeVector %float 3
  268. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  269. %4 = OpTypeFunction %void %3
  270. %5 = OpFunction %void None %4
  271. %img = OpFunctionParameter %3
  272. %entry = OpLabel
  273. %call = OpImageRead %v3float %img %coord
  274. OpReturn
  275. OpFunctionEnd
  276. )";
  277. CompileSuccessfully(spirv);
  278. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  279. EXPECT_THAT(getDiagnosticString(),
  280. HasSubstr("Expected Result Type to have 4 components"));
  281. }
  282. TEST_F(ValidateOpenCL, ImageRead_NonDepthVector4FloatResult_Ok) {
  283. std::string spirv = R"(
  284. OpCapability Addresses
  285. OpCapability Kernel
  286. OpCapability ImageBasic
  287. OpMemoryModel Physical64 OpenCL
  288. OpEntryPoint Kernel %5 "image_kernel"
  289. OpName %img "img"
  290. OpName %coord "coord"
  291. OpName %call "call"
  292. %uint = OpTypeInt 32 0
  293. %v2uint = OpTypeVector %uint 2
  294. %coord = OpConstantNull %v2uint
  295. %void = OpTypeVoid
  296. %float = OpTypeFloat 32
  297. %v4float = OpTypeVector %float 4
  298. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  299. %4 = OpTypeFunction %void %3
  300. %5 = OpFunction %void None %4
  301. %img = OpFunctionParameter %3
  302. %entry = OpLabel
  303. %call = OpImageRead %v4float %img %coord
  304. OpReturn
  305. OpFunctionEnd
  306. )";
  307. CompileSuccessfully(spirv);
  308. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  309. EXPECT_THAT(getDiagnosticString(), Eq(""));
  310. }
  311. TEST_F(ValidateOpenCL, ImageRead_NonDepthVector4IntResult_Ok) {
  312. std::string spirv = R"(
  313. OpCapability Addresses
  314. OpCapability Kernel
  315. OpCapability ImageBasic
  316. OpMemoryModel Physical64 OpenCL
  317. OpEntryPoint Kernel %5 "image_kernel"
  318. OpName %img "img"
  319. OpName %coord "coord"
  320. OpName %call "call"
  321. %uint = OpTypeInt 32 0
  322. %v2uint = OpTypeVector %uint 2
  323. %coord = OpConstantNull %v2uint
  324. %void = OpTypeVoid
  325. %v4uint = OpTypeVector %uint 4
  326. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  327. %4 = OpTypeFunction %void %3
  328. %5 = OpFunction %void None %4
  329. %img = OpFunctionParameter %3
  330. %entry = OpLabel
  331. %call = OpImageRead %v4uint %img %coord
  332. OpReturn
  333. OpFunctionEnd
  334. )";
  335. CompileSuccessfully(spirv);
  336. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  337. EXPECT_THAT(getDiagnosticString(), Eq(""));
  338. }
  339. TEST_F(ValidateOpenCL, ImageRead_DepthScalarFloatResult_Ok) {
  340. std::string spirv = R"(
  341. OpCapability Addresses
  342. OpCapability Kernel
  343. OpCapability ImageBasic
  344. OpMemoryModel Physical64 OpenCL
  345. OpEntryPoint Kernel %5 "image_kernel"
  346. OpName %img "img"
  347. OpName %coord "coord"
  348. OpName %call "call"
  349. %uint = OpTypeInt 32 0
  350. %v2uint = OpTypeVector %uint 2
  351. %coord = OpConstantNull %v2uint
  352. %void = OpTypeVoid
  353. %float = OpTypeFloat 32
  354. %3 = OpTypeImage %void 2D 1 0 0 0 Unknown ReadOnly
  355. %4 = OpTypeFunction %void %3
  356. %5 = OpFunction %void None %4
  357. %img = OpFunctionParameter %3
  358. %entry = OpLabel
  359. %call = OpImageRead %float %img %coord
  360. OpReturn
  361. OpFunctionEnd
  362. )";
  363. CompileSuccessfully(spirv);
  364. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  365. EXPECT_THAT(getDiagnosticString(), Eq(""));
  366. }
  367. TEST_F(ValidateOpenCL, ImageRead_DepthScalarIntResult_Bad) {
  368. std::string spirv = R"(
  369. OpCapability Addresses
  370. OpCapability Kernel
  371. OpCapability ImageBasic
  372. OpMemoryModel Physical64 OpenCL
  373. OpEntryPoint Kernel %5 "image_kernel"
  374. OpName %img "img"
  375. OpName %coord "coord"
  376. OpName %call "call"
  377. %uint = OpTypeInt 32 0
  378. %v2uint = OpTypeVector %uint 2
  379. %coord = OpConstantNull %v2uint
  380. %void = OpTypeVoid
  381. %float = OpTypeFloat 32
  382. %3 = OpTypeImage %void 2D 1 0 0 0 Unknown ReadOnly
  383. %4 = OpTypeFunction %void %3
  384. %5 = OpFunction %void None %4
  385. %img = OpFunctionParameter %3
  386. %entry = OpLabel
  387. %call = OpImageRead %uint %img %coord
  388. OpReturn
  389. OpFunctionEnd
  390. )";
  391. CompileSuccessfully(spirv);
  392. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  393. EXPECT_THAT(getDiagnosticString(),
  394. HasSubstr("Expected Result Type from a depth image "
  395. "read to result in a scalar float value"));
  396. }
  397. TEST_F(ValidateOpenCL, ImageRead_DepthVectorFloatResult_Bad) {
  398. std::string spirv = R"(
  399. OpCapability Addresses
  400. OpCapability Kernel
  401. OpCapability ImageBasic
  402. OpMemoryModel Physical64 OpenCL
  403. OpEntryPoint Kernel %5 "image_kernel"
  404. OpName %img "img"
  405. OpName %coord "coord"
  406. OpName %call "call"
  407. %uint = OpTypeInt 32 0
  408. %v2uint = OpTypeVector %uint 2
  409. %coord = OpConstantNull %v2uint
  410. %void = OpTypeVoid
  411. %float = OpTypeFloat 32
  412. %v4float = OpTypeVector %float 4
  413. %3 = OpTypeImage %void 2D 1 0 0 0 Unknown ReadOnly
  414. %4 = OpTypeFunction %void %3
  415. %5 = OpFunction %void None %4
  416. %img = OpFunctionParameter %3
  417. %entry = OpLabel
  418. %call = OpImageRead %v4float %img %coord
  419. OpReturn
  420. OpFunctionEnd
  421. )";
  422. CompileSuccessfully(spirv);
  423. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  424. EXPECT_THAT(getDiagnosticString(),
  425. HasSubstr("Expected Result Type from a depth image "
  426. "read to result in a scalar float value"));
  427. }
  428. TEST_F(ValidateOpenCL, ImageSampleExplicitLodWithConstOffsetBad) {
  429. std::string spirv = R"(
  430. OpCapability Addresses
  431. OpCapability Kernel
  432. OpCapability ImageBasic
  433. OpCapability LiteralSampler
  434. OpMemoryModel Physical64 OpenCL
  435. OpEntryPoint Kernel %5 "image_kernel"
  436. OpName %img "img"
  437. OpName %coord "coord"
  438. OpName %call "call"
  439. %uint = OpTypeInt 32 0
  440. %v2uint = OpTypeVector %uint 2
  441. %coord = OpConstantNull %v2uint
  442. %void = OpTypeVoid
  443. %3 = OpTypeImage %void 2D 0 0 0 0 Unknown ReadOnly
  444. %4 = OpTypeFunction %void %3
  445. %8 = OpTypeSampler
  446. %10 = OpTypeSampledImage %3
  447. %v4uint = OpTypeVector %uint 4
  448. %float = OpTypeFloat 32
  449. %9 = OpConstantSampler %8 None 0 Nearest
  450. %float_0 = OpConstant %float 0
  451. %5 = OpFunction %void None %4
  452. %6 = OpFunctionParameter %3
  453. %entry = OpLabel
  454. %img = OpSampledImage %10 %6 %9
  455. %call = OpImageSampleExplicitLod %v4uint %img %coord
  456. Lod|ConstOffset %float_0 %coord
  457. OpReturn
  458. OpFunctionEnd
  459. )";
  460. CompileSuccessfully(spirv);
  461. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_OPENCL_1_2));
  462. EXPECT_THAT(
  463. getDiagnosticString(),
  464. HasSubstr(
  465. "ConstOffset image operand not allowed in the OpenCL environment."
  466. "\n %call = OpImageSampleExplicitLod %v4uint %img "
  467. "%coord Lod|ConstOffset %float_0 %coord\n"));
  468. }
  469. } // namespace
  470. } // namespace val
  471. } // namespace spvtools