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