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
15 // Tests instructions from SPV_EXT_mesh_shader
16
17 #include <string>
18
19 #include "gmock/gmock.h"
20 #include "test/val/val_fixtures.h"
21
22 namespace spvtools {
23 namespace val {
24 namespace {
25
26 using ::testing::HasSubstr;
27 using ::testing::Values;
28
29 using ValidateMeshShading = spvtest::ValidateBase<bool>;
30
TEST_F(ValidateMeshShading,EmitMeshTasksEXTNotLastInstructionUniversal)31 TEST_F(ValidateMeshShading, EmitMeshTasksEXTNotLastInstructionUniversal) {
32 const std::string body = R"(
33 OpCapability MeshShadingEXT
34 OpExtension "SPV_EXT_mesh_shader"
35 OpMemoryModel Logical GLSL450
36 OpEntryPoint TaskEXT %main "main" %p
37 OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
38 %void = OpTypeVoid
39 %func = OpTypeFunction %void
40 %uint = OpTypeInt 32 0
41 %uint_1 = OpConstant %uint 1
42 %float = OpTypeFloat 32
43 %arr_float = OpTypeArray %float %uint_1
44 %Payload = OpTypeStruct %arr_float
45 %ptr_Payload = OpTypePointer TaskPayloadWorkgroupEXT %Payload
46 %p = OpVariable %ptr_Payload TaskPayloadWorkgroupEXT
47 %main = OpFunction %void None %func
48 %label1 = OpLabel
49 OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %p
50 OpBranch %label2
51 %label2 = OpLabel
52 OpReturn
53 OpFunctionEnd
54 )";
55
56 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_4);
57 EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT,
58 ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
59 EXPECT_THAT(getDiagnosticString(),
60 HasSubstr("Branch must appear in a block"));
61 }
62
TEST_F(ValidateMeshShading,EmitMeshTasksEXTNotLastInstructionVulkan)63 TEST_F(ValidateMeshShading, EmitMeshTasksEXTNotLastInstructionVulkan) {
64 const std::string body = R"(
65 OpCapability MeshShadingEXT
66 OpExtension "SPV_EXT_mesh_shader"
67 OpMemoryModel Logical GLSL450
68 OpEntryPoint TaskEXT %main "main" %p
69 OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
70 %void = OpTypeVoid
71 %func = OpTypeFunction %void
72 %uint = OpTypeInt 32 0
73 %uint_1 = OpConstant %uint 1
74 %float = OpTypeFloat 32
75 %arr_float = OpTypeArray %float %uint_1
76 %Payload = OpTypeStruct %arr_float
77 %ptr_Payload = OpTypePointer TaskPayloadWorkgroupEXT %Payload
78 %p = OpVariable %ptr_Payload TaskPayloadWorkgroupEXT
79 %main = OpFunction %void None %func
80 %label1 = OpLabel
81 OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %p
82 OpReturn
83 OpFunctionEnd
84 )";
85
86 CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
87 EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_VULKAN_1_2));
88 EXPECT_THAT(getDiagnosticString(),
89 HasSubstr("Return must appear in a block"));
90 }
91
TEST_F(ValidateMeshShading,BasicTaskSuccess)92 TEST_F(ValidateMeshShading, BasicTaskSuccess) {
93 const std::string body = R"(
94 OpCapability MeshShadingEXT
95 OpExtension "SPV_EXT_mesh_shader"
96 OpMemoryModel Logical GLSL450
97 OpEntryPoint TaskEXT %main "main"
98 %void = OpTypeVoid
99 %func = OpTypeFunction %void
100 %main = OpFunction %void None %func
101 %label = OpLabel
102 OpReturn
103 OpFunctionEnd
104 )";
105
106 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
107 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
108 }
109
TEST_F(ValidateMeshShading,BasicMeshSuccess)110 TEST_F(ValidateMeshShading, BasicMeshSuccess) {
111 const std::string body = R"(
112 OpCapability MeshShadingEXT
113 OpExtension "SPV_EXT_mesh_shader"
114 OpMemoryModel Logical GLSL450
115 OpEntryPoint MeshEXT %main "main"
116 OpExecutionMode %main OutputVertices 1
117 OpExecutionMode %main OutputPrimitivesEXT 1
118 OpExecutionMode %main OutputTrianglesEXT
119 %void = OpTypeVoid
120 %func = OpTypeFunction %void
121 %main = OpFunction %void None %func
122 %label = OpLabel
123 OpReturn
124 OpFunctionEnd
125 )";
126
127 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
128 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
129 }
130
TEST_F(ValidateMeshShading,VulkanBasicMeshAndTaskSuccess)131 TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskSuccess) {
132 const std::string body = R"(
133 OpCapability MeshShadingEXT
134 OpExtension "SPV_EXT_mesh_shader"
135 OpExtension "SPV_NV_mesh_shader"
136 OpMemoryModel Logical GLSL450
137 OpEntryPoint MeshEXT %mainMesh "mainMesh"
138 OpEntryPoint TaskEXT %mainTask "mainTask"
139 OpExecutionMode %mainMesh OutputVertices 1
140 OpExecutionMode %mainMesh OutputPrimitivesEXT 1
141 OpExecutionMode %mainMesh OutputTrianglesEXT
142 %void = OpTypeVoid
143 %func = OpTypeFunction %void
144 %mainMesh = OpFunction %void None %func
145 %labelMesh = OpLabel
146 OpReturn
147 OpFunctionEnd
148 %mainTask = OpFunction %void None %func
149 %labelTask = OpLabel
150 OpReturn
151 OpFunctionEnd
152 )";
153
154 CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
155 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
156 }
157
TEST_F(ValidateMeshShading,VulkanBasicMeshAndTaskBad)158 TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskBad) {
159 const std::string body = R"(
160 OpCapability MeshShadingEXT
161 OpCapability MeshShadingNV
162 OpExtension "SPV_EXT_mesh_shader"
163 OpExtension "SPV_NV_mesh_shader"
164 OpMemoryModel Logical GLSL450
165 OpEntryPoint MeshEXT %mainMesh "mainMesh"
166 OpEntryPoint TaskNV %mainTask "mainTask"
167 OpExecutionMode %mainMesh OutputVertices 1
168 OpExecutionMode %mainMesh OutputPrimitivesEXT 1
169 OpExecutionMode %mainMesh OutputTrianglesEXT
170 %void = OpTypeVoid
171 %func = OpTypeFunction %void
172 %mainMesh = OpFunction %void None %func
173 %labelMesh = OpLabel
174 OpReturn
175 OpFunctionEnd
176 %mainTask = OpFunction %void None %func
177 %labelTask = OpLabel
178 OpReturn
179 OpFunctionEnd
180 )";
181
182 CompileSuccessfully(body, SPV_ENV_VULKAN_1_2);
183 EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_VULKAN_1_2));
184 EXPECT_THAT(getDiagnosticString(),
185 AnyVUID("VUID-StandaloneSpirv-MeshEXT-07102"));
186 EXPECT_THAT(getDiagnosticString(),
187 HasSubstr("Module can't mix MeshEXT/TaskEXT with MeshNV/TaskNV "
188 "Execution Model."));
189 }
190
TEST_F(ValidateMeshShading,MeshMissingOutputVertices)191 TEST_F(ValidateMeshShading, MeshMissingOutputVertices) {
192 const std::string body = R"(
193 OpCapability MeshShadingEXT
194 OpExtension "SPV_EXT_mesh_shader"
195 OpMemoryModel Logical GLSL450
196 OpEntryPoint MeshEXT %main "main"
197 OpExecutionMode %main OutputPrimitivesEXT 1
198 OpExecutionMode %main OutputTrianglesEXT
199 %void = OpTypeVoid
200 %func = OpTypeFunction %void
201 %main = OpFunction %void None %func
202 %label = OpLabel
203 OpReturn
204 OpFunctionEnd
205 )";
206
207 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
208 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
209 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
210 EXPECT_THAT(
211 getDiagnosticString(),
212 HasSubstr("MeshEXT execution model entry points must specify both "
213 "OutputPrimitivesEXT and OutputVertices Execution Modes."));
214 }
215
TEST_F(ValidateMeshShading,MeshMissingOutputPrimitivesEXT)216 TEST_F(ValidateMeshShading, MeshMissingOutputPrimitivesEXT) {
217 const std::string body = R"(
218 OpCapability MeshShadingEXT
219 OpExtension "SPV_EXT_mesh_shader"
220 OpMemoryModel Logical GLSL450
221 OpEntryPoint MeshEXT %main "main"
222 OpExecutionMode %main OutputVertices 1
223 OpExecutionMode %main OutputTrianglesEXT
224 %void = OpTypeVoid
225 %func = OpTypeFunction %void
226 %main = OpFunction %void None %func
227 %label = OpLabel
228 OpReturn
229 OpFunctionEnd
230 )";
231
232 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
233 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
234 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
235 EXPECT_THAT(
236 getDiagnosticString(),
237 HasSubstr("MeshEXT execution model entry points must specify both "
238 "OutputPrimitivesEXT and OutputVertices Execution Modes."));
239 }
240
TEST_F(ValidateMeshShading,MeshMissingOutputType)241 TEST_F(ValidateMeshShading, MeshMissingOutputType) {
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 %void = OpTypeVoid
250 %func = OpTypeFunction %void
251 %main = OpFunction %void None %func
252 %label = OpLabel
253 OpReturn
254 OpFunctionEnd
255 )";
256
257 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
258 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
259 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
260 EXPECT_THAT(getDiagnosticString(),
261 HasSubstr("MeshEXT execution model entry points must specify "
262 "exactly one of OutputPoints, OutputLinesEXT, or "
263 "OutputTrianglesEXT Execution Modes."));
264 }
265
TEST_F(ValidateMeshShading,MeshMultipleOutputType)266 TEST_F(ValidateMeshShading, MeshMultipleOutputType) {
267 const std::string body = R"(
268 OpCapability MeshShadingEXT
269 OpExtension "SPV_EXT_mesh_shader"
270 OpMemoryModel Logical GLSL450
271 OpEntryPoint MeshEXT %main "main"
272 OpExecutionMode %main OutputVertices 1
273 OpExecutionMode %main OutputPrimitivesEXT 1
274 OpExecutionMode %main OutputLinesEXT
275 OpExecutionMode %main OutputTrianglesEXT
276 %void = OpTypeVoid
277 %func = OpTypeFunction %void
278 %main = OpFunction %void None %func
279 %label = OpLabel
280 OpReturn
281 OpFunctionEnd
282 )";
283
284 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
285 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
286 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
287 EXPECT_THAT(getDiagnosticString(),
288 HasSubstr("MeshEXT execution model entry points must specify "
289 "exactly one of OutputPoints, OutputLinesEXT, or "
290 "OutputTrianglesEXT Execution Modes."));
291 }
292
TEST_F(ValidateMeshShading,BadExecutionModelOutputLinesEXT)293 TEST_F(ValidateMeshShading, BadExecutionModelOutputLinesEXT) {
294 const std::string body = R"(
295 OpCapability MeshShadingEXT
296 OpExtension "SPV_EXT_mesh_shader"
297 OpMemoryModel Logical GLSL450
298 OpEntryPoint GLCompute %main "main"
299 OpExecutionMode %main OutputLinesEXT
300 %void = OpTypeVoid
301 %func = OpTypeFunction %void
302 %main = OpFunction %void None %func
303 %label = OpLabel
304 OpReturn
305 OpFunctionEnd
306 )";
307
308 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
309 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
310 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
311 EXPECT_THAT(getDiagnosticString(),
312 HasSubstr("Execution mode can only be used with the MeshEXT or "
313 "MeshNV execution model."));
314 }
315
TEST_F(ValidateMeshShading,BadExecutionModelOutputTrianglesEXT)316 TEST_F(ValidateMeshShading, BadExecutionModelOutputTrianglesEXT) {
317 const std::string body = R"(
318 OpCapability MeshShadingEXT
319 OpExtension "SPV_EXT_mesh_shader"
320 OpMemoryModel Logical GLSL450
321 OpEntryPoint GLCompute %main "main"
322 OpExecutionMode %main OutputTrianglesEXT
323 %void = OpTypeVoid
324 %func = OpTypeFunction %void
325 %main = OpFunction %void None %func
326 %label = OpLabel
327 OpReturn
328 OpFunctionEnd
329 )";
330
331 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
332 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
333 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
334 EXPECT_THAT(getDiagnosticString(),
335 HasSubstr("Execution mode can only be used with the MeshEXT or "
336 "MeshNV execution model."));
337 }
338
TEST_F(ValidateMeshShading,BadExecutionModelOutputPrimitivesEXT)339 TEST_F(ValidateMeshShading, BadExecutionModelOutputPrimitivesEXT) {
340 const std::string body = R"(
341 OpCapability MeshShadingEXT
342 OpExtension "SPV_EXT_mesh_shader"
343 OpMemoryModel Logical GLSL450
344 OpEntryPoint GLCompute %main "main"
345 OpExecutionMode %main OutputPrimitivesEXT 1
346 %void = OpTypeVoid
347 %func = OpTypeFunction %void
348 %main = OpFunction %void None %func
349 %label = OpLabel
350 OpReturn
351 OpFunctionEnd
352 )";
353
354 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
355 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
356 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
357 EXPECT_THAT(getDiagnosticString(),
358 HasSubstr("Execution mode can only be used with the MeshEXT or "
359 "MeshNV execution model."));
360 }
361
TEST_F(ValidateMeshShading,OpEmitMeshTasksBadGroupCountSignedInt)362 TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountSignedInt) {
363 const std::string body = R"(
364 OpCapability MeshShadingEXT
365 OpExtension "SPV_EXT_mesh_shader"
366 OpMemoryModel Logical GLSL450
367 OpEntryPoint TaskEXT %main "main"
368 %void = OpTypeVoid
369 %func = OpTypeFunction %void
370 %int = OpTypeInt 32 1
371 %uint = OpTypeInt 32 0
372 %int_1 = OpConstant %int 1
373 %uint_1 = OpConstant %uint 1
374 %main = OpFunction %void None %func
375 %label = OpLabel
376 OpEmitMeshTasksEXT %int_1 %uint_1 %uint_1
377 OpFunctionEnd
378 )";
379
380 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
381 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
382 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
383 EXPECT_THAT(getDiagnosticString(),
384 HasSubstr("Group Count X must be a 32-bit unsigned int scalar"));
385 }
386
TEST_F(ValidateMeshShading,OpEmitMeshTasksBadGroupCountVector)387 TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountVector) {
388 const std::string body = R"(
389 OpCapability MeshShadingEXT
390 OpExtension "SPV_EXT_mesh_shader"
391 OpMemoryModel Logical GLSL450
392 OpEntryPoint TaskEXT %main "main"
393 %void = OpTypeVoid
394 %func = OpTypeFunction %void
395 %uint = OpTypeInt 32 0
396 %v2uint = OpTypeVector %uint 2
397 %_ptr_v2uint = OpTypePointer Function %v2uint
398 %uint_1 = OpConstant %uint 1
399 %composite = OpConstantComposite %v2uint %uint_1 %uint_1
400 %_ptr_uint = OpTypePointer Function %uint
401 %main = OpFunction %void None %func
402 %label = OpLabel
403 %x = OpVariable %_ptr_v2uint Function
404 OpStore %x %composite
405 %13 = OpAccessChain %_ptr_uint %x %uint_1
406 %14 = OpLoad %uint %13
407 OpEmitMeshTasksEXT %14 %composite %uint_1
408 OpFunctionEnd
409 )";
410
411 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
412 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
413 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
414 EXPECT_THAT(getDiagnosticString(),
415 HasSubstr("Group Count Y must be a 32-bit unsigned int scalar"));
416 }
417
TEST_F(ValidateMeshShading,OpEmitMeshTasksBadPayload)418 TEST_F(ValidateMeshShading, OpEmitMeshTasksBadPayload) {
419 const std::string body = R"(
420 OpCapability MeshShadingEXT
421 OpExtension "SPV_EXT_mesh_shader"
422 OpMemoryModel Logical GLSL450
423 OpEntryPoint TaskEXT %main "main" %payload
424 %void = OpTypeVoid
425 %func = OpTypeFunction %void
426 %uint = OpTypeInt 32 0
427 %task = OpTypeStruct %uint
428 %_ptr_Uniform = OpTypePointer Uniform %task
429 %payload = OpVariable %_ptr_Uniform Uniform
430 %uint_1 = OpConstant %uint 1
431 %main = OpFunction %void None %func
432 %label = OpLabel
433 OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %payload
434 OpFunctionEnd
435 )";
436
437 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
438 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
439 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
440 EXPECT_THAT(getDiagnosticString(),
441 HasSubstr("Payload OpVariable must have a storage class of "
442 "TaskPayloadWorkgroupEXT"));
443 }
444
TEST_F(ValidateMeshShading,TaskPayloadWorkgroupBadExecutionModel)445 TEST_F(ValidateMeshShading, TaskPayloadWorkgroupBadExecutionModel) {
446 const std::string body = R"(
447 OpCapability MeshShadingEXT
448 OpExtension "SPV_EXT_mesh_shader"
449 OpMemoryModel Logical GLSL450
450 OpEntryPoint GLCompute %main "main" %payload
451 %void = OpTypeVoid
452 %func = OpTypeFunction %void
453 %uint = OpTypeInt 32 0
454 %_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint
455 %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT
456 %main = OpFunction %void None %func
457 %label = OpLabel
458 %load = OpLoad %uint %payload
459 OpReturn
460 OpFunctionEnd
461 )";
462
463 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
464 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
465 EXPECT_THAT(getDiagnosticString(),
466 HasSubstr("TaskPayloadWorkgroupEXT Storage Class is limited to "
467 "TaskEXT and MeshKHR execution model"));
468 }
469
TEST_F(ValidateMeshShading,OpSetMeshOutputsBadVertexCount)470 TEST_F(ValidateMeshShading, OpSetMeshOutputsBadVertexCount) {
471 const std::string body = R"(
472 OpCapability MeshShadingEXT
473 OpExtension "SPV_EXT_mesh_shader"
474 OpMemoryModel Logical GLSL450
475 OpEntryPoint MeshEXT %main "main"
476 OpExecutionMode %main OutputVertices 1
477 OpExecutionMode %main OutputPrimitivesNV 1
478 OpExecutionMode %main OutputTrianglesNV
479 %void = OpTypeVoid
480 %3 = OpTypeFunction %void
481 %int = OpTypeInt 32 1
482 %uint = OpTypeInt 32 0
483 %_ptr_int = OpTypePointer Function %int
484 %int_1 = OpConstant %int 1
485 %uint_1 = OpConstant %uint 1
486 %main = OpFunction %void None %3
487 %5 = OpLabel
488 %x = OpVariable %_ptr_int Function
489 OpStore %x %int_1
490 %load = OpLoad %int %x
491 OpSetMeshOutputsEXT %load %uint_1
492 OpReturn
493 OpFunctionEnd
494 )";
495
496 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
497 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
498 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
499 EXPECT_THAT(getDiagnosticString(),
500 HasSubstr("Vertex Count must be a 32-bit unsigned int scalar"));
501 }
502
TEST_F(ValidateMeshShading,OpSetMeshOutputsBadPrimitiveCount)503 TEST_F(ValidateMeshShading, OpSetMeshOutputsBadPrimitiveCount) {
504 const std::string body = R"(
505 OpCapability MeshShadingEXT
506 OpExtension "SPV_EXT_mesh_shader"
507 OpMemoryModel Logical GLSL450
508 OpEntryPoint MeshEXT %main "main"
509 OpExecutionMode %main OutputVertices 1
510 OpExecutionMode %main OutputPrimitivesNV 1
511 OpExecutionMode %main OutputTrianglesNV
512 %void = OpTypeVoid
513 %3 = OpTypeFunction %void
514 %int = OpTypeInt 32 1
515 %uint = OpTypeInt 32 0
516 %int_1 = OpConstant %int 1
517 %uint_1 = OpConstant %uint 1
518 %main = OpFunction %void None %3
519 %5 = OpLabel
520 OpSetMeshOutputsEXT %uint_1 %int_1
521 OpReturn
522 OpFunctionEnd
523 )";
524
525 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
526 EXPECT_EQ(SPV_ERROR_INVALID_DATA,
527 ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
528 EXPECT_THAT(
529 getDiagnosticString(),
530 HasSubstr("Primitive Count must be a 32-bit unsigned int scalar"));
531 }
532
TEST_F(ValidateMeshShading,OpSetMeshOutputsBadExecutionModel)533 TEST_F(ValidateMeshShading, OpSetMeshOutputsBadExecutionModel) {
534 const std::string body = R"(
535 OpCapability MeshShadingEXT
536 OpExtension "SPV_EXT_mesh_shader"
537 OpMemoryModel Logical GLSL450
538 OpEntryPoint TaskEXT %main "main"
539 %void = OpTypeVoid
540 %3 = OpTypeFunction %void
541 %uint = OpTypeInt 32 0
542 %uint_1 = OpConstant %uint 1
543 %main = OpFunction %void None %3
544 %5 = OpLabel
545 OpSetMeshOutputsEXT %uint_1 %uint_1
546 OpReturn
547 OpFunctionEnd
548 )";
549
550 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
551 EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
552 EXPECT_THAT(
553 getDiagnosticString(),
554 HasSubstr("OpSetMeshOutputsEXT requires MeshEXT execution model"));
555 }
556
TEST_F(ValidateMeshShading,OpSetMeshOutputsZeroSuccess)557 TEST_F(ValidateMeshShading, OpSetMeshOutputsZeroSuccess) {
558 const std::string body = R"(
559 OpCapability MeshShadingEXT
560 OpExtension "SPV_EXT_mesh_shader"
561 OpMemoryModel Logical GLSL450
562 OpEntryPoint MeshEXT %main "main"
563 OpExecutionMode %main OutputVertices 1
564 OpExecutionMode %main OutputPrimitivesNV 1
565 OpExecutionMode %main OutputTrianglesNV
566 %void = OpTypeVoid
567 %3 = OpTypeFunction %void
568 %uint = OpTypeInt 32 0
569 %uint_0 = OpConstant %uint 0
570 %main = OpFunction %void None %3
571 %5 = OpLabel
572 OpSetMeshOutputsEXT %uint_0 %uint_0
573 OpReturn
574 OpFunctionEnd
575 )";
576
577 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
578 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
579 }
580
TEST_F(ValidateMeshShading,OpEmitMeshTasksZeroSuccess)581 TEST_F(ValidateMeshShading, OpEmitMeshTasksZeroSuccess) {
582 const std::string body = R"(
583 OpCapability MeshShadingEXT
584 OpExtension "SPV_EXT_mesh_shader"
585 OpMemoryModel Logical GLSL450
586 OpEntryPoint TaskEXT %main "main"
587 %void = OpTypeVoid
588 %func = OpTypeFunction %void
589 %uint = OpTypeInt 32 0
590 %uint_0 = OpConstant %uint 1
591 %main = OpFunction %void None %func
592 %label = OpLabel
593 OpEmitMeshTasksEXT %uint_0 %uint_0 %uint_0
594 OpFunctionEnd
595 )";
596
597 CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5);
598 EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
599 }
600
601 } // namespace
602 } // namespace val
603 } // namespace spvtools
604