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"
330 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
332 fragmentSrc << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
333 << "layout(location = 0) in float in_color;\n"
334 << "layout(location = 0) out uint out_color;\n"
337 << " out_color = uint(in_color);\n"
339 programCollection.glslSources.add("fragment") << glu::FragmentSource(fragmentSrc.str());
343 DE_FATAL("Unsupported shader stage");
347 void initPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
349 std::ostringstream bdy;
351 bdy << " uvec4 allOnes = uvec4(0xFFFFFFFF);\n"
352 << " uvec4 allZeros = uvec4(0);\n"
353 << " uint tempResult = 0;\n"
354 << "#define MAKE_HIGH_BALLOT_RESULT(i) uvec4("
355 << "i >= 32 ? 0 : (0xFFFFFFFF << i), "
356 << "i >= 64 ? 0 : (0xFFFFFFFF << ((i < 32) ? 0 : (i - 32))), "
357 << "i >= 96 ? 0 : (0xFFFFFFFF << ((i < 64) ? 0 : (i - 64))), "
358 << " 0xFFFFFFFF << ((i < 96) ? 0 : (i - 96)))\n"
359 << "#define MAKE_SINGLE_BIT_BALLOT_RESULT(i) uvec4("
360 << "i >= 32 ? 0 : 0x1 << i, "
361 << "i < 32 || i >= 64 ? 0 : 0x1 << (i - 32), "
362 << "i < 64 || i >= 96 ? 0 : 0x1 << (i - 64), "
363 << "i < 96 ? 0 : 0x1 << (i - 96))\n";
365 switch (caseDef.opType)
368 DE_FATAL("Unknown op type!");
369 case OPTYPE_INVERSE_BALLOT:
370 bdy << " tempResult |= subgroupInverseBallot(allOnes) ? 0x1 : 0;\n"
371 << " tempResult |= subgroupInverseBallot(allZeros) ? 0 : 0x2;\n"
372 << " tempResult |= subgroupInverseBallot(subgroupBallot(true)) ? 0x4 : 0;\n"
373 << " tempResult |= 0x8;\n";
375 case OPTYPE_BALLOT_BIT_EXTRACT:
376 bdy << " tempResult |= subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID) ? 0x1 : 0;\n"
377 << " tempResult |= subgroupBallotBitExtract(allZeros, gl_SubgroupInvocationID) ? 0 : 0x2;\n"
378 << " tempResult |= subgroupBallotBitExtract(subgroupBallot(true), gl_SubgroupInvocationID) ? 0x4 : 0;\n"
379 << " tempResult |= 0x8;\n"
380 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
382 << " if (!subgroupBallotBitExtract(allOnes, gl_SubgroupInvocationID))\n"
384 << " tempResult &= ~0x8;\n"
388 case OPTYPE_BALLOT_BIT_COUNT:
389 bdy << " tempResult |= gl_SubgroupSize == subgroupBallotBitCount(allOnes) ? 0x1 : 0;\n"
390 << " tempResult |= 0 == subgroupBallotBitCount(allZeros) ? 0x2 : 0;\n"
391 << " tempResult |= 0 < subgroupBallotBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
392 << " tempResult |= 0 == subgroupBallotBitCount(MAKE_HIGH_BALLOT_RESULT(gl_SubgroupSize)) ? 0x8 : 0;\n";
394 case OPTYPE_BALLOT_INCLUSIVE_BIT_COUNT:
395 bdy << " uint inclusiveOffset = gl_SubgroupInvocationID + 1;\n"
396 << " tempResult |= inclusiveOffset == subgroupBallotInclusiveBitCount(allOnes) ? 0x1 : 0;\n"
397 << " tempResult |= 0 == subgroupBallotInclusiveBitCount(allZeros) ? 0x2 : 0;\n"
398 << " tempResult |= 0 < subgroupBallotInclusiveBitCount(subgroupBallot(true)) ? 0x4 : 0;\n"
399 << " tempResult |= 0x8;\n"
400 << " uvec4 inclusiveUndef = MAKE_HIGH_BALLOT_RESULT(inclusiveOffset);\n"
401 << " bool undefTerritory = false;\n"
402 << " for (uint i = 0; i <= 128; i++)\n"
404 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
405 << " if (iUndef == inclusiveUndef)"
407 << " undefTerritory = true;\n"
409 << " uint inclusiveBitCount = subgroupBallotInclusiveBitCount(iUndef);\n"
410 << " if (undefTerritory && (0 != inclusiveBitCount))\n"
412 << " tempResult &= ~0x8;\n"
414 << " else if (!undefTerritory && (0 == inclusiveBitCount))\n"
416 << " tempResult &= ~0x8;\n"
420 case OPTYPE_BALLOT_EXCLUSIVE_BIT_COUNT:
421 bdy << " uint exclusiveOffset = gl_SubgroupInvocationID;\n"
422 << " tempResult |= exclusiveOffset == subgroupBallotExclusiveBitCount(allOnes) ? 0x1 : 0;\n"
423 << " tempResult |= 0 == subgroupBallotExclusiveBitCount(allZeros) ? 0x2 : 0;\n"
424 << " tempResult |= 0x4;\n"
425 << " tempResult |= 0x8;\n"
426 << " uvec4 exclusiveUndef = MAKE_HIGH_BALLOT_RESULT(exclusiveOffset);\n"
427 << " bool undefTerritory = false;\n"
428 << " for (uint i = 0; i <= 128; i++)\n"
430 << " uvec4 iUndef = MAKE_HIGH_BALLOT_RESULT(i);\n"
431 << " if (iUndef == exclusiveUndef)"
433 << " undefTerritory = true;\n"
435 << " uint exclusiveBitCount = subgroupBallotExclusiveBitCount(iUndef);\n"
436 << " if (undefTerritory && (0 != exclusiveBitCount))\n"
438 << " tempResult &= ~0x4;\n"
440 << " else if (!undefTerritory && (0 == exclusiveBitCount))\n"
442 << " tempResult &= ~0x8;\n"
446 case OPTYPE_BALLOT_FIND_LSB:
447 bdy << " tempResult |= 0 == subgroupBallotFindLSB(allOnes) ? 0x1 : 0;\n"
448 << " if (subgroupElect())\n"
450 << " tempResult |= 0x2;\n"
454 << " tempResult |= 0 < subgroupBallotFindLSB(subgroupBallot(true)) ? 0x2 : 0;\n"
456 << " tempResult |= gl_SubgroupSize > subgroupBallotFindLSB(subgroupBallot(true)) ? 0x4 : 0;\n"
457 << " tempResult |= 0x8;\n"
458 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
460 << " if (i != subgroupBallotFindLSB(MAKE_HIGH_BALLOT_RESULT(i)))\n"
462 << " tempResult &= ~0x8;\n"
466 case OPTYPE_BALLOT_FIND_MSB:
467 bdy << " tempResult |= (gl_SubgroupSize - 1) == subgroupBallotFindMSB(allOnes) ? 0x1 : 0;\n"
468 << " if (subgroupElect())\n"
470 << " tempResult |= 0x2;\n"
474 << " tempResult |= 0 < subgroupBallotFindMSB(subgroupBallot(true)) ? 0x2 : 0;\n"
476 << " tempResult |= gl_SubgroupSize > subgroupBallotFindMSB(subgroupBallot(true)) ? 0x4 : 0;\n"
477 << " tempResult |= 0x8;\n"
478 << " for (uint i = 0; i < gl_SubgroupSize; i++)\n"
480 << " if (i != subgroupBallotFindMSB(MAKE_SINGLE_BIT_BALLOT_RESULT(i)))\n"
482 << " tempResult &= ~0x8;\n"
488 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
490 std::ostringstream src;
492 src << "#version 450\n"
493 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
494 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
495 "local_size_z_id = 2) in;\n"
496 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
498 << " uint result[];\n"
501 << "void main (void)\n"
503 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
504 << " highp uint offset = globalSize.x * ((globalSize.y * "
505 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
506 "gl_GlobalInvocationID.x;\n"
508 << " result[offset] = tempResult;\n"
511 programCollection.glslSources.add("comp")
512 << glu::ComputeSource(src.str());
514 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
516 programCollection.glslSources.add("vert")
517 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
519 std::ostringstream frag;
521 frag << "#version 450\n"
522 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
523 << "layout(location = 0) out uint result;\n"
524 << "void main (void)\n"
527 << " result = tempResult;\n"
530 programCollection.glslSources.add("frag")
531 << glu::FragmentSource(frag.str());
533 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
535 std::ostringstream src;
537 src << "#version 450\n"
538 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
539 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
541 << " uint result[];\n"
544 << "void main (void)\n"
547 << " result[gl_VertexIndex] = tempResult;\n"
550 programCollection.glslSources.add("vert")
551 << glu::VertexSource(src.str());
553 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
555 programCollection.glslSources.add("vert")
556 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
558 std::ostringstream src;
560 src << "#version 450\n"
561 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
562 << "layout(points) in;\n"
563 << "layout(points, max_vertices = 1) out;\n"
564 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
566 << " uint result[];\n"
569 << "void main (void)\n"
572 << " result[gl_PrimitiveIDIn] = tempResult;\n"
575 programCollection.glslSources.add("geom")
576 << glu::GeometrySource(src.str());
578 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
580 programCollection.glslSources.add("vert")
581 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
583 programCollection.glslSources.add("tese")
584 << glu::TessellationEvaluationSource("#version 450\nlayout(isolines) in;\nvoid main (void) {}\n");
586 std::ostringstream src;
588 src << "#version 450\n"
589 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
590 << "layout(vertices=1) out;\n"
591 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
593 << " uint result[];\n"
596 << "void main (void)\n"
599 << " result[gl_PrimitiveID] = tempResult;\n"
602 programCollection.glslSources.add("tesc")
603 << glu::TessellationControlSource(src.str());
605 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
607 programCollection.glslSources.add("vert")
608 << glu::VertexSource(subgroups::getVertShaderForStage(caseDef.shaderStage));
610 programCollection.glslSources.add("tesc")
611 << glu::TessellationControlSource("#version 450\nlayout(vertices=1) out;\nvoid main (void) { for(uint i = 0; i < 4; i++) { gl_TessLevelOuter[i] = 1.0f; } }\n");
613 std::ostringstream src;
615 src << "#version 450\n"
616 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
617 << "layout(isolines) in;\n"
618 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
620 << " uint result[];\n"
623 << "void main (void)\n"
626 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
629 programCollection.glslSources.add("tese")
630 << glu::TessellationEvaluationSource(src.str());
634 DE_FATAL("Unsupported shader stage");
638 tcu::TestStatus test (Context& context, const CaseDefinition caseDef)
640 if (!subgroups::isSubgroupSupported(context))
641 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
643 if (!subgroups::areSubgroupOperationsSupportedForStage(
644 context, caseDef.shaderStage))
646 if (subgroups::areSubgroupOperationsRequiredForStage(
647 caseDef.shaderStage))
649 return tcu::TestStatus::fail(
651 subgroups::getShaderStageName(caseDef.shaderStage) +
652 " is required to support subgroup operations!");
656 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
660 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
662 TCU_THROW(NotSupportedError, "Device does not support subgroup ballot operations");
665 if (caseDef.noSSBO && VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
667 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32_UINT,
668 DE_NULL, 0, checkVertexPipelineStages);
671 //Tests which don't use the SSBO
672 if ((VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) &&
673 (VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage))
675 if (!subgroups::isVertexSSBOSupportedForDevice(context))
677 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
681 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
683 return subgroups::makeFragmentTest(context, VK_FORMAT_R32_UINT,
684 DE_NULL, 0, checkFragment);
686 else if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
688 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT,
689 DE_NULL, 0, checkCompute);
691 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
693 return subgroups::makeVertexTest(context, VK_FORMAT_R32_UINT,
694 DE_NULL, 0, checkVertexPipelineStages);
696 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
698 return subgroups::makeGeometryTest(context, VK_FORMAT_R32_UINT,
699 DE_NULL, 0, checkVertexPipelineStages);
701 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
703 return subgroups::makeTessellationControlTest(context, VK_FORMAT_R32_UINT,
704 DE_NULL, 0, checkVertexPipelineStages);
706 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
708 return subgroups::makeTessellationEvaluationTest(context, VK_FORMAT_R32_UINT,
709 DE_NULL, 0, checkVertexPipelineStages);
711 return tcu::TestStatus::pass("OK");
719 tcu::TestCaseGroup* createSubgroupsBallotOtherTests(tcu::TestContext& testCtx)
721 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
722 testCtx, "ballot_other", "Subgroup ballot other category tests"));
724 const VkShaderStageFlags stages[] =
726 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
727 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
728 VK_SHADER_STAGE_GEOMETRY_BIT,
729 VK_SHADER_STAGE_VERTEX_BIT,
730 VK_SHADER_STAGE_FRAGMENT_BIT,
731 VK_SHADER_STAGE_COMPUTE_BIT
734 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
736 const VkShaderStageFlags stage = stages[stageIndex];
738 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
740 CaseDefinition caseDef = {opTypeIndex, stage, false};
742 std::ostringstream name;
744 std::string op = getOpTypeName(opTypeIndex);
746 name << de::toLower(op) << "_" << getShaderStageName(stage);
748 addFunctionCaseWithPrograms(group.get(), name.str(),
749 "", initPrograms, test, caseDef);
751 if (VK_SHADER_STAGE_VERTEX_BIT & stage )
753 caseDef.noSSBO = true;
754 addFunctionCaseWithPrograms(group.get(), name.str() + "_framebuffer", "",
755 initFrameBufferPrograms, test, caseDef);
761 return group.release();