1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2017 Codeplay Software Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Subgroups Tests
23 */ /*--------------------------------------------------------------------*/
25 #include "vktSubgroupsBallotOtherTests.hpp"
26 #include "vktSubgroupsTestsUtils.hpp"
40 OPTYPE_INVERSE_BALLOT = 0,
41 OPTYPE_BALLOT_BIT_EXTRACT,
42 OPTYPE_BALLOT_BIT_COUNT,
43 OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT,
44 OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT,
45 OPTYPE_BALLOT_FIND_LSB,
46 OPTYPE_BALLOT_FIND_MSB,
50 static bool checkVertexPipelineStages(std::vector<const void*> datas,
51 deUint32 width, deUint32)
53 const deUint32* data =
54 reinterpret_cast<const deUint32*>(datas[0]);
55 for (deUint32 x = 0; x < width; ++x)
57 deUint32 val = data[x];
68 static bool checkFragment(std::vector<const void*> datas,
69 deUint32 width, deUint32 height, deUint32)
71 const deUint32* data =
72 reinterpret_cast<const deUint32*>(datas[0]);
73 for (deUint32 x = 0; x < width; ++x)
75 for (deUint32 y = 0; y < height; ++y)
77 deUint32 val = data[x * height + y];
89 static bool checkCompute(std::vector<const void*> datas,
90 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
93 const deUint32* data =
94 reinterpret_cast<const deUint32*>(datas[0]);
96 for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
98 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
100 for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
102 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
104 for (deUint32 lY = 0; lY < localSize[1]; ++lY)
106 for (deUint32 lZ = 0; lZ < localSize[2];
109 const deUint32 globalInvocationX =
110 nX * localSize[0] + lX;
111 const deUint32 globalInvocationY =
112 nY * localSize[1] + lY;
113 const deUint32 globalInvocationZ =
114 nZ * localSize[2] + lZ;
116 const deUint32 globalSizeX =
117 numWorkgroups[0] * localSize[0];
118 const deUint32 globalSizeY =
119 numWorkgroups[1] * localSize[1];
121 const deUint32 offset =
128 if (0xf != data[offset])
142 std::string getOpTypeName(int opType)
147 DE_FATAL("Unsupported op type");
148 case OPTYPE_INVERSE_BALLOT:
149 return "subgroupInverseBallot";
150 case OPTYPE_BALLOT_BIT_EXTRACT:
151 return "subgroupBallotBitExtract";
152 case OPTYPE_BALLOT_BIT_COUNT:
153 return "subgroupBallotBitCount";
154 case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT:
155 return "subgroupBallotInclusiveBitCount";
156 case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT:
157 return "subgroupBallotExclusiveBitCount";
158 case OPTYPE_BALLOT_FIND_LSB:
159 return "subgroupBallotFindLSB";
160 case OPTYPE_BALLOT_FIND_MSB:
161 return "subgroupBallotFindMSB";
165 struct CaseDefinition
168 VkShaderStageFlags shaderStage;
172 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
174 std::ostringstream bdy;
176 bdy << " uvec4 allOnes = uvec4(0xFFFFFFFF);\n"
177 << " uvec4 allZeros = uvec4(0);\n"
178 << " uint tempResult = 0;\n"
179 << "#define MAKE_HIGH_BALLOT_RESULT(i) uvec4("
180 << "i >= 32 ? 0 : (0xFFFFFFFF << i), "
181 << "i >= 64 ? 0 : (0xFFFFFFFF << ((i < 32) ? 0 : (i - 32))), "
182 << "i >= 96 ? 0 : (0xFFFFFFFF << ((i < 64) ? 0 : (i - 64))), "
183 << " 0xFFFFFFFF << ((i < 96) ? 0 : (i - 96)))\n"
184 << "#define MAKE_SINGLE_BIT_BALLOT_RESULT(i) uvec4("
185 << "i >= 32 ? 0 : 0x1 << i, "
186 << "i < 32 || i >= 64 ? 0 : 0x1 << (i - 32), "
187 << "i < 64 || i >= 96 ? 0 : 0x1 << (i - 64), "
188 << "i < 96 ? 0 : 0x1 << (i - 96))\n";
190 switch (caseDef.opType)
193 DE_FATAL("Unknown op type!");
194 case OPTYPE_INVERSE_BALLOT:
195 bdy << " tempResult |= subgroupInverseBallot(allOnes) ? 0x1 : 0;\n"
196 << " tempResult |= subgroupInverseBallot(allZeros) ? 0 : 0x2;\n"
197 << " tempResult |= subgroupInverseBallot(subgroupBallot(true)) ? 0x4 : 0;\n"
198 << " tempResult |= 0x8;\n";
200 case OPTYPE_BALLOT_BIT_EXTRACT:
201 bdy << " tempResult |= subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID) ? 0x1 : 0;\n"
202 << " tempResult |= subgroupBallotBitExtract(allZeros, gl_SubgroupInvocationID) ? 0 : 0x2;\n"
203 << " tempResult |= subgroupBallotBitExtract(subgroupBallot(true), gl_SubgroupInvocationID) ? 0x4 : 0;\n"
204 << " tempResult |= 0x8;\n"
205 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
207 << " if (!subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID))\n"
209 << " tempResult &= ~0x8;\n"
213 case OPTYPE_BALLOT_BIT_COUNT:
214 bdy << " tempResult |= gl_SubgroupSize == subgroupBallotBitCount(allOnes) ? 0x1 : 0;\n"
215 << " tempResult |= 0 == subgroupBallotBitCount(allZeros) ? 0x2 : 0;\n"
216 << " tempResult |= 0 < subgroupBallotBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
217 << " tempResult |= 0 == subgroupBallotBitCount(MAKE_HIGH_BALLOT_RESULT(gl_SubgroupSize)) ? 0x8 : 0;\n";
219 case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT:
220 bdy << " uint inclusiveOffset = gl_SubgroupInvocationID + 1;\n"
221 << " tempResult |= inclusiveOffset == subgroupBallotInclusiveBitCount(allOnes) ? 0x1 : 0;\n"
222 << " tempResult |= 0 == subgroupBallotInclusiveBitCount(allZeros) ? 0x2 : 0;\n"
223 << " tempResult |= 0 < subgroupBallotInclusiveBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
224 << " tempResult |= 0x8;\n"
225 << " uvec4 inclusiveUndef = MAKE_HIGH_BALLOT_RESULT(inclusiveOffset);\n"
226 << " bool undefTerritory = false;\n"
227 << " for (uint i = 0; i <= 128; i++)\n"
229 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
230 << " if (iUndef == inclusiveUndef)"
232 << " undefTerritory = true;\n"
234 << " uint inclusiveBitCount = subgroupBallotInclusiveBitCount(iUndef);\n"
235 << " if (undefTerritory && (0 != inclusiveBitCount))\n"
237 << " tempResult &= ~0x8;\n"
239 << " else if (!undefTerritory && (0 == inclusiveBitCount))\n"
241 << " tempResult &= ~0x8;\n"
245 case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT:
246 bdy << " uint exclusiveOffset = gl_SubgroupInvocationID;\n"
247 << " tempResult |= exclusiveOffset == subgroupBallotExclusiveBitCount(allOnes) ? 0x1 : 0;\n"
248 << " tempResult |= 0 == subgroupBallotExclusiveBitCount(allZeros) ? 0x2 : 0;\n"
249 << " tempResult |= 0x4;\n"
250 << " tempResult |= 0x8;\n"
251 << " uvec4 exclusiveUndef = MAKE_HIGH_BALLOT_RESULT(exclusiveOffset);\n"
252 << " bool undefTerritory = false;\n"
253 << " for (uint i = 0; i <= 128; i++)\n"
255 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
256 << " if (iUndef == exclusiveUndef)"
258 << " undefTerritory = true;\n"
260 << " uint exclusiveBitCount = subgroupBallotExclusiveBitCount(iUndef);\n"
261 << " if (undefTerritory && (0 != exclusiveBitCount))\n"
263 << " tempResult &= ~0x4;\n"
265 << " else if (!undefTerritory && (0 == exclusiveBitCount))\n"
267 << " tempResult &= ~0x8;\n"
271 case OPTYPE_BALLOT_FIND_LSB:
272 bdy << " tempResult |= 0 == subgroupBallotFindLSB(allOnes) ? 0x1 : 0;\n"
273 << " if (subgroupElect())\n"
275 << " tempResult |= 0x2;\n"
279 << " tempResult |= 0 < subgroupBallotFindLSB(subgroupBallot(true)) ? 0x2 : 0;\n"
281 << " tempResult |= gl_SubgroupSize > subgroupBallotFindLSB(subgroupBallot(true)) ? 0x4 : 0;\n"
282 << " tempResult |= 0x8;\n"
283 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
285 << " if (i != subgroupBallotFindLSB(MAKE_HIGH_BALLOT_RESULT(i)))\n"
287 << " tempResult &= ~0x8;\n"
291 case OPTYPE_BALLOT_FIND_MSB:
292 bdy << " tempResult |= (gl_SubgroupSize - 1) == subgroupBallotFindMSB(allOnes) ? 0x1 : 0;\n"
293 << " if (subgroupElect())\n"
295 << " tempResult |= 0x2;\n"
299 << " tempResult |= 0 < subgroupBallotFindMSB(subgroupBallot(true)) ? 0x2 : 0;\n"
301 << " tempResult |= gl_SubgroupSize > subgroupBallotFindMSB(subgroupBallot(true)) ? 0x4 : 0;\n"
302 << " tempResult |= 0x8;\n"
303 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
305 << " if (i != subgroupBallotFindMSB(MAKE_SINGLE_BIT_BALLOT_RESULT(i)))\n"
307 << " tempResult &= ~0x8;\n"
313 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
315 std::ostringstream src;
316 std::ostringstream fragmentSrc;
318 src << "#version 450\n"
319 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
320 << "layout(location = 0) in highp vec4 in_position;\n"
321 << "layout(location = 0) out float out_color;\n"
323 << "void main (void)\n"
326 << " out_color = float(tempResult);\n"
327 << " gl_Position = in_position;\n"
328 << " gl_PointSize = 1.0f;\n"
331 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
333 fragmentSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
334 << "layout(location = 0) in float in_color;\n"
335 << "layout(location = 0) out uint out_color;\n"
338 << " out_color = uint(in_color);\n"
340 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
344 DE_FATAL("Unsupported shader stage");
348 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
350 std::ostringstream bdy;
352 bdy << " uvec4 allOnes = uvec4(0xFFFFFFFF);\n"
353 << " uvec4 allZeros = uvec4(0);\n"
354 << " uint tempResult = 0;\n"
355 << "#define MAKE_HIGH_BALLOT_RESULT(i) uvec4("
356 << "i >= 32 ? 0 : (0xFFFFFFFF << i), "
357 << "i >= 64 ? 0 : (0xFFFFFFFF << ((i < 32) ? 0 : (i - 32))), "
358 << "i >= 96 ? 0 : (0xFFFFFFFF << ((i < 64) ? 0 : (i - 64))), "
359 << " 0xFFFFFFFF << ((i < 96) ? 0 : (i - 96)))\n"
360 << "#define MAKE_SINGLE_BIT_BALLOT_RESULT(i) uvec4("
361 << "i >= 32 ? 0 : 0x1 << i, "
362 << "i < 32 || i >= 64 ? 0 : 0x1 << (i - 32), "
363 << "i < 64 || i >= 96 ? 0 : 0x1 << (i - 64), "
364 << "i < 96 ? 0 : 0x1 << (i - 96))\n";
366 switch (caseDef.opType)
369 DE_FATAL("Unknown op type!");
370 case OPTYPE_INVERSE_BALLOT:
371 bdy << " tempResult |= subgroupInverseBallot(allOnes) ? 0x1 : 0;\n"
372 << " tempResult |= subgroupInverseBallot(allZeros) ? 0 : 0x2;\n"
373 << " tempResult |= subgroupInverseBallot(subgroupBallot(true)) ? 0x4 : 0;\n"
374 << " tempResult |= 0x8;\n";
376 case OPTYPE_BALLOT_BIT_EXTRACT:
377 bdy << " tempResult |= subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID) ? 0x1 : 0;\n"
378 << " tempResult |= subgroupBallotBitExtract(allZeros, gl_SubgroupInvocationID) ? 0 : 0x2;\n"
379 << " tempResult |= subgroupBallotBitExtract(subgroupBallot(true), gl_SubgroupInvocationID) ? 0x4 : 0;\n"
380 << " tempResult |= 0x8;\n"
381 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
383 << " if (!subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID))\n"
385 << " tempResult &= ~0x8;\n"
389 case OPTYPE_BALLOT_BIT_COUNT:
390 bdy << " tempResult |= gl_SubgroupSize == subgroupBallotBitCount(allOnes) ? 0x1 : 0;\n"
391 << " tempResult |= 0 == subgroupBallotBitCount(allZeros) ? 0x2 : 0;\n"
392 << " tempResult |= 0 < subgroupBallotBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
393 << " tempResult |= 0 == subgroupBallotBitCount(MAKE_HIGH_BALLOT_RESULT(gl_SubgroupSize)) ? 0x8 : 0;\n";
395 case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT:
396 bdy << " uint inclusiveOffset = gl_SubgroupInvocationID + 1;\n"
397 << " tempResult |= inclusiveOffset == subgroupBallotInclusiveBitCount(allOnes) ? 0x1 : 0;\n"
398 << " tempResult |= 0 == subgroupBallotInclusiveBitCount(allZeros) ? 0x2 : 0;\n"
399 << " tempResult |= 0 < subgroupBallotInclusiveBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
400 << " tempResult |= 0x8;\n"
401 << " uvec4 inclusiveUndef = MAKE_HIGH_BALLOT_RESULT(inclusiveOffset);\n"
402 << " bool undefTerritory = false;\n"
403 << " for (uint i = 0; i <= 128; i++)\n"
405 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
406 << " if (iUndef == inclusiveUndef)"
408 << " undefTerritory = true;\n"
410 << " uint inclusiveBitCount = subgroupBallotInclusiveBitCount(iUndef);\n"
411 << " if (undefTerritory && (0 != inclusiveBitCount))\n"
413 << " tempResult &= ~0x8;\n"
415 << " else if (!undefTerritory && (0 == inclusiveBitCount))\n"
417 << " tempResult &= ~0x8;\n"
421 case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT:
422 bdy << " uint exclusiveOffset = gl_SubgroupInvocationID;\n"
423 << " tempResult |= exclusiveOffset == subgroupBallotExclusiveBitCount(allOnes) ? 0x1 : 0;\n"
424 << " tempResult |= 0 == subgroupBallotExclusiveBitCount(allZeros) ? 0x2 : 0;\n"
425 << " tempResult |= 0x4;\n"
426 << " tempResult |= 0x8;\n"
427 << " uvec4 exclusiveUndef = MAKE_HIGH_BALLOT_RESULT(exclusiveOffset);\n"
428 << " bool undefTerritory = false;\n"
429 << " for (uint i = 0; i <= 128; i++)\n"
431 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
432 << " if (iUndef == exclusiveUndef)"
434 << " undefTerritory = true;\n"
436 << " uint exclusiveBitCount = subgroupBallotExclusiveBitCount(iUndef);\n"
437 << " if (undefTerritory && (0 != exclusiveBitCount))\n"
439 << " tempResult &= ~0x4;\n"
441 << " else if (!undefTerritory && (0 == exclusiveBitCount))\n"
443 << " tempResult &= ~0x8;\n"
447 case OPTYPE_BALLOT_FIND_LSB:
448 bdy << " tempResult |= 0 == subgroupBallotFindLSB(allOnes) ? 0x1 : 0;\n"
449 << " if (subgroupElect())\n"
451 << " tempResult |= 0x2;\n"
455 << " tempResult |= 0 < subgroupBallotFindLSB(subgroupBallot(true)) ? 0x2 : 0;\n"
457 << " tempResult |= gl_SubgroupSize > subgroupBallotFindLSB(subgroupBallot(true)) ? 0x4 : 0;\n"
458 << " tempResult |= 0x8;\n"
459 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
461 << " if (i != subgroupBallotFindLSB(MAKE_HIGH_BALLOT_RESULT(i)))\n"
463 << " tempResult &= ~0x8;\n"
467 case OPTYPE_BALLOT_FIND_MSB:
468 bdy << " tempResult |= (gl_SubgroupSize - 1) == subgroupBallotFindMSB(allOnes) ? 0x1 : 0;\n"
469 << " if (subgroupElect())\n"
471 << " tempResult |= 0x2;\n"
475 << " tempResult |= 0 < subgroupBallotFindMSB(subgroupBallot(true)) ? 0x2 : 0;\n"
477 << " tempResult |= gl_SubgroupSize > subgroupBallotFindMSB(subgroupBallot(true)) ? 0x4 : 0;\n"
478 << " tempResult |= 0x8;\n"
479 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
481 << " if (i != subgroupBallotFindMSB(MAKE_SINGLE_BIT_BALLOT_RESULT(i)))\n"
483 << " tempResult &= ~0x8;\n"
489 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
491 std::ostringstream src;
493 src << "#version 450\n"
494 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
495 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
496 "local_size_z_id = 2) in;\n"
497 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
499 << " uint result[];\n"
502 << "void main (void)\n"
504 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
505 << " highp uint offset = globalSize.x * ((globalSize.y * "
506 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
507 "gl_GlobalInvocationID.x;\n"
509 << " result[offset] = tempResult;\n"
512 programCollection.glslSources.add("comp")
513 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
515 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
517 programCollection.glslSources.add("vert")
518 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
520 std::ostringstream frag;
522 frag << "#version 450\n"
523 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
524 << "layout(location = 0) out uint result;\n"
525 << "void main (void)\n"
528 << " result = tempResult;\n"
531 programCollection.glslSources.add("frag")
532 << glu::FragmentSource(frag.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
534 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
536 std::ostringstream src;
538 src << "#version 450\n"
539 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
540 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
542 << " uint result[];\n"
545 << "void main (void)\n"
548 << " result[gl_VertexIndex] = tempResult;\n"
549 << " gl_PointSize = 1.0;\n"
552 programCollection.glslSources.add("vert")
553 << glu::VertexSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
555 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
557 programCollection.glslSources.add("vert")
558 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
560 std::ostringstream src;
562 src << "#version 450\n"
563 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
564 << "layout(points) in;\n"
565 << "layout(points, max_vertices = 1) out;\n"
566 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
568 << " uint result[];\n"
571 << "void main (void)\n"
574 << " result[gl_PrimitiveIDIn] = tempResult;\n"
577 programCollection.glslSources.add("geom")
578 << glu::GeometrySource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
580 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
582 programCollection.glslSources.add("vert")
583 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
585 programCollection.glslSources.add("tese")
586 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
588 std::ostringstream src;
590 src << "#version 450\n"
591 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
592 << "layout(vertices=1) out;\n"
593 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
595 << " uint result[];\n"
598 << "void main (void)\n"
601 << " result[gl_PrimitiveID] = tempResult;\n"
604 programCollection.glslSources.add("tesc")
605 << glu::TessellationControlSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
607 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
609 programCollection.glslSources.add("vert")
610 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage)) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
612 programCollection.glslSources.add("tesc")
613 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
615 std::ostringstream src;
617 src << "#version 450\n"
618 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
619 << "layout(isolines) in;\n"
620 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
622 << " uint result[];\n"
625 << "void main (void)\n"
628 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
631 programCollection.glslSources.add("tese")
632 << glu::TessellationEvaluationSource(src.str()) << vk::ShaderBuildOptions(vk::SPIRV_VERSION_1_3, 0u);
636 DE_FATAL("Unsupported shader stage");
640 tcu::TestStatus test (Context& context, const CaseDefinition caseDef)
642 if (!subgroups::isSubgroupSupported(context))
643 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
645 if (!subgroups::areSubgroupOperationsSupportedForStage(
646 context, caseDef.shaderStage))
648 if (subgroups::areSubgroupOperationsRequiredForStage(
649 caseDef.shaderStage))
651 return tcu::TestStatus::fail(
653 subgroups::getShaderStageName(caseDef.shaderStage) +
654 " is required to support subgroup operations!");
658 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
662 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
664 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
667 if (caseDef.noSSBO && VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
669 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT,
670 DE_NULL, 0, checkVertexPipelineStages);
673 //Tests which don't use the SSBO
674 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
675 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
677 if (!subgroups::isVertexSSBOSupportedForDevice(context))
679 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
683 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
685 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
686 DE_NULL, 0, checkFragment);
688 else if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
690 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
691 DE_NULL, 0, checkCompute);
693 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
695 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
696 DE_NULL, 0, checkVertexPipelineStages);
698 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
700 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
701 DE_NULL, 0, checkVertexPipelineStages);
703 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
705 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
706 DE_NULL, 0, checkVertexPipelineStages);
708 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
710 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
711 DE_NULL, 0, checkVertexPipelineStages);
713 return tcu::TestStatus::pass("OK");
721 tcu::TestCaseGroup* createSubgroupsBallotOtherTests(tcu::TestContext& testCtx)
723 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
724 testCtx, "ballot_other", "Subgroup ballot other category tests"));
726 const VkShaderStageFlags stages[] =
728 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
729 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
730 VK_SHADER_STAGE_GEOMETRY_BIT,
731 VK_SHADER_STAGE_VERTEX_BIT,
732 VK_SHADER_STAGE_FRAGMENT_BIT,
733 VK_SHADER_STAGE_COMPUTE_BIT
736 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
738 const VkShaderStageFlags stage = stages[stageIndex];
740 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
742 CaseDefinition caseDef = {opTypeIndex, stage, false};
744 std::ostringstream name;
746 std::string op = getOpTypeName(opTypeIndex);
748 name << de::toLower(op) << "_" << getShaderStageName(stage);
750 addFunctionCaseWithPrograms(group.get(), name.str(),
751 "", initPrograms, test, caseDef);
753 if (VK_SHADER_STAGE_VERTEX_BIT & stage )
755 caseDef.noSSBO = true;
756 addFunctionCaseWithPrograms(group.get(), name.str() + "_framebuffer", "",
757 initFrameBufferPrograms, test, caseDef);
763 return group.release();