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