1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Google Inc.
7 * Copyright (c) 2017 Codeplay Software Ltd.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 */ /*!
22 * \file
23 * \brief Subgroups Tests
24 */ /*--------------------------------------------------------------------*/
25
26 #include "vktSubgroupsBallotTests.hpp"
27 #include "vktSubgroupsTestsUtils.hpp"
28
29 #include <string>
30 #include <vector>
31
32 using namespace tcu;
33 using namespace std;
34 using namespace vk;
35 using namespace vkt;
36
37 namespace
38 {
39 struct CaseDefinition
40 {
41 VkShaderStageFlags shaderStage;
42 de::SharedPtr<bool> geometryPointSizeSupported;
43 deBool extShaderSubGroupBallotTests;
44 deBool requiredSubgroupSize;
45 };
46
checkVertexPipelineStages(const void * internalData,vector<const void * > datas,deUint32 width,deUint32)47 static bool checkVertexPipelineStages (const void* internalData,
48 vector<const void*> datas,
49 deUint32 width,
50 deUint32)
51 {
52 DE_UNREF(internalData);
53
54 return subgroups::check(datas, width, 0x7);
55 }
56
checkCompute(const void * internalData,vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)57 static bool checkCompute (const void* internalData,
58 vector<const void*> datas,
59 const deUint32 numWorkgroups[3],
60 const deUint32 localSize[3],
61 deUint32)
62 {
63 DE_UNREF(internalData);
64
65 return subgroups::checkCompute(datas, numWorkgroups, localSize, 0x7);
66 }
67
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)68 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
69 {
70 const SpirVAsmBuildOptions buildOptionsSpr (programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
71 const string extensionHeader = (caseDef.extShaderSubGroupBallotTests ? "OpExtension \"SPV_KHR_shader_ballot\"\n" : "");
72 const string capabilityBallotHeader = (caseDef.extShaderSubGroupBallotTests ? "OpCapability SubgroupBallotKHR\n" : "OpCapability GroupNonUniformBallot\n");
73 const string subgroupSizeStr = de::toString(subgroups::maxSupportedSubgroupSize());
74
75 subgroups::setFragmentShaderFrameBuffer(programCollection);
76
77 if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
78 subgroups::setVertexShaderFrameBuffer(programCollection);
79
80 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
81 {
82 /*
83 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
84 "layout(location = 0) in highp vec4 in_position;\n"
85 "layout(location = 0) out float out_color;\n"
86 "layout(set = 0, binding = 0) uniform Buffer1\n"
87 "{\n"
88 " uint data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
89 "};\n"
90 "\n"
91 "void main (void)\n"
92 "{\n"
93 " uint tempResult = 0;\n"
94 " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1 : 0;\n"
95 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
96 " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2 : 0;\n"
97 " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4 : 0;\n"
98 " out_color = float(tempResult);\n"
99 " gl_Position = in_position;\n"
100 " gl_PointSize = 1.0f;\n"
101 "}\n";
102 */
103 const string vertex =
104 "; SPIR-V\n"
105 "; Version: 1.3\n"
106 "; Generator: Khronos Glslang Reference Front End; 2\n"
107 "; Bound: 76\n"
108 "; Schema: 0\n"
109 "OpCapability Shader\n"
110 "OpCapability GroupNonUniform\n"
111 + capabilityBallotHeader
112 + extensionHeader +
113 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
114 "OpMemoryModel Logical GLSL450\n"
115 "OpEntryPoint Vertex %4 \"main\" %35 %62 %70 %72\n"
116 "OpDecorate %30 ArrayStride 16\n"
117 "OpMemberDecorate %31 0 Offset 0\n"
118 "OpDecorate %31 Block\n"
119 "OpDecorate %33 DescriptorSet 0\n"
120 "OpDecorate %33 Binding 0\n"
121 "OpDecorate %35 RelaxedPrecision\n"
122 "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
123 "OpDecorate %36 RelaxedPrecision\n"
124 "OpDecorate %62 Location 0\n"
125 "OpMemberDecorate %68 0 BuiltIn Position\n"
126 "OpMemberDecorate %68 1 BuiltIn PointSize\n"
127 "OpMemberDecorate %68 2 BuiltIn ClipDistance\n"
128 "OpMemberDecorate %68 3 BuiltIn CullDistance\n"
129 "OpDecorate %68 Block\n"
130 "OpDecorate %72 Location 0\n"
131 "%2 = OpTypeVoid\n"
132 "%3 = OpTypeFunction %2\n"
133 "%6 = OpTypeInt 32 0\n"
134 "%7 = OpTypePointer Function %6\n"
135 "%9 = OpConstant %6 0\n"
136 "%10 = OpTypeVector %6 4\n"
137 "%11 = OpConstantComposite %10 %9 %9 %9 %9\n"
138 "%12 = OpTypeBool\n"
139 "%13 = OpConstantTrue %12\n"
140 "%14 = OpConstant %6 3\n"
141 "%16 = OpTypeVector %12 4\n"
142 "%20 = OpTypeInt 32 1\n"
143 "%21 = OpConstant %20 1\n"
144 "%22 = OpConstant %20 0\n"
145 "%27 = OpTypePointer Function %12\n"
146 "%29 = OpConstant %6 " + subgroupSizeStr + "\n"
147 "%30 = OpTypeArray %6 %29\n"
148 "%31 = OpTypeStruct %30\n"
149 "%32 = OpTypePointer Uniform %31\n"
150 "%33 = OpVariable %32 Uniform\n"
151 "%34 = OpTypePointer Input %6\n"
152 "%35 = OpVariable %34 Input\n"
153 "%37 = OpTypePointer Uniform %6\n"
154 "%46 = OpConstant %20 2\n"
155 "%51 = OpConstantFalse %12\n"
156 "%55 = OpConstant %20 4\n"
157 "%60 = OpTypeFloat 32\n"
158 "%61 = OpTypePointer Output %60\n"
159 "%62 = OpVariable %61 Output\n"
160 "%65 = OpTypeVector %60 4\n"
161 "%66 = OpConstant %6 1\n"
162 "%67 = OpTypeArray %60 %66\n"
163 "%68 = OpTypeStruct %65 %60 %67 %67\n"
164 "%69 = OpTypePointer Output %68\n"
165 "%70 = OpVariable %69 Output\n"
166 "%71 = OpTypePointer Input %65\n"
167 "%72 = OpVariable %71 Input\n"
168 "%74 = OpTypePointer Output %65\n"
169 "%76 = OpConstant %60 1\n"
170 "%4 = OpFunction %2 None %3\n"
171 "%5 = OpLabel\n"
172 "%8 = OpVariable %7 Function\n"
173 "%28 = OpVariable %27 Function\n"
174 "OpStore %8 %9\n"
175 "%15 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %13" : "OpGroupNonUniformBallot %10 %14 %13") + "\n"
176 "%17 = OpIEqual %16 %11 %15\n"
177 "%18 = OpAll %12 %17\n"
178 "%19 = OpLogicalNot %12 %18\n"
179 "%23 = OpSelect %20 %19 %21 %22\n"
180 "%24 = OpBitcast %6 %23\n"
181 "%25 = OpLoad %6 %8\n"
182 "%26 = OpBitwiseOr %6 %25 %24\n"
183 "OpStore %8 %26\n"
184 "%36 = OpLoad %6 %35\n"
185 "%38 = OpAccessChain %37 %33 %22 %36\n"
186 "%39 = OpLoad %6 %38\n"
187 "%40 = OpINotEqual %12 %39 %9\n"
188 "OpStore %28 %40\n"
189 "%41 = OpLoad %12 %28\n"
190 "%42 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %41" : "OpGroupNonUniformBallot %10 %14 %41") + "\n"
191 "%43 = OpIEqual %16 %11 %42\n"
192 "%44 = OpAll %12 %43\n"
193 "%45 = OpLogicalNot %12 %44\n"
194 "%47 = OpSelect %20 %45 %46 %22\n"
195 "%48 = OpBitcast %6 %47\n"
196 "%49 = OpLoad %6 %8\n"
197 "%50 = OpBitwiseOr %6 %49 %48\n"
198 "OpStore %8 %50\n"
199 "%52 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %51" : "OpGroupNonUniformBallot %10 %14 %51") + "\n"
200 "%53 = OpIEqual %16 %11 %52\n"
201 "%54 = OpAll %12 %53\n"
202 "%56 = OpSelect %20 %54 %55 %22\n"
203 "%57 = OpBitcast %6 %56\n"
204 "%58 = OpLoad %6 %8\n"
205 "%59 = OpBitwiseOr %6 %58 %57\n"
206 "OpStore %8 %59\n"
207 "%63 = OpLoad %6 %8\n"
208 "%64 = OpConvertUToF %60 %63\n"
209 "OpStore %62 %64\n"
210 "%73 = OpLoad %65 %72\n"
211 "%75 = OpAccessChain %74 %70 %22\n"
212 "OpStore %75 %73\n"
213 "%77 = OpAccessChain %61 %70 %21\n"
214 "OpStore %77 %76\n"
215 "OpReturn\n"
216 "OpFunctionEnd\n";
217 programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
218 }
219 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
220 {
221 /*
222 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
223 "layout(points) in;\n"
224 "layout(points, max_vertices = 1) out;\n"
225 "layout(location = 0) out float out_color;\n"
226 "layout(set = 0, binding = 0) uniform Buffer1\n"
227 "{\n"
228 " uint data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
229 "};\n"
230 "\n"
231 "void main (void)\n"
232 "{\n"
233 " uint tempResult = 0;\n"
234 " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1 : 0;\n"
235 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
236 " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2 : 0;\n"
237 " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4 : 0;\n"
238 " out_color = float(tempResult);\n"
239 " gl_Position = gl_in[0].gl_Position;\n"
240 " gl_PointSize = gl_in[0].gl_PointSize;\n"
241 " EmitVertex();\n"
242 " EndPrimitive();\n"
243 "}\n";
244 */
245 ostringstream geometry;
246
247 geometry
248 << "; SPIR-V\n"
249 << "; Version: 1.3\n"
250 << "; Generator: Khronos Glslang Reference Front End; 2\n"
251 << "; Bound: 80\n"
252 << "; Schema: 0\n"
253 << "OpCapability Geometry\n"
254 << (*caseDef.geometryPointSizeSupported ? "OpCapability GeometryPointSize\n" : "")
255 << "OpCapability GroupNonUniform\n"
256 << capabilityBallotHeader.c_str()
257 << extensionHeader.c_str()
258 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
259 << "OpMemoryModel Logical GLSL450\n"
260 << "OpEntryPoint Geometry %4 \"main\" %35 %62 %70 %74\n"
261 << "OpExecutionMode %4 InputPoints\n"
262 << "OpExecutionMode %4 Invocations 1\n"
263 << "OpExecutionMode %4 OutputPoints\n"
264 << "OpExecutionMode %4 OutputVertices 1\n"
265 << "OpDecorate %30 ArrayStride 16\n"
266 << "OpMemberDecorate %31 0 Offset 0\n"
267 << "OpDecorate %31 Block\n"
268 << "OpDecorate %33 DescriptorSet 0\n"
269 << "OpDecorate %33 Binding 0\n"
270 << "OpDecorate %35 RelaxedPrecision\n"
271 << "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
272 << "OpDecorate %36 RelaxedPrecision\n"
273 << "OpDecorate %62 Location 0\n"
274 << "OpMemberDecorate %68 0 BuiltIn Position\n"
275 << "OpMemberDecorate %68 1 BuiltIn PointSize\n"
276 << "OpMemberDecorate %68 2 BuiltIn ClipDistance\n"
277 << "OpMemberDecorate %68 3 BuiltIn CullDistance\n"
278 << "OpDecorate %68 Block\n"
279 << "OpMemberDecorate %71 0 BuiltIn Position\n"
280 << "OpMemberDecorate %71 1 BuiltIn PointSize\n"
281 << "OpMemberDecorate %71 2 BuiltIn ClipDistance\n"
282 << "OpMemberDecorate %71 3 BuiltIn CullDistance\n"
283 << "OpDecorate %71 Block\n"
284 << "%2 = OpTypeVoid\n"
285 << "%3 = OpTypeFunction %2\n"
286 << "%6 = OpTypeInt 32 0\n"
287 << "%7 = OpTypePointer Function %6\n"
288 << "%9 = OpConstant %6 0\n"
289 << "%10 = OpTypeVector %6 4\n"
290 << "%11 = OpConstantComposite %10 %9 %9 %9 %9\n"
291 << "%12 = OpTypeBool\n"
292 << "%13 = OpConstantTrue %12\n"
293 << "%14 = OpConstant %6 3\n"
294 << "%16 = OpTypeVector %12 4\n"
295 << "%20 = OpTypeInt 32 1\n"
296 << "%21 = OpConstant %20 1\n"
297 << "%22 = OpConstant %20 0\n"
298 << "%27 = OpTypePointer Function %12\n"
299 << "%29 = OpConstant %6 " << subgroupSizeStr << "\n"
300 << "%30 = OpTypeArray %6 %29\n"
301 << "%31 = OpTypeStruct %30\n"
302 << "%32 = OpTypePointer Uniform %31\n"
303 << "%33 = OpVariable %32 Uniform\n"
304 << "%34 = OpTypePointer Input %6\n"
305 << "%35 = OpVariable %34 Input\n"
306 << "%37 = OpTypePointer Uniform %6\n"
307 << "%46 = OpConstant %20 2\n"
308 << "%51 = OpConstantFalse %12\n"
309 << "%55 = OpConstant %20 4\n"
310 << "%60 = OpTypeFloat 32\n"
311 << "%61 = OpTypePointer Output %60\n"
312 << "%62 = OpVariable %61 Output\n"
313 << "%65 = OpTypeVector %60 4\n"
314 << "%66 = OpConstant %6 1\n"
315 << "%67 = OpTypeArray %60 %66\n"
316 << "%68 = OpTypeStruct %65 %60 %67 %67\n"
317 << "%69 = OpTypePointer Output %68\n"
318 << "%70 = OpVariable %69 Output\n"
319 << "%71 = OpTypeStruct %65 %60 %67 %67\n"
320 << "%72 = OpTypeArray %71 %66\n"
321 << "%73 = OpTypePointer Input %72\n"
322 << "%74 = OpVariable %73 Input\n"
323 << "%75 = OpTypePointer Input %65\n"
324 << "%78 = OpTypePointer Output %65\n"
325 << (*caseDef.geometryPointSizeSupported ?
326 "%80 = OpTypePointer Input %60\n"
327 "%81 = OpTypePointer Output %60\n" : "")
328 << "%4 = OpFunction %2 None %3\n"
329 << "%5 = OpLabel\n"
330 << "%8 = OpVariable %7 Function\n"
331 << "%28 = OpVariable %27 Function\n"
332 << "OpStore %8 %9\n"
333 << "%15 = " << (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %13" : "OpGroupNonUniformBallot %10 %14 %13") << "\n"
334 << "%17 = OpIEqual %16 %11 %15\n"
335 << "%18 = OpAll %12 %17\n"
336 << "%19 = OpLogicalNot %12 %18\n"
337 << "%23 = OpSelect %20 %19 %21 %22\n"
338 << "%24 = OpBitcast %6 %23\n"
339 << "%25 = OpLoad %6 %8\n"
340 << "%26 = OpBitwiseOr %6 %25 %24\n"
341 << "OpStore %8 %26\n"
342 << "%36 = OpLoad %6 %35\n"
343 << "%38 = OpAccessChain %37 %33 %22 %36\n"
344 << "%39 = OpLoad %6 %38\n"
345 << "%40 = OpINotEqual %12 %39 %9\n"
346 << "OpStore %28 %40\n"
347 << "%41 = OpLoad %12 %28\n"
348 << "%42 = " << (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %41" : "OpGroupNonUniformBallot %10 %14 %41") << "\n"
349 << "%43 = OpIEqual %16 %11 %42\n"
350 << "%44 = OpAll %12 %43\n"
351 << "%45 = OpLogicalNot %12 %44\n"
352 << "%47 = OpSelect %20 %45 %46 %22\n"
353 << "%48 = OpBitcast %6 %47\n"
354 << "%49 = OpLoad %6 %8\n"
355 << "%50 = OpBitwiseOr %6 %49 %48\n"
356 << "OpStore %8 %50\n"
357 << "%52 = " << (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %51" : "OpGroupNonUniformBallot %10 %14 %51") << "\n"
358 << "%53 = OpIEqual %16 %11 %52\n"
359 << "%54 = OpAll %12 %53\n"
360 << "%56 = OpSelect %20 %54 %55 %22\n"
361 << "%57 = OpBitcast %6 %56\n"
362 << "%58 = OpLoad %6 %8\n"
363 << "%59 = OpBitwiseOr %6 %58 %57\n"
364 << "OpStore %8 %59\n"
365 << "%63 = OpLoad %6 %8\n"
366 << "%64 = OpConvertUToF %60 %63\n"
367 << "OpStore %62 %64\n"
368 << "%76 = OpAccessChain %75 %74 %22 %22\n"
369 << "%77 = OpLoad %65 %76\n"
370 << "%79 = OpAccessChain %78 %70 %22\n"
371 << "OpStore %79 %77\n"
372 << (*caseDef.geometryPointSizeSupported ?
373 "%82 = OpAccessChain %80 %74 %22 %21\n"
374 "%83 = OpLoad %60 %82\n"
375 "%84 = OpAccessChain %81 %70 %21\n"
376 "OpStore %84 %83\n" : "")
377 << "OpEmitVertex\n"
378 << "OpEndPrimitive\n"
379 << "OpReturn\n"
380 << "OpFunctionEnd\n";
381 programCollection.spirvAsmSources.add("geometry") << geometry.str() << buildOptionsSpr;
382 }
383 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
384 {
385 /*
386 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
387 "layout(vertices = 2) out;\n"
388 "layout(location = 0) out float out_color[];\n"
389 "layout(set = 0, binding = 0) uniform Buffer1\n"
390 "{\n"
391 " uint data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
392 "};\n"
393 "\n"
394 "void main (void)\n"
395 "{\n"
396 " if (gl_InvocationID == 0)\n"
397 {\n"
398 " gl_TessLevelOuter[0] = 1.0f;\n"
399 " gl_TessLevelOuter[1] = 1.0f;\n"
400 " }\n"
401 " uint tempResult = 0;\n"
402 " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1 : 0;\n"
403 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
404 " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2 : 0;\n"
405 " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4 : 0;\n"
406 " out_color[gl_InvocationID] = float(tempResult);\n"
407 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
408 "}\n";
409 */
410 const string controlSource =
411 "; SPIR-V\n"
412 "; Version: 1.3\n"
413 "; Generator: Khronos Glslang Reference Front End; 2\n"
414 "; Bound: 102\n"
415 "; Schema: 0\n"
416 "OpCapability Tessellation\n"
417 "OpCapability GroupNonUniform\n"
418 + capabilityBallotHeader
419 + extensionHeader +
420 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
421 "OpMemoryModel Logical GLSL450\n"
422 "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %50 %78 %89 %95\n"
423 "OpExecutionMode %4 OutputVertices 2\n"
424 "OpDecorate %8 BuiltIn InvocationId\n"
425 "OpDecorate %20 Patch\n"
426 "OpDecorate %20 BuiltIn TessLevelOuter\n"
427 "OpDecorate %45 ArrayStride 16\n"
428 "OpMemberDecorate %46 0 Offset 0\n"
429 "OpDecorate %46 Block\n"
430 "OpDecorate %48 DescriptorSet 0\n"
431 "OpDecorate %48 Binding 0\n"
432 "OpDecorate %50 RelaxedPrecision\n"
433 "OpDecorate %50 BuiltIn SubgroupLocalInvocationId\n"
434 "OpDecorate %51 RelaxedPrecision\n"
435 "OpDecorate %78 Location 0\n"
436 "OpMemberDecorate %86 0 BuiltIn Position\n"
437 "OpMemberDecorate %86 1 BuiltIn PointSize\n"
438 "OpMemberDecorate %86 2 BuiltIn ClipDistance\n"
439 "OpMemberDecorate %86 3 BuiltIn CullDistance\n"
440 "OpDecorate %86 Block\n"
441 "OpMemberDecorate %91 0 BuiltIn Position\n"
442 "OpMemberDecorate %91 1 BuiltIn PointSize\n"
443 "OpMemberDecorate %91 2 BuiltIn ClipDistance\n"
444 "OpMemberDecorate %91 3 BuiltIn CullDistance\n"
445 "OpDecorate %91 Block\n"
446 "%2 = OpTypeVoid\n"
447 "%3 = OpTypeFunction %2\n"
448 "%6 = OpTypeInt 32 1\n"
449 "%7 = OpTypePointer Input %6\n"
450 "%8 = OpVariable %7 Input\n"
451 "%10 = OpConstant %6 0\n"
452 "%11 = OpTypeBool\n"
453 "%15 = OpTypeFloat 32\n"
454 "%16 = OpTypeInt 32 0\n"
455 "%17 = OpConstant %16 4\n"
456 "%18 = OpTypeArray %15 %17\n"
457 "%19 = OpTypePointer Output %18\n"
458 "%20 = OpVariable %19 Output\n"
459 "%21 = OpConstant %15 1\n"
460 "%22 = OpTypePointer Output %15\n"
461 "%24 = OpConstant %6 1\n"
462 "%26 = OpTypePointer Function %16\n"
463 "%28 = OpConstant %16 0\n"
464 "%29 = OpTypeVector %16 4\n"
465 "%30 = OpConstantComposite %29 %28 %28 %28 %28\n"
466 "%31 = OpConstantTrue %11\n"
467 "%32 = OpConstant %16 3\n"
468 "%34 = OpTypeVector %11 4\n"
469 "%42 = OpTypePointer Function %11\n"
470 "%44 = OpConstant %16 " + subgroupSizeStr + "\n"
471 "%45 = OpTypeArray %16 %44\n"
472 "%46 = OpTypeStruct %45\n"
473 "%47 = OpTypePointer Uniform %46\n"
474 "%48 = OpVariable %47 Uniform\n"
475 "%49 = OpTypePointer Input %16\n"
476 "%50 = OpVariable %49 Input\n"
477 "%52 = OpTypePointer Uniform %16\n"
478 "%61 = OpConstant %6 2\n"
479 "%66 = OpConstantFalse %11\n"
480 "%70 = OpConstant %6 4\n"
481 "%75 = OpConstant %16 2\n"
482 "%76 = OpTypeArray %15 %75\n"
483 "%77 = OpTypePointer Output %76\n"
484 "%78 = OpVariable %77 Output\n"
485 "%83 = OpTypeVector %15 4\n"
486 "%84 = OpConstant %16 1\n"
487 "%85 = OpTypeArray %15 %84\n"
488 "%86 = OpTypeStruct %83 %15 %85 %85\n"
489 "%87 = OpTypeArray %86 %75\n"
490 "%88 = OpTypePointer Output %87\n"
491 "%89 = OpVariable %88 Output\n"
492 "%91 = OpTypeStruct %83 %15 %85 %85\n"
493 "%92 = OpConstant %16 32\n"
494 "%93 = OpTypeArray %91 %92\n"
495 "%94 = OpTypePointer Input %93\n"
496 "%95 = OpVariable %94 Input\n"
497 "%97 = OpTypePointer Input %83\n"
498 "%100 = OpTypePointer Output %83\n"
499 "%4 = OpFunction %2 None %3\n"
500 "%5 = OpLabel\n"
501 "%27 = OpVariable %26 Function\n"
502 "%43 = OpVariable %42 Function\n"
503 "%9 = OpLoad %6 %8\n"
504 "%12 = OpIEqual %11 %9 %10\n"
505 "OpSelectionMerge %14 None\n"
506 "OpBranchConditional %12 %13 %14\n"
507 "%13 = OpLabel\n"
508 "%23 = OpAccessChain %22 %20 %10\n"
509 "OpStore %23 %21\n"
510 "%25 = OpAccessChain %22 %20 %24\n"
511 "OpStore %25 %21\n"
512 "OpBranch %14\n"
513 "%14 = OpLabel\n"
514 "OpStore %27 %28\n"
515 "%33 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %29 %31" : "OpGroupNonUniformBallot %29 %32 %31") + "\n"
516 "%35 = OpIEqual %34 %30 %33\n"
517 "%36 = OpAll %11 %35\n"
518 "%37 = OpLogicalNot %11 %36\n"
519 "%38 = OpSelect %6 %37 %24 %10\n"
520 "%39 = OpBitcast %16 %38\n"
521 "%40 = OpLoad %16 %27\n"
522 "%41 = OpBitwiseOr %16 %40 %39\n"
523 "OpStore %27 %41\n"
524 "%51 = OpLoad %16 %50\n"
525 "%53 = OpAccessChain %52 %48 %10 %51\n"
526 "%54 = OpLoad %16 %53\n"
527 "%55 = OpINotEqual %11 %54 %28\n"
528 "OpStore %43 %55\n"
529 "%56 = OpLoad %11 %43\n"
530 "%57 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %29 %56" : "OpGroupNonUniformBallot %29 %32 %56") + "\n"
531 "%58 = OpIEqual %34 %30 %57\n"
532 "%59 = OpAll %11 %58\n"
533 "%60 = OpLogicalNot %11 %59\n"
534 "%62 = OpSelect %6 %60 %61 %10\n"
535 "%63 = OpBitcast %16 %62\n"
536 "%64 = OpLoad %16 %27\n"
537 "%65 = OpBitwiseOr %16 %64 %63\n"
538 "OpStore %27 %65\n"
539 "%67 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %29 %66" : "OpGroupNonUniformBallot %29 %32 %66") + "\n"
540 "%68 = OpIEqual %34 %30 %67\n"
541 "%69 = OpAll %11 %68\n"
542 "%71 = OpSelect %6 %69 %70 %10\n"
543 "%72 = OpBitcast %16 %71\n"
544 "%73 = OpLoad %16 %27\n"
545 "%74 = OpBitwiseOr %16 %73 %72\n"
546 "OpStore %27 %74\n"
547 "%79 = OpLoad %6 %8\n"
548 "%80 = OpLoad %16 %27\n"
549 "%81 = OpConvertUToF %15 %80\n"
550 "%82 = OpAccessChain %22 %78 %79\n"
551 "OpStore %82 %81\n"
552 "%90 = OpLoad %6 %8\n"
553 "%96 = OpLoad %6 %8\n"
554 "%98 = OpAccessChain %97 %95 %96 %10\n"
555 "%99 = OpLoad %83 %98\n"
556 "%101 = OpAccessChain %100 %89 %90 %10\n"
557 "OpStore %101 %99\n"
558 "OpReturn\n"
559 "OpFunctionEnd\n";
560
561 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
562 subgroups::setTesEvalShaderFrameBuffer(programCollection);
563
564 }
565 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
566 {
567 /*
568 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
569 "layout(isolines, equal_spacing, ccw ) in;\n"
570 "layout(location = 0) out float out_color;\n"
571 "layout(set = 0, binding = 0) uniform Buffer1\n"
572 "{\n"
573 " uint data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
574 "};\n"
575 "\n"
576 "void main (void)\n"
577 "{\n"
578 " uint tempResult = 0;\n"
579 " tempResult |= !bool(uvec4(0) == subgroupBallot(true)) ? 0x1 : 0;\n"
580 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
581 " tempResult |= !bool(uvec4(0) == subgroupBallot(bData)) ? 0x2 : 0;\n"
582 " tempResult |= uvec4(0) == subgroupBallot(false) ? 0x4 : 0;\n"
583 " out_color = float(tempResult);\n"
584 " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
585 "}\n";
586 */
587 const string evaluationSource =
588 "; SPIR-V\n"
589 "; Version: 1.3\n"
590 "; Generator: Khronos Glslang Reference Front End; 2\n"
591 "; Bound: 91\n"
592 "; Schema: 0\n"
593 "OpCapability Tessellation\n"
594 "OpCapability GroupNonUniform\n"
595 + capabilityBallotHeader
596 + extensionHeader +
597 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
598 "OpMemoryModel Logical GLSL450\n"
599 "OpEntryPoint TessellationEvaluation %4 \"main\" %35 %62 %70 %75 %83\n"
600 "OpExecutionMode %4 Isolines\n"
601 "OpExecutionMode %4 SpacingEqual\n"
602 "OpExecutionMode %4 VertexOrderCcw\n"
603 "OpDecorate %30 ArrayStride 16\n"
604 "OpMemberDecorate %31 0 Offset 0\n"
605 "OpDecorate %31 Block\n"
606 "OpDecorate %33 DescriptorSet 0\n"
607 "OpDecorate %33 Binding 0\n"
608 "OpDecorate %35 RelaxedPrecision\n"
609 "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
610 "OpDecorate %36 RelaxedPrecision\n"
611 "OpDecorate %62 Location 0\n"
612 "OpMemberDecorate %68 0 BuiltIn Position\n"
613 "OpMemberDecorate %68 1 BuiltIn PointSize\n"
614 "OpMemberDecorate %68 2 BuiltIn ClipDistance\n"
615 "OpMemberDecorate %68 3 BuiltIn CullDistance\n"
616 "OpDecorate %68 Block\n"
617 "OpMemberDecorate %71 0 BuiltIn Position\n"
618 "OpMemberDecorate %71 1 BuiltIn PointSize\n"
619 "OpMemberDecorate %71 2 BuiltIn ClipDistance\n"
620 "OpMemberDecorate %71 3 BuiltIn CullDistance\n"
621 "OpDecorate %71 Block\n"
622 "OpDecorate %83 BuiltIn TessCoord\n"
623 "%2 = OpTypeVoid\n"
624 "%3 = OpTypeFunction %2\n"
625 "%6 = OpTypeInt 32 0\n"
626 "%7 = OpTypePointer Function %6\n"
627 "%9 = OpConstant %6 0\n"
628 "%10 = OpTypeVector %6 4\n"
629 "%11 = OpConstantComposite %10 %9 %9 %9 %9\n"
630 "%12 = OpTypeBool\n"
631 "%13 = OpConstantTrue %12\n"
632 "%14 = OpConstant %6 3\n"
633 "%16 = OpTypeVector %12 4\n"
634 "%20 = OpTypeInt 32 1\n"
635 "%21 = OpConstant %20 1\n"
636 "%22 = OpConstant %20 0\n"
637 "%27 = OpTypePointer Function %12\n"
638 "%29 = OpConstant %6 " + subgroupSizeStr + "\n"
639 "%30 = OpTypeArray %6 %29\n"
640 "%31 = OpTypeStruct %30\n"
641 "%32 = OpTypePointer Uniform %31\n"
642 "%33 = OpVariable %32 Uniform\n"
643 "%34 = OpTypePointer Input %6\n"
644 "%35 = OpVariable %34 Input\n"
645 "%37 = OpTypePointer Uniform %6\n"
646 "%46 = OpConstant %20 2\n"
647 "%51 = OpConstantFalse %12\n"
648 "%55 = OpConstant %20 4\n"
649 "%60 = OpTypeFloat 32\n"
650 "%61 = OpTypePointer Output %60\n"
651 "%62 = OpVariable %61 Output\n"
652 "%65 = OpTypeVector %60 4\n"
653 "%66 = OpConstant %6 1\n"
654 "%67 = OpTypeArray %60 %66\n"
655 "%68 = OpTypeStruct %65 %60 %67 %67\n"
656 "%69 = OpTypePointer Output %68\n"
657 "%70 = OpVariable %69 Output\n"
658 "%71 = OpTypeStruct %65 %60 %67 %67\n"
659 "%72 = OpConstant %6 32\n"
660 "%73 = OpTypeArray %71 %72\n"
661 "%74 = OpTypePointer Input %73\n"
662 "%75 = OpVariable %74 Input\n"
663 "%76 = OpTypePointer Input %65\n"
664 "%81 = OpTypeVector %60 3\n"
665 "%82 = OpTypePointer Input %81\n"
666 "%83 = OpVariable %82 Input\n"
667 "%84 = OpTypePointer Input %60\n"
668 "%89 = OpTypePointer Output %65\n"
669 "%4 = OpFunction %2 None %3\n"
670 "%5 = OpLabel\n"
671 "%8 = OpVariable %7 Function\n"
672 "%28 = OpVariable %27 Function\n"
673 "OpStore %8 %9\n"
674 "%15 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %13" : "OpGroupNonUniformBallot %10 %14 %13") + "\n"
675 "%17 = OpIEqual %16 %11 %15\n"
676 "%18 = OpAll %12 %17\n"
677 "%19 = OpLogicalNot %12 %18\n"
678 "%23 = OpSelect %20 %19 %21 %22\n"
679 "%24 = OpBitcast %6 %23\n"
680 "%25 = OpLoad %6 %8\n"
681 "%26 = OpBitwiseOr %6 %25 %24\n"
682 "OpStore %8 %26\n"
683 "%36 = OpLoad %6 %35\n"
684 "%38 = OpAccessChain %37 %33 %22 %36\n"
685 "%39 = OpLoad %6 %38\n"
686 "%40 = OpINotEqual %12 %39 %9\n"
687 "OpStore %28 %40\n"
688 "%41 = OpLoad %12 %28\n"
689 "%42 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %41" : "OpGroupNonUniformBallot %10 %14 %41") + "\n"
690 "%43 = OpIEqual %16 %11 %42\n"
691 "%44 = OpAll %12 %43\n"
692 "%45 = OpLogicalNot %12 %44\n"
693 "%47 = OpSelect %20 %45 %46 %22\n"
694 "%48 = OpBitcast %6 %47\n"
695 "%49 = OpLoad %6 %8\n"
696 "%50 = OpBitwiseOr %6 %49 %48\n"
697 "OpStore %8 %50\n"
698 "%52 = " + (caseDef.extShaderSubGroupBallotTests ? "OpSubgroupBallotKHR %10 %51" : "OpGroupNonUniformBallot %10 %14 %51") + "\n"
699 "%53 = OpIEqual %16 %11 %52\n"
700 "%54 = OpAll %12 %53\n"
701 "%56 = OpSelect %20 %54 %55 %22\n"
702 "%57 = OpBitcast %6 %56\n"
703 "%58 = OpLoad %6 %8\n"
704 "%59 = OpBitwiseOr %6 %58 %57\n"
705 "OpStore %8 %59\n"
706 "%63 = OpLoad %6 %8\n"
707 "%64 = OpConvertUToF %60 %63\n"
708 "OpStore %62 %64\n"
709 "%77 = OpAccessChain %76 %75 %22 %22\n"
710 "%78 = OpLoad %65 %77\n"
711 "%79 = OpAccessChain %76 %75 %21 %22\n"
712 "%80 = OpLoad %65 %79\n"
713 "%85 = OpAccessChain %84 %83 %9\n"
714 "%86 = OpLoad %60 %85\n"
715 "%87 = OpCompositeConstruct %65 %86 %86 %86 %86\n"
716 "%88 = OpExtInst %65 %1 FMix %78 %80 %87\n"
717 "%90 = OpAccessChain %89 %70 %22\n"
718 "OpStore %90 %88\n"
719 "OpReturn\n"
720 "OpFunctionEnd\n";
721 subgroups::setTesCtrlShaderFrameBuffer(programCollection);
722 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
723 }
724 else
725 {
726 DE_FATAL("Unsupported shader stage");
727 }
728 }
729
getExtHeader(const CaseDefinition & caseDef)730 string getExtHeader (const CaseDefinition& caseDef)
731 {
732 return (caseDef.extShaderSubGroupBallotTests ?
733 "#extension GL_ARB_shader_ballot: enable\n"
734 "#extension GL_ARB_gpu_shader_int64: enable\n"
735 "#extension GL_KHR_shader_subgroup_basic: enable\n"
736 :
737 "#extension GL_KHR_shader_subgroup_ballot: enable\n");
738 }
739
getBodySource(const CaseDefinition & caseDef)740 string getBodySource (const CaseDefinition& caseDef)
741 {
742 const string cmpStr = caseDef.extShaderSubGroupBallotTests ? "uint64_t(0) == ballotARB" : "uvec4(0) == subgroupBallot";
743
744 if (isAllComputeStages(caseDef.shaderStage))
745 {
746 const string cmpStrB = caseDef.extShaderSubGroupBallotTests ? "ballotARB" : "subgroupBallot";
747
748 return
749 " uint tempResult = 0;\n"
750 " tempResult |= sharedMemoryBallot(true) == " + cmpStrB + "(true) ? 0x1 : 0;\n"
751 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
752 " tempResult |= sharedMemoryBallot(bData) == " + cmpStrB + "(bData) ? 0x2 : 0;\n"
753 " tempResult |= " + cmpStr + "(false) ? 0x4 : 0;\n"
754 " tempRes = tempResult;\n";
755 }
756 else
757 {
758 return
759 " uint tempResult = 0;\n"
760 " tempResult |= !bool(" + cmpStr + "(true)) ? 0x1 : 0;\n"
761 " bool bData = data[gl_SubgroupInvocationID] != 0;\n"
762 " tempResult |= !bool(" + cmpStr + "(bData)) ? 0x2 : 0;\n"
763 " tempResult |= " + cmpStr + "(false) ? 0x4 : 0;\n"
764 " tempRes = tempResult;\n";
765 }
766 }
767
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)768 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
769 {
770 const SpirvVersion spirvVersion = isAllRayTracingStages(caseDef.shaderStage) ? SPIRV_VERSION_1_4 : SPIRV_VERSION_1_3;
771 const ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, spirvVersion, 0u);
772 const string extHeader = getExtHeader(caseDef);
773 const string testSrc = getBodySource(caseDef);
774 const string testHelper = !isAllComputeStages(caseDef.shaderStage) ? ""
775 : caseDef.extShaderSubGroupBallotTests ? subgroups::getSharedMemoryBallotHelperARB()
776 : subgroups::getSharedMemoryBallotHelper();
777 const bool pointSizeSupport = *caseDef.geometryPointSizeSupported;
778
779 subgroups::initStdPrograms(programCollection, buildOptions, caseDef.shaderStage, VK_FORMAT_R32_UINT, pointSizeSupport, extHeader, testSrc, testHelper);
780 }
781
supportedCheck(Context & context,CaseDefinition caseDef)782 void supportedCheck (Context& context, CaseDefinition caseDef)
783 {
784 if (!subgroups::isSubgroupSupported(context))
785 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
786
787 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
788 {
789 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
790 }
791
792 if (caseDef.extShaderSubGroupBallotTests && !context.requireDeviceFunctionality("VK_EXT_shader_subgroup_ballot"))
793 {
794 TCU_THROW(NotSupportedError, "Device does not support VK_EXT_shader_subgroup_ballot extension");
795 }
796
797 if (caseDef.extShaderSubGroupBallotTests && !subgroups::isInt64SupportedForDevice(context))
798 {
799 TCU_THROW(NotSupportedError, "Device does not support int64 data types");
800 }
801
802 if (caseDef.requiredSubgroupSize)
803 {
804 context.requireDeviceFunctionality("VK_EXT_subgroup_size_control");
805
806 const VkPhysicalDeviceSubgroupSizeControlFeaturesEXT& subgroupSizeControlFeatures = context.getSubgroupSizeControlFeaturesEXT();
807 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
808
809 if (subgroupSizeControlFeatures.subgroupSizeControl == DE_FALSE)
810 TCU_THROW(NotSupportedError, "Device does not support varying subgroup sizes nor required subgroup size");
811
812 if (subgroupSizeControlFeatures.computeFullSubgroups == DE_FALSE)
813 TCU_THROW(NotSupportedError, "Device does not support full subgroups in compute shaders");
814
815 if ((subgroupSizeControlProperties.requiredSubgroupSizeStages & caseDef.shaderStage) != caseDef.shaderStage)
816 TCU_THROW(NotSupportedError, "Required subgroup size is not supported for shader stage");
817 }
818
819 *caseDef.geometryPointSizeSupported = subgroups::isTessellationAndGeometryPointSizeSupported(context);
820
821 if (isAllRayTracingStages(caseDef.shaderStage))
822 {
823 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
824 }
825
826 subgroups::supportedCheckShader(context, caseDef.shaderStage);
827 }
828
noSSBOtest(Context & context,const CaseDefinition caseDef)829 TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
830 {
831 const subgroups::SSBOData inputData =
832 {
833 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
834 subgroups::SSBOData::LayoutStd140, // InputDataLayoutType layout;
835 VK_FORMAT_R32_UINT, // vk::VkFormat format;
836 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
837 };
838
839 switch (caseDef.shaderStage)
840 {
841 case VK_SHADER_STAGE_VERTEX_BIT: return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
842 case VK_SHADER_STAGE_GEOMETRY_BIT: return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages);
843 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
844 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, caseDef.shaderStage);
845 default: TCU_THROW(InternalError, "Unhandled shader stage");
846 }
847 }
848
test(Context & context,const CaseDefinition caseDef)849 TestStatus test (Context& context, const CaseDefinition caseDef)
850 {
851 if (isAllComputeStages(caseDef.shaderStage))
852 {
853 const VkPhysicalDeviceSubgroupSizeControlPropertiesEXT& subgroupSizeControlProperties = context.getSubgroupSizeControlPropertiesEXT();
854 TestLog& log = context.getTestContext().getLog();
855 const subgroups::SSBOData inputData =
856 {
857 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
858 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
859 VK_FORMAT_R32_UINT, // vk::VkFormat format;
860 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
861 };
862
863 if (caseDef.requiredSubgroupSize == DE_FALSE)
864 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute);
865
866 log << TestLog::Message << "Testing required subgroup size range [" << subgroupSizeControlProperties.minSubgroupSize << ", "
867 << subgroupSizeControlProperties.maxSubgroupSize << "]" << TestLog::EndMessage;
868
869 // According to the spec, requiredSubgroupSize must be a power-of-two integer.
870 for (deUint32 size = subgroupSizeControlProperties.minSubgroupSize; size <= subgroupSizeControlProperties.maxSubgroupSize; size *= 2)
871 {
872 TestStatus result = subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkCompute,
873 size, VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT);
874 if (result.getCode() != QP_TEST_RESULT_PASS)
875 {
876 log << TestLog::Message << "subgroupSize " << size << " failed" << TestLog::EndMessage;
877 return result;
878 }
879 }
880
881 return TestStatus::pass("OK");
882 }
883 else if (isAllGraphicsStages(caseDef.shaderStage))
884 {
885 const VkShaderStageFlags stages = subgroups::getPossibleGraphicsSubgroupStages(context, caseDef.shaderStage);
886 const subgroups::SSBOData inputData =
887 {
888 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
889 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
890 VK_FORMAT_R32_UINT, // vk::VkFormat format;
891 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
892 false, // bool isImage;
893 4u, // deUint32 binding;
894 stages, // vk::VkShaderStageFlags stages;
895 };
896
897 return subgroups::allStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
898 }
899 else if (isAllRayTracingStages(caseDef.shaderStage))
900 {
901 const VkShaderStageFlags stages = subgroups::getPossibleRayTracingSubgroupStages(context, caseDef.shaderStage);
902 const subgroups::SSBOData inputData =
903 {
904 subgroups::SSBOData::InitializeNonZero, // InputDataInitializeType initializeType;
905 subgroups::SSBOData::LayoutStd430, // InputDataLayoutType layout;
906 VK_FORMAT_R32_UINT, // vk::VkFormat format;
907 subgroups::maxSupportedSubgroupSize(), // vk::VkDeviceSize numElements;
908 false, // bool isImage;
909 6u, // deUint32 binding;
910 stages, // vk::VkShaderStageFlags stages;
911 };
912
913 return subgroups::allRayTracingStages(context, VK_FORMAT_R32_UINT, &inputData, 1, DE_NULL, checkVertexPipelineStages, stages);
914 }
915 else
916 TCU_THROW(InternalError, "Unknown stage or invalid stage set");
917 }
918 }
919
920 namespace vkt
921 {
922 namespace subgroups
923 {
createSubgroupsBallotTests(TestContext & testCtx)924 TestCaseGroup* createSubgroupsBallotTests(TestContext& testCtx)
925 {
926 de::MovePtr<TestCaseGroup> group (new TestCaseGroup(testCtx, "ballot", "Subgroup ballot category tests"));
927 de::MovePtr<TestCaseGroup> graphicGroup (new TestCaseGroup(testCtx, "graphics", "Subgroup ballot category tests: graphics"));
928 de::MovePtr<TestCaseGroup> computeGroup (new TestCaseGroup(testCtx, "compute", "Subgroup ballot category tests: compute"));
929 de::MovePtr<TestCaseGroup> framebufferGroup (new TestCaseGroup(testCtx, "framebuffer", "Subgroup ballot category tests: framebuffer"));
930 de::MovePtr<TestCaseGroup> raytracingGroup (new TestCaseGroup(testCtx, "ray_tracing", "Subgroup ballot category tests: ray tracing"));
931 de::MovePtr<TestCaseGroup> groupEXT (new TestCaseGroup(testCtx, "ext_shader_subgroup_ballot", "VK_EXT_shader_subgroups_ballot category tests"));
932 de::MovePtr<TestCaseGroup> graphicGroupEXT (new TestCaseGroup(testCtx, "graphics", "VK_EXT_shader_subgroups_ballot category tests: graphics"));
933 de::MovePtr<TestCaseGroup> computeGroupEXT (new TestCaseGroup(testCtx, "compute", "VK_EXT_shader_subgroups_ballot category tests: compute"));
934 de::MovePtr<TestCaseGroup> framebufferGroupEXT (new TestCaseGroup(testCtx, "framebuffer", "VK_EXT_shader_subgroups_ballot category tests: framebuffer"));
935 const VkShaderStageFlags stages[] =
936 {
937 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
938 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
939 VK_SHADER_STAGE_GEOMETRY_BIT,
940 VK_SHADER_STAGE_VERTEX_BIT,
941 };
942 const deBool boolValues[] =
943 {
944 DE_FALSE,
945 DE_TRUE
946 };
947
948 for (size_t groupSizeNdx = 0; groupSizeNdx < DE_LENGTH_OF_ARRAY(boolValues); ++groupSizeNdx)
949 {
950 const deBool requiredSubgroupSize = boolValues[groupSizeNdx];
951 const string testNameSuffix = requiredSubgroupSize ? "_requiredsubgroupsize" : "";
952
953 for (size_t extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(boolValues); ++extNdx)
954 {
955 const deBool extShaderSubGroupBallotTests = boolValues[extNdx];
956 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? computeGroupEXT.get() : computeGroup.get();
957 {
958 const CaseDefinition caseDef =
959 {
960 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags shaderStage;
961 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
962 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
963 requiredSubgroupSize, // deBool requiredSubgroupSize;
964 };
965 const string testName = getShaderStageName(caseDef.shaderStage) + testNameSuffix;
966
967 addFunctionCaseWithPrograms(testGroup, testName, "", supportedCheck, initPrograms, test, caseDef);
968 }
969 }
970 }
971
972 for (size_t extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(boolValues); ++extNdx)
973 {
974 const deBool extShaderSubGroupBallotTests = boolValues[extNdx];
975 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? graphicGroupEXT.get() : graphicGroup.get();
976 const CaseDefinition caseDef =
977 {
978 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags shaderStage;
979 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
980 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
981 DE_FALSE, // deBool requiredSubgroupSize;
982 };
983
984 addFunctionCaseWithPrograms(testGroup, "graphic", "", supportedCheck, initPrograms, test, caseDef);
985 }
986
987 {
988 const CaseDefinition caseDef =
989 {
990 SHADER_STAGE_ALL_RAY_TRACING, // VkShaderStageFlags shaderStage;
991 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
992 DE_FALSE, // deBool extShaderSubGroupBallotTests;
993 DE_FALSE, // deBool requiredSubgroupSize;
994 };
995
996 addFunctionCaseWithPrograms(raytracingGroup.get(), "test", "", supportedCheck, initPrograms, test, caseDef);
997 }
998
999 for (size_t extNdx = 0; extNdx < DE_LENGTH_OF_ARRAY(boolValues); ++extNdx)
1000 {
1001 const deBool extShaderSubGroupBallotTests = boolValues[extNdx];
1002 TestCaseGroup* testGroup = extShaderSubGroupBallotTests ? framebufferGroupEXT.get() : framebufferGroup.get();
1003
1004 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1005 {
1006 const CaseDefinition caseDef =
1007 {
1008 stages[stageIndex], // VkShaderStageFlags shaderStage;
1009 de::SharedPtr<bool>(new bool), // de::SharedPtr<bool> geometryPointSizeSupported;
1010 extShaderSubGroupBallotTests, // deBool extShaderSubGroupBallotTests;
1011 DE_FALSE // deBool requiredSubgroupSize;
1012 };
1013
1014 addFunctionCaseWithPrograms(testGroup, getShaderStageName(caseDef.shaderStage), "", supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
1015 }
1016 }
1017
1018 groupEXT->addChild(graphicGroupEXT.release());
1019 groupEXT->addChild(computeGroupEXT.release());
1020 groupEXT->addChild(framebufferGroupEXT.release());
1021
1022 group->addChild(graphicGroup.release());
1023 group->addChild(computeGroup.release());
1024 group->addChild(framebufferGroup.release());
1025 group->addChild(raytracingGroup.release());
1026 group->addChild(groupEXT.release());
1027
1028 return group.release();
1029 }
1030
1031 } // subgroups
1032 } // vkt
1033