1 /*------------------------------------------------------------------------
2 * OpenGL Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017-2019 The Khronos Group Inc.
6 * Copyright (c) 2017 Codeplay Software Ltd.
7 * Copyright (c) 2019 NVIDIA Corporation.
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 "glcSubgroupsShuffleTests.hpp"
27 #include "glcSubgroupsTestsUtils.hpp"
28
29 #include <string>
30 #include <vector>
31
32 using namespace tcu;
33 using namespace std;
34
35 namespace glc
36 {
37 namespace subgroups
38 {
39 namespace
40 {
41 enum OpType
42 {
43 OPTYPE_SHUFFLE = 0,
44 OPTYPE_SHUFFLE_XOR,
45 OPTYPE_SHUFFLE_UP,
46 OPTYPE_SHUFFLE_DOWN,
47 OPTYPE_LAST
48 };
49
checkVertexPipelineStages(std::vector<const void * > datas,deUint32 width,deUint32)50 static bool checkVertexPipelineStages(std::vector<const void*> datas,
51 deUint32 width, deUint32)
52 {
53 return glc::subgroups::check(datas, width, 1);
54 }
55
checkComputeStage(std::vector<const void * > datas,const deUint32 numWorkgroups[3],const deUint32 localSize[3],deUint32)56 static bool checkComputeStage(std::vector<const void*> datas,
57 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
58 deUint32)
59 {
60 return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 1);
61 }
62
getOpTypeName(int opType)63 std::string getOpTypeName(int opType)
64 {
65 switch (opType)
66 {
67 default:
68 DE_FATAL("Unsupported op type");
69 return "";
70 case OPTYPE_SHUFFLE:
71 return "subgroupShuffle";
72 case OPTYPE_SHUFFLE_XOR:
73 return "subgroupShuffleXor";
74 case OPTYPE_SHUFFLE_UP:
75 return "subgroupShuffleUp";
76 case OPTYPE_SHUFFLE_DOWN:
77 return "subgroupShuffleDown";
78 }
79 }
80
81 struct CaseDefinition
82 {
83 int opType;
84 ShaderStageFlags shaderStage;
85 Format format;
86 };
87
to_string(int x)88 const std::string to_string(int x) {
89 std::ostringstream oss;
90 oss << x;
91 return oss.str();
92 }
93
DeclSource(CaseDefinition caseDef,int baseBinding)94 const std::string DeclSource(CaseDefinition caseDef, int baseBinding)
95 {
96 return
97 "layout(binding = " + to_string(baseBinding) + ", std430) readonly buffer BufferB0\n"
98 "{\n"
99 " " + subgroups::getFormatNameForGLSL(caseDef.format) + " data1[];\n"
100 "};\n"
101 "layout(binding = " + to_string(baseBinding + 1) + ", std430) readonly buffer BufferB1\n"
102 "{\n"
103 " uint data2[];\n"
104 "};\n";
105 }
106
TestSource(CaseDefinition caseDef)107 const std::string TestSource(CaseDefinition caseDef)
108 {
109 std::string idTable[OPTYPE_LAST];
110 idTable[OPTYPE_SHUFFLE] = "id_in";
111 idTable[OPTYPE_SHUFFLE_XOR] = "gl_SubgroupInvocationID ^ id_in";
112 idTable[OPTYPE_SHUFFLE_UP] = "gl_SubgroupInvocationID - id_in";
113 idTable[OPTYPE_SHUFFLE_DOWN] = "gl_SubgroupInvocationID + id_in";
114
115 const std::string testSource =
116 " uint temp_res;\n"
117 " uvec4 mask = subgroupBallot(true);\n"
118 " uint id_in = data2[gl_SubgroupInvocationID] & (gl_SubgroupSize - 1u);\n"
119 " " + subgroups::getFormatNameForGLSL(caseDef.format) + " op = "
120 + getOpTypeName(caseDef.opType) + "(data1[gl_SubgroupInvocationID], id_in);\n"
121 " uint id = " + idTable[caseDef.opType] + ";\n"
122 " if ((id < gl_SubgroupSize) && subgroupBallotBitExtract(mask, id))\n"
123 " {\n"
124 " temp_res = (op == data1[id]) ? 1u : 0u;\n"
125 " }\n"
126 " else\n"
127 " {\n"
128 " temp_res = 1u; // Invocation we read from was inactive, so we can't verify results!\n"
129 " }\n";
130
131 return testSource;
132 }
133
initFrameBufferPrograms(SourceCollections & programCollection,CaseDefinition caseDef)134 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
135 {
136 subgroups::setFragmentShaderFrameBuffer(programCollection);
137
138 if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
139 subgroups::setVertexShaderFrameBuffer(programCollection);
140
141 const std::string extSource =
142 (OPTYPE_SHUFFLE == caseDef.opType || OPTYPE_SHUFFLE_XOR == caseDef.opType) ?
143 "#extension GL_KHR_shader_subgroup_shuffle: enable\n" :
144 "#extension GL_KHR_shader_subgroup_shuffle_relative: enable\n";
145
146 const std::string testSource = TestSource(caseDef);
147
148 if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
149 {
150 std::ostringstream vertexSrc;
151 vertexSrc << "${VERSION_DECL}\n"
152 << extSource
153 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
154 << "layout(location = 0) in highp vec4 in_position;\n"
155 << "layout(location = 0) out float result;\n"
156 << "layout(binding = 0, std140) uniform Buffer0\n"
157 << "{\n"
158 << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
159 << "};\n"
160 << "layout(binding = 1, std140) uniform Buffer1\n"
161 << "{\n"
162 << " uint data2[" << subgroups::maxSupportedSubgroupSize() << "];\n"
163 << "};\n"
164 << "\n"
165 << "void main (void)\n"
166 << "{\n"
167 << testSource
168 << " result = float(temp_res);\n"
169 << " gl_Position = in_position;\n"
170 << " gl_PointSize = 1.0f;\n"
171 << "}\n";
172 programCollection.add("vert") << glu::VertexSource(vertexSrc.str());
173 }
174 else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
175 {
176 std::ostringstream geometry;
177
178 geometry << "${VERSION_DECL}\n"
179 << extSource
180 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
181 << "layout(points) in;\n"
182 << "layout(points, max_vertices = 1) out;\n"
183 << "layout(location = 0) out float out_color;\n"
184 << "layout(binding = 0, std140) uniform Buffer0\n"
185 << "{\n"
186 << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
187 << "};\n"
188 << "layout(binding = 1, std140) uniform Buffer1\n"
189 << "{\n"
190 << " uint data2[" << subgroups::maxSupportedSubgroupSize() << "];\n"
191 << "};\n"
192 << "\n"
193 << "void main (void)\n"
194 << "{\n"
195 << testSource
196 << " out_color = float(temp_res);\n"
197 << " gl_Position = gl_in[0].gl_Position;\n"
198 << " EmitVertex();\n"
199 << " EndPrimitive();\n"
200 << "}\n";
201
202 programCollection.add("geometry") << glu::GeometrySource(geometry.str());
203 }
204 else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
205 {
206 std::ostringstream controlSource;
207
208 controlSource << "${VERSION_DECL}\n"
209 << extSource
210 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
211 << "layout(vertices = 2) out;\n"
212 << "layout(location = 0) out float out_color[];\n"
213 << "layout(binding = 0, std140) uniform Buffer0\n"
214 << "{\n"
215 << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
216 << "};\n"
217 << "layout(binding = 1, std140) uniform Buffer1\n"
218 << "{\n"
219 << " uint data2[" << subgroups::maxSupportedSubgroupSize() << "];\n"
220 << "};\n"
221 << "\n"
222 << "void main (void)\n"
223 << "{\n"
224 << " if (gl_InvocationID == 0)\n"
225 <<" {\n"
226 << " gl_TessLevelOuter[0] = 1.0f;\n"
227 << " gl_TessLevelOuter[1] = 1.0f;\n"
228 << " }\n"
229 << testSource
230 << " out_color[gl_InvocationID] = float(temp_res);\n"
231 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
232 << "}\n";
233
234 programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str());
235 subgroups::setTesEvalShaderFrameBuffer(programCollection);
236
237 }
238 else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
239 {
240 std::ostringstream evaluationSource;
241 evaluationSource << "${VERSION_DECL}\n"
242 << extSource
243 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
244 << "layout(isolines, equal_spacing, ccw ) in;\n"
245 << "layout(location = 0) out float out_color;\n"
246 << "layout(binding = 0, std140) uniform Buffer0\n"
247 << "{\n"
248 << " " << subgroups::getFormatNameForGLSL(caseDef.format) << " data1[" << subgroups::maxSupportedSubgroupSize() << "];\n"
249 << "};\n"
250 << "layout(binding = 1, std140) uniform Buffer1\n"
251 << "{\n"
252 << " uint data2[" << subgroups::maxSupportedSubgroupSize() << "];\n"
253 << "};\n"
254 << "\n"
255 << "void main (void)\n"
256 << "{\n"
257 << testSource
258 << " out_color = float(temp_res);\n"
259 << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
260 << "}\n";
261
262 subgroups::setTesCtrlShaderFrameBuffer(programCollection);
263 programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str());
264 }
265 else
266 {
267 DE_FATAL("Unsupported shader stage");
268 }
269 }
270
initPrograms(SourceCollections & programCollection,CaseDefinition caseDef)271 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
272 {
273 const std::string versionSource =
274 "${VERSION_DECL}\n";
275 const std::string vSource =
276 "#extension GL_KHR_shader_subgroup_ballot: enable\n";
277 const std::string eSource =
278 (OPTYPE_SHUFFLE == caseDef.opType || OPTYPE_SHUFFLE_XOR == caseDef.opType) ?
279 "#extension GL_KHR_shader_subgroup_shuffle: enable\n" :
280 "#extension GL_KHR_shader_subgroup_shuffle_relative: enable\n";
281 const std::string extSource = vSource + eSource;
282
283 const std::string testSource = TestSource(caseDef);
284
285 if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
286 {
287 std::ostringstream src;
288
289 src << versionSource + extSource
290 << "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n"
291 << "layout(binding = 0, std430) buffer Buffer0\n"
292 << "{\n"
293 << " uint result[];\n"
294 << "};\n"
295 << DeclSource(caseDef, 1)
296 << "\n"
297 << "void main (void)\n"
298 << "{\n"
299 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
300 << " highp uint offset = globalSize.x * ((globalSize.y * "
301 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
302 "gl_GlobalInvocationID.x;\n"
303 << testSource
304 << " result[offset] = temp_res;\n"
305 << "}\n";
306
307 programCollection.add("comp") << glu::ComputeSource(src.str());
308 }
309 else
310 {
311 const std::string declSource = DeclSource(caseDef, 4);
312
313 {
314 const string vertex =
315 versionSource + extSource +
316 "layout(binding = 0, std430) buffer Buffer0\n"
317 "{\n"
318 " uint result[];\n"
319 "} b0;\n"
320 + declSource +
321 "\n"
322 "void main (void)\n"
323 "{\n"
324 + testSource +
325 " b0.result[gl_VertexID] = temp_res;\n"
326 " float pixelSize = 2.0f/1024.0f;\n"
327 " float pixelPosition = pixelSize/2.0f - 1.0f;\n"
328 " gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
329 " gl_PointSize = 1.0f;\n"
330 "}\n";
331
332 programCollection.add("vert") << glu::VertexSource(vertex);
333 }
334
335 {
336 const string tesc =
337 versionSource + extSource +
338 "layout(vertices=1) out;\n"
339 "layout(binding = 1, std430) buffer Buffer1\n"
340 "{\n"
341 " uint result[];\n"
342 "} b1;\n"
343 + declSource +
344 "\n"
345 "void main (void)\n"
346 "{\n"
347 + testSource +
348 " b1.result[gl_PrimitiveID] = temp_res;\n"
349 " if (gl_InvocationID == 0)\n"
350 " {\n"
351 " gl_TessLevelOuter[0] = 1.0f;\n"
352 " gl_TessLevelOuter[1] = 1.0f;\n"
353 " }\n"
354 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
355 "}\n";
356
357 programCollection.add("tesc") << glu::TessellationControlSource(tesc);
358 }
359
360 {
361 const string tese =
362 versionSource + extSource +
363 "layout(isolines) in;\n"
364 "layout(binding = 2, std430) buffer Buffer2\n"
365 "{\n"
366 " uint result[];\n"
367 "} b2;\n"
368 + declSource +
369 "\n"
370 "void main (void)\n"
371 "{\n"
372 + testSource +
373 " b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = temp_res;\n"
374 " float pixelSize = 2.0f/1024.0f;\n"
375 " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
376 "}\n";
377
378 programCollection.add("tese") << glu::TessellationEvaluationSource(tese);
379 }
380
381 {
382 const string geometry =
383 // version is added by addGeometryShadersFromTemplate
384 extSource +
385 "layout(${TOPOLOGY}) in;\n"
386 "layout(points, max_vertices = 1) out;\n"
387 "layout(binding = 3, std430) buffer Buffer3\n"
388 "{\n"
389 " uint result[];\n"
390 "} b3;\n"
391 + declSource +
392 "\n"
393 "void main (void)\n"
394 "{\n"
395 + testSource +
396 " b3.result[gl_PrimitiveIDIn] = temp_res;\n"
397 " gl_Position = gl_in[0].gl_Position;\n"
398 " EmitVertex();\n"
399 " EndPrimitive();\n"
400 "}\n";
401
402 subgroups::addGeometryShadersFromTemplate(geometry, programCollection);
403 }
404 {
405 const string fragment =
406 versionSource + extSource +
407 "precision highp int;\n"
408 "precision highp float;\n"
409 "layout(location = 0) out uint result;\n"
410 + declSource +
411 "void main (void)\n"
412 "{\n"
413 + testSource +
414 " result = temp_res;\n"
415 "}\n";
416
417 programCollection.add("fragment") << glu::FragmentSource(fragment);
418 }
419
420 subgroups::addNoSubgroupShader(programCollection);
421 }
422 }
423
supportedCheck(Context & context,CaseDefinition caseDef)424 void supportedCheck (Context& context, CaseDefinition caseDef)
425 {
426 if (!subgroups::isSubgroupSupported(context))
427 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
428
429 switch (caseDef.opType)
430 {
431 case OPTYPE_SHUFFLE:
432 case OPTYPE_SHUFFLE_XOR:
433 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_SHUFFLE_BIT))
434 {
435 TCU_THROW(NotSupportedError, "Device does not support subgroup shuffle operations");
436 }
437 break;
438 default:
439 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT))
440 {
441 TCU_THROW(NotSupportedError, "Device does not support subgroup shuffle relative operations");
442 }
443 break;
444 }
445
446 if (subgroups::isDoubleFormat(caseDef.format) &&
447 !subgroups::isDoubleSupportedForDevice(context))
448 TCU_THROW(NotSupportedError, "Device does not support subgroup double operations");
449 }
450
noSSBOtest(Context & context,const CaseDefinition caseDef)451 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
452 {
453 if (!subgroups::areSubgroupOperationsSupportedForStage(
454 context, caseDef.shaderStage))
455 {
456 if (subgroups::areSubgroupOperationsRequiredForStage(
457 caseDef.shaderStage))
458 {
459 return tcu::TestStatus::fail(
460 "Shader stage " +
461 subgroups::getShaderStageName(caseDef.shaderStage) +
462 " is required to support subgroup operations!");
463 }
464 else
465 {
466 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
467 }
468 }
469
470 subgroups::SSBOData inputData[2];
471 inputData[0].format = caseDef.format;
472 inputData[0].layout = subgroups::SSBOData::LayoutStd140;
473 inputData[0].numElements = subgroups::maxSupportedSubgroupSize();
474 inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
475 inputData[0].binding = 0u;
476
477 inputData[1].format = FORMAT_R32_UINT;
478 inputData[1].layout = subgroups::SSBOData::LayoutStd140;
479 inputData[1].numElements = inputData[0].numElements;
480 inputData[1].initializeType = subgroups::SSBOData::InitializeNonZero;
481 inputData[1].binding = 1u;
482
483 if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
484 return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, inputData, 2, checkVertexPipelineStages);
485 else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
486 return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, inputData, 2, checkVertexPipelineStages);
487 else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
488 return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, inputData, 2, checkVertexPipelineStages, SHADER_STAGE_TESS_CONTROL_BIT);
489 else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
490 return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, inputData, 2, checkVertexPipelineStages, SHADER_STAGE_TESS_EVALUATION_BIT);
491 else
492 TCU_THROW(InternalError, "Unhandled shader stage");
493 }
494
495
test(Context & context,const CaseDefinition caseDef)496 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
497 {
498 switch (caseDef.opType)
499 {
500 case OPTYPE_SHUFFLE:
501 case OPTYPE_SHUFFLE_XOR:
502 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_SHUFFLE_BIT))
503 {
504 TCU_THROW(NotSupportedError, "Device does not support subgroup shuffle operations");
505 }
506 break;
507 default:
508 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT))
509 {
510 TCU_THROW(NotSupportedError, "Device does not support subgroup shuffle relative operations");
511 }
512 break;
513 }
514
515 if (subgroups::isDoubleFormat(caseDef.format) && !subgroups::isDoubleSupportedForDevice(context))
516 {
517 TCU_THROW(NotSupportedError, "Device does not support subgroup double operations");
518 }
519
520 if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
521 {
522 if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
523 {
524 return tcu::TestStatus::fail(
525 "Shader stage " +
526 subgroups::getShaderStageName(caseDef.shaderStage) +
527 " is required to support subgroup operations!");
528 }
529 subgroups::SSBOData inputData[2];
530 inputData[0].format = caseDef.format;
531 inputData[0].layout = subgroups::SSBOData::LayoutStd430;
532 inputData[0].numElements = subgroups::maxSupportedSubgroupSize();
533 inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
534 inputData[0].binding = 1u;
535
536 inputData[1].format = FORMAT_R32_UINT;
537 inputData[1].layout = subgroups::SSBOData::LayoutStd430;
538 inputData[1].numElements = inputData[0].numElements;
539 inputData[1].initializeType = subgroups::SSBOData::InitializeNonZero;
540 inputData[1].binding = 2u;
541
542 return subgroups::makeComputeTest(context, FORMAT_R32_UINT, inputData, 2, checkComputeStage);
543 }
544
545 else
546 {
547 int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR);
548
549 ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages);
550
551 if (SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
552 {
553 if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0)
554 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
555 else
556 stages = SHADER_STAGE_FRAGMENT_BIT;
557 }
558
559 if ((ShaderStageFlags)0u == stages)
560 TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
561
562 subgroups::SSBOData inputData[2];
563 inputData[0].format = caseDef.format;
564 inputData[0].layout = subgroups::SSBOData::LayoutStd430;
565 inputData[0].numElements = subgroups::maxSupportedSubgroupSize();
566 inputData[0].initializeType = subgroups::SSBOData::InitializeNonZero;
567 inputData[0].binding = 4u;
568 inputData[0].stages = stages;
569
570 inputData[1].format = FORMAT_R32_UINT;
571 inputData[1].layout = subgroups::SSBOData::LayoutStd430;
572 inputData[1].numElements = inputData[0].numElements;
573 inputData[1].initializeType = subgroups::SSBOData::InitializeNonZero;
574 inputData[1].binding = 5u;
575 inputData[1].stages = stages;
576
577 return subgroups::allStages(context, FORMAT_R32_UINT, inputData, 2, checkVertexPipelineStages, stages);
578 }
579 }
580 }
581
createSubgroupsShuffleTests(deqp::Context & testCtx)582 deqp::TestCaseGroup* createSubgroupsShuffleTests(deqp::Context& testCtx)
583 {
584
585 de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup(
586 testCtx, "graphics", "Subgroup shuffle category tests: graphics"));
587 de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup(
588 testCtx, "compute", "Subgroup shuffle category tests: compute"));
589 de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup(
590 testCtx, "framebuffer", "Subgroup shuffle category tests: framebuffer"));
591
592 const Format formats[] =
593 {
594 FORMAT_R32_SINT, FORMAT_R32G32_SINT, FORMAT_R32G32B32_SINT,
595 FORMAT_R32G32B32A32_SINT, FORMAT_R32_UINT, FORMAT_R32G32_UINT,
596 FORMAT_R32G32B32_UINT, FORMAT_R32G32B32A32_UINT,
597 FORMAT_R32_SFLOAT, FORMAT_R32G32_SFLOAT,
598 FORMAT_R32G32B32_SFLOAT, FORMAT_R32G32B32A32_SFLOAT,
599 FORMAT_R64_SFLOAT, FORMAT_R64G64_SFLOAT,
600 FORMAT_R64G64B64_SFLOAT, FORMAT_R64G64B64A64_SFLOAT,
601 FORMAT_R32_BOOL, FORMAT_R32G32_BOOL,
602 FORMAT_R32G32B32_BOOL, FORMAT_R32G32B32A32_BOOL,
603 };
604
605 const ShaderStageFlags stages[] =
606 {
607 SHADER_STAGE_VERTEX_BIT,
608 SHADER_STAGE_TESS_EVALUATION_BIT,
609 SHADER_STAGE_TESS_CONTROL_BIT,
610 SHADER_STAGE_GEOMETRY_BIT,
611 };
612
613 for (int formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(formats); ++formatIndex)
614 {
615 const Format format = formats[formatIndex];
616
617 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
618 {
619
620 const string name =
621 de::toLower(getOpTypeName(opTypeIndex)) +
622 "_" + subgroups::getFormatNameForGLSL(format);
623
624 {
625 const CaseDefinition caseDef =
626 {
627 opTypeIndex,
628 SHADER_STAGE_ALL_GRAPHICS,
629 format
630 };
631 SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
632 }
633
634 {
635 const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT, format};
636 SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), name, "", supportedCheck, initPrograms, test, caseDef);
637 }
638
639 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
640 {
641 const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format};
642 SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(), name + "_" + getShaderStageName(caseDef.shaderStage), "",
643 supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
644 }
645 }
646 }
647
648 de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup(
649 testCtx, "shuffle", "Subgroup shuffle category tests"));
650
651 group->addChild(graphicGroup.release());
652 group->addChild(computeGroup.release());
653 group->addChild(framebufferGroup.release());
654
655 return group.release();
656 }
657
658 } // subgroups
659 } // glc
660