@@ -128,6 +128,104 @@ TEST_F(ValidateMeshShading, BasicMeshSuccess) {
128128 EXPECT_EQ (SPV_SUCCESS, ValidateInstructions (SPV_ENV_UNIVERSAL_1_5));
129129}
130130
131+ // https://godbolt.org/z/Kvb1rsceP
132+ TEST_F (ValidateMeshShading, BasicMeshBuiltinSuccess) {
133+ const std::string body = R"(
134+ OpCapability MeshShadingEXT
135+ OpExtension "SPV_EXT_mesh_shader"
136+ OpMemoryModel Logical GLSL450
137+ OpEntryPoint MeshEXT %main "main" %gl_MeshVerticesEXT %vertexOutput %gl_MeshPrimitivesEXT %gl_LocalInvocationIndex %gl_PrimitiveTriangleIndicesEXT
138+ OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
139+ OpExecutionMode %main OutputVertices 3
140+ OpExecutionMode %main OutputPrimitivesEXT 1
141+ OpExecutionMode %main OutputTrianglesEXT
142+ OpDecorate %gl_MeshPerVertexEXT Block
143+ OpMemberDecorate %gl_MeshPerVertexEXT 0 BuiltIn Position
144+ OpMemberDecorate %gl_MeshPerVertexEXT 1 BuiltIn PointSize
145+ OpMemberDecorate %gl_MeshPerVertexEXT 2 BuiltIn ClipDistance
146+ OpMemberDecorate %gl_MeshPerVertexEXT 3 BuiltIn CullDistance
147+ OpDecorate %VertexOutput Block
148+ OpDecorate %vertexOutput Location 0
149+ OpDecorate %gl_MeshPerPrimitiveEXT Block
150+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 0 BuiltIn PrimitiveId
151+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 0 PerPrimitiveEXT
152+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 1 BuiltIn Layer
153+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 1 PerPrimitiveEXT
154+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 2 BuiltIn ViewportIndex
155+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 2 PerPrimitiveEXT
156+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 3 BuiltIn CullPrimitiveEXT
157+ OpMemberDecorate %gl_MeshPerPrimitiveEXT 3 PerPrimitiveEXT
158+ OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
159+ OpDecorate %gl_PrimitiveTriangleIndicesEXT BuiltIn PrimitiveTriangleIndicesEXT
160+ %void = OpTypeVoid
161+ %4 = OpTypeFunction %void
162+ %uint = OpTypeInt 32 0
163+ %uint_1 = OpConstant %uint 1
164+ %uint_3 = OpConstant %uint 3
165+ %float = OpTypeFloat 32
166+ %v4float = OpTypeVector %float 4
167+ %_arr_float_uint_1 = OpTypeArray %float %uint_1
168+ %gl_MeshPerVertexEXT = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
169+ %_arr_gl_MeshPerVertexEXT_uint_3 = OpTypeArray %gl_MeshPerVertexEXT %uint_3
170+ %_ptr_Output__arr_gl_MeshPerVertexEXT_uint_3 = OpTypePointer Output %_arr_gl_MeshPerVertexEXT_uint_3
171+ %gl_MeshVerticesEXT = OpVariable %_ptr_Output__arr_gl_MeshPerVertexEXT_uint_3 Output
172+ %int = OpTypeInt 32 1
173+ %int_0 = OpConstant %int 0
174+ %float_0 = OpConstant %float 0
175+ %20 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
176+ %_ptr_Output_v4float = OpTypePointer Output %v4float
177+ %int_1 = OpConstant %int 1
178+ %int_2 = OpConstant %int 2
179+ %VertexOutput = OpTypeStruct %v4float
180+ %_arr_VertexOutput_uint_3 = OpTypeArray %VertexOutput %uint_3
181+ %_ptr_Output__arr_VertexOutput_uint_3 = OpTypePointer Output %_arr_VertexOutput_uint_3
182+ %vertexOutput = OpVariable %_ptr_Output__arr_VertexOutput_uint_3 Output
183+ %bool = OpTypeBool
184+ %gl_MeshPerPrimitiveEXT = OpTypeStruct %int %int %int %bool
185+ %_arr_gl_MeshPerPrimitiveEXT_uint_1 = OpTypeArray %gl_MeshPerPrimitiveEXT %uint_1
186+ %_ptr_Output__arr_gl_MeshPerPrimitiveEXT_uint_1 = OpTypePointer Output %_arr_gl_MeshPerPrimitiveEXT_uint_1
187+ %gl_MeshPrimitivesEXT = OpVariable %_ptr_Output__arr_gl_MeshPerPrimitiveEXT_uint_1 Output
188+ %_ptr_Input_uint = OpTypePointer Input %uint
189+ %gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
190+ %int_3 = OpConstant %int 3
191+ %false = OpConstantFalse %bool
192+ %_ptr_Output_bool = OpTypePointer Output %bool
193+ %v3uint = OpTypeVector %uint 3
194+ %_arr_v3uint_uint_1 = OpTypeArray %v3uint %uint_1
195+ %_ptr_Output__arr_v3uint_uint_1 = OpTypePointer Output %_arr_v3uint_uint_1
196+ %gl_PrimitiveTriangleIndicesEXT = OpVariable %_ptr_Output__arr_v3uint_uint_1 Output
197+ %uint_0 = OpConstant %uint 0
198+ %52 = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0
199+ %_ptr_Output_v3uint = OpTypePointer Output %v3uint
200+ %main = OpFunction %void None %4
201+ %6 = OpLabel
202+ OpSetMeshOutputsEXT %uint_3 %uint_1
203+ %22 = OpAccessChain %_ptr_Output_v4float %gl_MeshVerticesEXT %int_0 %int_0
204+ OpStore %22 %20
205+ %24 = OpAccessChain %_ptr_Output_v4float %gl_MeshVerticesEXT %int_1 %int_0
206+ OpStore %24 %20
207+ %26 = OpAccessChain %_ptr_Output_v4float %gl_MeshVerticesEXT %int_2 %int_0
208+ OpStore %26 %20
209+ %31 = OpAccessChain %_ptr_Output_v4float %vertexOutput %int_0 %int_0
210+ OpStore %31 %20
211+ %32 = OpAccessChain %_ptr_Output_v4float %vertexOutput %int_1 %int_0
212+ OpStore %32 %20
213+ %33 = OpAccessChain %_ptr_Output_v4float %vertexOutput %int_2 %int_0
214+ OpStore %33 %20
215+ %41 = OpLoad %uint %gl_LocalInvocationIndex
216+ %45 = OpAccessChain %_ptr_Output_bool %gl_MeshPrimitivesEXT %41 %int_3
217+ OpStore %45 %false
218+ %50 = OpLoad %uint %gl_LocalInvocationIndex
219+ %54 = OpAccessChain %_ptr_Output_v3uint %gl_PrimitiveTriangleIndicesEXT %50
220+ OpStore %54 %52
221+ OpReturn
222+ OpFunctionEnd
223+ )" ;
224+
225+ CompileSuccessfully (body, SPV_ENV_VULKAN_1_3);
226+ EXPECT_EQ (SPV_SUCCESS, ValidateInstructions (SPV_ENV_VULKAN_1_3));
227+ }
228+
131229TEST_F (ValidateMeshShading, VulkanBasicMeshAndTaskSuccess) {
132230 const std::string body = R"(
133231 OpCapability MeshShadingEXT
@@ -672,6 +770,81 @@ TEST_F(ValidateMeshShading, OpEmitMeshTasksZeroSuccess) {
672770 EXPECT_EQ (SPV_SUCCESS, ValidateInstructions (SPV_ENV_UNIVERSAL_1_5));
673771}
674772
773+ TEST_F (ValidateMeshShading, MeshOutputScalar) {
774+ const std::string body = R"(
775+ OpCapability MeshShadingEXT
776+ OpExtension "SPV_EXT_mesh_shader"
777+ OpMemoryModel Logical GLSL450
778+ OpEntryPoint MeshEXT %main "main" %x
779+ OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
780+ OpExecutionMode %main OutputVertices 3
781+ OpExecutionMode %main OutputPrimitivesEXT 1
782+ OpExecutionMode %main OutputTrianglesEXT
783+ OpDecorate %x Location 0
784+ %void = OpTypeVoid
785+ %4 = OpTypeFunction %void
786+ %uint = OpTypeInt 32 0
787+ %uint_1 = OpConstant %uint 1
788+ %uint_3 = OpConstant %uint 3
789+ %o_ptr = OpTypePointer Output %uint
790+ %x = OpVariable %o_ptr Output
791+ %main = OpFunction %void None %4
792+ %6 = OpLabel
793+ OpSetMeshOutputsEXT %uint_3 %uint_1
794+ OpReturn
795+ OpFunctionEnd
796+ )" ;
797+
798+ CompileSuccessfully (body, SPV_ENV_VULKAN_1_3);
799+ EXPECT_EQ (SPV_ERROR_INVALID_DATA, ValidateInstructions (SPV_ENV_VULKAN_1_3));
800+ EXPECT_THAT (getDiagnosticString (),
801+ HasSubstr (" In the MeshEXT Execution Mode, all Output Variables "
802+ " must contain an Array." ));
803+ }
804+
805+ TEST_F (ValidateMeshShading, MeshOutputScalarStruct) {
806+ const std::string body = R"(
807+ OpCapability MeshShadingEXT
808+ OpExtension "SPV_EXT_mesh_shader"
809+ OpMemoryModel Logical GLSL450
810+ OpEntryPoint MeshEXT %main "main" %vertexOutput
811+ OpExecutionModeId %main LocalSizeId %uint_1 %uint_1 %uint_1
812+ OpExecutionMode %main OutputVertices 3
813+ OpExecutionMode %main OutputPrimitivesEXT 1
814+ OpExecutionMode %main OutputTrianglesEXT
815+ OpDecorate %VertexOutput Block
816+ OpMemberDecorate %VertexOutput 0 Location 0
817+ %void = OpTypeVoid
818+ %4 = OpTypeFunction %void
819+ %uint = OpTypeInt 32 0
820+ %uint_1 = OpConstant %uint 1
821+ %uint_3 = OpConstant %uint 3
822+ %float = OpTypeFloat 32
823+ %v4float = OpTypeVector %float 4
824+ %VertexOutput = OpTypeStruct %v4float
825+ %_ptr_Output_uint_3 = OpTypePointer Output %VertexOutput
826+ %vertexOutput = OpVariable %_ptr_Output_uint_3 Output
827+ %int = OpTypeInt 32 1
828+ %int_0 = OpConstant %int 0
829+ %float_0 = OpConstant %float 0
830+ %19 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
831+ %_ptr_Output_v4float = OpTypePointer Output %v4float
832+ %main = OpFunction %void None %4
833+ %6 = OpLabel
834+ OpSetMeshOutputsEXT %uint_3 %uint_1
835+ %21 = OpAccessChain %_ptr_Output_v4float %vertexOutput %int_0
836+ OpStore %21 %19
837+ OpReturn
838+ OpFunctionEnd
839+ )" ;
840+
841+ CompileSuccessfully (body, SPV_ENV_VULKAN_1_3);
842+ EXPECT_EQ (SPV_ERROR_INVALID_DATA, ValidateInstructions (SPV_ENV_VULKAN_1_3));
843+ EXPECT_THAT (getDiagnosticString (),
844+ HasSubstr (" In the MeshEXT Execution Mode, all Output Variables "
845+ " must contain an Array." ));
846+ }
847+
675848TEST_F (ValidateMeshShading, BadPerPrimitiveEXTStorageClassInMeshEXT) {
676849 const std::string body = R"(
677850 OpCapability MeshShadingEXT
0 commit comments