b825a74de7d9464cdf56145a9040c7390027b001
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / subgroups / glcSubgroupsBuiltinVarTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Codeplay Software Ltd.
7  *
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */ /*!
21  * \file
22  * \brief Subgroups Tests
23  */ /*--------------------------------------------------------------------*/
24
25 #include "vktSubgroupsBuiltinVarTests.hpp"
26 #include "vktSubgroupsTestsUtils.hpp"
27
28 #include <string>
29 #include <vector>
30
31 using namespace tcu;
32 using namespace std;
33 using namespace vk;
34
35 namespace vkt
36 {
37 namespace subgroups
38 {
39
40 bool checkVertexPipelineStagesSubgroupSize(std::vector<const void*> datas,
41                 deUint32 width, deUint32 subgroupSize)
42 {
43         const deUint32* data =
44                 reinterpret_cast<const deUint32*>(datas[0]);
45         for (deUint32 x = 0; x < width; ++x)
46         {
47                 deUint32 val = data[x * 4];
48
49                 if (subgroupSize != val)
50                         return false;
51         }
52
53         return true;
54 }
55
56 bool checkVertexPipelineStagesSubgroupInvocationID(std::vector<const void*> datas,
57                 deUint32 width, deUint32 subgroupSize)
58 {
59         const deUint32* data =
60                 reinterpret_cast<const deUint32*>(datas[0]);
61         vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
62
63         for (deUint32 x = 0; x < width; ++x)
64         {
65                 deUint32 subgroupInvocationID = data[(x * 4) + 1];
66
67                 if (subgroupInvocationID >= subgroupSize)
68                         return false;
69                 subgroupInvocationHits[subgroupInvocationID]++;
70         }
71
72         const deUint32 totalSize = width;
73
74         deUint32 totalInvocationsRun = 0;
75         for (deUint32 i = 0; i < subgroupSize; ++i)
76         {
77                 totalInvocationsRun += subgroupInvocationHits[i];
78         }
79
80         if (totalInvocationsRun != totalSize)
81                 return false;
82
83         return true;
84 }
85
86 static bool checkComputeSubgroupSize(std::vector<const void*> datas,
87                                                                          const deUint32 numWorkgroups[3], const deUint32 localSize[3],
88                                                                          deUint32 subgroupSize)
89 {
90         const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
91
92         for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
93         {
94                 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
95                 {
96                         for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
97                         {
98                                 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
99                                 {
100                                         for (deUint32 lY = 0; lY < localSize[1]; ++lY)
101                                         {
102                                                 for (deUint32 lZ = 0; lZ < localSize[2];
103                                                                 ++lZ)
104                                                 {
105                                                         const deUint32 globalInvocationX =
106                                                                 nX * localSize[0] + lX;
107                                                         const deUint32 globalInvocationY =
108                                                                 nY * localSize[1] + lY;
109                                                         const deUint32 globalInvocationZ =
110                                                                 nZ * localSize[2] + lZ;
111
112                                                         const deUint32 globalSizeX =
113                                                                 numWorkgroups[0] * localSize[0];
114                                                         const deUint32 globalSizeY =
115                                                                 numWorkgroups[1] * localSize[1];
116
117                                                         const deUint32 offset =
118                                                                 globalSizeX *
119                                                                 ((globalSizeY *
120                                                                   globalInvocationZ) +
121                                                                  globalInvocationY) +
122                                                                 globalInvocationX;
123
124                                                         if (subgroupSize != data[offset * 4])
125                                                                 return false;
126                                                 }
127                                         }
128                                 }
129                         }
130                 }
131         }
132
133         return true;
134 }
135
136 static bool checkComputeSubgroupInvocationID(std::vector<const void*> datas,
137                 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
138                 deUint32 subgroupSize)
139 {
140         const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
141
142         for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
143         {
144                 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
145                 {
146                         for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
147                         {
148                                 const deUint32 totalLocalSize =
149                                         localSize[0] * localSize[1] * localSize[2];
150                                 vector<deUint32> subgroupInvocationHits(subgroupSize, 0);
151
152                                 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
153                                 {
154                                         for (deUint32 lY = 0; lY < localSize[1]; ++lY)
155                                         {
156                                                 for (deUint32 lZ = 0; lZ < localSize[2];
157                                                                 ++lZ)
158                                                 {
159                                                         const deUint32 globalInvocationX =
160                                                                 nX * localSize[0] + lX;
161                                                         const deUint32 globalInvocationY =
162                                                                 nY * localSize[1] + lY;
163                                                         const deUint32 globalInvocationZ =
164                                                                 nZ * localSize[2] + lZ;
165
166                                                         const deUint32 globalSizeX =
167                                                                 numWorkgroups[0] * localSize[0];
168                                                         const deUint32 globalSizeY =
169                                                                 numWorkgroups[1] * localSize[1];
170
171                                                         const deUint32 offset =
172                                                                 globalSizeX *
173                                                                 ((globalSizeY *
174                                                                   globalInvocationZ) +
175                                                                  globalInvocationY) +
176                                                                 globalInvocationX;
177
178                                                         deUint32 subgroupInvocationID = data[(offset * 4) + 1];
179
180                                                         if (subgroupInvocationID >= subgroupSize)
181                                                                 return false;
182
183                                                         subgroupInvocationHits[subgroupInvocationID]++;
184                                                 }
185                                         }
186                                 }
187
188                                 deUint32 totalInvocationsRun = 0;
189                                 for (deUint32 i = 0; i < subgroupSize; ++i)
190                                 {
191                                         totalInvocationsRun += subgroupInvocationHits[i];
192                                 }
193
194                                 if (totalInvocationsRun != totalLocalSize)
195                                         return false;
196                         }
197                 }
198         }
199
200         return true;
201 }
202
203 static bool checkComputeNumSubgroups    (std::vector<const void*>       datas,
204                                                                                 const deUint32                          numWorkgroups[3],
205                                                                                 const deUint32                          localSize[3],
206                                                                                 deUint32)
207 {
208         const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
209
210         for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
211         {
212                 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
213                 {
214                         for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
215                         {
216                                 const deUint32 totalLocalSize =
217                                         localSize[0] * localSize[1] * localSize[2];
218
219                                 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
220                                 {
221                                         for (deUint32 lY = 0; lY < localSize[1]; ++lY)
222                                         {
223                                                 for (deUint32 lZ = 0; lZ < localSize[2];
224                                                                 ++lZ)
225                                                 {
226                                                         const deUint32 globalInvocationX =
227                                                                 nX * localSize[0] + lX;
228                                                         const deUint32 globalInvocationY =
229                                                                 nY * localSize[1] + lY;
230                                                         const deUint32 globalInvocationZ =
231                                                                 nZ * localSize[2] + lZ;
232
233                                                         const deUint32 globalSizeX =
234                                                                 numWorkgroups[0] * localSize[0];
235                                                         const deUint32 globalSizeY =
236                                                                 numWorkgroups[1] * localSize[1];
237
238                                                         const deUint32 offset =
239                                                                 globalSizeX *
240                                                                 ((globalSizeY *
241                                                                   globalInvocationZ) +
242                                                                  globalInvocationY) +
243                                                                 globalInvocationX;
244
245                                                         deUint32 numSubgroups = data[(offset * 4) + 2];
246
247                                                         if (numSubgroups > totalLocalSize)
248                                                                 return false;
249                                                 }
250                                         }
251                                 }
252                         }
253                 }
254         }
255
256         return true;
257 }
258
259 static bool checkComputeSubgroupID      (std::vector<const void*>       datas,
260                                                                         const deUint32                          numWorkgroups[3],
261                                                                         const deUint32                          localSize[3],
262                                                                         deUint32)
263 {
264         const deUint32* data = reinterpret_cast<const deUint32*>(datas[0]);
265
266         for (deUint32 nX = 0; nX < numWorkgroups[0]; ++nX)
267         {
268                 for (deUint32 nY = 0; nY < numWorkgroups[1]; ++nY)
269                 {
270                         for (deUint32 nZ = 0; nZ < numWorkgroups[2]; ++nZ)
271                         {
272                                 for (deUint32 lX = 0; lX < localSize[0]; ++lX)
273                                 {
274                                         for (deUint32 lY = 0; lY < localSize[1]; ++lY)
275                                         {
276                                                 for (deUint32 lZ = 0; lZ < localSize[2];
277                                                                 ++lZ)
278                                                 {
279                                                         const deUint32 globalInvocationX =
280                                                                 nX * localSize[0] + lX;
281                                                         const deUint32 globalInvocationY =
282                                                                 nY * localSize[1] + lY;
283                                                         const deUint32 globalInvocationZ =
284                                                                 nZ * localSize[2] + lZ;
285
286                                                         const deUint32 globalSizeX =
287                                                                 numWorkgroups[0] * localSize[0];
288                                                         const deUint32 globalSizeY =
289                                                                 numWorkgroups[1] * localSize[1];
290
291                                                         const deUint32 offset =
292                                                                 globalSizeX *
293                                                                 ((globalSizeY *
294                                                                   globalInvocationZ) +
295                                                                  globalInvocationY) +
296                                                                 globalInvocationX;
297
298                                                         deUint32 numSubgroups = data[(offset * 4) + 2];
299                                                         deUint32 subgroupID = data[(offset * 4) + 3];
300
301                                                         if (subgroupID >= numSubgroups)
302                                                                 return false;
303                                                 }
304                                         }
305                                 }
306                         }
307                 }
308         }
309
310         return true;
311 }
312
313 namespace
314 {
315 struct CaseDefinition
316 {
317         std::string varName;
318         VkShaderStageFlags shaderStage;
319 };
320 }
321
322 void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
323 {
324         const vk::ShaderBuildOptions    buildOptions    (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
325         const vk::SpirVAsmBuildOptions  buildOptionsSpr (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3);
326
327         {
328                 /*
329                         "layout(location = 0) in vec4 in_color;\n"
330                         "layout(location = 0) out uvec4 out_color;\n"
331                         "void main()\n"
332                         "{\n"
333                          "      out_color = uvec4(in_color);\n"
334                          "}\n";
335                 */
336                 const string fragment =
337                         "; SPIR-V\n"
338                         "; Version: 1.3\n"
339                         "; Generator: Khronos Glslang Reference Front End; 2\n"
340                         "; Bound: 16\n"
341                         "; Schema: 0\n"
342                         "OpCapability Shader\n"
343                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
344                         "OpMemoryModel Logical GLSL450\n"
345                         "OpEntryPoint Fragment %4 \"main\" %9 %13\n"
346                         "OpExecutionMode %4 OriginUpperLeft\n"
347                         "OpDecorate %9 Location 0\n"
348                         "OpDecorate %13 Location 0\n"
349                         "%2 = OpTypeVoid\n"
350                         "%3 = OpTypeFunction %2\n"
351                         "%6 = OpTypeInt 32 0\n"
352                         "%7 = OpTypeVector %6 4\n"
353                         "%8 = OpTypePointer Output %7\n"
354                         "%9 = OpVariable %8 Output\n"
355                         "%10 = OpTypeFloat 32\n"
356                         "%11 = OpTypeVector %10 4\n"
357                         "%12 = OpTypePointer Input %11\n"
358                         "%13 = OpVariable %12 Input\n"
359                         "%4 = OpFunction %2 None %3\n"
360                         "%5 = OpLabel\n"
361                         "%14 = OpLoad %11 %13\n"
362                         "%15 = OpConvertFToU %7 %14\n"
363                         "OpStore %9 %15\n"
364                         "OpReturn\n"
365                         "OpFunctionEnd\n";
366                 programCollection.spirvAsmSources.add("fragment") << fragment << buildOptionsSpr;
367         }
368
369         if (VK_SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
370                 subgroups::setVertexShaderFrameBuffer(programCollection);
371
372         if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
373         {
374                 /*
375                         "#extension GL_KHR_shader_subgroup_basic: enable\n"
376                         "layout(location = 0) out vec4 out_color;\n"
377                         "layout(location = 0) in highp vec4 in_position;\n"
378                         "\n"
379                         "void main (void)\n"
380                         "{\n"
381                         "  out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 1.0f, 1.0f);\n"
382                         "  gl_Position = in_position;\n"
383                         "  gl_PointSize = 1.0f;\n"
384                         "}\n";
385                 */
386                 const string vertex =
387                         "; SPIR-V\n"
388                         "; Version: 1.3\n"
389                         "; Generator: Khronos Glslang Reference Front End; 2\n"
390                         "; Bound: 31\n"
391                         "; Schema: 0\n"
392                         "OpCapability Shader\n"
393                         "OpCapability GroupNonUniform\n"
394                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
395                         "OpMemoryModel Logical GLSL450\n"
396                         "OpEntryPoint Vertex %4 \"main\" %9 %12 %15 %24 %28\n"
397                         "OpDecorate %9 Location 0\n"
398                         "OpDecorate %12 RelaxedPrecision\n"
399                         "OpDecorate %12 BuiltIn SubgroupSize\n"
400                         "OpDecorate %13 RelaxedPrecision\n"
401                         "OpDecorate %15 RelaxedPrecision\n"
402                         "OpDecorate %15 BuiltIn SubgroupLocalInvocationId\n"
403                         "OpDecorate %16 RelaxedPrecision\n"
404                         "OpMemberDecorate %22 0 BuiltIn Position\n"
405                         "OpMemberDecorate %22 1 BuiltIn PointSize\n"
406                         "OpMemberDecorate %22 2 BuiltIn ClipDistance\n"
407                         "OpMemberDecorate %22 3 BuiltIn CullDistance\n"
408                         "OpDecorate %22 Block\n"
409                         "OpDecorate %28 Location 0\n"
410                         "%2 = OpTypeVoid\n"
411                         "%3 = OpTypeFunction %2\n"
412                         "%6 = OpTypeFloat 32\n"
413                         "%7 = OpTypeVector %6 4\n"
414                         "%8 = OpTypePointer Output %7\n"
415                         "%9 = OpVariable %8 Output\n"
416                         "%10 = OpTypeInt 32 0\n"
417                         "%11 = OpTypePointer Input %10\n"
418                         "%12 = OpVariable %11 Input\n"
419                         "%15 = OpVariable %11 Input\n"
420                         "%18 = OpConstant %6 1\n"
421                         "%20 = OpConstant %10 1\n"
422                         "%21 = OpTypeArray %6 %20\n"
423                         "%22 = OpTypeStruct %7 %6 %21 %21\n"
424                         "%23 = OpTypePointer Output %22\n"
425                         "%24 = OpVariable %23 Output\n"
426                         "%25 = OpTypeInt 32 1\n"
427                         "%26 = OpConstant %25 0\n"
428                         "%27 = OpTypePointer Input %7\n"
429                         "%28 = OpVariable %27 Input\n"
430                         "%31 = OpConstant %25 1\n"
431                         "%32 = OpTypePointer Output %6\n"
432                         "%4 = OpFunction %2 None %3\n"
433                         "%5 = OpLabel\n"
434                         "%13 = OpLoad %10 %12\n"
435                         "%14 = OpConvertUToF %6 %13\n"
436                         "%16 = OpLoad %10 %15\n"
437                         "%17 = OpConvertUToF %6 %16\n"
438                         "%19 = OpCompositeConstruct %7 %14 %17 %18 %18\n"
439                         "OpStore %9 %19\n"
440                         "%29 = OpLoad %7 %28\n"
441                         "%30 = OpAccessChain %8 %24 %26\n"
442                         "OpStore %30 %29\n"
443                         "%33 = OpAccessChain %32 %24 %31\n"
444                         "OpStore %33 %18\n"
445                         "OpReturn\n"
446                         "OpFunctionEnd\n";
447                 programCollection.spirvAsmSources.add("vert") << vertex << buildOptionsSpr;
448         }
449         else if (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT == caseDef.shaderStage)
450         {
451                 /*
452                         "#extension GL_EXT_tessellation_shader : require\n"
453                         "layout(vertices = 2) out;\n"
454                         "layout(location = 0) out vec4 out_color[];\n"
455                         "void main (void)\n"
456                         "{\n"
457                         "  if (gl_InvocationID == 0)\n"
458                           {\n"
459                         "    gl_TessLevelOuter[0] = 1.0f;\n"
460                         "    gl_TessLevelOuter[1] = 1.0f;\n"
461                         "  }\n"
462                         "  out_color[gl_InvocationID] = vec4(0.0f);\n"
463                         "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
464                         "}\n";
465                 */
466                 const string controlSource =
467                         "; SPIR-V\n"
468                         "; Version: 1.3\n"
469                         "; Generator: Khronos Glslang Reference Front End; 2\n"
470                         "; Bound: 53\n"
471                         "; Schema: 0\n"
472                         "OpCapability Tessellation\n"
473                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
474                         "OpMemoryModel Logical GLSL450\n"
475                         "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %30 %41 %47\n"
476                         "OpExecutionMode %4 OutputVertices 2\n"
477                         "OpDecorate %8 BuiltIn InvocationId\n"
478                         "OpDecorate %20 Patch\n"
479                         "OpDecorate %20 BuiltIn TessLevelOuter\n"
480                         "OpDecorate %30 Location 0\n"
481                         "OpMemberDecorate %38 0 BuiltIn Position\n"
482                         "OpMemberDecorate %38 1 BuiltIn PointSize\n"
483                         "OpMemberDecorate %38 2 BuiltIn ClipDistance\n"
484                         "OpMemberDecorate %38 3 BuiltIn CullDistance\n"
485                         "OpDecorate %38 Block\n"
486                         "OpMemberDecorate %43 0 BuiltIn Position\n"
487                         "OpMemberDecorate %43 1 BuiltIn PointSize\n"
488                         "OpMemberDecorate %43 2 BuiltIn ClipDistance\n"
489                         "OpMemberDecorate %43 3 BuiltIn CullDistance\n"
490                         "OpDecorate %43 Block\n"
491                         "%2 = OpTypeVoid\n"
492                         "%3 = OpTypeFunction %2\n"
493                         "%6 = OpTypeInt 32 1\n"
494                         "%7 = OpTypePointer Input %6\n"
495                         "%8 = OpVariable %7 Input\n"
496                         "%10 = OpConstant %6 0\n"
497                         "%11 = OpTypeBool\n"
498                         "%15 = OpTypeFloat 32\n"
499                         "%16 = OpTypeInt 32 0\n"
500                         "%17 = OpConstant %16 4\n"
501                         "%18 = OpTypeArray %15 %17\n"
502                         "%19 = OpTypePointer Output %18\n"
503                         "%20 = OpVariable %19 Output\n"
504                         "%21 = OpConstant %15 1\n"
505                         "%22 = OpTypePointer Output %15\n"
506                         "%24 = OpConstant %6 1\n"
507                         "%26 = OpTypeVector %15 4\n"
508                         "%27 = OpConstant %16 2\n"
509                         "%28 = OpTypeArray %26 %27\n"
510                         "%29 = OpTypePointer Output %28\n"
511                         "%30 = OpVariable %29 Output\n"
512                         "%32 = OpConstant %15 0\n"
513                         "%33 = OpConstantComposite %26 %32 %32 %32 %32\n"
514                         "%34 = OpTypePointer Output %26\n"
515                         "%36 = OpConstant %16 1\n"
516                         "%37 = OpTypeArray %15 %36\n"
517                         "%38 = OpTypeStruct %26 %15 %37 %37\n"
518                         "%39 = OpTypeArray %38 %27\n"
519                         "%40 = OpTypePointer Output %39\n"
520                         "%41 = OpVariable %40 Output\n"
521                         "%43 = OpTypeStruct %26 %15 %37 %37\n"
522                         "%44 = OpConstant %16 32\n"
523                         "%45 = OpTypeArray %43 %44\n"
524                         "%46 = OpTypePointer Input %45\n"
525                         "%47 = OpVariable %46 Input\n"
526                         "%49 = OpTypePointer Input %26\n"
527                         "%4 = OpFunction %2 None %3\n"
528                         "%5 = OpLabel\n"
529                         "%9 = OpLoad %6 %8\n"
530                         "%12 = OpIEqual %11 %9 %10\n"
531                         "OpSelectionMerge %14 None\n"
532                         "OpBranchConditional %12 %13 %14\n"
533                         "%13 = OpLabel\n"
534                         "%23 = OpAccessChain %22 %20 %10\n"
535                         "OpStore %23 %21\n"
536                         "%25 = OpAccessChain %22 %20 %24\n"
537                         "OpStore %25 %21\n"
538                         "OpBranch %14\n"
539                         "%14 = OpLabel\n"
540                         "%31 = OpLoad %6 %8\n"
541                         "%35 = OpAccessChain %34 %30 %31\n"
542                         "OpStore %35 %33\n"
543                         "%42 = OpLoad %6 %8\n"
544                         "%48 = OpLoad %6 %8\n"
545                         "%50 = OpAccessChain %49 %47 %48 %10\n"
546                         "%51 = OpLoad %26 %50\n"
547                         "%52 = OpAccessChain %34 %41 %42 %10\n"
548                         "OpStore %52 %51\n"
549                         "OpReturn\n"
550                         "OpFunctionEnd\n";
551                 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
552
553                 /*
554                         "#extension GL_KHR_shader_subgroup_basic: enable\n"
555                         "#extension GL_EXT_tessellation_shader : require\n"
556                         "layout(isolines, equal_spacing, ccw ) in;\n"
557                         "layout(location = 0) in vec4 in_color[];\n"
558                         "layout(location = 0) out vec4 out_color;\n"
559                         "\n"
560                         "void main (void)\n"
561                         "{\n"
562                         "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
563                         "  out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0.0f, 0.0f);\n"
564                         "}\n";
565                 */
566                 const string evaluationSource =
567                         "; SPIR-V\n"
568                         "; Version: 1.3\n"
569                         "; Generator: Khronos Glslang Reference Front End; 2\n"
570                         "; Bound: 51\n"
571                         "; Schema: 0\n"
572                         "OpCapability Tessellation\n"
573                         "OpCapability GroupNonUniform\n"
574                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
575                         "OpMemoryModel Logical GLSL450\n"
576                         "OpEntryPoint TessellationEvaluation %4 \"main\" %13 %20 %29 %38 %40 %43 %50\n"
577                         "OpExecutionMode %4 Isolines\n"
578                         "OpExecutionMode %4 SpacingEqual\n"
579                         "OpExecutionMode %4 VertexOrderCcw\n"
580                         "OpMemberDecorate %11 0 BuiltIn Position\n"
581                         "OpMemberDecorate %11 1 BuiltIn PointSize\n"
582                         "OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
583                         "OpMemberDecorate %11 3 BuiltIn CullDistance\n"
584                         "OpDecorate %11 Block\n"
585                         "OpMemberDecorate %16 0 BuiltIn Position\n"
586                         "OpMemberDecorate %16 1 BuiltIn PointSize\n"
587                         "OpMemberDecorate %16 2 BuiltIn ClipDistance\n"
588                         "OpMemberDecorate %16 3 BuiltIn CullDistance\n"
589                         "OpDecorate %16 Block\n"
590                         "OpDecorate %29 BuiltIn TessCoord\n"
591                         "OpDecorate %38 Location 0\n"
592                         "OpDecorate %40 RelaxedPrecision\n"
593                         "OpDecorate %40 BuiltIn SubgroupSize\n"
594                         "OpDecorate %41 RelaxedPrecision\n"
595                         "OpDecorate %43 RelaxedPrecision\n"
596                         "OpDecorate %43 BuiltIn SubgroupLocalInvocationId\n"
597                         "OpDecorate %44 RelaxedPrecision\n"
598                         "OpDecorate %50 Location 0\n"
599                         "%2 = OpTypeVoid\n"
600                         "%3 = OpTypeFunction %2\n"
601                         "%6 = OpTypeFloat 32\n"
602                         "%7 = OpTypeVector %6 4\n"
603                         "%8 = OpTypeInt 32 0\n"
604                         "%9 = OpConstant %8 1\n"
605                         "%10 = OpTypeArray %6 %9\n"
606                         "%11 = OpTypeStruct %7 %6 %10 %10\n"
607                         "%12 = OpTypePointer Output %11\n"
608                         "%13 = OpVariable %12 Output\n"
609                         "%14 = OpTypeInt 32 1\n"
610                         "%15 = OpConstant %14 0\n"
611                         "%16 = OpTypeStruct %7 %6 %10 %10\n"
612                         "%17 = OpConstant %8 32\n"
613                         "%18 = OpTypeArray %16 %17\n"
614                         "%19 = OpTypePointer Input %18\n"
615                         "%20 = OpVariable %19 Input\n"
616                         "%21 = OpTypePointer Input %7\n"
617                         "%24 = OpConstant %14 1\n"
618                         "%27 = OpTypeVector %6 3\n"
619                         "%28 = OpTypePointer Input %27\n"
620                         "%29 = OpVariable %28 Input\n"
621                         "%30 = OpConstant %8 0\n"
622                         "%31 = OpTypePointer Input %6\n"
623                         "%36 = OpTypePointer Output %7\n"
624                         "%38 = OpVariable %36 Output\n"
625                         "%39 = OpTypePointer Input %8\n"
626                         "%40 = OpVariable %39 Input\n"
627                         "%43 = OpVariable %39 Input\n"
628                         "%46 = OpConstant %6 0\n"
629                         "%48 = OpTypeArray %7 %17\n"
630                         "%49 = OpTypePointer Input %48\n"
631                         "%50 = OpVariable %49 Input\n"
632                         "%4 = OpFunction %2 None %3\n"
633                         "%5 = OpLabel\n"
634                         "%22 = OpAccessChain %21 %20 %15 %15\n"
635                         "%23 = OpLoad %7 %22\n"
636                         "%25 = OpAccessChain %21 %20 %24 %15\n"
637                         "%26 = OpLoad %7 %25\n"
638                         "%32 = OpAccessChain %31 %29 %30\n"
639                         "%33 = OpLoad %6 %32\n"
640                         "%34 = OpCompositeConstruct %7 %33 %33 %33 %33\n"
641                         "%35 = OpExtInst %7 %1 FMix %23 %26 %34\n"
642                         "%37 = OpAccessChain %36 %13 %15\n"
643                         "OpStore %37 %35\n"
644                         "%41 = OpLoad %8 %40\n"
645                         "%42 = OpConvertUToF %6 %41\n"
646                         "%44 = OpLoad %8 %43\n"
647                         "%45 = OpConvertUToF %6 %44\n"
648                         "%47 = OpCompositeConstruct %7 %42 %45 %46 %46\n"
649                         "OpStore %38 %47\n"
650                         "OpReturn\n"
651                         "OpFunctionEnd\n";
652
653                 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
654         }
655         else if (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT == caseDef.shaderStage)
656         {
657                 /*
658                         "#extension GL_EXT_tessellation_shader : require\n"
659                         "#extension GL_KHR_shader_subgroup_basic: enable\n"
660                         "layout(vertices = 2) out;\n"
661                         "layout(location = 0) out vec4 out_color[];\n"
662                         "void main (void)\n"
663                         "{\n"
664                         "  if (gl_InvocationID == 0)\n"
665                           {\n"
666                         "    gl_TessLevelOuter[0] = 1.0f;\n"
667                         "    gl_TessLevelOuter[1] = 1.0f;\n"
668                         "  }\n"
669                         "  out_color[gl_InvocationID] = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
670                         "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
671                         "}\n";
672                 */
673                 const string controlSource =
674                         "; SPIR-V\n"
675                         "; Version: 1.3\n"
676                         "; Generator: Khronos Glslang Reference Front End; 2\n"
677                         "; Bound: 60\n"
678                         "; Schema: 0\n"
679                         "OpCapability Tessellation\n"
680                         "OpCapability GroupNonUniform\n"
681                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
682                         "OpMemoryModel Logical GLSL450\n"
683                         "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %30 %33 %36 %48 %54\n"
684                         "OpExecutionMode %4 OutputVertices 2\n"
685                         "OpDecorate %8 BuiltIn InvocationId\n"
686                         "OpDecorate %20 Patch\n"
687                         "OpDecorate %20 BuiltIn TessLevelOuter\n"
688                         "OpDecorate %30 Location 0\n"
689                         "OpDecorate %33 RelaxedPrecision\n"
690                         "OpDecorate %33 BuiltIn SubgroupSize\n"
691                         "OpDecorate %34 RelaxedPrecision\n"
692                         "OpDecorate %36 RelaxedPrecision\n"
693                         "OpDecorate %36 BuiltIn SubgroupLocalInvocationId\n"
694                         "OpDecorate %37 RelaxedPrecision\n"
695                         "OpMemberDecorate %45 0 BuiltIn Position\n"
696                         "OpMemberDecorate %45 1 BuiltIn PointSize\n"
697                         "OpMemberDecorate %45 2 BuiltIn ClipDistance\n"
698                         "OpMemberDecorate %45 3 BuiltIn CullDistance\n"
699                         "OpDecorate %45 Block\n"
700                         "OpMemberDecorate %50 0 BuiltIn Position\n"
701                         "OpMemberDecorate %50 1 BuiltIn PointSize\n"
702                         "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
703                         "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
704                         "OpDecorate %50 Block\n"
705                         "%2 = OpTypeVoid\n"
706                         "%3 = OpTypeFunction %2\n"
707                         "%6 = OpTypeInt 32 1\n"
708                         "%7 = OpTypePointer Input %6\n"
709                         "%8 = OpVariable %7 Input\n"
710                         "%10 = OpConstant %6 0\n"
711                         "%11 = OpTypeBool\n"
712                         "%15 = OpTypeFloat 32\n"
713                         "%16 = OpTypeInt 32 0\n"
714                         "%17 = OpConstant %16 4\n"
715                         "%18 = OpTypeArray %15 %17\n"
716                         "%19 = OpTypePointer Output %18\n"
717                         "%20 = OpVariable %19 Output\n"
718                         "%21 = OpConstant %15 1\n"
719                         "%22 = OpTypePointer Output %15\n"
720                         "%24 = OpConstant %6 1\n"
721                         "%26 = OpTypeVector %15 4\n"
722                         "%27 = OpConstant %16 2\n"
723                         "%28 = OpTypeArray %26 %27\n"
724                         "%29 = OpTypePointer Output %28\n"
725                         "%30 = OpVariable %29 Output\n"
726                         "%32 = OpTypePointer Input %16\n"
727                         "%33 = OpVariable %32 Input\n"
728                         "%36 = OpVariable %32 Input\n"
729                         "%39 = OpConstant %15 0\n"
730                         "%41 = OpTypePointer Output %26\n"
731                         "%43 = OpConstant %16 1\n"
732                         "%44 = OpTypeArray %15 %43\n"
733                         "%45 = OpTypeStruct %26 %15 %44 %44\n"
734                         "%46 = OpTypeArray %45 %27\n"
735                         "%47 = OpTypePointer Output %46\n"
736                         "%48 = OpVariable %47 Output\n"
737                         "%50 = OpTypeStruct %26 %15 %44 %44\n"
738                         "%51 = OpConstant %16 32\n"
739                         "%52 = OpTypeArray %50 %51\n"
740                         "%53 = OpTypePointer Input %52\n"
741                         "%54 = OpVariable %53 Input\n"
742                         "%56 = OpTypePointer Input %26\n"
743                         "%4 = OpFunction %2 None %3\n"
744                         "%5 = OpLabel\n"
745                         "%9 = OpLoad %6 %8\n"
746                         "%12 = OpIEqual %11 %9 %10\n"
747                         "OpSelectionMerge %14 None\n"
748                         "OpBranchConditional %12 %13 %14\n"
749                         "%13 = OpLabel\n"
750                         "%23 = OpAccessChain %22 %20 %10\n"
751                         "OpStore %23 %21\n"
752                         "%25 = OpAccessChain %22 %20 %24\n"
753                         "OpStore %25 %21\n"
754                         "OpBranch %14\n"
755                         "%14 = OpLabel\n"
756                         "%31 = OpLoad %6 %8\n"
757                         "%34 = OpLoad %16 %33\n"
758                         "%35 = OpConvertUToF %15 %34\n"
759                         "%37 = OpLoad %16 %36\n"
760                         "%38 = OpConvertUToF %15 %37\n"
761                         "%40 = OpCompositeConstruct %26 %35 %38 %39 %39\n"
762                         "%42 = OpAccessChain %41 %30 %31\n"
763                         "OpStore %42 %40\n"
764                         "%49 = OpLoad %6 %8\n"
765                         "%55 = OpLoad %6 %8\n"
766                         "%57 = OpAccessChain %56 %54 %55 %10\n"
767                         "%58 = OpLoad %26 %57\n"
768                         "%59 = OpAccessChain %41 %48 %49 %10\n"
769                         "OpStore %59 %58\n"
770                         "OpReturn\n"
771                         "OpFunctionEnd\n";
772                 programCollection.spirvAsmSources.add("tesc") << controlSource << buildOptionsSpr;
773
774                 /*
775                         "#extension GL_KHR_shader_subgroup_basic: enable\n"
776                         "#extension GL_EXT_tessellation_shader : require\n"
777                         "layout(isolines, equal_spacing, ccw ) in;\n"
778                         "layout(location = 0) in vec4 in_color[];\n"
779                         "layout(location = 0) out vec4 out_color;\n"
780                         "\n"
781                         "void main (void)\n"
782                         "{\n"
783                         "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
784                         "  out_color = in_color[0];\n"
785                         "}\n";
786                 */
787                 const string  evaluationSource =
788                         "; SPIR-V\n"
789                         "; Version: 1.3\n"
790                         "; Generator: Khronos Glslang Reference Front End; 2\n"
791                         "; Bound: 44\n"
792                         "; Schema: 0\n"
793                         "OpCapability Tessellation\n"
794                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
795                         "OpMemoryModel Logical GLSL450\n"
796                         "OpEntryPoint TessellationEvaluation %4 \"main\" %13 %20 %29 %38 %41\n"
797                         "OpExecutionMode %4 Isolines\n"
798                         "OpExecutionMode %4 SpacingEqual\n"
799                         "OpExecutionMode %4 VertexOrderCcw\n"
800                         "OpMemberDecorate %11 0 BuiltIn Position\n"
801                         "OpMemberDecorate %11 1 BuiltIn PointSize\n"
802                         "OpMemberDecorate %11 2 BuiltIn ClipDistance\n"
803                         "OpMemberDecorate %11 3 BuiltIn CullDistance\n"
804                         "OpDecorate %11 Block\n"
805                         "OpMemberDecorate %16 0 BuiltIn Position\n"
806                         "OpMemberDecorate %16 1 BuiltIn PointSize\n"
807                         "OpMemberDecorate %16 2 BuiltIn ClipDistance\n"
808                         "OpMemberDecorate %16 3 BuiltIn CullDistance\n"
809                         "OpDecorate %16 Block\n"
810                         "OpDecorate %29 BuiltIn TessCoord\n"
811                         "OpDecorate %38 Location 0\n"
812                         "OpDecorate %41 Location 0\n"
813                         "%2 = OpTypeVoid\n"
814                         "%3 = OpTypeFunction %2\n"
815                         "%6 = OpTypeFloat 32\n"
816                         "%7 = OpTypeVector %6 4\n"
817                         "%8 = OpTypeInt 32 0\n"
818                         "%9 = OpConstant %8 1\n"
819                         "%10 = OpTypeArray %6 %9\n"
820                         "%11 = OpTypeStruct %7 %6 %10 %10\n"
821                         "%12 = OpTypePointer Output %11\n"
822                         "%13 = OpVariable %12 Output\n"
823                         "%14 = OpTypeInt 32 1\n"
824                         "%15 = OpConstant %14 0\n"
825                         "%16 = OpTypeStruct %7 %6 %10 %10\n"
826                         "%17 = OpConstant %8 32\n"
827                         "%18 = OpTypeArray %16 %17\n"
828                         "%19 = OpTypePointer Input %18\n"
829                         "%20 = OpVariable %19 Input\n"
830                         "%21 = OpTypePointer Input %7\n"
831                         "%24 = OpConstant %14 1\n"
832                         "%27 = OpTypeVector %6 3\n"
833                         "%28 = OpTypePointer Input %27\n"
834                         "%29 = OpVariable %28 Input\n"
835                         "%30 = OpConstant %8 0\n"
836                         "%31 = OpTypePointer Input %6\n"
837                         "%36 = OpTypePointer Output %7\n"
838                         "%38 = OpVariable %36 Output\n"
839                         "%39 = OpTypeArray %7 %17\n"
840                         "%40 = OpTypePointer Input %39\n"
841                         "%41 = OpVariable %40 Input\n"
842                         "%4 = OpFunction %2 None %3\n"
843                         "%5 = OpLabel\n"
844                         "%22 = OpAccessChain %21 %20 %15 %15\n"
845                         "%23 = OpLoad %7 %22\n"
846                         "%25 = OpAccessChain %21 %20 %24 %15\n"
847                         "%26 = OpLoad %7 %25\n"
848                         "%32 = OpAccessChain %31 %29 %30\n"
849                         "%33 = OpLoad %6 %32\n"
850                         "%34 = OpCompositeConstruct %7 %33 %33 %33 %33\n"
851                         "%35 = OpExtInst %7 %1 FMix %23 %26 %34\n"
852                         "%37 = OpAccessChain %36 %13 %15\n"
853                         "OpStore %37 %35\n"
854                         "%42 = OpAccessChain %21 %41 %15\n"
855                         "%43 = OpLoad %7 %42\n"
856                         "OpStore %38 %43\n"
857                         "OpReturn\n"
858                         "OpFunctionEnd\n";
859                 programCollection.spirvAsmSources.add("tese") << evaluationSource << buildOptionsSpr;
860         }
861         else if (VK_SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
862         {
863                 /*
864                         "#version 450\n"
865                         "#extension GL_KHR_shader_subgroup_basic: enable\n"
866                         "layout(points) in;\n"
867                         "layout(points, max_vertices = 1) out;\n"
868                         "layout(location = 0) out vec4 out_color;\n"
869                         "void main (void)\n"
870                         "{\n"
871                         "  out_color = vec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
872                         "  gl_Position = gl_in[0].gl_Position;\n"
873                         "  EmitVertex();\n"
874                         "  EndPrimitive();\n"
875                         "}\n";
876                 */
877                 const string geometry =
878                         "; SPIR-V\n"
879                         "; Version: 1.3\n"
880                         "; Generator: Khronos Glslang Reference Front End; 2\n"
881                         "; Bound: 35\n"
882                         "; Schema: 0\n"
883                         "OpCapability Geometry\n"
884                         "OpCapability GroupNonUniform\n"
885                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
886                         "OpMemoryModel Logical GLSL450\n"
887                         "OpEntryPoint Geometry %4 \"main\" %9 %12 %15 %24 %30\n"
888                         "OpExecutionMode %4 InputPoints\n"
889                         "OpExecutionMode %4 Invocations 1\n"
890                         "OpExecutionMode %4 OutputPoints\n"
891                         "OpExecutionMode %4 OutputVertices 1\n"
892                         "OpDecorate %9 Location 0\n"
893                         "OpDecorate %12 RelaxedPrecision\n"
894                         "OpDecorate %12 BuiltIn SubgroupSize\n"
895                         "OpDecorate %13 RelaxedPrecision\n"
896                         "OpDecorate %15 RelaxedPrecision\n"
897                         "OpDecorate %15 BuiltIn SubgroupLocalInvocationId\n"
898                         "OpDecorate %16 RelaxedPrecision\n"
899                         "OpMemberDecorate %22 0 BuiltIn Position\n"
900                         "OpMemberDecorate %22 1 BuiltIn PointSize\n"
901                         "OpMemberDecorate %22 2 BuiltIn ClipDistance\n"
902                         "OpMemberDecorate %22 3 BuiltIn CullDistance\n"
903                         "OpDecorate %22 Block\n"
904                         "OpMemberDecorate %27 0 BuiltIn Position\n"
905                         "OpMemberDecorate %27 1 BuiltIn PointSize\n"
906                         "OpMemberDecorate %27 2 BuiltIn ClipDistance\n"
907                         "OpMemberDecorate %27 3 BuiltIn CullDistance\n"
908                         "OpDecorate %27 Block\n"
909                         "%2 = OpTypeVoid\n"
910                         "%3 = OpTypeFunction %2\n"
911                         "%6 = OpTypeFloat 32\n"
912                         "%7 = OpTypeVector %6 4\n"
913                         "%8 = OpTypePointer Output %7\n"
914                         "%9 = OpVariable %8 Output\n"
915                         "%10 = OpTypeInt 32 0\n"
916                         "%11 = OpTypePointer Input %10\n"
917                         "%12 = OpVariable %11 Input\n"
918                         "%15 = OpVariable %11 Input\n"
919                         "%18 = OpConstant %6 0\n"
920                         "%20 = OpConstant %10 1\n"
921                         "%21 = OpTypeArray %6 %20\n"
922                         "%22 = OpTypeStruct %7 %6 %21 %21\n"
923                         "%23 = OpTypePointer Output %22\n"
924                         "%24 = OpVariable %23 Output\n"
925                         "%25 = OpTypeInt 32 1\n"
926                         "%26 = OpConstant %25 0\n"
927                         "%27 = OpTypeStruct %7 %6 %21 %21\n"
928                         "%28 = OpTypeArray %27 %20\n"
929                         "%29 = OpTypePointer Input %28\n"
930                         "%30 = OpVariable %29 Input\n"
931                         "%31 = OpTypePointer Input %7\n"
932                         "%4 = OpFunction %2 None %3\n"
933                         "%5 = OpLabel\n"
934                         "%13 = OpLoad %10 %12\n"
935                         "%14 = OpConvertUToF %6 %13\n"
936                         "%16 = OpLoad %10 %15\n"
937                         "%17 = OpConvertUToF %6 %16\n"
938                         "%19 = OpCompositeConstruct %7 %14 %17 %18 %18\n"
939                         "OpStore %9 %19\n"
940                         "%32 = OpAccessChain %31 %30 %26 %26\n"
941                         "%33 = OpLoad %7 %32\n"
942                         "%34 = OpAccessChain %8 %24 %26\n"
943                         "OpStore %34 %33\n"
944                         "OpEmitVertex\n"
945                         "OpEndPrimitive\n"
946                         "OpReturn\n"
947                         "OpFunctionEnd\n";
948                 programCollection.spirvAsmSources.add("geometry") << geometry << buildOptionsSpr;
949         }
950         else
951         {
952                 DE_FATAL("Unsupported shader stage");
953         }
954 }
955
956 void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
957 {
958         if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
959         {
960                 std::ostringstream src;
961
962                 src << "#version 450\n"
963                         << "#extension GL_KHR_shader_subgroup_basic: enable\n"
964                         << "layout (local_size_x_id = 0, local_size_y_id = 1, "
965                         "local_size_z_id = 2) in;\n"
966                         << "layout(set = 0, binding = 0, std430) buffer Output\n"
967                         << "{\n"
968                         << "  uvec4 result[];\n"
969                         << "};\n"
970                         << "\n"
971                         << "void main (void)\n"
972                         << "{\n"
973                         << "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
974                         << "  highp uint offset = globalSize.x * ((globalSize.y * "
975                         "gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
976                         "gl_GlobalInvocationID.x;\n"
977                         << "  result[offset] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, gl_NumSubgroups, gl_SubgroupID);\n"
978                         << "}\n";
979
980                 programCollection.glslSources.add("comp")
981                                 << glu::ComputeSource(src.str()) << vk::ShaderBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
982         }
983         else
984         {
985                 {
986                         /*
987                                 "#version 450\n"
988                                 "#extension GL_KHR_shader_subgroup_basic: enable\n"
989                                 "layout(set = 0, binding = 0, std430) buffer Output\n"
990                                 "{\n"
991                                 "  uvec4 result[];\n"
992                                 "};\n"
993                                 "\n"
994                                 "void main (void)\n"
995                                 "{\n"
996                                 "  result[gl_VertexIndex] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
997                                 "  float pixelSize = 2.0f/1024.0f;\n"
998                                 "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
999                                 "  gl_Position = vec4(float(gl_VertexIndex) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1000                                 "  gl_PointSize = 1.0f;\n"
1001                                 "}\n";
1002                         */
1003                         const string vertex =
1004                                 "; SPIR-V\n"
1005                                 "; Version: 1.3\n"
1006                                 "; Generator: Khronos Glslang Reference Front End; 1\n"
1007                                 "; Bound: 52\n"
1008                                 "; Schema: 0\n"
1009                                 "OpCapability Shader\n"
1010                                 "OpCapability GroupNonUniform\n"
1011                                 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1012                                 "OpMemoryModel Logical GLSL450\n"
1013                                 "OpEntryPoint Vertex %4 \"main\" %15 %18 %20 %41\n"
1014                                 "OpDecorate %8 ArrayStride 16\n"
1015                                 "OpMemberDecorate %9 0 Offset 0\n"
1016                                 "OpDecorate %9 BufferBlock\n"
1017                                 "OpDecorate %11 DescriptorSet 0\n"
1018                                 "OpDecorate %11 Binding 0\n"
1019                                 "OpDecorate %15 BuiltIn VertexIndex\n"
1020                                 "OpDecorate %18 RelaxedPrecision\n"
1021                                 "OpDecorate %18 BuiltIn SubgroupSize\n"
1022                                 "OpDecorate %19 RelaxedPrecision\n"
1023                                 "OpDecorate %20 RelaxedPrecision\n"
1024                                 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1025                                 "OpDecorate %21 RelaxedPrecision\n"
1026                                 "OpMemberDecorate %39 0 BuiltIn Position\n"
1027                                 "OpMemberDecorate %39 1 BuiltIn PointSize\n"
1028                                 "OpMemberDecorate %39 2 BuiltIn ClipDistance\n"
1029                                 "OpMemberDecorate %39 3 BuiltIn CullDistance\n"
1030                                 "OpDecorate %39 Block\n"
1031                                 "%2 = OpTypeVoid\n"
1032                                 "%3 = OpTypeFunction %2\n"
1033                                 "%6 = OpTypeInt 32 0\n"
1034                                 "%7 = OpTypeVector %6 4\n"
1035                                 "%8 = OpTypeRuntimeArray %7\n"
1036                                 "%9 = OpTypeStruct %8\n"
1037                                 "%10 = OpTypePointer Uniform %9\n"
1038                                 "%11 = OpVariable %10 Uniform\n"
1039                                 "%12 = OpTypeInt 32 1\n"
1040                                 "%13 = OpConstant %12 0\n"
1041                                 "%14 = OpTypePointer Input %12\n"
1042                                 "%15 = OpVariable %14 Input\n"
1043                                 "%17 = OpTypePointer Input %6\n"
1044                                 "%18 = OpVariable %17 Input\n"
1045                                 "%20 = OpVariable %17 Input\n"
1046                                 "%22 = OpConstant %6 0\n"
1047                                 "%24 = OpTypePointer Uniform %7\n"
1048                                 "%26 = OpTypeFloat 32\n"
1049                                 "%27 = OpTypePointer Function %26\n"
1050                                 "%29 = OpConstant %26 0.00195313\n"
1051                                 "%32 = OpConstant %26 2\n"
1052                                 "%34 = OpConstant %26 1\n"
1053                                 "%36 = OpTypeVector %26 4\n"
1054                                 "%37 = OpConstant %6 1\n"
1055                                 "%38 = OpTypeArray %26 %37\n"
1056                                 "%39 = OpTypeStruct %36 %26 %38 %38\n"
1057                                 "%40 = OpTypePointer Output %39\n"
1058                                 "%41 = OpVariable %40 Output\n"
1059                                 "%48 = OpConstant %26 0\n"
1060                                 "%50 = OpTypePointer Output %36\n"
1061                                 "%52 = OpConstant %12 1\n"
1062                                 "%53 = OpTypePointer Output %26\n"
1063                                 "%4 = OpFunction %2 None %3\n"
1064                                 "%5 = OpLabel\n"
1065                                 "%28 = OpVariable %27 Function\n"
1066                                 "%30 = OpVariable %27 Function\n"
1067                                 "%16 = OpLoad %12 %15\n"
1068                                 "%19 = OpLoad %6 %18\n"
1069                                 "%21 = OpLoad %6 %20\n"
1070                                 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1071                                 "%25 = OpAccessChain %24 %11 %13 %16\n"
1072                                 "OpStore %25 %23\n"
1073                                 "OpStore %28 %29\n"
1074                                 "%31 = OpLoad %26 %28\n"
1075                                 "%33 = OpFDiv %26 %31 %32\n"
1076                                 "%35 = OpFSub %26 %33 %34\n"
1077                                 "OpStore %30 %35\n"
1078                                 "%42 = OpLoad %12 %15\n"
1079                                 "%43 = OpConvertSToF %26 %42\n"
1080                                 "%44 = OpLoad %26 %28\n"
1081                                 "%45 = OpFMul %26 %43 %44\n"
1082                                 "%46 = OpLoad %26 %30\n"
1083                                 "%47 = OpFAdd %26 %45 %46\n"
1084                                 "%49 = OpCompositeConstruct %36 %47 %48 %48 %34\n"
1085                                 "%51 = OpAccessChain %50 %41 %13\n"
1086                                 "OpStore %51 %49\n"
1087                                 "%54 = OpAccessChain %53 %41 %52\n"
1088                                 "OpStore %54 %34\n"
1089                                 "OpReturn\n"
1090                                 "OpFunctionEnd\n";
1091                                 programCollection.spirvAsmSources.add("vert") << vertex << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1092                 }
1093
1094                 {
1095                         /*
1096                                 "#version 450\n"
1097                                 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1098                                 "layout(vertices=1) out;\n"
1099                                 "layout(set = 0, binding = 1, std430) buffer Output\n"
1100                                 "{\n"
1101                                 "  uvec4 result[];\n"
1102                                 "};\n"
1103                                 "\n"
1104                                 "void main (void)\n"
1105                                 "{\n"
1106                                 "  result[gl_PrimitiveID] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1107                                 "  if (gl_InvocationID == 0)\n"
1108                                 "  {\n"
1109                                 "    gl_TessLevelOuter[0] = 1.0f;\n"
1110                                 "    gl_TessLevelOuter[1] = 1.0f;\n"
1111                                 "  }\n"
1112                                 "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1113                                 "}\n";
1114                         */
1115                         const string tesc =
1116                                 "; SPIR-V\n"
1117                                 "; Version: 1.3\n"
1118                                 "; Generator: Khronos Glslang Reference Front End; 1\n"
1119                                 "; Bound: 61\n"
1120                                 "; Schema: 0\n"
1121                                 "OpCapability Tessellation\n"
1122                                 "OpCapability GroupNonUniform\n"
1123                                 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1124                                 "OpMemoryModel Logical GLSL450\n"
1125                                 "OpEntryPoint TessellationControl %4 \"main\" %15 %18 %20 %26 %36 %48 %54\n"
1126                                 "OpExecutionMode %4 OutputVertices 1\n"
1127                                 "OpDecorate %8 ArrayStride 16\n"
1128                                 "OpMemberDecorate %9 0 Offset 0\n"
1129                                 "OpDecorate %9 BufferBlock\n"
1130                                 "OpDecorate %11 DescriptorSet 0\n"
1131                                 "OpDecorate %11 Binding 1\n"
1132                                 "OpDecorate %15 BuiltIn PrimitiveId\n"
1133                                 "OpDecorate %18 RelaxedPrecision\n"
1134                                 "OpDecorate %18 BuiltIn SubgroupSize\n"
1135                                 "OpDecorate %19 RelaxedPrecision\n"
1136                                 "OpDecorate %20 RelaxedPrecision\n"
1137                                 "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1138                                 "OpDecorate %21 RelaxedPrecision\n"
1139                                 "OpDecorate %26 BuiltIn InvocationId\n"
1140                                 "OpDecorate %36 Patch\n"
1141                                 "OpDecorate %36 BuiltIn TessLevelOuter\n"
1142                                 "OpMemberDecorate %45 0 BuiltIn Position\n"
1143                                 "OpMemberDecorate %45 1 BuiltIn PointSize\n"
1144                                 "OpMemberDecorate %45 2 BuiltIn ClipDistance\n"
1145                                 "OpMemberDecorate %45 3 BuiltIn CullDistance\n"
1146                                 "OpDecorate %45 Block\n"
1147                                 "OpMemberDecorate %50 0 BuiltIn Position\n"
1148                                 "OpMemberDecorate %50 1 BuiltIn PointSize\n"
1149                                 "OpMemberDecorate %50 2 BuiltIn ClipDistance\n"
1150                                 "OpMemberDecorate %50 3 BuiltIn CullDistance\n"
1151                                 "OpDecorate %50 Block\n"
1152                                 "%2 = OpTypeVoid\n"
1153                                 "%3 = OpTypeFunction %2\n"
1154                                 "%6 = OpTypeInt 32 0\n"
1155                                 "%7 = OpTypeVector %6 4\n"
1156                                 "%8 = OpTypeRuntimeArray %7\n"
1157                                 "%9 = OpTypeStruct %8\n"
1158                                 "%10 = OpTypePointer Uniform %9\n"
1159                                 "%11 = OpVariable %10 Uniform\n"
1160                                 "%12 = OpTypeInt 32 1\n"
1161                                 "%13 = OpConstant %12 0\n"
1162                                 "%14 = OpTypePointer Input %12\n"
1163                                 "%15 = OpVariable %14 Input\n"
1164                                 "%17 = OpTypePointer Input %6\n"
1165                                 "%18 = OpVariable %17 Input\n"
1166                                 "%20 = OpVariable %17 Input\n"
1167                                 "%22 = OpConstant %6 0\n"
1168                                 "%24 = OpTypePointer Uniform %7\n"
1169                                 "%26 = OpVariable %14 Input\n"
1170                                 "%28 = OpTypeBool\n"
1171                                 "%32 = OpTypeFloat 32\n"
1172                                 "%33 = OpConstant %6 4\n"
1173                                 "%34 = OpTypeArray %32 %33\n"
1174                                 "%35 = OpTypePointer Output %34\n"
1175                                 "%36 = OpVariable %35 Output\n"
1176                                 "%37 = OpConstant %32 1\n"
1177                                 "%38 = OpTypePointer Output %32\n"
1178                                 "%40 = OpConstant %12 1\n"
1179                                 "%42 = OpTypeVector %32 4\n"
1180                                 "%43 = OpConstant %6 1\n"
1181                                 "%44 = OpTypeArray %32 %43\n"
1182                                 "%45 = OpTypeStruct %42 %32 %44 %44\n"
1183                                 "%46 = OpTypeArray %45 %43\n"
1184                                 "%47 = OpTypePointer Output %46\n"
1185                                 "%48 = OpVariable %47 Output\n"
1186                                 "%50 = OpTypeStruct %42 %32 %44 %44\n"
1187                                 "%51 = OpConstant %6 32\n"
1188                                 "%52 = OpTypeArray %50 %51\n"
1189                                 "%53 = OpTypePointer Input %52\n"
1190                                 "%54 = OpVariable %53 Input\n"
1191                                 "%56 = OpTypePointer Input %42\n"
1192                                 "%59 = OpTypePointer Output %42\n"
1193                                 "%4 = OpFunction %2 None %3\n"
1194                                 "%5 = OpLabel\n"
1195                                 "%16 = OpLoad %12 %15\n"
1196                                 "%19 = OpLoad %6 %18\n"
1197                                 "%21 = OpLoad %6 %20\n"
1198                                 "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1199                                 "%25 = OpAccessChain %24 %11 %13 %16\n"
1200                                 "OpStore %25 %23\n"
1201                                 "%27 = OpLoad %12 %26\n"
1202                                 "%29 = OpIEqual %28 %27 %13\n"
1203                                 "OpSelectionMerge %31 None\n"
1204                                 "OpBranchConditional %29 %30 %31\n"
1205                                 "%30 = OpLabel\n"
1206                                 "%39 = OpAccessChain %38 %36 %13\n"
1207                                 "OpStore %39 %37\n"
1208                                 "%41 = OpAccessChain %38 %36 %40\n"
1209                                 "OpStore %41 %37\n"
1210                                 "OpBranch %31\n"
1211                                 "%31 = OpLabel\n"
1212                                 "%49 = OpLoad %12 %26\n"
1213                                 "%55 = OpLoad %12 %26\n"
1214                                 "%57 = OpAccessChain %56 %54 %55 %13\n"
1215                                 "%58 = OpLoad %42 %57\n"
1216                                 "%60 = OpAccessChain %59 %48 %49 %13\n"
1217                                 "OpStore %60 %58\n"
1218                                 "OpReturn\n"
1219                                 "OpFunctionEnd\n";
1220                                 programCollection.spirvAsmSources.add("tesc") << tesc << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1221                 }
1222
1223                 {
1224                         /*
1225                                 "#version 450\n"
1226                                 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1227                                 "layout(isolines) in;\n"
1228                                 "layout(set = 0, binding = 2, std430) buffer Output\n"
1229                                 "{\n"
1230                                 "  uvec4 result[];\n"
1231                                 "};\n"
1232                                 "\n"
1233                                 "void main (void)\n"
1234                                 "{\n"
1235                                 "  result[gl_PrimitiveID * 2 + uint(gl_TessCoord.x + 0.5)] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1236                                 "  float pixelSize = 2.0f/1024.0f;\n"
1237                                 "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1238                                 "}\n";
1239                         */
1240                         const string tese =
1241                                 "; SPIR - V\n"
1242                                 "; Version: 1.3\n"
1243                                 "; Generator: Khronos Glslang Reference Front End; 2\n"
1244                                 "; Bound: 67\n"
1245                                 "; Schema: 0\n"
1246                                 "OpCapability Tessellation\n"
1247                                 "OpCapability GroupNonUniform\n"
1248                                 "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1249                                 "OpMemoryModel Logical GLSL450\n"
1250                                 "OpEntryPoint TessellationEvaluation %4 \"main\" %15 %23 %33 %35 %48 %53\n"
1251                                 "OpExecutionMode %4 Isolines\n"
1252                                 "OpExecutionMode %4 SpacingEqual\n"
1253                                 "OpExecutionMode %4 VertexOrderCcw\n"
1254                                 "OpDecorate %8 ArrayStride 16\n"
1255                                 "OpMemberDecorate %9 0 Offset 0\n"
1256                                 "OpDecorate %9 BufferBlock\n"
1257                                 "OpDecorate %11 DescriptorSet 0\n"
1258                                 "OpDecorate %11 Binding 2\n"
1259                                 "OpDecorate %15 BuiltIn PrimitiveId\n"
1260                                 "OpDecorate %23 BuiltIn TessCoord\n"
1261                                 "OpDecorate %33 RelaxedPrecision\n"
1262                                 "OpDecorate %33 BuiltIn SubgroupSize\n"
1263                                 "OpDecorate %34 RelaxedPrecision\n"
1264                                 "OpDecorate %35 RelaxedPrecision\n"
1265                                 "OpDecorate %35 BuiltIn SubgroupLocalInvocationId\n"
1266                                 "OpDecorate %36 RelaxedPrecision\n"
1267                                 "OpMemberDecorate %46 0 BuiltIn Position\n"
1268                                 "OpMemberDecorate %46 1 BuiltIn PointSize\n"
1269                                 "OpMemberDecorate %46 2 BuiltIn ClipDistance\n"
1270                                 "OpMemberDecorate %46 3 BuiltIn CullDistance\n"
1271                                 "OpDecorate %46 Block\n"
1272                                 "OpMemberDecorate %49 0 BuiltIn Position\n"
1273                                 "OpMemberDecorate %49 1 BuiltIn PointSize\n"
1274                                 "OpMemberDecorate %49 2 BuiltIn ClipDistance\n"
1275                                 "OpMemberDecorate %49 3 BuiltIn CullDistance\n"
1276                                 "OpDecorate %49 Block\n"
1277                                 "%2 = OpTypeVoid\n"
1278                                 "%3 = OpTypeFunction %2\n"
1279                                 "%6 = OpTypeInt 32 0\n"
1280                                 "%7 = OpTypeVector %6 4\n"
1281                                 "%8 = OpTypeRuntimeArray %7\n"
1282                                 "%9 = OpTypeStruct %8\n"
1283                                 "%10 = OpTypePointer Uniform %9\n"
1284                                 "%11 = OpVariable %10 Uniform\n"
1285                                 "%12 = OpTypeInt 32 1\n"
1286                                 "%13 = OpConstant %12 0\n"
1287                                 "%14 = OpTypePointer Input %12\n"
1288                                 "%15 = OpVariable %14 Input\n"
1289                                 "%17 = OpConstant %12 2\n"
1290                                 "%20 = OpTypeFloat 32\n"
1291                                 "%21 = OpTypeVector %20 3\n"
1292                                 "%22 = OpTypePointer Input %21\n"
1293                                 "%23 = OpVariable %22 Input\n"
1294                                 "%24 = OpConstant %6 0\n"
1295                                 "%25 = OpTypePointer Input %20\n"
1296                                 "%28 = OpConstant %20 0.5\n"
1297                                 "%32 = OpTypePointer Input %6\n"
1298                                 "%33 = OpVariable %32 Input\n"
1299                                 "%35 = OpVariable %32 Input\n"
1300                                 "%38 = OpTypePointer Uniform %7\n"
1301                                 "%40 = OpTypePointer Function %20\n"
1302                                 "%42 = OpConstant %20 0.00195313\n"
1303                                 "%43 = OpTypeVector %20 4\n"
1304                                 "%44 = OpConstant %6 1\n"
1305                                 "%45 = OpTypeArray %20 %44\n"
1306                                 "%46 = OpTypeStruct %43 %20 %45 %45\n"
1307                                 "%47 = OpTypePointer Output %46\n"
1308                                 "%48 = OpVariable %47 Output\n"
1309                                 "%49 = OpTypeStruct %43 %20 %45 %45\n"
1310                                 "%50 = OpConstant %6 32\n"
1311                                 "%51 = OpTypeArray %49 %50\n"
1312                                 "%52 = OpTypePointer Input %51\n"
1313                                 "%53 = OpVariable %52 Input\n"
1314                                 "%54 = OpTypePointer Input %43\n"
1315                                 "%61 = OpConstant %20 2\n"
1316                                 "%65 = OpTypePointer Output %43\n"
1317                                 "%4 = OpFunction %2 None %3\n"
1318                                 "%5 = OpLabel\n"
1319                                 "%41 = OpVariable %40 Function\n"
1320                                 "%16 = OpLoad %12 %15\n"
1321                                 "%18 = OpIMul %12 %16 %17\n"
1322                                 "%19 = OpBitcast %6 %18\n"
1323                                 "%26 = OpAccessChain %25 %23 %24\n"
1324                                 "%27 = OpLoad %20 %26\n"
1325                                 "%29 = OpFAdd %20 %27 %28\n"
1326                                 "%30 = OpConvertFToU %6 %29\n"
1327                                 "%31 = OpIAdd %6 %19 %30\n"
1328                                 "%34 = OpLoad %6 %33\n"
1329                                 "%36 = OpLoad %6 %35\n"
1330                                 "%37 = OpCompositeConstruct %7 %34 %36 %24 %24\n"
1331                                 "%39 = OpAccessChain %38 %11 %13 %31\n"
1332                                 "OpStore %39 %37\n"
1333                                 "OpStore %41 %42\n"
1334                                 "%55 = OpAccessChain %54 %53 %13 %13\n"
1335                                 "%56 = OpLoad %43 %55\n"
1336                                 "%57 = OpAccessChain %25 %23 %24\n"
1337                                 "%58 = OpLoad %20 %57\n"
1338                                 "%59 = OpLoad %20 %41\n"
1339                                 "%60 = OpFMul %20 %58 %59\n"
1340                                 "%62 = OpFDiv %20 %60 %61\n"
1341                                 "%63 = OpCompositeConstruct %43 %62 %62 %62 %62\n"
1342                                 "%64 = OpFAdd %43 %56 %63\n"
1343                                 "%66 = OpAccessChain %65 %48 %13\n"
1344                                 "OpStore %66 %64\n"
1345                                 "OpReturn\n"
1346                                 "OpFunctionEnd\n";
1347                                 programCollection.spirvAsmSources.add("tese") << tese << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1348                 }
1349
1350                 {
1351                         /*
1352                                 "#version 450\n"
1353                                 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1354                                 "// Note: ${TOPOLOGY} variable is substituted manually at SPIR-V ASM level"
1355                                 "layout(${TOPOLOGY}) in;\n"
1356                                 "layout(points, max_vertices = 1) out;\n"
1357                                 "layout(set = 0, binding = 3, std430) buffer Output\n"
1358                                 "{\n"
1359                                 "  uvec4 result[];\n"
1360                                 "};\n"
1361                                 "\n"
1362                                 "void main (void)\n"
1363                                 "{\n"
1364                                 "  result[gl_PrimitiveIDIn] = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1365                                 "  gl_Position = gl_in[0].gl_Position;\n"
1366                                 "  EmitVertex();\n"
1367                                 "  EndPrimitive();\n"
1368                                 "}\n";
1369                         */
1370                         const string geometry =
1371                         "; SPIR-V\n"
1372                         "; Version: 1.3\n"
1373                         "; Generator: Khronos Glslang Reference Front End; 1\n"
1374                         "; Bound: 42\n"
1375                         "; Schema: 0\n"
1376                         "OpCapability Geometry\n"
1377                         "OpCapability GroupNonUniform\n"
1378                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1379                         "OpMemoryModel Logical GLSL450\n"
1380                         "OpEntryPoint Geometry %4 \"main\" %15 %18 %20 %32 %36\n"
1381                         "OpExecutionMode %4 ${TOPOLOGY}\n"
1382                         "OpExecutionMode %4 Invocations 1\n"
1383                         "OpExecutionMode %4 OutputPoints\n"
1384                         "OpExecutionMode %4 OutputVertices 1\n"
1385                         "OpDecorate %8 ArrayStride 16\n"
1386                         "OpMemberDecorate %9 0 Offset 0\n"
1387                         "OpDecorate %9 BufferBlock\n"
1388                         "OpDecorate %11 DescriptorSet 0\n"
1389                         "OpDecorate %11 Binding 3\n"
1390                         "OpDecorate %15 BuiltIn PrimitiveId\n"
1391                         "OpDecorate %18 RelaxedPrecision\n"
1392                         "OpDecorate %18 BuiltIn SubgroupSize\n"
1393                         "OpDecorate %19 RelaxedPrecision\n"
1394                         "OpDecorate %20 RelaxedPrecision\n"
1395                         "OpDecorate %20 BuiltIn SubgroupLocalInvocationId\n"
1396                         "OpDecorate %21 RelaxedPrecision\n"
1397                         "OpMemberDecorate %30 0 BuiltIn Position\n"
1398                         "OpMemberDecorate %30 1 BuiltIn PointSize\n"
1399                         "OpMemberDecorate %30 2 BuiltIn ClipDistance\n"
1400                         "OpMemberDecorate %30 3 BuiltIn CullDistance\n"
1401                         "OpDecorate %30 Block\n"
1402                         "OpMemberDecorate %33 0 BuiltIn Position\n"
1403                         "OpMemberDecorate %33 1 BuiltIn PointSize\n"
1404                         "OpMemberDecorate %33 2 BuiltIn ClipDistance\n"
1405                         "OpMemberDecorate %33 3 BuiltIn CullDistance\n"
1406                         "OpDecorate %33 Block\n"
1407                         "%2 = OpTypeVoid\n"
1408                         "%3 = OpTypeFunction %2\n"
1409                         "%6 = OpTypeInt 32 0\n"
1410                         "%7 = OpTypeVector %6 4\n"
1411                         "%8 = OpTypeRuntimeArray %7\n"
1412                         "%9 = OpTypeStruct %8\n"
1413                         "%10 = OpTypePointer Uniform %9\n"
1414                         "%11 = OpVariable %10 Uniform\n"
1415                         "%12 = OpTypeInt 32 1\n"
1416                         "%13 = OpConstant %12 0\n"
1417                         "%14 = OpTypePointer Input %12\n"
1418                         "%15 = OpVariable %14 Input\n"
1419                         "%17 = OpTypePointer Input %6\n"
1420                         "%18 = OpVariable %17 Input\n"
1421                         "%20 = OpVariable %17 Input\n"
1422                         "%22 = OpConstant %6 0\n"
1423                         "%24 = OpTypePointer Uniform %7\n"
1424                         "%26 = OpTypeFloat 32\n"
1425                         "%27 = OpTypeVector %26 4\n"
1426                         "%28 = OpConstant %6 1\n"
1427                         "%29 = OpTypeArray %26 %28\n"
1428                         "%30 = OpTypeStruct %27 %26 %29 %29\n"
1429                         "%31 = OpTypePointer Output %30\n"
1430                         "%32 = OpVariable %31 Output\n"
1431                         "%33 = OpTypeStruct %27 %26 %29 %29\n"
1432                         "%34 = OpTypeArray %33 %28\n"
1433                         "%35 = OpTypePointer Input %34\n"
1434                         "%36 = OpVariable %35 Input\n"
1435                         "%37 = OpTypePointer Input %27\n"
1436                         "%40 = OpTypePointer Output %27\n"
1437                         "%4 = OpFunction %2 None %3\n"
1438                         "%5 = OpLabel\n"
1439                         "%16 = OpLoad %12 %15\n"
1440                         "%19 = OpLoad %6 %18\n"
1441                         "%21 = OpLoad %6 %20\n"
1442                         "%23 = OpCompositeConstruct %7 %19 %21 %22 %22\n"
1443                         "%25 = OpAccessChain %24 %11 %13 %16\n"
1444                         "OpStore %25 %23\n"
1445                         "%38 = OpAccessChain %37 %36 %13 %13\n"
1446                         "%39 = OpLoad %27 %38\n"
1447                         "%41 = OpAccessChain %40 %32 %13\n"
1448                         "OpStore %41 %39\n"
1449                         "OpEmitVertex\n"
1450                         "OpEndPrimitive\n"
1451                         "OpReturn\n"
1452                         "OpFunctionEnd\n";
1453                         addGeometryShadersFromTemplate(geometry, SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3), programCollection.spirvAsmSources);
1454                 }
1455
1456                 {
1457                         /*
1458                                 "#version 450\n"
1459                                 "#extension GL_KHR_shader_subgroup_basic: enable\n"
1460                                 "layout(location = 0) out uvec4 data;\n"
1461                                 "void main (void)\n"
1462                                 "{\n"
1463                                 "  data = uvec4(gl_SubgroupSize, gl_SubgroupInvocationID, 0, 0);\n"
1464                                 "}\n";
1465                         */
1466                         const string fragment =
1467                         "; SPIR-V\n"
1468                         "; Version: 1.3\n"
1469                         "; Generator: Khronos Glslang Reference Front End; 1\n"
1470                         "; Bound: 17\n"
1471                         "; Schema: 0\n"
1472                         "OpCapability Shader\n"
1473                         "OpCapability GroupNonUniform\n"
1474                         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1475                         "OpMemoryModel Logical GLSL450\n"
1476                         "OpEntryPoint Fragment %4 \"main\" %9 %11 %13\n"
1477                         "OpExecutionMode %4 OriginUpperLeft\n"
1478                         "OpDecorate %9 Location 0\n"
1479                         "OpDecorate %11 RelaxedPrecision\n"
1480                         "OpDecorate %11 Flat\n"
1481                         "OpDecorate %11 BuiltIn SubgroupSize\n"
1482                         "OpDecorate %12 RelaxedPrecision\n"
1483                         "OpDecorate %13 RelaxedPrecision\n"
1484                         "OpDecorate %13 Flat\n"
1485                         "OpDecorate %13 BuiltIn SubgroupLocalInvocationId\n"
1486                         "OpDecorate %14 RelaxedPrecision\n"
1487                         "%2 = OpTypeVoid\n"
1488                         "%3 = OpTypeFunction %2\n"
1489                         "%6 = OpTypeInt 32 0\n"
1490                         "%7 = OpTypeVector %6 4\n"
1491                         "%8 = OpTypePointer Output %7\n"
1492                         "%9 = OpVariable %8 Output\n"
1493                         "%10 = OpTypePointer Input %6\n"
1494                         "%11 = OpVariable %10 Input\n"
1495                         "%13 = OpVariable %10 Input\n"
1496                         "%15 = OpConstant %6 0\n"
1497                         "%4 = OpFunction %2 None %3\n"
1498                         "%5 = OpLabel\n"
1499                         "%12 = OpLoad %6 %11\n"
1500                         "%14 = OpLoad %6 %13\n"
1501                         "%16 = OpCompositeConstruct %7 %12 %14 %15 %15\n"
1502                         "OpStore %9 %16\n"
1503                         "OpReturn\n"
1504                         "OpFunctionEnd\n";
1505
1506                         programCollection.spirvAsmSources.add("fragment") << fragment << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3);
1507                 }
1508
1509                 subgroups::addNoSubgroupShader(programCollection);
1510         }
1511 }
1512
1513 void supportedCheck (Context& context, CaseDefinition caseDef)
1514 {
1515         DE_UNREF(caseDef);
1516         if (!subgroups::isSubgroupSupported(context))
1517                 TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1518 }
1519
1520 tcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
1521 {
1522         if (!areSubgroupOperationsSupportedForStage(
1523                                 context, caseDef.shaderStage))
1524         {
1525                 if (areSubgroupOperationsRequiredForStage(caseDef.shaderStage))
1526                 {
1527                         return tcu::TestStatus::fail(
1528                                            "Shader stage " + getShaderStageName(caseDef.shaderStage) +
1529                                            " is required to support subgroup operations!");
1530                 }
1531                 else
1532                 {
1533                         TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1534                 }
1535         }
1536
1537         if (VK_SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1538         {
1539                 if ("gl_SubgroupSize" == caseDef.varName)
1540                 {
1541                         return makeVertexFrameBufferTest(
1542                                            context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1543                 }
1544                 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1545                 {
1546                         return makeVertexFrameBufferTest(
1547                                            context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1548                 }
1549                 else
1550                 {
1551                         return tcu::TestStatus::fail(
1552                                            caseDef.varName + " failed (unhandled error checking case " +
1553                                            caseDef.varName + ")!");
1554                 }
1555         }
1556         else if ((VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) & caseDef.shaderStage )
1557         {
1558                 if ("gl_SubgroupSize" == caseDef.varName)
1559                 {
1560                         return makeTessellationEvaluationFrameBufferTest(
1561                                         context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1562                 }
1563                 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1564                 {
1565                         return makeTessellationEvaluationFrameBufferTest(
1566                                         context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1567                 }
1568                 else
1569                 {
1570                         return tcu::TestStatus::fail(
1571                                         caseDef.varName + " failed (unhandled error checking case " +
1572                                         caseDef.varName + ")!");
1573                 }
1574         }
1575         else if (VK_SHADER_STAGE_GEOMETRY_BIT & caseDef.shaderStage )
1576         {
1577                 if ("gl_SubgroupSize" == caseDef.varName)
1578                 {
1579                         return makeGeometryFrameBufferTest(
1580                                         context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize);
1581                 }
1582                 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1583                 {
1584                         return makeGeometryFrameBufferTest(
1585                                         context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID);
1586                 }
1587                 else
1588                 {
1589                         return tcu::TestStatus::fail(
1590                                         caseDef.varName + " failed (unhandled error checking case " +
1591                                         caseDef.varName + ")!");
1592                 }
1593         }
1594         else
1595         {
1596                 TCU_THROW(InternalError, "Unhandled shader stage");
1597         }
1598 }
1599
1600
1601 tcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1602 {
1603         if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1604         {
1605                 if (!areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
1606                 {
1607                         return tcu::TestStatus::fail(
1608                                            "Shader stage " + getShaderStageName(caseDef.shaderStage) +
1609                                            " is required to support subgroup operations!");
1610                 }
1611
1612                 if ("gl_SubgroupSize" == caseDef.varName)
1613                 {
1614                         return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupSize);
1615                 }
1616                 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1617                 {
1618                         return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupInvocationID);
1619                 }
1620                 else if ("gl_NumSubgroups" == caseDef.varName)
1621                 {
1622                         return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeNumSubgroups);
1623                 }
1624                 else if ("gl_SubgroupID" == caseDef.varName)
1625                 {
1626                         return makeComputeTest(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkComputeSubgroupID);
1627                 }
1628                 else
1629                 {
1630                         return tcu::TestStatus::fail(
1631                                         caseDef.varName + " failed (unhandled error checking case " +
1632                                         caseDef.varName + ")!");
1633                 }
1634         }
1635         else
1636         {
1637                 VkPhysicalDeviceSubgroupProperties subgroupProperties;
1638                 subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
1639                 subgroupProperties.pNext = DE_NULL;
1640
1641                 VkPhysicalDeviceProperties2 properties;
1642                 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1643                 properties.pNext = &subgroupProperties;
1644
1645                 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
1646
1647                 VkShaderStageFlagBits stages = (VkShaderStageFlagBits)(caseDef.shaderStage  & subgroupProperties.supportedStages);
1648
1649                 if (VK_SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
1650                 {
1651                         if ( (stages & VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
1652                                 TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1653                         else
1654                                 stages = VK_SHADER_STAGE_FRAGMENT_BIT;
1655                 }
1656
1657                 if ((VkShaderStageFlagBits)0u == stages)
1658                         TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
1659
1660                 if ("gl_SubgroupSize" == caseDef.varName)
1661                 {
1662                         return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupSize, stages);
1663                 }
1664                 else if ("gl_SubgroupInvocationID" == caseDef.varName)
1665                 {
1666                         return subgroups::allStages(context, VK_FORMAT_R32G32B32A32_UINT, DE_NULL, 0, checkVertexPipelineStagesSubgroupInvocationID, stages);
1667                 }
1668                 else
1669                 {
1670                         return tcu::TestStatus::fail(
1671                                            caseDef.varName + " failed (unhandled error checking case " +
1672                                            caseDef.varName + ")!");
1673                 }
1674         }
1675 }
1676
1677 tcu::TestCaseGroup* createSubgroupsBuiltinVarTests(tcu::TestContext& testCtx)
1678 {
1679         de::MovePtr<tcu::TestCaseGroup> graphicGroup(new tcu::TestCaseGroup(
1680                 testCtx, "graphics", "Subgroup builtin variable tests: graphics"));
1681         de::MovePtr<tcu::TestCaseGroup> computeGroup(new tcu::TestCaseGroup(
1682                 testCtx, "compute", "Subgroup builtin variable tests: compute"));
1683         de::MovePtr<tcu::TestCaseGroup> framebufferGroup(new tcu::TestCaseGroup(
1684                 testCtx, "framebuffer", "Subgroup builtin variable tests: framebuffer"));
1685
1686         const char* const all_stages_vars[] =
1687         {
1688                 "SubgroupSize",
1689                 "SubgroupInvocationID"
1690         };
1691
1692         const char* const compute_only_vars[] =
1693         {
1694                 "NumSubgroups",
1695                 "SubgroupID"
1696         };
1697
1698         const VkShaderStageFlags stages[] =
1699         {
1700                 VK_SHADER_STAGE_VERTEX_BIT,
1701                 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1702                 VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
1703                 VK_SHADER_STAGE_GEOMETRY_BIT,
1704         };
1705
1706         for (int a = 0; a < DE_LENGTH_OF_ARRAY(all_stages_vars); ++a)
1707         {
1708                 const std::string var = all_stages_vars[a];
1709                 const std::string varLower = de::toLower(var);
1710
1711                 {
1712                         const CaseDefinition caseDef = { "gl_" + var, VK_SHADER_STAGE_ALL_GRAPHICS};
1713
1714                         addFunctionCaseWithPrograms(graphicGroup.get(),
1715                                                                                 varLower, "",
1716                                                                                 supportedCheck, initPrograms, test, caseDef);
1717                 }
1718
1719                 {
1720                         const CaseDefinition caseDef = {"gl_" + var, VK_SHADER_STAGE_COMPUTE_BIT};
1721                         addFunctionCaseWithPrograms(computeGroup.get(),
1722                                                 varLower + "_" + getShaderStageName(caseDef.shaderStage), "",
1723                                                 supportedCheck, initPrograms, test, caseDef);
1724                 }
1725
1726                 for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1727                 {
1728                         const CaseDefinition caseDef = {"gl_" + var, stages[stageIndex]};
1729                         addFunctionCaseWithPrograms(framebufferGroup.get(),
1730                                                 varLower + "_" + getShaderStageName(caseDef.shaderStage), "",
1731                                                 supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
1732                 }
1733         }
1734
1735         for (int a = 0; a < DE_LENGTH_OF_ARRAY(compute_only_vars); ++a)
1736         {
1737                 const std::string var = compute_only_vars[a];
1738
1739                 const CaseDefinition caseDef = {"gl_" + var, VK_SHADER_STAGE_COMPUTE_BIT};
1740
1741                 addFunctionCaseWithPrograms(computeGroup.get(), de::toLower(var), "",
1742                                                                         supportedCheck, initPrograms, test, caseDef);
1743         }
1744
1745         de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(
1746                 testCtx, "builtin_var", "Subgroup builtin variable tests"));
1747
1748         group->addChild(graphicGroup.release());
1749         group->addChild(computeGroup.release());
1750         group->addChild(framebufferGroup.release());
1751
1752         return group.release();
1753 }
1754
1755 } // subgroups
1756 } // vkt