diff options
author | Spencer Fricke <spencerfricke@gmail.com> | 2022-09-23 18:06:46 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-23 18:06:46 +0300 |
commit | b53d7a8affabb230a47fb4123b040573a3062d4a (patch) | |
tree | 17ad86d1bfe312ac8a0d4b8fc4b6f4185287b3ae /test | |
parent | 265b455c996f7314ff995ecc3f5e3548365dbe87 (diff) |
spirv-val: Add initial SPV_EXT_mesh_shader validation (#4924)
* Move TaskEXT check to OpEmitMeshTasksEXT
* Add MeshNV for Execution Model alias
Diffstat (limited to 'test')
-rw-r--r-- | test/val/val_id_test.cpp | 4 | ||||
-rw-r--r-- | test/val/val_memory_test.cpp | 49 | ||||
-rw-r--r-- | test/val/val_mesh_shading_test.cpp | 509 |
3 files changed, 560 insertions, 2 deletions
diff --git a/test/val/val_id_test.cpp b/test/val/val_id_test.cpp index 3cf7575a1..deda95b49 100644 --- a/test/val/val_id_test.cpp +++ b/test/val/val_id_test.cpp @@ -2091,9 +2091,9 @@ TEST_F(ValidateIdWithMessage, OpVariableGood) { TEST_F(ValidateIdWithMessage, OpVariableInitializerConstantGood) { std::string spirv = kGLSL450MemoryModel + R"( %1 = OpTypeInt 32 0 -%2 = OpTypePointer Input %1 +%2 = OpTypePointer Output %1 %3 = OpConstant %1 42 -%4 = OpVariable %2 Input %3)"; +%4 = OpVariable %2 Output %3)"; CompileSuccessfully(spirv.c_str()); EXPECT_EQ(SPV_SUCCESS, ValidateInstructions()); } diff --git a/test/val/val_memory_test.cpp b/test/val/val_memory_test.cpp index ec1a00077..35e8af756 100644 --- a/test/val/val_memory_test.cpp +++ b/test/val/val_memory_test.cpp @@ -472,6 +472,55 @@ OpFunctionEnd "= OpVariable %_ptr_Input_float Input %float_1\n")); } +TEST_F(ValidateMemory, UniversalInitializerWithDisallowedStorageClassesBad) { + std::string spirv = R"( +OpCapability Shader +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %func "func" +OpExecutionMode %func OriginUpperLeft +%float = OpTypeFloat 32 +%float_ptr = OpTypePointer Input %float +%init_val = OpConstant %float 1.0 +%1 = OpVariable %float_ptr Input %init_val +%void = OpTypeVoid +%functy = OpTypeFunction %void +%func = OpFunction %void None %functy +%2 = OpLabel +OpReturn +OpFunctionEnd +)"; + CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_3); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr( + "OpVariable, <id> '5[%5]', initializer are not allowed for Input")); +} + +TEST_F(ValidateMemory, InitializerWithTaskPayloadWorkgroupEXT) { + std::string spirv = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" %payload + %void = OpTypeVoid + %func = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint + %uint_1 = OpConstant %uint 1 + %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT %uint_1 + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + CompileSuccessfully(spirv.c_str(), SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("OpVariable, <id> '2[%2]', initializer are not allowed " + "for TaskPayloadWorkgroupEXT")); +} + TEST_F(ValidateMemory, ArrayLenCorrectResultType) { std::string spirv = R"( OpCapability Shader diff --git a/test/val/val_mesh_shading_test.cpp b/test/val/val_mesh_shading_test.cpp index d10f40d87..ce6999dcb 100644 --- a/test/val/val_mesh_shading_test.cpp +++ b/test/val/val_mesh_shading_test.cpp @@ -90,6 +90,515 @@ TEST_F(ValidateMeshShading, EmitMeshTasksEXTNotLastInstructionVulkan) { HasSubstr("Return must appear in a block")); } +TEST_F(ValidateMeshShading, BasicTaskSuccess) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); +} + +TEST_F(ValidateMeshShading, BasicMeshSuccess) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesEXT 1 + OpExecutionMode %main OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); +} + +TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskSuccess) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpExtension "SPV_NV_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %mainMesh "mainMesh" + OpEntryPoint TaskEXT %mainTask "mainTask" + OpExecutionMode %mainMesh OutputVertices 1 + OpExecutionMode %mainMesh OutputPrimitivesEXT 1 + OpExecutionMode %mainMesh OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %mainMesh = OpFunction %void None %func + %labelMesh = OpLabel + OpReturn + OpFunctionEnd + %mainTask = OpFunction %void None %func + %labelTask = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_VULKAN_1_2); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2)); +} + +TEST_F(ValidateMeshShading, VulkanBasicMeshAndTaskBad) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpCapability MeshShadingNV + OpExtension "SPV_EXT_mesh_shader" + OpExtension "SPV_NV_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %mainMesh "mainMesh" + OpEntryPoint TaskNV %mainTask "mainTask" + OpExecutionMode %mainMesh OutputVertices 1 + OpExecutionMode %mainMesh OutputPrimitivesEXT 1 + OpExecutionMode %mainMesh OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %mainMesh = OpFunction %void None %func + %labelMesh = OpLabel + OpReturn + OpFunctionEnd + %mainTask = OpFunction %void None %func + %labelTask = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_VULKAN_1_2); + EXPECT_EQ(SPV_ERROR_INVALID_LAYOUT, ValidateInstructions(SPV_ENV_VULKAN_1_2)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-MeshEXT-07102")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Module can't mix MeshEXT/TaskEXT with MeshNV/TaskNV " + "Execution Model.")); +} + +TEST_F(ValidateMeshShading, MeshMissingOutputVertices) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputPrimitivesEXT 1 + OpExecutionMode %main OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("MeshEXT execution model entry points must specify both " + "OutputPrimitivesEXT and OutputVertices Execution Modes.")); +} + +TEST_F(ValidateMeshShading, MeshMissingOutputPrimitivesEXT) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("MeshEXT execution model entry points must specify both " + "OutputPrimitivesEXT and OutputVertices Execution Modes.")); +} + +TEST_F(ValidateMeshShading, MeshMissingOutputType) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesEXT 1 + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("MeshEXT execution model entry points must specify " + "exactly one of OutputPoints, OutputLinesEXT, or " + "OutputTrianglesEXT Execution Modes.")); +} + +TEST_F(ValidateMeshShading, MeshMultipleOutputType) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesEXT 1 + OpExecutionMode %main OutputLinesEXT + OpExecutionMode %main OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("MeshEXT execution model entry points must specify " + "exactly one of OutputPoints, OutputLinesEXT, or " + "OutputTrianglesEXT Execution Modes.")); +} + +TEST_F(ValidateMeshShading, BadExecutionModelOutputLinesEXT) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main OutputLinesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Execution mode can only be used with the MeshEXT or " + "MeshNV execution model.")); +} + +TEST_F(ValidateMeshShading, BadExecutionModelOutputTrianglesEXT) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main OutputTrianglesEXT + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Execution mode can only be used with the MeshEXT or " + "MeshNV execution model.")); +} + +TEST_F(ValidateMeshShading, BadExecutionModelOutputPrimitivesEXT) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" + OpExecutionMode %main OutputPrimitivesEXT 1 + %void = OpTypeVoid + %func = OpTypeFunction %void + %main = OpFunction %void None %func + %label = OpLabel + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Execution mode can only be used with the MeshEXT or " + "MeshNV execution model.")); +} + +TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountSignedInt) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" + %void = OpTypeVoid + %func = OpTypeFunction %void + %int = OpTypeInt 32 1 + %uint = OpTypeInt 32 0 + %int_1 = OpConstant %int 1 + %uint_1 = OpConstant %uint 1 + %main = OpFunction %void None %func + %label = OpLabel + OpEmitMeshTasksEXT %int_1 %uint_1 %uint_1 + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Group Count X must be a 32-bit unsigned int scalar")); +} + +TEST_F(ValidateMeshShading, OpEmitMeshTasksBadGroupCountVector) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" + %void = OpTypeVoid + %func = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %v2uint = OpTypeVector %uint 2 +%_ptr_v2uint = OpTypePointer Function %v2uint + %uint_1 = OpConstant %uint 1 + %composite = OpConstantComposite %v2uint %uint_1 %uint_1 + %_ptr_uint = OpTypePointer Function %uint + %main = OpFunction %void None %func + %label = OpLabel + %x = OpVariable %_ptr_v2uint Function + OpStore %x %composite + %13 = OpAccessChain %_ptr_uint %x %uint_1 + %14 = OpLoad %uint %13 + OpEmitMeshTasksEXT %14 %composite %uint_1 + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Group Count Y must be a 32-bit unsigned int scalar")); +} + +TEST_F(ValidateMeshShading, OpEmitMeshTasksBadPayload) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" %payload + %void = OpTypeVoid + %func = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %task = OpTypeStruct %uint +%_ptr_Uniform = OpTypePointer Uniform %task + %payload = OpVariable %_ptr_Uniform Uniform + %uint_1 = OpConstant %uint 1 + %main = OpFunction %void None %func + %label = OpLabel + OpEmitMeshTasksEXT %uint_1 %uint_1 %uint_1 %payload + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Payload OpVariable must have a storage class of " + "TaskPayloadWorkgroupEXT")); +} + +TEST_F(ValidateMeshShading, TaskPayloadWorkgroupBadExecutionModel) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %main "main" %payload + %void = OpTypeVoid + %func = OpTypeFunction %void + %uint = OpTypeInt 32 0 +%_ptr_TaskPayloadWorkgroupEXT = OpTypePointer TaskPayloadWorkgroupEXT %uint + %payload = OpVariable %_ptr_TaskPayloadWorkgroupEXT TaskPayloadWorkgroupEXT + %main = OpFunction %void None %func + %label = OpLabel + %load = OpLoad %uint %payload + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("TaskPayloadWorkgroupEXT Storage Class is limited to " + "TaskEXT and MeshKHR execution model")); +} + +TEST_F(ValidateMeshShading, OpSetMeshOutputsBadVertexCount) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesNV 1 + OpExecutionMode %main OutputTrianglesNV + %void = OpTypeVoid + %3 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %uint = OpTypeInt 32 0 + %_ptr_int = OpTypePointer Function %int + %int_1 = OpConstant %int 1 + %uint_1 = OpConstant %uint 1 + %main = OpFunction %void None %3 + %5 = OpLabel + %x = OpVariable %_ptr_int Function + OpStore %x %int_1 + %load = OpLoad %int %x + OpSetMeshOutputsEXT %load %uint_1 + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Vertex Count must be a 32-bit unsigned int scalar")); +} + +TEST_F(ValidateMeshShading, OpSetMeshOutputsBadPrimitiveCount) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesNV 1 + OpExecutionMode %main OutputTrianglesNV + %void = OpTypeVoid + %3 = OpTypeFunction %void + %int = OpTypeInt 32 1 + %uint = OpTypeInt 32 0 + %int_1 = OpConstant %int 1 + %uint_1 = OpConstant %uint 1 + %main = OpFunction %void None %3 + %5 = OpLabel + OpSetMeshOutputsEXT %uint_1 %int_1 + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_DATA, + ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("Primitive Count must be a 32-bit unsigned int scalar")); +} + +TEST_F(ValidateMeshShading, OpSetMeshOutputsBadExecutionModel) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" + %void = OpTypeVoid + %3 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %uint_1 = OpConstant %uint 1 + %main = OpFunction %void None %3 + %5 = OpLabel + OpSetMeshOutputsEXT %uint_1 %uint_1 + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("OpSetMeshOutputsEXT requires MeshEXT execution model")); +} + +TEST_F(ValidateMeshShading, OpSetMeshOutputsZeroSuccess) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint MeshEXT %main "main" + OpExecutionMode %main OutputVertices 1 + OpExecutionMode %main OutputPrimitivesNV 1 + OpExecutionMode %main OutputTrianglesNV + %void = OpTypeVoid + %3 = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 0 + %main = OpFunction %void None %3 + %5 = OpLabel + OpSetMeshOutputsEXT %uint_0 %uint_0 + OpReturn + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); +} + +TEST_F(ValidateMeshShading, OpEmitMeshTasksZeroSuccess) { + const std::string body = R"( + OpCapability MeshShadingEXT + OpExtension "SPV_EXT_mesh_shader" + OpMemoryModel Logical GLSL450 + OpEntryPoint TaskEXT %main "main" + %void = OpTypeVoid + %func = OpTypeFunction %void + %uint = OpTypeInt 32 0 + %uint_0 = OpConstant %uint 1 + %main = OpFunction %void None %func + %label = OpLabel + OpEmitMeshTasksEXT %uint_0 %uint_0 %uint_0 + OpFunctionEnd +)"; + + CompileSuccessfully(body, SPV_ENV_UNIVERSAL_1_5); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5)); +} + } // namespace } // namespace val } // namespace spvtools |