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 "vktSubgroupsBasicTests.hpp"
26 #include "vktSubgroupsTestsUtils.hpp"
38 static const deUint32 ELECTED_VALUE = 42u;
39 static const deUint32 UNELECTED_VALUE = 13u;
40 static const vk::VkDeviceSize SHADER_BUFFER_SIZE = 4096ull; // min(maxUniformBufferRange, maxImageDimension1D)
42 static bool checkFragmentSubgroupBarriersNoSSBO(std::vector<const void*> datas,
43 deUint32 width, deUint32 height, deUint32)
45 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
47 for (deUint32 x = 0u; x < width; ++x)
49 for (deUint32 y = 0u; y < height; ++y)
51 const deUint32 ndx = (x * height + y) * 4u;
52 if (1.0f == resultData[ndx +2])
54 if(resultData[ndx] != resultData[ndx +1])
59 else if (resultData[ndx] != resultData[ndx +3])
69 static bool checkVertexPipelineStagesSubgroupElectNoSSBO(std::vector<const void*> datas,
70 deUint32 width, deUint32)
72 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
73 float poisonValuesFound = 0.0f;
74 float numSubgroupsUsed = 0.0f;
76 for (deUint32 x = 0; x < width; ++x)
78 deUint32 val = static_cast<deUint32>(resultData[x * 2]);
79 numSubgroupsUsed += resultData[x * 2 + 1];
84 // some garbage value was found!
89 poisonValuesFound += 1.0f;
93 return numSubgroupsUsed == poisonValuesFound;
96 static bool checkVertexPipelineStagesSubgroupElect(std::vector<const void*> datas,
97 deUint32 width, deUint32)
99 const deUint32* const resultData =
100 reinterpret_cast<const deUint32*>(datas[0]);
101 deUint32 poisonValuesFound = 0;
103 for (deUint32 x = 0; x < width; ++x)
105 deUint32 val = resultData[x];
110 // some garbage value was found!
112 case UNELECTED_VALUE:
120 // we used an atomicly incremented counter to note how many subgroups we used for the vertex shader
121 const deUint32 numSubgroupsUsed =
122 *reinterpret_cast<const deUint32*>(datas[1]);
124 return numSubgroupsUsed == poisonValuesFound;
127 static bool checkVertexPipelineStagesSubgroupBarriers(std::vector<const void*> datas,
128 deUint32 width, deUint32)
130 const deUint32* const resultData = reinterpret_cast<const deUint32*>(datas[0]);
132 // We used this SSBO to generate our unique value!
133 const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[3]);
135 for (deUint32 x = 0; x < width; ++x)
137 deUint32 val = resultData[x];
146 static bool checkVertexPipelineStagesSubgroupBarriersNoSSBO(std::vector<const void*> datas,
147 deUint32 width, deUint32)
149 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
151 for (deUint32 x = 0u; x < width; ++x)
153 const deUint32 ndx = x*4u;
154 if (1.0f == resultData[ndx +2])
156 if(resultData[ndx] != resultData[ndx +1])
159 else if (resultData[ndx] != resultData[ndx +3])
167 static bool checkTessellationEvaluationSubgroupBarriersNoSSBO(std::vector<const void*> datas,
168 deUint32 width, deUint32)
170 const float* const resultData = reinterpret_cast<const float*>(datas[0]);
172 for (deUint32 x = 0u; x < width; ++x)
174 const deUint32 ndx = x*4u;
175 if (0.0f == resultData[ndx +2] && resultData[ndx] != resultData[ndx +3])
183 static bool checkComputeSubgroupElect(std::vector<const void*> datas,
184 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
187 return vkt::subgroups::checkCompute(datas, numWorkgroups, localSize, 1);
190 static bool checkComputeSubgroupBarriers(std::vector<const void*> datas,
191 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
194 // We used this SSBO to generate our unique value!
195 const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[2]);
196 return vkt::subgroups::checkCompute(datas, numWorkgroups, localSize, ref);
202 OPTYPE_SUBGROUP_BARRIER,
203 OPTYPE_SUBGROUP_MEMORY_BARRIER,
204 OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER,
205 OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED,
206 OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE,
210 std::string getOpTypeName(int opType)
215 DE_FATAL("Unsupported op type");
218 return "subgroupElect";
219 case OPTYPE_SUBGROUP_BARRIER:
220 return "subgroupBarrier";
221 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
222 return "subgroupMemoryBarrier";
223 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
224 return "subgroupMemoryBarrierBuffer";
225 case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
226 return "subgroupMemoryBarrierShared";
227 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
228 return "subgroupMemoryBarrierImage";
232 struct CaseDefinition
235 VkShaderStageFlags shaderStage;
238 void initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
240 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
241 const vk::SpirVAsmBuildOptions buildOptionsSpr (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3);
243 if(VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage)
246 "layout(location = 0) in vec4 in_color;\n"
247 "layout(location = 0) out vec4 out_color;\n"
250 " out_color = in_color;\n"
253 const string fragment =
256 "; Generator: Khronos Glslang Reference Front End; 2\n"
259 "OpCapability Shader\n"
260 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
261 "OpMemoryModel Logical GLSL450\n"
262 "OpEntryPoint Fragment %4 \"main\" %9 %11\n"
263 "OpExecutionMode %4 OriginUpperLeft\n"
264 "OpDecorate %9 Location 0\n"
265 "OpDecorate %11 Location 0\n"
267 "%3 = OpTypeFunction %2\n"
268 "%6 = OpTypeFloat 32\n"
269 "%7 = OpTypeVector %6 4\n"
270 "%8 = OpTypePointer Output %7\n"
271 "%9 = OpVariable %8 Output\n"
272 "%10 = OpTypePointer Input %7\n"
273 "%11 = OpVariable %10 Input\n"
274 "%4 = OpFunction %2 None %3\n"
276 "%12 = OpLoad %7 %11\n"
280 programCollection.spirvAsmSources.add("fragment") << fragment;
282 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
288 " vec2 uv = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);\n"
289 " gl_Position = vec4(uv * 2.0f + -1.0f, 0.0f, 1.0f);\n"
290 " gl_PointSize = 1.0f;\n"
293 const string vertex =
296 "; Generator: Khronos Glslang Reference Front End; 2\n"
299 "OpCapability Shader\n"
300 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
301 "OpMemoryModel Logical GLSL450\n"
302 "OpEntryPoint Vertex %4 \"main\" %12 %29\n"
303 "OpDecorate %12 BuiltIn VertexIndex\n"
304 "OpMemberDecorate %27 0 BuiltIn Position\n"
305 "OpMemberDecorate %27 1 BuiltIn PointSize\n"
306 "OpMemberDecorate %27 2 BuiltIn ClipDistance\n"
307 "OpMemberDecorate %27 3 BuiltIn CullDistance\n"
308 "OpDecorate %27 Block\n"
310 "%3 = OpTypeFunction %2\n"
311 "%6 = OpTypeFloat 32\n"
312 "%7 = OpTypeVector %6 2\n"
313 "%8 = OpTypePointer Function %7\n"
314 "%10 = OpTypeInt 32 1\n"
315 "%11 = OpTypePointer Input %10\n"
316 "%12 = OpVariable %11 Input\n"
317 "%14 = OpConstant %10 1\n"
318 "%16 = OpConstant %10 2\n"
319 "%23 = OpTypeVector %6 4\n"
320 "%24 = OpTypeInt 32 0\n"
321 "%25 = OpConstant %24 1\n"
322 "%26 = OpTypeArray %6 %25\n"
323 "%27 = OpTypeStruct %23 %6 %26 %26\n"
324 "%28 = OpTypePointer Output %27\n"
325 "%29 = OpVariable %28 Output\n"
326 "%30 = OpConstant %10 0\n"
327 "%32 = OpConstant %6 2\n"
328 "%34 = OpConstant %6 -1\n"
329 "%37 = OpConstant %6 0\n"
330 "%38 = OpConstant %6 1\n"
331 "%42 = OpTypePointer Output %23\n"
332 "%44 = OpTypePointer Output %6\n"
333 "%4 = OpFunction %2 None %3\n"
335 "%9 = OpVariable %8 Function\n"
336 "%13 = OpLoad %10 %12\n"
337 "%15 = OpShiftLeftLogical %10 %13 %14\n"
338 "%17 = OpBitwiseAnd %10 %15 %16\n"
339 "%18 = OpConvertSToF %6 %17\n"
340 "%19 = OpLoad %10 %12\n"
341 "%20 = OpBitwiseAnd %10 %19 %16\n"
342 "%21 = OpConvertSToF %6 %20\n"
343 "%22 = OpCompositeConstruct %7 %18 %21\n"
345 "%31 = OpLoad %7 %9\n"
346 "%33 = OpVectorTimesScalar %7 %31 %32\n"
347 "%35 = OpCompositeConstruct %7 %34 %34\n"
348 "%36 = OpFAdd %7 %33 %35\n"
349 "%39 = OpCompositeExtract %6 %36 0\n"
350 "%40 = OpCompositeExtract %6 %36 1\n"
351 "%41 = OpCompositeConstruct %23 %39 %40 %37 %38\n"
352 "%43 = OpAccessChain %42 %29 %30\n"
354 "%45 = OpAccessChain %44 %29 %14\n"
358 programCollection.spirvAsmSources.add("vert") << vertex;
360 else if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
361 subgroups::setVertexShaderFrameBuffer(programCollection);
363 if (OPTYPE_ELECT == caseDef.opType)
365 std::ostringstream electedValue ;
366 std::ostringstream unelectedValue;
367 electedValue << ELECTED_VALUE;
368 unelectedValue << UNELECTED_VALUE;
370 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
373 "#extension GL_KHR_shader_subgroup_basic: enable\n"
374 "layout(location = 0) out vec4 out_color;\n"
375 "layout(location = 0) in highp vec4 in_position;\n"
379 " if (subgroupElect())\n"
381 " out_color.r = " << ELECTED_VALUE << ";\n"
382 " out_color.g = 1.0f;\n"
386 " out_color.r = " << UNELECTED_VALUE << ";\n"
387 " out_color.g = 0.0f;\n"
389 " gl_Position = in_position;\n"
390 " gl_PointSize = 1.0f;\n"
393 const string vertex =
396 "; Generator: Khronos Glslang Reference Front End; 2\n"
399 "OpCapability Shader\n"
400 "OpCapability GroupNonUniform\n"
401 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
402 "OpMemoryModel Logical GLSL450\n"
403 "OpEntryPoint Vertex %4 \"main\" %15 %31 %35\n"
404 "OpDecorate %15 Location 0\n"
405 "OpMemberDecorate %29 0 BuiltIn Position\n"
406 "OpMemberDecorate %29 1 BuiltIn PointSize\n"
407 "OpMemberDecorate %29 2 BuiltIn ClipDistance\n"
408 "OpMemberDecorate %29 3 BuiltIn CullDistance\n"
409 "OpDecorate %29 Block\n"
410 "OpDecorate %35 Location 0\n"
412 "%3 = OpTypeFunction %2\n"
414 "%7 = OpTypeInt 32 0\n"
415 "%8 = OpConstant %7 3\n"
416 "%12 = OpTypeFloat 32\n"
417 "%13 = OpTypeVector %12 4\n"
418 "%14 = OpTypePointer Output %13\n"
419 "%15 = OpVariable %14 Output\n"
420 "%16 = OpConstant %12 " + electedValue.str() + "\n"
421 "%17 = OpConstant %7 0\n"
422 "%18 = OpTypePointer Output %12\n"
423 "%20 = OpConstant %12 1\n"
424 "%21 = OpConstant %7 1\n"
425 "%24 = OpConstant %12 " + unelectedValue.str() + "\n"
426 "%26 = OpConstant %12 0\n"
427 "%28 = OpTypeArray %12 %21\n"
428 "%29 = OpTypeStruct %13 %12 %28 %28\n"
429 "%30 = OpTypePointer Output %29\n"
430 "%31 = OpVariable %30 Output\n"
431 "%32 = OpTypeInt 32 1\n"
432 "%33 = OpConstant %32 0\n"
433 "%34 = OpTypePointer Input %13\n"
434 "%35 = OpVariable %34 Input\n"
435 "%38 = OpConstant %32 1\n"
436 "%4 = OpFunction %2 None %3\n"
438 "%9 = OpGroupNonUniformElect %6 %8\n"
439 "OpSelectionMerge %11 None\n"
440 "OpBranchConditional %9 %10 %23\n"
442 "%19 = OpAccessChain %18 %15 %17\n"
444 "%22 = OpAccessChain %18 %15 %21\n"
448 "%25 = OpAccessChain %18 %15 %17\n"
450 "%27 = OpAccessChain %18 %15 %21\n"
454 "%36 = OpLoad %13 %35\n"
455 "%37 = OpAccessChain %14 %31 %33\n"
457 "%39 = OpAccessChain %18 %31 %38\n"
461 programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
463 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
467 "#extension GL_KHR_shader_subgroup_basic: enable\n"
468 "layout(points) in;\n"
469 "layout(points, max_vertices = 1) out;\n"
470 "layout(location = 0) out vec4 out_color;\n"
473 " if (subgroupElect())\n"
475 " out_color.r = " << ELECTED_VALUE << ";\n"
476 " out_color.g = 1.0f;\n"
480 " out_color.r = " << UNELECTED_VALUE << ";\n"
481 " out_color.g = 0.0f;\n"
483 " gl_Position = gl_in[0].gl_Position;\n"
488 const string geometry =
491 "; Generator: Khronos Glslang Reference Front End; 2\n"
494 "OpCapability Geometry\n"
495 "OpCapability GroupNonUniform\n"
496 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
497 "OpMemoryModel Logical GLSL450\n"
498 "OpEntryPoint Geometry %4 \"main\" %15 %31 %37\n"
499 "OpExecutionMode %4 InputPoints\n"
500 "OpExecutionMode %4 Invocations 1\n"
501 "OpExecutionMode %4 OutputPoints\n"
502 "OpExecutionMode %4 OutputVertices 1\n"
503 "OpDecorate %15 Location 0\n"
504 "OpMemberDecorate %29 0 BuiltIn Position\n"
505 "OpMemberDecorate %29 1 BuiltIn PointSize\n"
506 "OpMemberDecorate %29 2 BuiltIn ClipDistance\n"
507 "OpMemberDecorate %29 3 BuiltIn CullDistance\n"
508 "OpDecorate %29 Block\n"
509 "OpMemberDecorate %34 0 BuiltIn Position\n"
510 "OpMemberDecorate %34 1 BuiltIn PointSize\n"
511 "OpMemberDecorate %34 2 BuiltIn ClipDistance\n"
512 "OpMemberDecorate %34 3 BuiltIn CullDistance\n"
513 "OpDecorate %34 Block\n"
515 "%3 = OpTypeFunction %2\n"
517 "%7 = OpTypeInt 32 0\n"
518 "%8 = OpConstant %7 3\n"
519 "%12 = OpTypeFloat 32\n"
520 "%13 = OpTypeVector %12 4\n"
521 "%14 = OpTypePointer Output %13\n"
522 "%15 = OpVariable %14 Output\n"
523 "%16 = OpConstant %12 " + electedValue.str() + "\n"
524 "%17 = OpConstant %7 0\n"
525 "%18 = OpTypePointer Output %12\n"
526 "%20 = OpConstant %12 1\n"
527 "%21 = OpConstant %7 1\n"
528 "%24 = OpConstant %12 " + unelectedValue.str() + "\n"
529 "%26 = OpConstant %12 0\n"
530 "%28 = OpTypeArray %12 %21\n"
531 "%29 = OpTypeStruct %13 %12 %28 %28\n"
532 "%30 = OpTypePointer Output %29\n"
533 "%31 = OpVariable %30 Output\n"
534 "%32 = OpTypeInt 32 1\n"
535 "%33 = OpConstant %32 0\n"
536 "%34 = OpTypeStruct %13 %12 %28 %28\n"
537 "%35 = OpTypeArray %34 %21\n"
538 "%36 = OpTypePointer Input %35\n"
539 "%37 = OpVariable %36 Input\n"
540 "%38 = OpTypePointer Input %13\n"
541 "%4 = OpFunction %2 None %3\n"
543 "%9 = OpGroupNonUniformElect %6 %8\n"
544 "OpSelectionMerge %11 None\n"
545 "OpBranchConditional %9 %10 %23\n"
547 "%19 = OpAccessChain %18 %15 %17\n"
549 "%22 = OpAccessChain %18 %15 %21\n"
553 "%25 = OpAccessChain %18 %15 %17\n"
555 "%27 = OpAccessChain %18 %15 %21\n"
559 "%39 = OpAccessChain %38 %37 %33 %33\n"
560 "%40 = OpLoad %13 %39\n"
561 "%41 = OpAccessChain %14 %31 %33\n"
567 programCollection.spirvAsmSources.add("geometry") << geometry << buildOptionsSpr;
569 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
572 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
573 << "#extension GL_EXT_tessellation_shader : require\n"
574 << "layout(vertices = 2) out;\n"
575 << "void main (void)\n"
577 << " if (gl_InvocationID == 0)\n"
579 << " gl_TessLevelOuter[0] = 1.0f;\n"
580 << " gl_TessLevelOuter[1] = 1.0f;\n"
582 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
585 const string controlSource =
588 "; Generator: Khronos Glslang Reference Front End; 2\n"
591 "OpCapability Tessellation\n"
592 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
593 "OpMemoryModel Logical GLSL450\n"
594 "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %33 %39\n"
595 "OpExecutionMode %4 OutputVertices 2\n"
596 "OpDecorate %8 BuiltIn InvocationId\n"
597 "OpDecorate %20 Patch\n"
598 "OpDecorate %20 BuiltIn TessLevelOuter\n"
599 "OpMemberDecorate %29 0 BuiltIn Position\n"
600 "OpMemberDecorate %29 1 BuiltIn PointSize\n"
601 "OpMemberDecorate %29 2 BuiltIn ClipDistance\n"
602 "OpMemberDecorate %29 3 BuiltIn CullDistance\n"
603 "OpDecorate %29 Block\n"
604 "OpMemberDecorate %35 0 BuiltIn Position\n"
605 "OpMemberDecorate %35 1 BuiltIn PointSize\n"
606 "OpMemberDecorate %35 2 BuiltIn ClipDistance\n"
607 "OpMemberDecorate %35 3 BuiltIn CullDistance\n"
608 "OpDecorate %35 Block\n"
610 "%3 = OpTypeFunction %2\n"
611 "%6 = OpTypeInt 32 1\n"
612 "%7 = OpTypePointer Input %6\n"
613 "%8 = OpVariable %7 Input\n"
614 "%10 = OpConstant %6 0\n"
616 "%15 = OpTypeFloat 32\n"
617 "%16 = OpTypeInt 32 0\n"
618 "%17 = OpConstant %16 4\n"
619 "%18 = OpTypeArray %15 %17\n"
620 "%19 = OpTypePointer Output %18\n"
621 "%20 = OpVariable %19 Output\n"
622 "%21 = OpConstant %15 1\n"
623 "%22 = OpTypePointer Output %15\n"
624 "%24 = OpConstant %6 1\n"
625 "%26 = OpTypeVector %15 4\n"
626 "%27 = OpConstant %16 1\n"
627 "%28 = OpTypeArray %15 %27\n"
628 "%29 = OpTypeStruct %26 %15 %28 %28\n"
629 "%30 = OpConstant %16 2\n"
630 "%31 = OpTypeArray %29 %30\n"
631 "%32 = OpTypePointer Output %31\n"
632 "%33 = OpVariable %32 Output\n"
633 "%35 = OpTypeStruct %26 %15 %28 %28\n"
634 "%36 = OpConstant %16 32\n"
635 "%37 = OpTypeArray %35 %36\n"
636 "%38 = OpTypePointer Input %37\n"
637 "%39 = OpVariable %38 Input\n"
638 "%41 = OpTypePointer Input %26\n"
639 "%44 = OpTypePointer Output %26\n"
640 "%4 = OpFunction %2 None %3\n"
642 "%9 = OpLoad %6 %8\n"
643 "%12 = OpIEqual %11 %9 %10\n"
644 "OpSelectionMerge %14 None\n"
645 "OpBranchConditional %12 %13 %14\n"
647 "%23 = OpAccessChain %22 %20 %10\n"
649 "%25 = OpAccessChain %22 %20 %24\n"
653 "%34 = OpLoad %6 %8\n"
654 "%40 = OpLoad %6 %8\n"
655 "%42 = OpAccessChain %41 %39 %40 %10\n"
656 "%43 = OpLoad %26 %42\n"
657 "%45 = OpAccessChain %44 %33 %34 %10\n"
661 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
664 "#extension GL_KHR_shader_subgroup_basic: enable\n"
665 "#extension GL_EXT_tessellation_shader : require\n"
666 "layout(isolines, equal_spacing, ccw ) in;\n"
667 "layout(location = 0) out vec4 out_color;\n"
671 " if (subgroupElect())\n"
673 " out_color.r = " << 2 * ELECTED_VALUE - UNELECTED_VALUE << ";\n"
674 " out_color.g = 2.0f;\n"
678 " out_color.r = " << UNELECTED_VALUE << ";\n"
679 " out_color.g = 0.0f;\n"
681 " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
685 const string evaluationSource =
688 "; Generator: Khronos Glslang Reference Front End; 2\n"
691 "OpCapability Tessellation\n"
692 "OpCapability GroupNonUniform\n"
693 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
694 "OpMemoryModel Logical GLSL450\n"
695 "OpEntryPoint TessellationEvaluation %4 \"main\" %15 %31 %38 %47\n"
696 "OpExecutionMode %4 Isolines\n"
697 "OpExecutionMode %4 SpacingEqual\n"
698 "OpExecutionMode %4 VertexOrderCcw\n"
699 "OpDecorate %15 Location 0\n"
700 "OpMemberDecorate %29 0 BuiltIn Position\n"
701 "OpMemberDecorate %29 1 BuiltIn PointSize\n"
702 "OpMemberDecorate %29 2 BuiltIn ClipDistance\n"
703 "OpMemberDecorate %29 3 BuiltIn CullDistance\n"
704 "OpDecorate %29 Block\n"
705 "OpMemberDecorate %34 0 BuiltIn Position\n"
706 "OpMemberDecorate %34 1 BuiltIn PointSize\n"
707 "OpMemberDecorate %34 2 BuiltIn ClipDistance\n"
708 "OpMemberDecorate %34 3 BuiltIn CullDistance\n"
709 "OpDecorate %34 Block\n"
710 "OpDecorate %47 BuiltIn TessCoord\n"
712 "%3 = OpTypeFunction %2\n"
714 "%7 = OpTypeInt 32 0\n"
715 "%8 = OpConstant %7 3\n"
716 "%12 = OpTypeFloat 32\n"
717 "%13 = OpTypeVector %12 4\n"
718 "%14 = OpTypePointer Output %13\n"
719 "%15 = OpVariable %14 Output\n"
720 "%16 = OpConstant %12 71\n"//electedValue
721 "%17 = OpConstant %7 0\n"
722 "%18 = OpTypePointer Output %12\n"
723 "%20 = OpConstant %12 2\n"
724 "%21 = OpConstant %7 1\n"
725 "%24 = OpConstant %12 " + unelectedValue.str() + "\n"
726 "%26 = OpConstant %12 0\n"
727 "%28 = OpTypeArray %12 %21\n"
728 "%29 = OpTypeStruct %13 %12 %28 %28\n"
729 "%30 = OpTypePointer Output %29\n"
730 "%31 = OpVariable %30 Output\n"
731 "%32 = OpTypeInt 32 1\n"
732 "%33 = OpConstant %32 0\n"
733 "%34 = OpTypeStruct %13 %12 %28 %28\n"
734 "%35 = OpConstant %7 32\n"
735 "%36 = OpTypeArray %34 %35\n"
736 "%37 = OpTypePointer Input %36\n"
737 "%38 = OpVariable %37 Input\n"
738 "%39 = OpTypePointer Input %13\n"
739 "%42 = OpConstant %32 1\n"
740 "%45 = OpTypeVector %12 3\n"
741 "%46 = OpTypePointer Input %45\n"
742 "%47 = OpVariable %46 Input\n"
743 "%48 = OpTypePointer Input %12\n"
744 "%4 = OpFunction %2 None %3\n"
746 "%9 = OpGroupNonUniformElect %6 %8\n"
747 "OpSelectionMerge %11 None\n"
748 "OpBranchConditional %9 %10 %23\n"
750 "%19 = OpAccessChain %18 %15 %17\n"
752 "%22 = OpAccessChain %18 %15 %21\n"
756 "%25 = OpAccessChain %18 %15 %17\n"
758 "%27 = OpAccessChain %18 %15 %21\n"
762 "%40 = OpAccessChain %39 %38 %33 %33\n"
763 "%41 = OpLoad %13 %40\n"
764 "%43 = OpAccessChain %39 %38 %42 %33\n"
765 "%44 = OpLoad %13 %43\n"
766 "%49 = OpAccessChain %48 %47 %17\n"
767 "%50 = OpLoad %12 %49\n"
768 "%51 = OpCompositeConstruct %13 %50 %50 %50 %50\n"
769 "%52 = OpExtInst %13 %1 FMix %41 %44 %51\n"
770 "%53 = OpAccessChain %14 %31 %33\n"
775 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
777 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
780 "#extension GL_KHR_shader_subgroup_basic: enable\n"
781 "#extension GL_EXT_tessellation_shader : require\n"
782 "layout(vertices = 2) out;\n"
783 "layout(location = 0) out vec4 out_color[];\n"
786 " if (gl_InvocationID == 0)\n"
788 " gl_TessLevelOuter[0] = 1.0f;\n"
789 " gl_TessLevelOuter[1] = 1.0f;\n"
791 " if (subgroupElect())\n"
793 " out_color[gl_InvocationID].r = " << ELECTED_VALUE << ";\n"
794 " out_color[gl_InvocationID].g = 1.0f;\n"
798 " out_color[gl_InvocationID].r = " << UNELECTED_VALUE << ";\n"
799 " out_color[gl_InvocationID].g = 0.0f;\n"
801 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
804 const string controlSource =
807 "; Generator: Khronos Glslang Reference Front End; 2\n"
810 "OpCapability Tessellation\n"
811 "OpCapability GroupNonUniform\n"
812 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
813 "OpMemoryModel Logical GLSL450\n"
814 "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %34 %53 %59\n"
815 "OpExecutionMode %4 OutputVertices 2\n"
816 "OpDecorate %8 BuiltIn InvocationId\n"
817 "OpDecorate %20 Patch\n"
818 "OpDecorate %20 BuiltIn TessLevelOuter\n"
819 "OpDecorate %34 Location 0\n"
820 "OpMemberDecorate %50 0 BuiltIn Position\n"
821 "OpMemberDecorate %50 1 BuiltIn PointSize\n"
822 "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
823 "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
824 "OpDecorate %50 Block\n"
825 "OpMemberDecorate %55 0 BuiltIn Position\n"
826 "OpMemberDecorate %55 1 BuiltIn PointSize\n"
827 "OpMemberDecorate %55 2 BuiltIn ClipDistance\n"
828 "OpMemberDecorate %55 3 BuiltIn CullDistance\n"
829 "OpDecorate %55 Block\n"
831 "%3 = OpTypeFunction %2\n"
832 "%6 = OpTypeInt 32 1\n"
833 "%7 = OpTypePointer Input %6\n"
834 "%8 = OpVariable %7 Input\n"
835 "%10 = OpConstant %6 0\n"
837 "%15 = OpTypeFloat 32\n"
838 "%16 = OpTypeInt 32 0\n"
839 "%17 = OpConstant %16 4\n"
840 "%18 = OpTypeArray %15 %17\n"
841 "%19 = OpTypePointer Output %18\n"
842 "%20 = OpVariable %19 Output\n"
843 "%21 = OpConstant %15 1\n"
844 "%22 = OpTypePointer Output %15\n"
845 "%24 = OpConstant %6 1\n"
846 "%26 = OpConstant %16 3\n"
847 "%30 = OpTypeVector %15 4\n"
848 "%31 = OpConstant %16 2\n"
849 "%32 = OpTypeArray %30 %31\n"
850 "%33 = OpTypePointer Output %32\n"
851 "%34 = OpVariable %33 Output\n"
852 "%36 = OpConstant %15 " + electedValue.str() + "\n"
853 "%37 = OpConstant %16 0\n"
854 "%40 = OpConstant %16 1\n"
855 "%44 = OpConstant %15 " + unelectedValue.str() + "\n"
856 "%47 = OpConstant %15 0\n"
857 "%49 = OpTypeArray %15 %40\n"
858 "%50 = OpTypeStruct %30 %15 %49 %49\n"
859 "%51 = OpTypeArray %50 %31\n"
860 "%52 = OpTypePointer Output %51\n"
861 "%53 = OpVariable %52 Output\n"
862 "%55 = OpTypeStruct %30 %15 %49 %49\n"
863 "%56 = OpConstant %16 32\n"
864 "%57 = OpTypeArray %55 %56\n"
865 "%58 = OpTypePointer Input %57\n"
866 "%59 = OpVariable %58 Input\n"
867 "%61 = OpTypePointer Input %30\n"
868 "%64 = OpTypePointer Output %30\n"
869 "%4 = OpFunction %2 None %3\n"
871 "%9 = OpLoad %6 %8\n"
872 "%12 = OpIEqual %11 %9 %10\n"
873 "OpSelectionMerge %14 None\n"
874 "OpBranchConditional %12 %13 %14\n"
876 "%23 = OpAccessChain %22 %20 %10\n"
878 "%25 = OpAccessChain %22 %20 %24\n"
882 "%27 = OpGroupNonUniformElect %11 %26\n"
883 "OpSelectionMerge %29 None\n"
884 "OpBranchConditional %27 %28 %42\n"
886 "%35 = OpLoad %6 %8\n"
887 "%38 = OpAccessChain %22 %34 %35 %37\n"
889 "%39 = OpLoad %6 %8\n"
890 "%41 = OpAccessChain %22 %34 %39 %40\n"
894 "%43 = OpLoad %6 %8\n"
895 "%45 = OpAccessChain %22 %34 %43 %37\n"
897 "%46 = OpLoad %6 %8\n"
898 "%48 = OpAccessChain %22 %34 %46 %40\n"
902 "%54 = OpLoad %6 %8\n"
903 "%60 = OpLoad %6 %8\n"
904 "%62 = OpAccessChain %61 %59 %60 %10\n"
905 "%63 = OpLoad %30 %62\n"
906 "%65 = OpAccessChain %64 %53 %54 %10\n"
910 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
913 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
914 "#extension GL_EXT_tessellation_shader : require\n"
915 "layout(isolines, equal_spacing, ccw ) in;\n"
916 "layout(location = 0) in vec4 in_color[];\n"
917 "layout(location = 0) out vec4 out_color;\n"
921 " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
922 " out_color = in_color[0];\n"
926 const string evaluationSource =
929 "; Generator: Khronos Glslang Reference Front End; 2\n"
932 "OpCapability Tessellation\n"
933 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
934 "OpMemoryModel Logical GLSL450\n"
935 "OpEntryPoint TessellationEvaluation %4 \"main\" %13 %20 %29 %38 %41\n"
936 "OpExecutionMode %4 Isolines\n"
937 "OpExecutionMode %4 SpacingEqual\n"
938 "OpExecutionMode %4 VertexOrderCcw\n"
939 "OpMemberDecorate %11 0 BuiltIn Position\n"
940 "OpMemberDecorate %11 1 BuiltIn PointSize\n"
941 "OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
942 "OpMemberDecorate %11 3 BuiltIn CullDistance\n"
943 "OpDecorate %11 Block\n"
944 "OpMemberDecorate %16 0 BuiltIn Position\n"
945 "OpMemberDecorate %16 1 BuiltIn PointSize\n"
946 "OpMemberDecorate %16 2 BuiltIn ClipDistance\n"
947 "OpMemberDecorate %16 3 BuiltIn CullDistance\n"
948 "OpDecorate %16 Block\n"
949 "OpDecorate %29 BuiltIn TessCoord\n"
950 "OpDecorate %38 Location 0\n"
951 "OpDecorate %41 Location 0\n"
953 "%3 = OpTypeFunction %2\n"
954 "%6 = OpTypeFloat 32\n"
955 "%7 = OpTypeVector %6 4\n"
956 "%8 = OpTypeInt 32 0\n"
957 "%9 = OpConstant %8 1\n"
958 "%10 = OpTypeArray %6 %9\n"
959 "%11 = OpTypeStruct %7 %6 %10 %10\n"
960 "%12 = OpTypePointer Output %11\n"
961 "%13 = OpVariable %12 Output\n"
962 "%14 = OpTypeInt 32 1\n"
963 "%15 = OpConstant %14 0\n"
964 "%16 = OpTypeStruct %7 %6 %10 %10\n"
965 "%17 = OpConstant %8 32\n"
966 "%18 = OpTypeArray %16 %17\n"
967 "%19 = OpTypePointer Input %18\n"
968 "%20 = OpVariable %19 Input\n"
969 "%21 = OpTypePointer Input %7\n"
970 "%24 = OpConstant %14 1\n"
971 "%27 = OpTypeVector %6 3\n"
972 "%28 = OpTypePointer Input %27\n"
973 "%29 = OpVariable %28 Input\n"
974 "%30 = OpConstant %8 0\n"
975 "%31 = OpTypePointer Input %6\n"
976 "%36 = OpTypePointer Output %7\n"
977 "%38 = OpVariable %36 Output\n"
978 "%39 = OpTypeArray %7 %17\n"
979 "%40 = OpTypePointer Input %39\n"
980 "%41 = OpVariable %40 Input\n"
981 "%4 = OpFunction %2 None %3\n"
983 "%22 = OpAccessChain %21 %20 %15 %15\n"
984 "%23 = OpLoad %7 %22\n"
985 "%25 = OpAccessChain %21 %20 %24 %15\n"
986 "%26 = OpLoad %7 %25\n"
987 "%32 = OpAccessChain %31 %29 %30\n"
988 "%33 = OpLoad %6 %32\n"
989 "%34 = OpCompositeConstruct %7 %33 %33 %33 %33\n"
990 "%35 = OpExtInst %7 %1 FMix %23 %26 %34\n"
991 "%37 = OpAccessChain %36 %13 %15\n"
993 "%42 = OpAccessChain %21 %41 %15\n"
994 "%43 = OpLoad %7 %42\n"
998 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
1002 DE_FATAL("Unsupported shader stage");
1007 std::ostringstream bdy;
1008 string color = (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage) ? "out_color[gl_InvocationID].b = 1.0f;\n" : "out_color.b = 1.0f;\n";
1009 switch (caseDef.opType)
1012 DE_FATAL("Unhandled op type!");
1014 case OPTYPE_SUBGROUP_BARRIER:
1015 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
1016 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
1018 bdy << " tempResult2 = tempBuffer[id];\n"
1019 << " if (subgroupElect())\n"
1021 << " tempResult = value;\n"
1026 << " tempResult = tempBuffer[id];\n"
1028 << " " << getOpTypeName(caseDef.opType) << "();\n";
1031 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
1032 bdy <<"tempResult2 = imageLoad(tempImage, ivec2(id, 0)).x;\n"
1033 << " if (subgroupElect())\n"
1035 << " tempResult = value;\n"
1040 << " tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n"
1042 << " subgroupMemoryBarrierImage();\n";
1047 if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1049 std::ostringstream fragment;
1050 fragment << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1051 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1052 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1053 << "layout(location = 0) out vec4 out_color;\n"
1055 << "layout(set = 0, binding = 0) uniform Buffer1\n"
1057 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
1060 << "layout(set = 0, binding = 1) uniform Buffer2\n"
1064 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
1065 << "void main (void)\n"
1067 << " if (gl_HelperInvocation) return;\n"
1068 << " uint id = 0;\n"
1069 << " if (subgroupElect())\n"
1071 << " id = uint(gl_FragCoord.x);\n"
1073 << " id = subgroupBroadcastFirst(id);\n"
1074 << " uint localId = id;\n"
1075 << " uint tempResult = 0u;\n"
1076 << " uint tempResult2 = 0u;\n"
1077 << " out_color.b = 0.0f;\n"
1079 << " out_color.r = float(tempResult);\n"
1080 << " out_color.g = float(value);\n"
1081 << " out_color.a = float(tempResult2);\n"
1083 programCollection.glslSources.add("fragment")
1084 << glu::FragmentSource(fragment.str()) << buildOptions;
1086 else if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1088 std::ostringstream vertex;
1089 vertex << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1090 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1091 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1093 << "layout(location = 0) out vec4 out_color;\n"
1094 << "layout(location = 0) in highp vec4 in_position;\n"
1096 << "layout(set = 0, binding = 0) uniform Buffer1\n"
1098 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
1101 << "layout(set = 0, binding = 1) uniform Buffer2\n"
1105 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
1106 << "void main (void)\n"
1108 << " uint id = 0;\n"
1109 << " if (subgroupElect())\n"
1111 << " id = gl_VertexIndex;\n"
1113 << " id = subgroupBroadcastFirst(id);\n"
1114 << " uint tempResult = 0u;\n"
1115 << " uint tempResult2 = 0u;\n"
1116 << " out_color.b = 0.0f;\n"
1118 << " out_color.r = float(tempResult);\n"
1119 << " out_color.g = float(value);\n"
1120 << " out_color.a = float(tempResult2);\n"
1121 << " gl_Position = in_position;\n"
1122 << " gl_PointSize = 1.0f;\n"
1124 programCollection.glslSources.add("vert")
1125 << glu::VertexSource(vertex.str()) << buildOptions;
1127 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
1129 std::ostringstream geometry;
1131 geometry << "#version 450\n"
1132 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1133 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1134 << "layout(points) in;\n"
1135 << "layout(points, max_vertices = 1) out;\n"
1136 << "layout(location = 0) out vec4 out_color;\n"
1137 << "layout(set = 0, binding = 0) uniform Buffer1\n"
1139 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
1142 << "layout(set = 0, binding = 1) uniform Buffer2\n"
1146 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
1147 << "void main (void)\n"
1149 << " uint id = 0;\n"
1150 << " if (subgroupElect())\n"
1152 << " id = gl_InvocationID;\n"
1154 << " id = subgroupBroadcastFirst(id);\n"
1155 << " uint tempResult = 0u;\n"
1156 << " uint tempResult2 = 0u;\n"
1157 << " out_color.b = 0.0f;\n"
1159 << " out_color.r = float(tempResult);\n"
1160 << " out_color.g = float(value);\n"
1161 << " out_color.a = float(tempResult2);\n"
1162 << " gl_Position = gl_in[0].gl_Position;\n"
1163 << " EmitVertex();\n"
1164 << " EndPrimitive();\n"
1167 programCollection.glslSources.add("geometry")
1168 << glu::GeometrySource(geometry.str()) << buildOptions;
1170 else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
1172 std::ostringstream controlSource;
1173 std::ostringstream evaluationSource;
1175 controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1176 << "#extension GL_EXT_tessellation_shader : require\n"
1177 << "layout(vertices = 2) out;\n"
1178 << "void main (void)\n"
1180 << " if (gl_InvocationID == 0)\n"
1182 << " gl_TessLevelOuter[0] = 1.0f;\n"
1183 << " gl_TessLevelOuter[1] = 1.0f;\n"
1185 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1188 evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1189 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1190 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1191 << "#extension GL_EXT_tessellation_shader : require\n"
1192 << "layout(isolines, equal_spacing, ccw ) in;\n"
1193 << "layout(location = 0) out vec4 out_color;\n"
1194 << "layout(set = 0, binding = 0) uniform Buffer1\n"
1196 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
1199 << "layout(set = 0, binding = 1) uniform Buffer2\n"
1203 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
1204 << "void main (void)\n"
1206 << " uint id = 0;\n"
1207 << " if (subgroupElect())\n"
1209 << " id = gl_PrimitiveID;\n"
1211 << " id = subgroupBroadcastFirst(id);\n"
1212 << " uint tempResult = 0u;\n"
1213 << " uint tempResult2 = 0u;\n"
1214 << " out_color.b = 0.0f;\n"
1216 << " out_color.r = float(tempResult);\n"
1217 << " out_color.g = float(value);\n"
1218 << " out_color.a = float(tempResult2);\n"
1219 << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
1222 programCollection.glslSources.add("tesc")
1223 << glu::TessellationControlSource(controlSource.str()) << buildOptions;
1224 programCollection.glslSources.add("tese")
1225 << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
1227 else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
1229 std::ostringstream controlSource;
1230 std::ostringstream evaluationSource;
1232 controlSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1233 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1234 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1235 << "#extension GL_EXT_tessellation_shader : require\n"
1236 << "layout(vertices = 2) out;\n"
1237 << "layout(location = 0) out vec4 out_color[];\n"
1238 << "layout(set = 0, binding = 0) uniform Buffer1\n"
1240 << " uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
1243 << "layout(set = 0, binding = 1) uniform Buffer2\n"
1247 << (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(set = 0, binding = 2, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
1248 << "void main (void)\n"
1250 << " uint id = 0;\n"
1251 << " if (gl_InvocationID == 0)\n"
1253 << " gl_TessLevelOuter[0] = 1.0f;\n"
1254 << " gl_TessLevelOuter[1] = 1.0f;\n"
1256 << " if (subgroupElect())\n"
1258 << " id = gl_InvocationID;\n"
1260 << " id = subgroupBroadcastFirst(id);\n"
1261 << " uint tempResult = 0u;\n"
1262 << " uint tempResult2 = 0u;\n"
1263 << " out_color[gl_InvocationID].b = 0.0f;\n"
1265 << " out_color[gl_InvocationID].r = float(tempResult);\n"
1266 << " out_color[gl_InvocationID].g = float(value);\n"
1267 << " out_color[gl_InvocationID].a = float(tempResult2);\n"
1268 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1271 evaluationSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
1272 << "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1273 << "#extension GL_EXT_tessellation_shader : require\n"
1274 << "layout(isolines, equal_spacing, ccw ) in;\n"
1275 << "layout(location = 0) in vec4 in_color[];\n"
1276 << "layout(location = 0) out vec4 out_color;\n"
1278 << "void main (void)\n"
1280 << " gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
1281 << " out_color = in_color[0];\n"
1284 programCollection.glslSources.add("tesc")
1285 << glu::TessellationControlSource(controlSource.str()) << buildOptions;
1286 programCollection.glslSources.add("tese")
1287 << glu::TessellationEvaluationSource(evaluationSource.str()) << buildOptions;
1291 DE_FATAL("Unsupported shader stage");
1296 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
1298 if (OPTYPE_ELECT == caseDef.opType)
1300 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1302 std::ostringstream src;
1304 src << "#version 450\n"
1305 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1306 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
1307 "local_size_z_id = 2) in;\n"
1308 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1310 << " uint result[];\n"
1313 << subgroups::getSharedMemoryBallotHelper()
1314 << "void main (void)\n"
1316 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
1317 << " highp uint offset = globalSize.x * ((globalSize.y * "
1318 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
1319 "gl_GlobalInvocationID.x;\n"
1320 << " uint value = " << UNELECTED_VALUE << ";\n"
1321 << " if (subgroupElect())\n"
1323 << " value = " << ELECTED_VALUE << ";\n"
1325 << " uvec4 bits = bitCount(sharedMemoryBallot(value == " << ELECTED_VALUE << "));\n"
1326 << " result[offset] = bits.x + bits.y + bits.z + bits.w;\n"
1329 programCollection.glslSources.add("comp")
1330 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1335 std::ostringstream vertex;
1336 vertex << "#version 450\n"
1337 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1338 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1340 << " uint result[];\n"
1342 << "layout(set = 0, binding = 4, std430) buffer Buffer2\n"
1344 << " uint numSubgroupsExecuted;\n"
1347 << "void main (void)\n"
1349 << " if (subgroupElect())\n"
1351 << " result[gl_VertexIndex] = " << ELECTED_VALUE << ";\n"
1352 << " atomicAdd(numSubgroupsExecuted, 1);\n"
1356 << " result[gl_VertexIndex] = " << UNELECTED_VALUE << ";\n"
1358 << " float pixelSize = 2.0f/1024.0f;\n"
1359 << " float pixelPosition = pixelSize/2.0f - 1.0f;\n"
1360 << " gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1361 << " gl_PointSize = 1.0f;\n"
1363 programCollection.glslSources.add("vert")
1364 << glu::VertexSource(vertex.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1368 std::ostringstream tesc;
1369 tesc << "#version 450\n"
1370 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1371 << "layout(vertices=1) out;\n"
1372 << "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
1374 << " uint result[];\n"
1376 << "layout(set = 0, binding = 5, std430) buffer Buffer2\n"
1378 << " uint numSubgroupsExecuted;\n"
1381 << "void main (void)\n"
1383 << " if (subgroupElect())\n"
1385 << " result[gl_PrimitiveID] = " << ELECTED_VALUE << ";\n"
1386 << " atomicAdd(numSubgroupsExecuted, 1);\n"
1390 << " result[gl_PrimitiveID] = " << UNELECTED_VALUE << ";\n"
1392 << " if (gl_InvocationID == 0)\n"
1394 << " gl_TessLevelOuter[0] = 1.0f;\n"
1395 << " gl_TessLevelOuter[1] = 1.0f;\n"
1397 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1399 programCollection.glslSources.add("tesc")
1400 << glu::TessellationControlSource(tesc.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1404 std::ostringstream tese;
1405 tese << "#version 450\n"
1406 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1407 << "layout(isolines) in;\n"
1408 << "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
1410 << " uint result[];\n"
1412 << "layout(set = 0, binding = 6, std430) buffer Buffer2\n"
1414 << " uint numSubgroupsExecuted;\n"
1417 << "void main (void)\n"
1419 << " if (subgroupElect())\n"
1421 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << ELECTED_VALUE << ";\n"
1422 << " atomicAdd(numSubgroupsExecuted, 1);\n"
1426 << " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = " << UNELECTED_VALUE << ";\n"
1428 << " float pixelSize = 2.0f/1024.0f;\n"
1429 << " gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1431 programCollection.glslSources.add("tese")
1432 << glu::TessellationEvaluationSource(tese.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1436 std::ostringstream geometry;
1437 geometry << "#version 450\n"
1438 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1439 << "layout(${TOPOLOGY}) in;\n"
1440 << "layout(points, max_vertices = 1) out;\n"
1441 << "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
1443 << " uint result[];\n"
1445 << "layout(set = 0, binding = 7, std430) buffer Buffer2\n"
1447 << " uint numSubgroupsExecuted;\n"
1450 << "void main (void)\n"
1452 << " if (subgroupElect())\n"
1454 << " result[gl_PrimitiveIDIn] = " << ELECTED_VALUE << ";\n"
1455 << " atomicAdd(numSubgroupsExecuted, 1);\n"
1459 << " result[gl_PrimitiveIDIn] = " << UNELECTED_VALUE << ";\n"
1461 << " gl_Position = gl_in[0].gl_Position;\n"
1462 << " EmitVertex();\n"
1463 << " EndPrimitive();\n"
1465 subgroups::addGeometryShadersFromTemplate(geometry.str(), vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u),
1466 programCollection.glslSources);
1470 std::ostringstream fragment;
1471 fragment << "#version 450\n"
1472 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1473 << "layout(location = 0) out uint data;\n"
1474 << "layout(set = 0, binding = 8, std430) buffer Buffer\n"
1476 << " uint numSubgroupsExecuted;\n"
1478 << "void main (void)\n"
1480 << " if (gl_HelperInvocation) return;\n"
1481 << " if (subgroupElect())\n"
1483 << " data = " << ELECTED_VALUE << ";\n"
1484 << " atomicAdd(numSubgroupsExecuted, 1);\n"
1488 << " data = " << UNELECTED_VALUE << ";\n"
1491 programCollection.glslSources.add("fragment")
1492 << glu::FragmentSource(fragment.str())<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1494 subgroups::addNoSubgroupShader(programCollection);
1499 std::ostringstream bdy;
1501 switch (caseDef.opType)
1504 DE_FATAL("Unhandled op type!");
1506 case OPTYPE_SUBGROUP_BARRIER:
1507 case OPTYPE_SUBGROUP_MEMORY_BARRIER:
1508 case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
1509 bdy << " if (subgroupElect())\n"
1511 << " tempBuffer[id] = value;\n"
1513 << " " << getOpTypeName(caseDef.opType) << "();\n"
1514 << " tempResult = tempBuffer[id];\n";
1516 case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
1517 bdy << " if (subgroupElect())\n"
1519 << " tempShared[localId] = value;\n"
1521 << " subgroupMemoryBarrierShared();\n"
1522 << " tempResult = tempShared[localId];\n";
1524 case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
1525 bdy << " if (subgroupElect())\n"
1527 << " imageStore(tempImage, ivec2(id, 0), ivec4(value));\n"
1529 << " subgroupMemoryBarrierImage();\n"
1530 << " tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n";
1534 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1536 std::ostringstream src;
1538 src << "#version 450\n"
1539 << "#extension GL_KHR_shader_subgroup_basic: enable\n"
1540 << "layout (local_size_x_id = 0, local_size_y_id = 1, "
1541 "local_size_z_id = 2) in;\n"
1542 << "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1544 << " uint result[];\n"
1546 << "layout(set = 0, binding = 1, std430) buffer Buffer2\n"
1548 << " uint tempBuffer[];\n"
1550 << "layout(set = 0, binding = 2, std430) buffer Buffer3\n"
1554 << "layout(set = 0, binding = 3, r32ui) uniform uimage2D tempImage;\n"
1555 << "shared uint tempShared[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];\n"
1557 << "void main (void)\n"
1559 << " uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
1560 << " highp uint offset = globalSize.x * ((globalSize.y * "
1561 "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
1562 "gl_GlobalInvocationID.x;\n"
1563 << " uint localId = gl_SubgroupID;\n"
1564 << " uint id = globalSize.x * ((globalSize.y * "
1565 "gl_WorkGroupID.z) + gl_WorkGroupID.y) + "
1566 "gl_WorkGroupID.x + localId;\n"
1567 << " uint tempResult = 0;\n"
1569 << " result[offset] = tempResult;\n"
1572 programCollection.glslSources.add("comp")
1573 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1578 const string vertex =
1580 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1581 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1582 "layout(set = 0, binding = 0, std430) buffer Buffer1\n"
1586 "layout(set = 0, binding = 4, std430) buffer Buffer2\n"
1588 " uint tempBuffer[];\n"
1590 "layout(set = 0, binding = 5, std430) buffer Buffer3\n"
1592 " uint subgroupID;\n"
1594 "layout(set = 0, binding = 6, std430) buffer Buffer4\n"
1598 "layout(set = 0, binding = 7, r32ui) uniform uimage2D tempImage;\n"
1599 "void main (void)\n"
1602 " if (subgroupElect())\n"
1604 " id = atomicAdd(subgroupID, 1);\n"
1606 " id = subgroupBroadcastFirst(id);\n"
1607 " uint localId = id;\n"
1608 " uint tempResult = 0;\n"
1610 " result[gl_VertexIndex] = tempResult;\n"
1611 " float pixelSize = 2.0f/1024.0f;\n"
1612 " float pixelPosition = pixelSize/2.0f - 1.0f;\n"
1613 " gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1614 " gl_PointSize = 1.0f;\n"
1616 programCollection.glslSources.add("vert")
1617 << glu::VertexSource(vertex) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1623 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1624 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1625 "layout(vertices=1) out;\n"
1626 "layout(set = 0, binding = 1, std430) buffer Buffer1\n"
1630 "layout(set = 0, binding = 8, std430) buffer Buffer2\n"
1632 " uint tempBuffer[];\n"
1634 "layout(set = 0, binding = 9, std430) buffer Buffer3\n"
1636 " uint subgroupID;\n"
1638 "layout(set = 0, binding = 10, std430) buffer Buffer4\n"
1642 "layout(set = 0, binding = 11, r32ui) uniform uimage2D tempImage;\n"
1643 "void main (void)\n"
1646 " if (subgroupElect())\n"
1648 " id = atomicAdd(subgroupID, 1);\n"
1650 " id = subgroupBroadcastFirst(id);\n"
1651 " uint localId = id;\n"
1652 " uint tempResult = 0;\n"
1654 " result[gl_PrimitiveID] = tempResult;\n"
1655 " if (gl_InvocationID == 0)\n"
1657 " gl_TessLevelOuter[0] = 1.0f;\n"
1658 " gl_TessLevelOuter[1] = 1.0f;\n"
1660 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1662 programCollection.glslSources.add("tesc")
1663 << glu::TessellationControlSource(tesc) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1669 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1670 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1671 "layout(isolines) in;\n"
1672 "layout(set = 0, binding = 2, std430) buffer Buffer1\n"
1676 "layout(set = 0, binding = 12, std430) buffer Buffer2\n"
1678 " uint tempBuffer[];\n"
1680 "layout(set = 0, binding = 13, std430) buffer Buffer3\n"
1682 " uint subgroupID;\n"
1684 "layout(set = 0, binding = 14, std430) buffer Buffer4\n"
1688 "layout(set = 0, binding = 15, r32ui) uniform uimage2D tempImage;\n"
1689 "void main (void)\n"
1692 " if (subgroupElect())\n"
1694 " id = atomicAdd(subgroupID, 1);\n"
1696 " id = subgroupBroadcastFirst(id);\n"
1697 " uint localId = id;\n"
1698 " uint tempResult = 0;\n"
1700 " result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = tempResult;\n"
1701 " float pixelSize = 2.0f/1024.0f;\n"" gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1703 programCollection.glslSources.add("tese")
1704 << glu::TessellationEvaluationSource(tese) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1708 const string geometry =
1710 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1711 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1712 "layout(${TOPOLOGY}) in;\n"
1713 "layout(points, max_vertices = 1) out;\n"
1714 "layout(set = 0, binding = 3, std430) buffer Buffer1\n"
1718 "layout(set = 0, binding = 16, std430) buffer Buffer2\n"
1720 " uint tempBuffer[];\n"
1722 "layout(set = 0, binding = 17, std430) buffer Buffer3\n"
1724 " uint subgroupID;\n"
1726 "layout(set = 0, binding = 18, std430) buffer Buffer4\n"
1730 "layout(set = 0, binding = 19, r32ui) uniform uimage2D tempImage;\n"
1731 "void main (void)\n"
1734 " if (subgroupElect())\n"
1736 " id = atomicAdd(subgroupID, 1);\n"
1738 " id = subgroupBroadcastFirst(id);\n"
1739 " uint localId = id;\n"
1740 " uint tempResult = 0;\n"
1742 " result[gl_PrimitiveIDIn] = tempResult;\n"
1743 " gl_Position = gl_in[0].gl_Position;\n"
1745 " EndPrimitive();\n"
1747 subgroups::addGeometryShadersFromTemplate(geometry, vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u),
1748 programCollection.glslSources);
1752 const string fragment =
1754 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1755 "#extension GL_KHR_shader_subgroup_ballot: enable\n"
1756 "layout(location = 0) out uint result;\n"
1757 "layout(set = 0, binding = 20, std430) buffer Buffer1\n"
1759 " uint tempBuffer[];\n"
1761 "layout(set = 0, binding = 21, std430) buffer Buffer2\n"
1763 " uint subgroupID;\n"
1765 "layout(set = 0, binding = 22, std430) buffer Buffer3\n"
1769 "layout(set = 0, binding = 23, r32ui) uniform uimage2D tempImage;\n"
1770 "void main (void)\n"
1772 " if (gl_HelperInvocation) return;\n"
1774 " if (subgroupElect())\n"
1776 " id = atomicAdd(subgroupID, 1);\n"
1778 " id = subgroupBroadcastFirst(id);\n"
1779 " uint localId = id;\n"
1780 " uint tempResult = 0;\n"
1782 " result = tempResult;\n"
1784 programCollection.glslSources.add("fragment")
1785 << glu::FragmentSource(fragment)<< vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
1788 subgroups::addNoSubgroupShader(programCollection);
1793 void supportedCheck (Context& context, CaseDefinition caseDef)
1796 if (!subgroups::isSubgroupSupported(context))
1797 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1800 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
1802 if (!subgroups::areSubgroupOperationsSupportedForStage(
1803 context, caseDef.shaderStage))
1805 if (subgroups::areSubgroupOperationsRequiredForStage(
1806 caseDef.shaderStage))
1808 return tcu::TestStatus::fail(
1810 subgroups::getShaderStageName(caseDef.shaderStage) +
1811 " is required to support subgroup operations!");
1815 TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1819 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BASIC_BIT))
1821 return tcu::TestStatus::fail(
1822 "Subgroup feature " +
1823 subgroups::getSubgroupFeatureName(VK_SUBGROUP_FEATURE_BASIC_BIT) +
1824 " is a required capability!");
1827 if (OPTYPE_ELECT != caseDef.opType && VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1829 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1831 TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1835 const deUint32 inputDatasCount = OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1836 std::vector<subgroups::SSBOData> inputDatas (inputDatasCount);
1838 inputDatas[0].format = VK_FORMAT_R32_UINT;
1839 inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1840 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1842 inputDatas[1].format = VK_FORMAT_R32_UINT;
1843 inputDatas[1].numElements = 1ull;
1844 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1846 if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1848 inputDatas[2].format = VK_FORMAT_R32_UINT;
1849 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1850 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1851 inputDatas[2].isImage = true;
1854 if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1856 if (OPTYPE_ELECT == caseDef.opType)
1857 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1859 return subgroups::makeVertexFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1861 else if (VK_SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1863 return subgroups::makeFragmentFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkFragmentSubgroupBarriersNoSSBO);
1865 else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
1867 if (OPTYPE_ELECT == caseDef.opType)
1868 return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1870 return subgroups::makeGeometryFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1873 if (OPTYPE_ELECT == caseDef.opType)
1874 return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO, caseDef.shaderStage);
1876 return subgroups::makeTessellationEvaluationFrameBufferTest(context, VK_FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount,
1877 (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)? checkVertexPipelineStagesSubgroupBarriersNoSSBO : checkTessellationEvaluationSubgroupBarriersNoSSBO,
1878 caseDef.shaderStage);
1881 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1883 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BASIC_BIT))
1885 return tcu::TestStatus::fail(
1886 "Subgroup feature " +
1887 subgroups::getSubgroupFeatureName(VK_SUBGROUP_FEATURE_BASIC_BIT) +
1888 " is a required capability!");
1891 if (OPTYPE_ELECT != caseDef.opType && VK_SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1893 if (!subgroups::isSubgroupFeatureSupportedForDevice(context, VK_SUBGROUP_FEATURE_BALLOT_BIT))
1895 TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1899 if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1901 if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
1903 return tcu::TestStatus::fail("Shader stage " +
1904 subgroups::getShaderStageName(caseDef.shaderStage) +
1905 " is required to support subgroup operations!");
1908 if (OPTYPE_ELECT == caseDef.opType)
1910 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, DE_NULL, 0, checkComputeSubgroupElect);
1914 const deUint32 inputDatasCount = 3;
1915 subgroups::SSBOData inputDatas[inputDatasCount];
1916 inputDatas[0].format = VK_FORMAT_R32_UINT;
1917 inputDatas[0].numElements = SHADER_BUFFER_SIZE;
1918 inputDatas[0].initializeType = subgroups::SSBOData::InitializeNone;
1920 inputDatas[1].format = VK_FORMAT_R32_UINT;
1921 inputDatas[1].numElements = 1;
1922 inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1924 inputDatas[2].format = VK_FORMAT_R32_UINT;
1925 inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1926 inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1927 inputDatas[2].isImage = true;
1929 return subgroups::makeComputeTest(context, VK_FORMAT_R32_UINT, inputDatas, inputDatasCount, checkComputeSubgroupBarriers);
1934 if (!subgroups::isFragmentSSBOSupportedForDevice(context))
1936 TCU_THROW(NotSupportedError, "Subgroup basic operation require that the fragment stage be able to write to SSBOs!");
1939 VkPhysicalDeviceSubgroupProperties subgroupProperties;
1940 subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
1941 subgroupProperties.pNext = DE_NULL;
1943 VkPhysicalDeviceProperties2 properties;
1944 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1945 properties.pNext = &subgroupProperties;
1947 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
1949 VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage & subgroupProperties.supportedStages);
1951 if ( VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
1953 if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
1954 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1956 stages = VK_SHADER_STAGE_FRAGMENT_BIT;
1959 if ((VkShaderStageFlagBits)0u == stages)
1960 TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
1962 if (OPTYPE_ELECT == caseDef.opType)
1964 const deUint32 inputCount = 5u;
1965 subgroups::SSBOData inputData[inputCount];
1967 inputData[0].format = VK_FORMAT_R32_UINT;
1968 inputData[0].numElements = 1;
1969 inputData[0].initializeType = subgroups::SSBOData::InitializeZero;
1970 inputData[0].binding = 4u;
1971 inputData[0].stages = VK_SHADER_STAGE_VERTEX_BIT;
1973 inputData[1].format = VK_FORMAT_R32_UINT;
1974 inputData[1].numElements = 1;
1975 inputData[1].initializeType = subgroups::SSBOData::InitializeZero;
1976 inputData[1].binding = 5u;
1977 inputData[1].stages = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1979 inputData[2].format = VK_FORMAT_R32_UINT;
1980 inputData[2].numElements = 1;
1981 inputData[2].initializeType = subgroups::SSBOData::InitializeZero;
1982 inputData[2].binding = 6u;
1983 inputData[2].stages = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
1985 inputData[3].format = VK_FORMAT_R32_UINT;
1986 inputData[3].numElements = 1;
1987 inputData[3].initializeType = subgroups::SSBOData::InitializeZero;
1988 inputData[3].binding = 7u;
1989 inputData[3].stages = VK_SHADER_STAGE_GEOMETRY_BIT;
1991 inputData[4].format = VK_FORMAT_R32_UINT;
1992 inputData[4].numElements = 1;
1993 inputData[4].initializeType = subgroups::SSBOData::InitializeZero;
1994 inputData[4].binding = 8u;
1995 inputData[4].stages = VK_SHADER_STAGE_FRAGMENT_BIT;
1997 return subgroups::allStages(context, VK_FORMAT_R32_UINT, inputData, inputCount, checkVertexPipelineStagesSubgroupElect, stages);
2001 const VkShaderStageFlagBits stagesBits[] =
2003 VK_SHADER_STAGE_VERTEX_BIT,
2004 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
2005 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
2006 VK_SHADER_STAGE_GEOMETRY_BIT,
2007 VK_SHADER_STAGE_FRAGMENT_BIT,
2010 const deUint32 inputDatasCount = DE_LENGTH_OF_ARRAY(stagesBits) * 4u;
2011 subgroups::SSBOData inputDatas[inputDatasCount];
2013 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stagesBits); ++ndx)
2015 const deUint32 index = ndx*4;
2016 inputDatas[index].format = VK_FORMAT_R32_UINT;
2017 inputDatas[index].numElements = SHADER_BUFFER_SIZE;
2018 inputDatas[index].initializeType = subgroups::SSBOData::InitializeNonZero;
2019 inputDatas[index].binding = index + 4u;
2020 inputDatas[index].stages = stagesBits[ndx];
2022 inputDatas[index + 1].format = VK_FORMAT_R32_UINT;
2023 inputDatas[index + 1].numElements = 1;
2024 inputDatas[index + 1].initializeType = subgroups::SSBOData::InitializeZero;
2025 inputDatas[index + 1].binding = index + 5u;
2026 inputDatas[index + 1].stages = stagesBits[ndx];
2028 inputDatas[index + 2].format = VK_FORMAT_R32_UINT;
2029 inputDatas[index + 2].numElements = 1;
2030 inputDatas[index + 2].initializeType = subgroups::SSBOData::InitializeNonZero;
2031 inputDatas[index + 2].binding = index + 6u;
2032 inputDatas[index + 2].stages = stagesBits[ndx];
2034 inputDatas[index + 3].format = VK_FORMAT_R32_UINT;
2035 inputDatas[index + 3].numElements = SHADER_BUFFER_SIZE;
2036 inputDatas[index + 3].initializeType = subgroups::SSBOData::InitializeNone;
2037 inputDatas[index + 3].isImage = true;
2038 inputDatas[index + 3].binding = index + 7u;
2039 inputDatas[index + 3].stages = stagesBits[ndx];
2042 return subgroups::allStages(context, VK_FORMAT_R32_UINT, inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers, stages);
2052 tcu::TestCaseGroup* createSubgroupsBasicTests(tcu::TestContext& testCtx)
2054 de::MovePtr<tcu::TestCaseGroup> graphicGroup(new tcu::TestCaseGroup(
2055 testCtx, "graphics", "Subgroup basic category tests: graphics"));
2056 de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(
2057 testCtx, "compute", "Subgroup basic category tests: compute"));
2058 de::MovePtr<tcu::TestCaseGroup> framebufferGroup(new tcu::TestCaseGroup(
2059 testCtx, "framebuffer", "Subgroup basic category tests: framebuffer"));
2062 const VkShaderStageFlags stages[] =
2064 VK_SHADER_STAGE_FRAGMENT_BIT,
2065 VK_SHADER_STAGE_VERTEX_BIT,
2066 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
2067 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
2068 VK_SHADER_STAGE_GEOMETRY_BIT,
2071 for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
2073 const std::string op = de::toLower(getOpTypeName(opTypeIndex));
2076 const CaseDefinition caseDef = {opTypeIndex, VK_SHADER_STAGE_COMPUTE_BIT};
2077 addFunctionCaseWithPrograms(computeGroup.get(), op, "",
2078 supportedCheck, initPrograms, test, caseDef);
2081 if (OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED == opTypeIndex)
2083 // Shared isn't available in non compute shaders.
2088 const CaseDefinition caseDef = {opTypeIndex, VK_SHADER_STAGE_ALL_GRAPHICS};
2089 addFunctionCaseWithPrograms(graphicGroup.get(),
2091 supportedCheck, initPrograms, test, caseDef);
2094 if (OPTYPE_ELECT == opTypeIndex)
2096 for (int stageIndex = 1; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
2098 const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex]};
2099 addFunctionCaseWithPrograms(framebufferGroup.get(),
2100 op + "_" + getShaderStageName(caseDef.shaderStage), "",
2101 supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
2106 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
2108 const CaseDefinition caseDefFrag = {opTypeIndex, stages[stageIndex]};
2109 addFunctionCaseWithPrograms(framebufferGroup.get(),
2110 op + "_" + getShaderStageName(caseDefFrag.shaderStage), "",
2111 supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDefFrag);
2117 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
2118 testCtx, "basic", "Subgroup basic category tests"));
2120 group->addChild(graphicGroup.release());
2121 group->addChild(computeGroup.release());
2122 group->addChild(framebufferGroup.release());
2124 return group.release();