• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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