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