val_mesh_shading_test.cpp 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. // Copyright (c) 2022 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. // Tests instructions from SPV_EXT_mesh_shader
  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::HasSubstr;
  22. using ::testing::Values;
  23. using ValidateMeshShading = spvtest::ValidateBase<bool>;
  24. TEST_F(ValidateMeshShading, EmitMeshTasksEXTNotLastInstructionUniversal) {
  25. const std::string body = R"(
  26. OpCapability MeshShadingEXT
  27. OpExtension "SPV_EXT_mesh_shader"
  28. OpMemoryModel Logical GLSL450
  29. OpEntryPoint TaskEXT %main "main" %p
  30. OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
  31. %void = OpTypeVoid
  32. %func = OpTypeFunction %void
  33. %uint = OpTypeInt 32 0
  34. %uint_1 = OpConstant %uint 1
  35. %float = OpTypeFloat 32
  36. %arr_float = OpTypeArray %float %uint_1
  37. %Payload = OpTypeStruct %arr_float
  38. %ptr_Payload = OpTypePointer TaskPayloadWorkgroupEXT %Payload
  39. %p = OpVariable %ptr_Payload TaskPayloadWorkgroupEXT
  40. %main = OpFunction %void None %func
  41. %label1 = OpLabel
  42. OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %p
  43. OpBranch %label2
  44. %label2 = OpLabel
  45. OpReturn
  46. OpFunctionEnd
  47. )";
  48. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_4);
  49. EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT,
  50. ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
  51. EXPECT_THAT(getDiagnosticString(),
  52. HasSubstr("Branch must appear in a block"));
  53. }
  54. TEST_F(ValidateMeshShading, EmitMeshTasksEXTNotLastInstructionVulkan) {
  55. const std::string body = R"(
  56. OpCapability MeshShadingEXT
  57. OpExtension "SPV_EXT_mesh_shader"
  58. OpMemoryModel Logical GLSL450
  59. OpEntryPoint TaskEXT %main "main" %p
  60. OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
  61. %void = OpTypeVoid
  62. %func = OpTypeFunction %void
  63. %uint = OpTypeInt 32 0
  64. %uint_1 = OpConstant %uint 1
  65. %float = OpTypeFloat 32
  66. %arr_float = OpTypeArray %float %uint_1
  67. %Payload = OpTypeStruct %arr_float
  68. %ptr_Payload = OpTypePointer TaskPayloadWorkgroupEXT %Payload
  69. %p = OpVariable %ptr_Payload TaskPayloadWorkgroupEXT
  70. %main = OpFunction %void None %func
  71. %label1 = OpLabel
  72. OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %p
  73. OpReturn
  74. OpFunctionEnd
  75. )";
  76. CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
  77. EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  78. EXPECT_THAT(getDiagnosticString(),
  79. HasSubstr("Return must appear in a block"));
  80. }
  81. TEST_F(ValidateMeshShading, BasicTaskSuccess) {
  82. const std::string body = R"(
  83. OpCapability MeshShadingEXT
  84. OpExtension "SPV_EXT_mesh_shader"
  85. OpMemoryModel Logical GLSL450
  86. OpEntryPoint TaskEXT %main "main"
  87. %void = OpTypeVoid
  88. %func = OpTypeFunction %void
  89. %main = OpFunction %void None %func
  90. %label = OpLabel
  91. OpReturn
  92. OpFunctionEnd
  93. )";
  94. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  95. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  96. }
  97. TEST_F(ValidateMeshShading, BasicMeshSuccess) {
  98. const std::string body = R"(
  99. OpCapability MeshShadingEXT
  100. OpExtension "SPV_EXT_mesh_shader"
  101. OpMemoryModel Logical GLSL450
  102. OpEntryPoint MeshEXT %main "main"
  103. OpExecutionMode %main OutputVertices 1
  104. OpExecutionMode %main OutputPrimitivesEXT 1
  105. OpExecutionMode %main OutputTrianglesEXT
  106. %void = OpTypeVoid
  107. %func = OpTypeFunction %void
  108. %main = OpFunction %void None %func
  109. %label = OpLabel
  110. OpReturn
  111. OpFunctionEnd
  112. )";
  113. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  114. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  115. }
  116. TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskSuccess) {
  117. const std::string body = R"(
  118. OpCapability MeshShadingEXT
  119. OpExtension "SPV_EXT_mesh_shader"
  120. OpExtension "SPV_NV_mesh_shader"
  121. OpMemoryModel Logical GLSL450
  122. OpEntryPoint MeshEXT %mainMesh "mainMesh"
  123. OpEntryPoint TaskEXT %mainTask "mainTask"
  124. OpExecutionMode %mainMesh OutputVertices 1
  125. OpExecutionMode %mainMesh OutputPrimitivesEXT 1
  126. OpExecutionMode %mainMesh OutputTrianglesEXT
  127. %void = OpTypeVoid
  128. %func = OpTypeFunction %void
  129. %mainMesh = OpFunction %void None %func
  130. %labelMesh = OpLabel
  131. OpReturn
  132. OpFunctionEnd
  133. %mainTask = OpFunction %void None %func
  134. %labelTask = OpLabel
  135. OpReturn
  136. OpFunctionEnd
  137. )";
  138. CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
  139. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  140. }
  141. TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskBad) {
  142. const std::string body = R"(
  143. OpCapability MeshShadingEXT
  144. OpCapability MeshShadingNV
  145. OpExtension "SPV_EXT_mesh_shader"
  146. OpExtension "SPV_NV_mesh_shader"
  147. OpMemoryModel Logical GLSL450
  148. OpEntryPoint MeshEXT %mainMesh "mainMesh"
  149. OpEntryPoint TaskNV %mainTask "mainTask"
  150. OpExecutionMode %mainMesh OutputVertices 1
  151. OpExecutionMode %mainMesh OutputPrimitivesEXT 1
  152. OpExecutionMode %mainMesh OutputTrianglesEXT
  153. %void = OpTypeVoid
  154. %func = OpTypeFunction %void
  155. %mainMesh = OpFunction %void None %func
  156. %labelMesh = OpLabel
  157. OpReturn
  158. OpFunctionEnd
  159. %mainTask = OpFunction %void None %func
  160. %labelTask = OpLabel
  161. OpReturn
  162. OpFunctionEnd
  163. )";
  164. CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
  165. EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  166. EXPECT_THAT(getDiagnosticString(),
  167. AnyVUID("VUID-StandaloneSpirv-MeshEXT-07102"));
  168. EXPECT_THAT(getDiagnosticString(),
  169. HasSubstr("Module can't mix MeshEXT/TaskEXT with MeshNV/TaskNV "
  170. "Execution Model."));
  171. }
  172. TEST_F(ValidateMeshShading, MeshMissingOutputVertices) {
  173. const std::string body = R"(
  174. OpCapability MeshShadingEXT
  175. OpExtension "SPV_EXT_mesh_shader"
  176. OpMemoryModel Logical GLSL450
  177. OpEntryPoint MeshEXT %main "main"
  178. OpExecutionMode %main OutputPrimitivesEXT 1
  179. OpExecutionMode %main OutputTrianglesEXT
  180. %void = OpTypeVoid
  181. %func = OpTypeFunction %void
  182. %main = OpFunction %void None %func
  183. %label = OpLabel
  184. OpReturn
  185. OpFunctionEnd
  186. )";
  187. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  188. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  189. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  190. EXPECT_THAT(
  191. getDiagnosticString(),
  192. HasSubstr("MeshEXT execution model entry points must specify both "
  193. "OutputPrimitivesEXT and OutputVertices Execution Modes."));
  194. }
  195. TEST_F(ValidateMeshShading, MeshMissingOutputPrimitivesEXT) {
  196. const std::string body = R"(
  197. OpCapability MeshShadingEXT
  198. OpExtension "SPV_EXT_mesh_shader"
  199. OpMemoryModel Logical GLSL450
  200. OpEntryPoint MeshEXT %main "main"
  201. OpExecutionMode %main OutputVertices 1
  202. OpExecutionMode %main OutputTrianglesEXT
  203. %void = OpTypeVoid
  204. %func = OpTypeFunction %void
  205. %main = OpFunction %void None %func
  206. %label = OpLabel
  207. OpReturn
  208. OpFunctionEnd
  209. )";
  210. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  211. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  212. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  213. EXPECT_THAT(
  214. getDiagnosticString(),
  215. HasSubstr("MeshEXT execution model entry points must specify both "
  216. "OutputPrimitivesEXT and OutputVertices Execution Modes."));
  217. }
  218. TEST_F(ValidateMeshShading, MeshMissingOutputType) {
  219. const std::string body = R"(
  220. OpCapability MeshShadingEXT
  221. OpExtension "SPV_EXT_mesh_shader"
  222. OpMemoryModel Logical GLSL450
  223. OpEntryPoint MeshEXT %main "main"
  224. OpExecutionMode %main OutputVertices 1
  225. OpExecutionMode %main OutputPrimitivesEXT 1
  226. %void = OpTypeVoid
  227. %func = OpTypeFunction %void
  228. %main = OpFunction %void None %func
  229. %label = OpLabel
  230. OpReturn
  231. OpFunctionEnd
  232. )";
  233. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  234. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  235. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  236. EXPECT_THAT(getDiagnosticString(),
  237. HasSubstr("MeshEXT execution model entry points must specify "
  238. "exactly one of OutputPoints, OutputLinesEXT, or "
  239. "OutputTrianglesEXT Execution Modes."));
  240. }
  241. TEST_F(ValidateMeshShading, MeshMultipleOutputType) {
  242. const std::string body = R"(
  243. OpCapability MeshShadingEXT
  244. OpExtension "SPV_EXT_mesh_shader"
  245. OpMemoryModel Logical GLSL450
  246. OpEntryPoint MeshEXT %main "main"
  247. OpExecutionMode %main OutputVertices 1
  248. OpExecutionMode %main OutputPrimitivesEXT 1
  249. OpExecutionMode %main OutputLinesEXT
  250. OpExecutionMode %main OutputTrianglesEXT
  251. %void = OpTypeVoid
  252. %func = OpTypeFunction %void
  253. %main = OpFunction %void None %func
  254. %label = OpLabel
  255. OpReturn
  256. OpFunctionEnd
  257. )";
  258. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  259. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  260. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  261. EXPECT_THAT(getDiagnosticString(),
  262. HasSubstr("MeshEXT execution model entry points must specify "
  263. "exactly one of OutputPoints, OutputLinesEXT, or "
  264. "OutputTrianglesEXT Execution Modes."));
  265. }
  266. TEST_F(ValidateMeshShading, BadExecutionModelOutputLinesEXT) {
  267. const std::string body = R"(
  268. OpCapability MeshShadingEXT
  269. OpExtension "SPV_EXT_mesh_shader"
  270. OpMemoryModel Logical GLSL450
  271. OpEntryPoint GLCompute %main "main"
  272. OpExecutionMode %main OutputLinesEXT
  273. %void = OpTypeVoid
  274. %func = OpTypeFunction %void
  275. %main = OpFunction %void None %func
  276. %label = OpLabel
  277. OpReturn
  278. OpFunctionEnd
  279. )";
  280. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  281. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  282. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  283. EXPECT_THAT(getDiagnosticString(),
  284. HasSubstr("Execution mode can only be used with the MeshEXT or "
  285. "MeshNV execution model."));
  286. }
  287. TEST_F(ValidateMeshShading, BadExecutionModelOutputTrianglesEXT) {
  288. const std::string body = R"(
  289. OpCapability MeshShadingEXT
  290. OpExtension "SPV_EXT_mesh_shader"
  291. OpMemoryModel Logical GLSL450
  292. OpEntryPoint GLCompute %main "main"
  293. OpExecutionMode %main OutputTrianglesEXT
  294. %void = OpTypeVoid
  295. %func = OpTypeFunction %void
  296. %main = OpFunction %void None %func
  297. %label = OpLabel
  298. OpReturn
  299. OpFunctionEnd
  300. )";
  301. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  302. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  303. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  304. EXPECT_THAT(getDiagnosticString(),
  305. HasSubstr("Execution mode can only be used with the MeshEXT or "
  306. "MeshNV execution model."));
  307. }
  308. TEST_F(ValidateMeshShading, BadExecutionModelOutputPrimitivesEXT) {
  309. const std::string body = R"(
  310. OpCapability MeshShadingEXT
  311. OpExtension "SPV_EXT_mesh_shader"
  312. OpMemoryModel Logical GLSL450
  313. OpEntryPoint GLCompute %main "main"
  314. OpExecutionMode %main OutputPrimitivesEXT 1
  315. %void = OpTypeVoid
  316. %func = OpTypeFunction %void
  317. %main = OpFunction %void None %func
  318. %label = OpLabel
  319. OpReturn
  320. OpFunctionEnd
  321. )";
  322. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  323. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  324. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  325. EXPECT_THAT(getDiagnosticString(),
  326. HasSubstr("Execution mode can only be used with the MeshEXT or "
  327. "MeshNV execution model."));
  328. }
  329. TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountSignedInt) {
  330. const std::string body = R"(
  331. OpCapability MeshShadingEXT
  332. OpExtension "SPV_EXT_mesh_shader"
  333. OpMemoryModel Logical GLSL450
  334. OpEntryPoint TaskEXT %main "main"
  335. %void = OpTypeVoid
  336. %func = OpTypeFunction %void
  337. %int = OpTypeInt 32 1
  338. %uint = OpTypeInt 32 0
  339. %int_1 = OpConstant %int 1
  340. %uint_1 = OpConstant %uint 1
  341. %main = OpFunction %void None %func
  342. %label = OpLabel
  343. OpEmitMeshTasksEXT %int_1 %uint_1 %uint_1
  344. OpFunctionEnd
  345. )";
  346. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  347. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  348. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  349. EXPECT_THAT(getDiagnosticString(),
  350. HasSubstr("Group Count X must be a 32-bit unsigned int scalar"));
  351. }
  352. TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountVector) {
  353. const std::string body = R"(
  354. OpCapability MeshShadingEXT
  355. OpExtension "SPV_EXT_mesh_shader"
  356. OpMemoryModel Logical GLSL450
  357. OpEntryPoint TaskEXT %main "main"
  358. %void = OpTypeVoid
  359. %func = OpTypeFunction %void
  360. %uint = OpTypeInt 32 0
  361. %v2uint = OpTypeVector %uint 2
  362. %_ptr_v2uint = OpTypePointer Function %v2uint
  363. %uint_1 = OpConstant %uint 1
  364. %composite = OpConstantComposite %v2uint %uint_1 %uint_1
  365. %_ptr_uint = OpTypePointer Function %uint
  366. %main = OpFunction %void None %func
  367. %label = OpLabel
  368. %x = OpVariable %_ptr_v2uint Function
  369. OpStore %x %composite
  370. %13 = OpAccessChain %_ptr_uint %x %uint_1
  371. %14 = OpLoad %uint %13
  372. OpEmitMeshTasksEXT %14 %composite %uint_1
  373. OpFunctionEnd
  374. )";
  375. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  376. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  377. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  378. EXPECT_THAT(getDiagnosticString(),
  379. HasSubstr("Group Count Y must be a 32-bit unsigned int scalar"));
  380. }
  381. TEST_F(ValidateMeshShading, OpEmitMeshTasksBadPayload) {
  382. const std::string body = R"(
  383. OpCapability MeshShadingEXT
  384. OpExtension "SPV_EXT_mesh_shader"
  385. OpMemoryModel Logical GLSL450
  386. OpEntryPoint TaskEXT %main "main" %payload
  387. %void = OpTypeVoid
  388. %func = OpTypeFunction %void
  389. %uint = OpTypeInt 32 0
  390. %task = OpTypeStruct %uint
  391. %_ptr_Uniform = OpTypePointer Uniform %task
  392. %payload = OpVariable %_ptr_Uniform Uniform
  393. %uint_1 = OpConstant %uint 1
  394. %main = OpFunction %void None %func
  395. %label = OpLabel
  396. OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %payload
  397. OpFunctionEnd
  398. )";
  399. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  400. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  401. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  402. EXPECT_THAT(getDiagnosticString(),
  403. HasSubstr("Payload OpVariable must have a storage class of "
  404. "TaskPayloadWorkgroupEXT"));
  405. }
  406. TEST_F(ValidateMeshShading, TaskPayloadWorkgroupBadExecutionModel) {
  407. const std::string body = R"(
  408. OpCapability MeshShadingEXT
  409. OpExtension "SPV_EXT_mesh_shader"
  410. OpMemoryModel Logical GLSL450
  411. OpEntryPoint GLCompute %main "main" %payload
  412. %void = OpTypeVoid
  413. %func = OpTypeFunction %void
  414. %uint = OpTypeInt 32 0
  415. %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
  416. %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
  417. %main = OpFunction %void None %func
  418. %label = OpLabel
  419. %load = OpLoad %uint %payload
  420. OpReturn
  421. OpFunctionEnd
  422. )";
  423. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  424. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  425. EXPECT_THAT(getDiagnosticString(),
  426. HasSubstr("TaskPayloadWorkgroupEXT Storage Class is limited to "
  427. "TaskEXT and MeshKHR execution model"));
  428. }
  429. TEST_F(ValidateMeshShading, BadMultipleTaskPayloadWorkgroupEXT) {
  430. const std::string body = R"(
  431. OpCapability MeshShadingEXT
  432. OpExtension "SPV_EXT_mesh_shader"
  433. OpMemoryModel Logical GLSL450
  434. OpEntryPoint TaskEXT %main "main" %payload %payload1
  435. %void = OpTypeVoid
  436. %func = OpTypeFunction %void
  437. %uint = OpTypeInt 32 0
  438. %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
  439. %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
  440. %payload1 = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
  441. %main = OpFunction %void None %func
  442. %label = OpLabel
  443. %load = OpLoad %uint %payload
  444. OpReturn
  445. OpFunctionEnd
  446. )";
  447. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  448. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  449. EXPECT_THAT(getDiagnosticString(),
  450. HasSubstr("There can be at most one OpVariable with storage "
  451. "class TaskPayloadWorkgroupEXT associated with "
  452. "an OpEntryPoint"));
  453. }
  454. TEST_F(ValidateMeshShading, TaskPayloadWorkgroupTaskExtExecutionModel) {
  455. const std::string body = R"(
  456. OpCapability MeshShadingEXT
  457. OpExtension "SPV_EXT_mesh_shader"
  458. OpMemoryModel Logical GLSL450
  459. OpEntryPoint TaskEXT %main "main" %payload
  460. %void = OpTypeVoid
  461. %func = OpTypeFunction %void
  462. %uint = OpTypeInt 32 0
  463. %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
  464. %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
  465. %main = OpFunction %void None %func
  466. %label = OpLabel
  467. %load = OpLoad %uint %payload
  468. OpReturn
  469. OpFunctionEnd
  470. )";
  471. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  472. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  473. }
  474. TEST_F(ValidateMeshShading, TaskPayloadWorkgroupMeshExtExecutionModel) {
  475. const std::string body = R"(
  476. OpCapability MeshShadingEXT
  477. OpExtension "SPV_EXT_mesh_shader"
  478. OpMemoryModel Logical GLSL450
  479. OpEntryPoint MeshEXT %main "main" %payload
  480. OpExecutionMode %main OutputVertices 1
  481. OpExecutionMode %main OutputPrimitivesEXT 1
  482. OpExecutionMode %main OutputTrianglesEXT
  483. %void = OpTypeVoid
  484. %func = OpTypeFunction %void
  485. %uint = OpTypeInt 32 0
  486. %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
  487. %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
  488. %main = OpFunction %void None %func
  489. %label = OpLabel
  490. %load = OpLoad %uint %payload
  491. OpReturn
  492. OpFunctionEnd
  493. )";
  494. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  495. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  496. }
  497. TEST_F(ValidateMeshShading, OpSetMeshOutputsBadVertexCount) {
  498. const std::string body = R"(
  499. OpCapability MeshShadingEXT
  500. OpExtension "SPV_EXT_mesh_shader"
  501. OpMemoryModel Logical GLSL450
  502. OpEntryPoint MeshEXT %main "main"
  503. OpExecutionMode %main OutputVertices 1
  504. OpExecutionMode %main OutputPrimitivesNV 1
  505. OpExecutionMode %main OutputTrianglesNV
  506. %void = OpTypeVoid
  507. %3 = OpTypeFunction %void
  508. %int = OpTypeInt 32 1
  509. %uint = OpTypeInt 32 0
  510. %_ptr_int = OpTypePointer Function %int
  511. %int_1 = OpConstant %int 1
  512. %uint_1 = OpConstant %uint 1
  513. %main = OpFunction %void None %3
  514. %5 = OpLabel
  515. %x = OpVariable %_ptr_int Function
  516. OpStore %x %int_1
  517. %load = OpLoad %int %x
  518. OpSetMeshOutputsEXT %load %uint_1
  519. OpReturn
  520. OpFunctionEnd
  521. )";
  522. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  523. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  524. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  525. EXPECT_THAT(getDiagnosticString(),
  526. HasSubstr("Vertex Count must be a 32-bit unsigned int scalar"));
  527. }
  528. TEST_F(ValidateMeshShading, OpSetMeshOutputsBadPrimitiveCount) {
  529. const std::string body = R"(
  530. OpCapability MeshShadingEXT
  531. OpExtension "SPV_EXT_mesh_shader"
  532. OpMemoryModel Logical GLSL450
  533. OpEntryPoint MeshEXT %main "main"
  534. OpExecutionMode %main OutputVertices 1
  535. OpExecutionMode %main OutputPrimitivesNV 1
  536. OpExecutionMode %main OutputTrianglesNV
  537. %void = OpTypeVoid
  538. %3 = OpTypeFunction %void
  539. %int = OpTypeInt 32 1
  540. %uint = OpTypeInt 32 0
  541. %int_1 = OpConstant %int 1
  542. %uint_1 = OpConstant %uint 1
  543. %main = OpFunction %void None %3
  544. %5 = OpLabel
  545. OpSetMeshOutputsEXT %uint_1 %int_1
  546. OpReturn
  547. OpFunctionEnd
  548. )";
  549. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  550. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  551. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  552. EXPECT_THAT(
  553. getDiagnosticString(),
  554. HasSubstr("Primitive Count must be a 32-bit unsigned int scalar"));
  555. }
  556. TEST_F(ValidateMeshShading, OpSetMeshOutputsBadExecutionModel) {
  557. const std::string body = R"(
  558. OpCapability MeshShadingEXT
  559. OpExtension "SPV_EXT_mesh_shader"
  560. OpMemoryModel Logical GLSL450
  561. OpEntryPoint TaskEXT %main "main"
  562. %void = OpTypeVoid
  563. %3 = OpTypeFunction %void
  564. %uint = OpTypeInt 32 0
  565. %uint_1 = OpConstant %uint 1
  566. %main = OpFunction %void None %3
  567. %5 = OpLabel
  568. OpSetMeshOutputsEXT %uint_1 %uint_1
  569. OpReturn
  570. OpFunctionEnd
  571. )";
  572. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  573. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  574. EXPECT_THAT(
  575. getDiagnosticString(),
  576. HasSubstr("OpSetMeshOutputsEXT requires MeshEXT execution model"));
  577. }
  578. TEST_F(ValidateMeshShading, OpSetMeshOutputsZeroSuccess) {
  579. const std::string body = R"(
  580. OpCapability MeshShadingEXT
  581. OpExtension "SPV_EXT_mesh_shader"
  582. OpMemoryModel Logical GLSL450
  583. OpEntryPoint MeshEXT %main "main"
  584. OpExecutionMode %main OutputVertices 1
  585. OpExecutionMode %main OutputPrimitivesNV 1
  586. OpExecutionMode %main OutputTrianglesNV
  587. %void = OpTypeVoid
  588. %3 = OpTypeFunction %void
  589. %uint = OpTypeInt 32 0
  590. %uint_0 = OpConstant %uint 0
  591. %main = OpFunction %void None %3
  592. %5 = OpLabel
  593. OpSetMeshOutputsEXT %uint_0 %uint_0
  594. OpReturn
  595. OpFunctionEnd
  596. )";
  597. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  598. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  599. }
  600. TEST_F(ValidateMeshShading, OpEmitMeshTasksZeroSuccess) {
  601. const std::string body = R"(
  602. OpCapability MeshShadingEXT
  603. OpExtension "SPV_EXT_mesh_shader"
  604. OpMemoryModel Logical GLSL450
  605. OpEntryPoint TaskEXT %main "main"
  606. %void = OpTypeVoid
  607. %func = OpTypeFunction %void
  608. %uint = OpTypeInt 32 0
  609. %uint_0 = OpConstant %uint 1
  610. %main = OpFunction %void None %func
  611. %label = OpLabel
  612. OpEmitMeshTasksEXT %uint_0 %uint_0 %uint_0
  613. OpFunctionEnd
  614. )";
  615. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  616. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  617. }
  618. TEST_F(ValidateMeshShading, BadPerPrimitiveEXTStorageClassInMeshEXT) {
  619. const std::string body = R"(
  620. OpCapability MeshShadingEXT
  621. OpExtension "SPV_EXT_mesh_shader"
  622. %1 = OpExtInstImport "GLSL.std.450"
  623. OpMemoryModel Logical GLSL450
  624. OpEntryPoint MeshEXT %main "main" %gl_LocalInvocationID %blk %triangleNormal
  625. OpExecutionMode %main LocalSize 32 1 1
  626. OpExecutionMode %main OutputVertices 81
  627. OpExecutionMode %main OutputPrimitivesNV 32
  628. OpExecutionMode %main OutputTrianglesNV
  629. OpSource GLSL 450
  630. OpSourceExtension "GL_EXT_mesh_shader"
  631. OpName %main "main"
  632. OpName %iid "iid"
  633. OpName %gl_LocalInvocationID "gl_LocalInvocationID"
  634. OpName %myblock "myblock"
  635. OpMemberName %myblock 0 "f"
  636. OpName %blk "blk"
  637. OpName %triangleNormal "triangleNormal"
  638. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  639. OpMemberDecorate %myblock 0 PerPrimitiveEXT
  640. OpDecorate %myblock Block
  641. OpDecorate %blk Location 0
  642. OpDecorate %triangleNormal PerPrimitiveEXT
  643. OpDecorate %triangleNormal Location 0
  644. OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
  645. %void = OpTypeVoid
  646. %3 = OpTypeFunction %void
  647. %uint = OpTypeInt 32 0
  648. %_ptr_Function_uint = OpTypePointer Function %uint
  649. %v3uint = OpTypeVector %uint 3
  650. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  651. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  652. %uint_0 = OpConstant %uint 0
  653. %_ptr_Input_uint = OpTypePointer Input %uint
  654. %float = OpTypeFloat 32
  655. %myblock = OpTypeStruct %float
  656. %uint_32 = OpConstant %uint 32
  657. %_arr_myblock_uint_32 = OpTypeArray %myblock %uint_32
  658. %_ptr_Output__arr_myblock_uint_32 = OpTypePointer Output %_arr_myblock_uint_32
  659. %blk = OpVariable %_ptr_Output__arr_myblock_uint_32 Output
  660. %int = OpTypeInt 32 1
  661. %int_0 = OpConstant %int 0
  662. %float_11 = OpConstant %float 11
  663. %_ptr_Output_float = OpTypePointer Output %float
  664. %v3float = OpTypeVector %float 3
  665. %_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32
  666. %_ptr_Output__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32
  667. %triangleNormal = OpVariable %_ptr_Output__arr_v3float_uint_32 Input
  668. %33 = OpConstantComposite %v3float %float_11 %float_11 %float_11
  669. %_ptr_Output_v3float = OpTypePointer Output %v3float
  670. %uint_1 = OpConstant %uint 1
  671. %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_32 %uint_1 %uint_1
  672. %main = OpFunction %void None %3
  673. %5 = OpLabel
  674. %iid = OpVariable %_ptr_Function_uint Function
  675. %14 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0
  676. %15 = OpLoad %uint %14
  677. OpStore %iid %15
  678. %22 = OpLoad %uint %iid
  679. %27 = OpAccessChain %_ptr_Output_float %blk %22 %int_0
  680. OpStore %27 %float_11
  681. OpReturn
  682. OpFunctionEnd
  683. )";
  684. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  685. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  686. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  687. EXPECT_THAT(getDiagnosticString(),
  688. HasSubstr("PerPrimitiveEXT decoration must be applied only to "
  689. "variables in the Output Storage Class in the Storage "
  690. "Class in the MeshEXT Execution Model."));
  691. }
  692. TEST_F(ValidateMeshShading, VulkanPerPrimitiveEXTStorageClassInMeshEXT) {
  693. const std::string body = R"(
  694. OpCapability MeshShadingEXT
  695. OpExtension "SPV_EXT_mesh_shader"
  696. %1 = OpExtInstImport "GLSL.std.450"
  697. OpMemoryModel Logical GLSL450
  698. OpEntryPoint MeshEXT %main "main" %gl_LocalInvocationID %blk %triangleNormal
  699. OpExecutionMode %main LocalSize 32 1 1
  700. OpExecutionMode %main OutputVertices 81
  701. OpExecutionMode %main OutputPrimitivesNV 32
  702. OpExecutionMode %main OutputTrianglesNV
  703. OpSource GLSL 450
  704. OpSourceExtension "GL_EXT_mesh_shader"
  705. OpName %main "main"
  706. OpName %iid "iid"
  707. OpName %gl_LocalInvocationID "gl_LocalInvocationID"
  708. OpName %myblock "myblock"
  709. OpMemberName %myblock 0 "f"
  710. OpName %blk "blk"
  711. OpName %triangleNormal "triangleNormal"
  712. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  713. OpMemberDecorate %myblock 0 PerPrimitiveEXT
  714. OpDecorate %myblock Block
  715. OpDecorate %blk Location 0
  716. OpDecorate %triangleNormal PerPrimitiveEXT
  717. OpDecorate %triangleNormal Location 0
  718. OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
  719. %void = OpTypeVoid
  720. %3 = OpTypeFunction %void
  721. %uint = OpTypeInt 32 0
  722. %_ptr_Function_uint = OpTypePointer Function %uint
  723. %v3uint = OpTypeVector %uint 3
  724. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  725. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  726. %uint_0 = OpConstant %uint 0
  727. %_ptr_Input_uint = OpTypePointer Input %uint
  728. %float = OpTypeFloat 32
  729. %myblock = OpTypeStruct %float
  730. %uint_32 = OpConstant %uint 32
  731. %_arr_myblock_uint_32 = OpTypeArray %myblock %uint_32
  732. %_ptr_Output__arr_myblock_uint_32 = OpTypePointer Output %_arr_myblock_uint_32
  733. %blk = OpVariable %_ptr_Output__arr_myblock_uint_32 Output
  734. %int = OpTypeInt 32 1
  735. %int_0 = OpConstant %int 0
  736. %float_11 = OpConstant %float 11
  737. %_ptr_Output_float = OpTypePointer Output %float
  738. %v3float = OpTypeVector %float 3
  739. %_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32
  740. %_ptr_Output__arr_v3float_uint_32 = OpTypePointer Input %_arr_v3float_uint_32
  741. %triangleNormal = OpVariable %_ptr_Output__arr_v3float_uint_32 Input
  742. %33 = OpConstantComposite %v3float %float_11 %float_11 %float_11
  743. %_ptr_Output_v3float = OpTypePointer Output %v3float
  744. %uint_1 = OpConstant %uint 1
  745. %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_32 %uint_1 %uint_1
  746. %main = OpFunction %void None %3
  747. %5 = OpLabel
  748. %iid = OpVariable %_ptr_Function_uint Function
  749. %14 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0
  750. %15 = OpLoad %uint %14
  751. OpStore %iid %15
  752. %22 = OpLoad %uint %iid
  753. %27 = OpAccessChain %_ptr_Output_float %blk %22 %int_0
  754. OpStore %27 %float_11
  755. OpReturn
  756. OpFunctionEnd
  757. )";
  758. CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
  759. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
  760. EXPECT_THAT(getDiagnosticString(),
  761. AnyVUID("VUID-PrimitiveId-PrimitiveId-04336"));
  762. }
  763. TEST_F(ValidateMeshShading, BadPerPrimitiveEXTStorageClassInFrag) {
  764. const std::string body = R"(
  765. OpCapability Shader
  766. OpCapability MeshShadingEXT
  767. OpExtension "SPV_EXT_mesh_shader"
  768. %1 = OpExtInstImport "GLSL.std.450"
  769. OpMemoryModel Logical GLSL450
  770. OpEntryPoint Fragment %main "main" %triangleNormal
  771. OpExecutionMode %main OriginUpperLeft
  772. OpSource GLSL 450
  773. OpSourceExtension "GL_EXT_mesh_shader"
  774. OpName %main "main"
  775. OpName %triangleNormal "triangleNormal"
  776. OpDecorate %triangleNormal PerPrimitiveNV
  777. OpDecorate %triangleNormal Location 0
  778. %void = OpTypeVoid
  779. %3 = OpTypeFunction %void
  780. %float = OpTypeFloat 32
  781. %v3float = OpTypeVector %float 3
  782. %uint = OpTypeInt 32 0
  783. %uint_3 = OpConstant %uint 3
  784. %_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3
  785. %_ptr_Input__arr_v3float_uint_3 = OpTypePointer Output %_arr_v3float_uint_3
  786. %triangleNormal = OpVariable %_ptr_Input__arr_v3float_uint_3 Output
  787. %int = OpTypeInt 32 1
  788. %int_0 = OpConstant %int 0
  789. %_ptr_Input_v3float = OpTypePointer Input %v3float
  790. %main = OpFunction %void None %3
  791. %5 = OpLabel
  792. %18 = OpAccessChain %_ptr_Input_v3float %triangleNormal %int_0
  793. %19 = OpLoad %v3float %18
  794. OpReturn
  795. OpFunctionEnd
  796. )";
  797. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  798. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  799. ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  800. EXPECT_THAT(getDiagnosticString(),
  801. HasSubstr("PerPrimitiveEXT decoration must be applied only to "
  802. "variables in the Input Storage Class in the Fragment "
  803. "Execution Model."));
  804. }
  805. TEST_F(ValidateMeshShading, PerPrimitiveEXTStorageClassInFrag) {
  806. const std::string body = R"(
  807. OpCapability Shader
  808. OpCapability MeshShadingEXT
  809. OpExtension "SPV_EXT_mesh_shader"
  810. %1 = OpExtInstImport "GLSL.std.450"
  811. OpMemoryModel Logical GLSL450
  812. OpEntryPoint Fragment %main "main" %res3 %triangleNormal
  813. OpExecutionMode %main OriginUpperLeft
  814. OpSource GLSL 450
  815. OpSourceExtension "GL_EXT_mesh_shader"
  816. OpName %main "main"
  817. OpName %res3 "res3"
  818. OpName %triangleNormal "triangleNormal"
  819. OpDecorate %res3 Location 0
  820. OpDecorate %triangleNormal PerPrimitiveNV
  821. OpDecorate %triangleNormal Location 0
  822. %void = OpTypeVoid
  823. %3 = OpTypeFunction %void
  824. %float = OpTypeFloat 32
  825. %v3float = OpTypeVector %float 3
  826. %_ptr_Output_v3float = OpTypePointer Output %v3float
  827. %res3 = OpVariable %_ptr_Output_v3float Output
  828. %uint = OpTypeInt 32 0
  829. %uint_3 = OpConstant %uint 3
  830. %_arr_v3float_uint_3 = OpTypeArray %v3float %uint_3
  831. %_ptr_Input__arr_v3float_uint_3 = OpTypePointer Input %_arr_v3float_uint_3
  832. %triangleNormal = OpVariable %_ptr_Input__arr_v3float_uint_3 Input
  833. %int = OpTypeInt 32 1
  834. %int_0 = OpConstant %int 0
  835. %_ptr_Input_v3float = OpTypePointer Input %v3float
  836. %main = OpFunction %void None %3
  837. %5 = OpLabel
  838. %18 = OpAccessChain %_ptr_Input_v3float %triangleNormal %int_0
  839. %19 = OpLoad %v3float %18
  840. OpStore %res3 %19
  841. OpReturn
  842. OpFunctionEnd
  843. )";
  844. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  845. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  846. }
  847. TEST_F(ValidateMeshShading, PerPrimitiveEXTStorageClassInMeshEXT) {
  848. const std::string body = R"(
  849. OpCapability MeshShadingEXT
  850. OpExtension "SPV_EXT_mesh_shader"
  851. %1 = OpExtInstImport "GLSL.std.450"
  852. OpMemoryModel Logical GLSL450
  853. OpEntryPoint MeshEXT %main "main" %gl_LocalInvocationID %blk %triangleNormal
  854. OpExecutionMode %main LocalSize 32 1 1
  855. OpExecutionMode %main OutputVertices 81
  856. OpExecutionMode %main OutputPrimitivesNV 32
  857. OpExecutionMode %main OutputTrianglesNV
  858. OpSource GLSL 450
  859. OpSourceExtension "GL_EXT_mesh_shader"
  860. OpName %main "main"
  861. OpName %iid "iid"
  862. OpName %gl_LocalInvocationID "gl_LocalInvocationID"
  863. OpName %myblock "myblock"
  864. OpMemberName %myblock 0 "f"
  865. OpName %blk "blk"
  866. OpName %triangleNormal "triangleNormal"
  867. OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
  868. OpMemberDecorate %myblock 0 PerPrimitiveNV
  869. OpDecorate %myblock Block
  870. OpDecorate %blk Location 0
  871. OpDecorate %triangleNormal PerPrimitiveNV
  872. OpDecorate %triangleNormal Location 0
  873. OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize
  874. %void = OpTypeVoid
  875. %3 = OpTypeFunction %void
  876. %uint = OpTypeInt 32 0
  877. %_ptr_Function_uint = OpTypePointer Function %uint
  878. %v3uint = OpTypeVector %uint 3
  879. %_ptr_Input_v3uint = OpTypePointer Input %v3uint
  880. %gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
  881. %uint_0 = OpConstant %uint 0
  882. %_ptr_Input_uint = OpTypePointer Input %uint
  883. %float = OpTypeFloat 32
  884. %myblock = OpTypeStruct %float
  885. %uint_32 = OpConstant %uint 32
  886. %_arr_myblock_uint_32 = OpTypeArray %myblock %uint_32
  887. %_ptr_Output__arr_myblock_uint_32 = OpTypePointer Output %_arr_myblock_uint_32
  888. %blk = OpVariable %_ptr_Output__arr_myblock_uint_32 Output
  889. %int = OpTypeInt 32 1
  890. %int_0 = OpConstant %int 0
  891. %float_11 = OpConstant %float 11
  892. %_ptr_Output_float = OpTypePointer Output %float
  893. %v3float = OpTypeVector %float 3
  894. %_arr_v3float_uint_32 = OpTypeArray %v3float %uint_32
  895. %_ptr_Output__arr_v3float_uint_32 = OpTypePointer Output %_arr_v3float_uint_32
  896. %triangleNormal = OpVariable %_ptr_Output__arr_v3float_uint_32 Output
  897. %33 = OpConstantComposite %v3float %float_11 %float_11 %float_11
  898. %_ptr_Output_v3float = OpTypePointer Output %v3float
  899. %uint_1 = OpConstant %uint 1
  900. %gl_WorkGroupSize = OpConstantComposite %v3uint %uint_32 %uint_1 %uint_1
  901. %main = OpFunction %void None %3
  902. %5 = OpLabel
  903. %iid = OpVariable %_ptr_Function_uint Function
  904. %14 = OpAccessChain %_ptr_Input_uint %gl_LocalInvocationID %uint_0
  905. %15 = OpLoad %uint %14
  906. OpStore %iid %15
  907. %22 = OpLoad %uint %iid
  908. %27 = OpAccessChain %_ptr_Output_float %blk %22 %int_0
  909. OpStore %27 %float_11
  910. %32 = OpLoad %uint %iid
  911. %35 = OpAccessChain %_ptr_Output_v3float %triangleNormal %32
  912. OpStore %35 %33
  913. OpReturn
  914. OpFunctionEnd
  915. )";
  916. CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
  917. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
  918. }
  919. } // namespace
  920. } // namespace val
  921. } // namespace spvtools