1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Tests
3e5c31af7Sopenharmony_ci * ------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2017-2019 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci * Copyright (c) 2017 Codeplay Software Ltd.
7e5c31af7Sopenharmony_ci * Copyright (c) 2019 NVIDIA Corporation.
8e5c31af7Sopenharmony_ci *
9e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
10e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
11e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
14e5c31af7Sopenharmony_ci *
15e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
16e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
17e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
19e5c31af7Sopenharmony_ci * limitations under the License.
20e5c31af7Sopenharmony_ci *
21e5c31af7Sopenharmony_ci */ /*!
22e5c31af7Sopenharmony_ci * \file
23e5c31af7Sopenharmony_ci * \brief Subgroups Tests
24e5c31af7Sopenharmony_ci */ /*--------------------------------------------------------------------*/
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "glcSubgroupsBasicTests.hpp"
27e5c31af7Sopenharmony_ci#include "glcSubgroupsTestsUtils.hpp"
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include <string>
30e5c31af7Sopenharmony_ci#include <vector>
31e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_ciusing namespace tcu;
34e5c31af7Sopenharmony_ciusing namespace std;
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_cinamespace glc
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_cinamespace subgroups
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_cinamespace
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_cistatic const deUint32			ELECTED_VALUE		= 42u;
44e5c31af7Sopenharmony_cistatic const deUint32			UNELECTED_VALUE		= 13u;
45e5c31af7Sopenharmony_cistatic const deUint64			SHADER_BUFFER_SIZE	= 4096ull;
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_cistatic bool checkFragmentSubgroupBarriersNoSSBO(std::vector<const void*> datas,
48e5c31af7Sopenharmony_ci		deUint32 width, deUint32 height, deUint32)
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_ci	const float* const	resultData	= reinterpret_cast<const float*>(datas[0]);
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ci	for (deUint32 x = 0u; x < width; ++x)
53e5c31af7Sopenharmony_ci	{
54e5c31af7Sopenharmony_ci		for (deUint32 y = 0u; y < height; ++y)
55e5c31af7Sopenharmony_ci		{
56e5c31af7Sopenharmony_ci			const deUint32 ndx = (x * height + y) * 4u;
57e5c31af7Sopenharmony_ci			if (1.0f == resultData[ndx +2])
58e5c31af7Sopenharmony_ci			{
59e5c31af7Sopenharmony_ci				if(resultData[ndx] != resultData[ndx +1])
60e5c31af7Sopenharmony_ci				{
61e5c31af7Sopenharmony_ci					return false;
62e5c31af7Sopenharmony_ci				}
63e5c31af7Sopenharmony_ci			}
64e5c31af7Sopenharmony_ci			else if (resultData[ndx] != resultData[ndx +3])
65e5c31af7Sopenharmony_ci			{
66e5c31af7Sopenharmony_ci				return false;
67e5c31af7Sopenharmony_ci			}
68e5c31af7Sopenharmony_ci		}
69e5c31af7Sopenharmony_ci	}
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_ci	return true;
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStagesSubgroupElectNoSSBO(std::vector<const void*> datas,
75e5c31af7Sopenharmony_ci		deUint32 width, deUint32)
76e5c31af7Sopenharmony_ci{
77e5c31af7Sopenharmony_ci	const float* const	resultData			= reinterpret_cast<const float*>(datas[0]);
78e5c31af7Sopenharmony_ci	float				poisonValuesFound	= 0.0f;
79e5c31af7Sopenharmony_ci	float				numSubgroupsUsed	= 0.0f;
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < width; ++x)
82e5c31af7Sopenharmony_ci	{
83e5c31af7Sopenharmony_ci		deUint32 val = static_cast<deUint32>(resultData[x * 2]);
84e5c31af7Sopenharmony_ci		numSubgroupsUsed += resultData[x * 2 + 1];
85e5c31af7Sopenharmony_ci
86e5c31af7Sopenharmony_ci		switch (val)
87e5c31af7Sopenharmony_ci		{
88e5c31af7Sopenharmony_ci			default:
89e5c31af7Sopenharmony_ci				// some garbage value was found!
90e5c31af7Sopenharmony_ci				return false;
91e5c31af7Sopenharmony_ci			case UNELECTED_VALUE:
92e5c31af7Sopenharmony_ci				break;
93e5c31af7Sopenharmony_ci			case ELECTED_VALUE:
94e5c31af7Sopenharmony_ci				poisonValuesFound += 1.0f;
95e5c31af7Sopenharmony_ci				break;
96e5c31af7Sopenharmony_ci		}
97e5c31af7Sopenharmony_ci	}
98e5c31af7Sopenharmony_ci	return numSubgroupsUsed == poisonValuesFound;
99e5c31af7Sopenharmony_ci}
100e5c31af7Sopenharmony_ci
101e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStagesSubgroupElect(std::vector<const void*> datas,
102e5c31af7Sopenharmony_ci		deUint32 width, deUint32)
103e5c31af7Sopenharmony_ci{
104e5c31af7Sopenharmony_ci	const deUint32* const resultData =
105e5c31af7Sopenharmony_ci		reinterpret_cast<const deUint32*>(datas[0]);
106e5c31af7Sopenharmony_ci	deUint32 poisonValuesFound = 0;
107e5c31af7Sopenharmony_ci
108e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < width; ++x)
109e5c31af7Sopenharmony_ci	{
110e5c31af7Sopenharmony_ci		deUint32 val = resultData[x];
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_ci		switch (val)
113e5c31af7Sopenharmony_ci		{
114e5c31af7Sopenharmony_ci			default:
115e5c31af7Sopenharmony_ci				// some garbage value was found!
116e5c31af7Sopenharmony_ci				return false;
117e5c31af7Sopenharmony_ci			case UNELECTED_VALUE:
118e5c31af7Sopenharmony_ci				break;
119e5c31af7Sopenharmony_ci			case ELECTED_VALUE:
120e5c31af7Sopenharmony_ci				poisonValuesFound++;
121e5c31af7Sopenharmony_ci				break;
122e5c31af7Sopenharmony_ci		}
123e5c31af7Sopenharmony_ci	}
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	// we used an atomicly incremented counter to note how many subgroups we used for the vertex shader
126e5c31af7Sopenharmony_ci	const deUint32 numSubgroupsUsed =
127e5c31af7Sopenharmony_ci		*reinterpret_cast<const deUint32*>(datas[1]);
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci	return numSubgroupsUsed == poisonValuesFound;
130e5c31af7Sopenharmony_ci}
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStagesSubgroupBarriers(std::vector<const void*> datas,
133e5c31af7Sopenharmony_ci		deUint32 width, deUint32)
134e5c31af7Sopenharmony_ci{
135e5c31af7Sopenharmony_ci	const deUint32* const resultData = reinterpret_cast<const deUint32*>(datas[0]);
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_ci	// We used this SSBO to generate our unique value!
138e5c31af7Sopenharmony_ci	const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[1]);
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < width; ++x)
141e5c31af7Sopenharmony_ci	{
142e5c31af7Sopenharmony_ci		deUint32 val = resultData[x];
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci		if (val != ref)
145e5c31af7Sopenharmony_ci			return false;
146e5c31af7Sopenharmony_ci	}
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci	return true;
149e5c31af7Sopenharmony_ci}
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStagesSubgroupBarriersNoSSBO(std::vector<const void*> datas,
152e5c31af7Sopenharmony_ci		deUint32 width, deUint32)
153e5c31af7Sopenharmony_ci{
154e5c31af7Sopenharmony_ci	const float* const	resultData	= reinterpret_cast<const float*>(datas[0]);
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_ci	for (deUint32 x = 0u; x < width; ++x)
157e5c31af7Sopenharmony_ci	{
158e5c31af7Sopenharmony_ci		const deUint32 ndx = x*4u;
159e5c31af7Sopenharmony_ci		if (1.0f == resultData[ndx +2])
160e5c31af7Sopenharmony_ci		{
161e5c31af7Sopenharmony_ci			if(resultData[ndx] != resultData[ndx +1])
162e5c31af7Sopenharmony_ci				return false;
163e5c31af7Sopenharmony_ci		}
164e5c31af7Sopenharmony_ci		else if (resultData[ndx] != resultData[ndx +3])
165e5c31af7Sopenharmony_ci		{
166e5c31af7Sopenharmony_ci			return false;
167e5c31af7Sopenharmony_ci		}
168e5c31af7Sopenharmony_ci	}
169e5c31af7Sopenharmony_ci	return true;
170e5c31af7Sopenharmony_ci}
171e5c31af7Sopenharmony_ci
172e5c31af7Sopenharmony_cistatic bool checkTessellationEvaluationSubgroupBarriersNoSSBO(std::vector<const void*> datas,
173e5c31af7Sopenharmony_ci		deUint32 width, deUint32)
174e5c31af7Sopenharmony_ci{
175e5c31af7Sopenharmony_ci	const float* const	resultData	= reinterpret_cast<const float*>(datas[0]);
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	for (deUint32 x = 0u; x < width; ++x)
178e5c31af7Sopenharmony_ci	{
179e5c31af7Sopenharmony_ci		const deUint32 ndx = x*4u;
180e5c31af7Sopenharmony_ci		if (0.0f == resultData[ndx +2] && resultData[ndx] != resultData[ndx +3])
181e5c31af7Sopenharmony_ci		{
182e5c31af7Sopenharmony_ci			return false;
183e5c31af7Sopenharmony_ci		}
184e5c31af7Sopenharmony_ci	}
185e5c31af7Sopenharmony_ci	return true;
186e5c31af7Sopenharmony_ci}
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_cistatic bool checkComputeSubgroupElect(std::vector<const void*> datas,
189e5c31af7Sopenharmony_ci									  const deUint32 numWorkgroups[3], const deUint32 localSize[3],
190e5c31af7Sopenharmony_ci									  deUint32)
191e5c31af7Sopenharmony_ci{
192e5c31af7Sopenharmony_ci	return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 1);
193e5c31af7Sopenharmony_ci}
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_cistatic bool checkComputeSubgroupBarriers(std::vector<const void*> datas,
196e5c31af7Sopenharmony_ci		const deUint32 numWorkgroups[3], const deUint32 localSize[3],
197e5c31af7Sopenharmony_ci		deUint32)
198e5c31af7Sopenharmony_ci{
199e5c31af7Sopenharmony_ci	// We used this SSBO to generate our unique value!
200e5c31af7Sopenharmony_ci	const deUint32 ref = *reinterpret_cast<const deUint32*>(datas[1]);
201e5c31af7Sopenharmony_ci	return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, ref);
202e5c31af7Sopenharmony_ci}
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_cienum OpType
205e5c31af7Sopenharmony_ci{
206e5c31af7Sopenharmony_ci	OPTYPE_ELECT = 0,
207e5c31af7Sopenharmony_ci	OPTYPE_SUBGROUP_BARRIER,
208e5c31af7Sopenharmony_ci	OPTYPE_SUBGROUP_MEMORY_BARRIER,
209e5c31af7Sopenharmony_ci	OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER,
210e5c31af7Sopenharmony_ci	OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED,
211e5c31af7Sopenharmony_ci	OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE,
212e5c31af7Sopenharmony_ci	OPTYPE_LAST
213e5c31af7Sopenharmony_ci};
214e5c31af7Sopenharmony_ci
215e5c31af7Sopenharmony_cistd::string getOpTypeName(int opType)
216e5c31af7Sopenharmony_ci{
217e5c31af7Sopenharmony_ci	switch (opType)
218e5c31af7Sopenharmony_ci	{
219e5c31af7Sopenharmony_ci		default:
220e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported op type");
221e5c31af7Sopenharmony_ci			return "";
222e5c31af7Sopenharmony_ci		case OPTYPE_ELECT:
223e5c31af7Sopenharmony_ci			return "subgroupElect";
224e5c31af7Sopenharmony_ci		case OPTYPE_SUBGROUP_BARRIER:
225e5c31af7Sopenharmony_ci			return "subgroupBarrier";
226e5c31af7Sopenharmony_ci		case OPTYPE_SUBGROUP_MEMORY_BARRIER:
227e5c31af7Sopenharmony_ci			return "subgroupMemoryBarrier";
228e5c31af7Sopenharmony_ci		case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
229e5c31af7Sopenharmony_ci			return "subgroupMemoryBarrierBuffer";
230e5c31af7Sopenharmony_ci		case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
231e5c31af7Sopenharmony_ci			return "subgroupMemoryBarrierShared";
232e5c31af7Sopenharmony_ci		case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
233e5c31af7Sopenharmony_ci			return "subgroupMemoryBarrierImage";
234e5c31af7Sopenharmony_ci	}
235e5c31af7Sopenharmony_ci}
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_cistruct CaseDefinition
238e5c31af7Sopenharmony_ci{
239e5c31af7Sopenharmony_ci	int							opType;
240e5c31af7Sopenharmony_ci	subgroups::ShaderStageFlags	shaderStage;
241e5c31af7Sopenharmony_ci};
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_civoid initFrameBufferPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
244e5c31af7Sopenharmony_ci{
245e5c31af7Sopenharmony_ci	if(subgroups::SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage)
246e5c31af7Sopenharmony_ci	{
247e5c31af7Sopenharmony_ci		const string fragmentGLSL =
248e5c31af7Sopenharmony_ci			"${VERSION_DECL}\n"
249e5c31af7Sopenharmony_ci			"layout(location = 0) in highp vec4 in_color;\n"
250e5c31af7Sopenharmony_ci			"layout(location = 0) out highp vec4 out_color;\n"
251e5c31af7Sopenharmony_ci			"void main()\n"
252e5c31af7Sopenharmony_ci			"{\n"
253e5c31af7Sopenharmony_ci			"	out_color = in_color;\n"
254e5c31af7Sopenharmony_ci			"}\n";
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci		programCollection.add("fragment") << glu::FragmentSource(fragmentGLSL);
257e5c31af7Sopenharmony_ci	}
258e5c31af7Sopenharmony_ci	if (subgroups::SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
259e5c31af7Sopenharmony_ci	{
260e5c31af7Sopenharmony_ci		const string vertexGLSL =
261e5c31af7Sopenharmony_ci			"${VERSION_DECL}\n"
262e5c31af7Sopenharmony_ci			"void main (void)\n"
263e5c31af7Sopenharmony_ci			"{\n"
264e5c31af7Sopenharmony_ci			"  vec2 uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);\n"
265e5c31af7Sopenharmony_ci			"  gl_Position = vec4(uv * 2.0f + -1.0f, 0.0f, 1.0f);\n"
266e5c31af7Sopenharmony_ci			"  gl_PointSize = 1.0f;\n"
267e5c31af7Sopenharmony_ci			"}\n";
268e5c31af7Sopenharmony_ci
269e5c31af7Sopenharmony_ci		programCollection.add("vert") << glu::VertexSource(vertexGLSL);
270e5c31af7Sopenharmony_ci	}
271e5c31af7Sopenharmony_ci	else if (subgroups::SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
272e5c31af7Sopenharmony_ci		subgroups::setVertexShaderFrameBuffer(programCollection);
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_ci	if (OPTYPE_ELECT == caseDef.opType)
275e5c31af7Sopenharmony_ci	{
276e5c31af7Sopenharmony_ci		std::ostringstream electedValue ;
277e5c31af7Sopenharmony_ci		std::ostringstream unelectedValue;
278e5c31af7Sopenharmony_ci		electedValue << ELECTED_VALUE;
279e5c31af7Sopenharmony_ci		unelectedValue << UNELECTED_VALUE;
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci		if (subgroups::SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
282e5c31af7Sopenharmony_ci		{
283e5c31af7Sopenharmony_ci			const string vertexGLSL =
284e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
285e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_basic: enable\n"
286e5c31af7Sopenharmony_ci				"layout(location = 0) out vec4 out_color;\n"
287e5c31af7Sopenharmony_ci				"layout(location = 0) in highp vec4 in_position;\n"
288e5c31af7Sopenharmony_ci				"\n"
289e5c31af7Sopenharmony_ci				"void main (void)\n"
290e5c31af7Sopenharmony_ci				"{\n"
291e5c31af7Sopenharmony_ci				"  if (subgroupElect())\n"
292e5c31af7Sopenharmony_ci				"  {\n"
293e5c31af7Sopenharmony_ci				"    out_color.r = " + electedValue.str() + ".0f;\n"
294e5c31af7Sopenharmony_ci				"    out_color.g = 1.0f;\n"
295e5c31af7Sopenharmony_ci				"  }\n"
296e5c31af7Sopenharmony_ci				"  else\n"
297e5c31af7Sopenharmony_ci				"  {\n"
298e5c31af7Sopenharmony_ci				"    out_color.r = " + unelectedValue.str() + ".0f;\n"
299e5c31af7Sopenharmony_ci				"    out_color.g = 0.0f;\n"
300e5c31af7Sopenharmony_ci				"  }\n"
301e5c31af7Sopenharmony_ci				"  gl_Position = in_position;\n"
302e5c31af7Sopenharmony_ci				"  gl_PointSize = 1.0f;\n"
303e5c31af7Sopenharmony_ci				"}\n";
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ci			programCollection.add("vert") << glu::VertexSource(vertexGLSL);
306e5c31af7Sopenharmony_ci		}
307e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
308e5c31af7Sopenharmony_ci		{
309e5c31af7Sopenharmony_ci			const string geometryGLSL =
310e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
311e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_basic: enable\n"
312e5c31af7Sopenharmony_ci				"layout(points) in;\n"
313e5c31af7Sopenharmony_ci				"layout(points, max_vertices = 1) out;\n"
314e5c31af7Sopenharmony_ci				"layout(location = 0) out vec4 out_color;\n"
315e5c31af7Sopenharmony_ci				"void main (void)\n"
316e5c31af7Sopenharmony_ci				"{\n"
317e5c31af7Sopenharmony_ci				"  if (subgroupElect())\n"
318e5c31af7Sopenharmony_ci				"  {\n"
319e5c31af7Sopenharmony_ci				"    out_color.r = " + electedValue.str() + ".0f;\n"
320e5c31af7Sopenharmony_ci				"    out_color.g = 1.0f;\n"
321e5c31af7Sopenharmony_ci				"  }\n"
322e5c31af7Sopenharmony_ci				"  else\n"
323e5c31af7Sopenharmony_ci				"  {\n"
324e5c31af7Sopenharmony_ci				"    out_color.r = " + unelectedValue.str() + ".0f;\n"
325e5c31af7Sopenharmony_ci				"    out_color.g = 0.0f;\n"
326e5c31af7Sopenharmony_ci				"  }\n"
327e5c31af7Sopenharmony_ci				"  gl_Position = gl_in[0].gl_Position;\n"
328e5c31af7Sopenharmony_ci				"  EmitVertex();\n"
329e5c31af7Sopenharmony_ci				"  EndPrimitive();\n"
330e5c31af7Sopenharmony_ci				"}\n";
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_ci			programCollection.add("geometry") << glu::GeometrySource(geometryGLSL);
333e5c31af7Sopenharmony_ci		}
334e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
335e5c31af7Sopenharmony_ci		{
336e5c31af7Sopenharmony_ci			const string controlSourceGLSL =
337e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
338e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_basic: enable\n"
339e5c31af7Sopenharmony_ci				"${TESS_EXTENSION}\n"
340e5c31af7Sopenharmony_ci				"layout(vertices = 2) out;\n"
341e5c31af7Sopenharmony_ci				"void main (void)\n"
342e5c31af7Sopenharmony_ci				"{\n"
343e5c31af7Sopenharmony_ci				"  if (gl_InvocationID == 0)\n"
344e5c31af7Sopenharmony_ci				"  {\n"
345e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[0] = 1.0f;\n"
346e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[1] = 1.0f;\n"
347e5c31af7Sopenharmony_ci				"  }\n"
348e5c31af7Sopenharmony_ci				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
349e5c31af7Sopenharmony_ci				"}\n";
350e5c31af7Sopenharmony_ci
351e5c31af7Sopenharmony_ci			programCollection.add("tesc") << glu::TessellationControlSource(controlSourceGLSL);
352e5c31af7Sopenharmony_ci
353e5c31af7Sopenharmony_ci			const string evaluationSourceGLSL =
354e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
355e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_basic: enable\n"
356e5c31af7Sopenharmony_ci				"${TESS_EXTENSION}\n"
357e5c31af7Sopenharmony_ci				"layout(isolines, equal_spacing, ccw ) in;\n"
358e5c31af7Sopenharmony_ci				"layout(location = 0) out vec4 out_color;\n"
359e5c31af7Sopenharmony_ci				"\n"
360e5c31af7Sopenharmony_ci				"void main (void)\n"
361e5c31af7Sopenharmony_ci				"{\n"
362e5c31af7Sopenharmony_ci				"  if (subgroupElect())\n"
363e5c31af7Sopenharmony_ci				"  {\n"
364e5c31af7Sopenharmony_ci				"    out_color.r = 2.0f * " + electedValue.str() + ".0f - " + unelectedValue.str() + ".0f;\n"
365e5c31af7Sopenharmony_ci				"    out_color.g = 2.0f;\n"
366e5c31af7Sopenharmony_ci				"  }\n"
367e5c31af7Sopenharmony_ci				"  else\n"
368e5c31af7Sopenharmony_ci				"  {\n"
369e5c31af7Sopenharmony_ci				"    out_color.r = " + unelectedValue.str() + ".0f;\n"
370e5c31af7Sopenharmony_ci				"    out_color.g = 0.0f;\n"
371e5c31af7Sopenharmony_ci				"  }\n"
372e5c31af7Sopenharmony_ci				"  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
373e5c31af7Sopenharmony_ci				"}\n";
374e5c31af7Sopenharmony_ci
375e5c31af7Sopenharmony_ci			programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSourceGLSL);
376e5c31af7Sopenharmony_ci		}
377e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
378e5c31af7Sopenharmony_ci		{
379e5c31af7Sopenharmony_ci			const string  controlSourceGLSL =
380e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
381e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_basic: enable\n"
382e5c31af7Sopenharmony_ci				"${TESS_EXTENSION}\n"
383e5c31af7Sopenharmony_ci				"layout(vertices = 2) out;\n"
384e5c31af7Sopenharmony_ci				"layout(location = 0) out vec4 out_color[];\n"
385e5c31af7Sopenharmony_ci				"void main (void)\n"
386e5c31af7Sopenharmony_ci				"{\n"
387e5c31af7Sopenharmony_ci				"  if (gl_InvocationID == 0)\n"
388e5c31af7Sopenharmony_ci				"  {\n"
389e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[0] = 1.0f;\n"
390e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[1] = 1.0f;\n"
391e5c31af7Sopenharmony_ci				"  }\n"
392e5c31af7Sopenharmony_ci				"  if (subgroupElect())\n"
393e5c31af7Sopenharmony_ci				"  {\n"
394e5c31af7Sopenharmony_ci				"    out_color[gl_InvocationID].r = " + electedValue.str() + ".0f;\n"
395e5c31af7Sopenharmony_ci				"    out_color[gl_InvocationID].g = 1.0f;\n"
396e5c31af7Sopenharmony_ci				"  }\n"
397e5c31af7Sopenharmony_ci				"  else\n"
398e5c31af7Sopenharmony_ci				"  {\n"
399e5c31af7Sopenharmony_ci				"    out_color[gl_InvocationID].r = " + unelectedValue.str() + ".0f;\n"
400e5c31af7Sopenharmony_ci				"    out_color[gl_InvocationID].g = 0.0f;\n"
401e5c31af7Sopenharmony_ci				"  }\n"
402e5c31af7Sopenharmony_ci				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
403e5c31af7Sopenharmony_ci				"}\n";
404e5c31af7Sopenharmony_ci
405e5c31af7Sopenharmony_ci			programCollection.add("tesc") << glu::TessellationControlSource(controlSourceGLSL);
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci			const string evaluationSourceGLSL =
408e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
409e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
410e5c31af7Sopenharmony_ci				"${TESS_EXTENSION}\n"
411e5c31af7Sopenharmony_ci				"layout(isolines, equal_spacing, ccw ) in;\n"
412e5c31af7Sopenharmony_ci				"layout(location = 0) in vec4 in_color[];\n"
413e5c31af7Sopenharmony_ci				"layout(location = 0) out vec4 out_color;\n"
414e5c31af7Sopenharmony_ci				"\n"
415e5c31af7Sopenharmony_ci				"void main (void)\n"
416e5c31af7Sopenharmony_ci				"{\n"
417e5c31af7Sopenharmony_ci				"  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
418e5c31af7Sopenharmony_ci				"  out_color = in_color[0];\n"
419e5c31af7Sopenharmony_ci				"}\n";
420e5c31af7Sopenharmony_ci
421e5c31af7Sopenharmony_ci			programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSourceGLSL);
422e5c31af7Sopenharmony_ci		}
423e5c31af7Sopenharmony_ci		else
424e5c31af7Sopenharmony_ci		{
425e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported shader stage");
426e5c31af7Sopenharmony_ci		}
427e5c31af7Sopenharmony_ci	}
428e5c31af7Sopenharmony_ci	else
429e5c31af7Sopenharmony_ci	{
430e5c31af7Sopenharmony_ci		std::ostringstream bdy;
431e5c31af7Sopenharmony_ci		string color = (subgroups::SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage) ? "out_color[gl_InvocationID].b = 1.0f;\n" : "out_color.b = 1.0f;\n";
432e5c31af7Sopenharmony_ci		switch (caseDef.opType)
433e5c31af7Sopenharmony_ci		{
434e5c31af7Sopenharmony_ci			default:
435e5c31af7Sopenharmony_ci				DE_FATAL("Unhandled op type!");
436e5c31af7Sopenharmony_ci				break;
437e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_BARRIER:
438e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER:
439e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
440e5c31af7Sopenharmony_ci			{
441e5c31af7Sopenharmony_ci				bdy << "  tempResult2 = tempBuffer[id];\n"
442e5c31af7Sopenharmony_ci					<< "  if (subgroupElect())\n"
443e5c31af7Sopenharmony_ci					<< "  {\n"
444e5c31af7Sopenharmony_ci					<< "    tempResult = value;\n"
445e5c31af7Sopenharmony_ci					<< "    " << color
446e5c31af7Sopenharmony_ci					<< "  }\n"
447e5c31af7Sopenharmony_ci					<< "  else\n"
448e5c31af7Sopenharmony_ci					<< "  {\n"
449e5c31af7Sopenharmony_ci					<< "    tempResult = tempBuffer[id];\n"
450e5c31af7Sopenharmony_ci					<< "  }\n"
451e5c31af7Sopenharmony_ci					<< "  " << getOpTypeName(caseDef.opType) << "();\n";
452e5c31af7Sopenharmony_ci				break;
453e5c31af7Sopenharmony_ci			}
454e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
455e5c31af7Sopenharmony_ci				bdy << "  tempResult2 = imageLoad(tempImage, ivec2(id, 0)).x;\n"
456e5c31af7Sopenharmony_ci					<< "  if (subgroupElect())\n"
457e5c31af7Sopenharmony_ci					<< "  {\n"
458e5c31af7Sopenharmony_ci					<< "    tempResult = value;\n"
459e5c31af7Sopenharmony_ci					<< "    " << color
460e5c31af7Sopenharmony_ci					<< "  }\n"
461e5c31af7Sopenharmony_ci					<< "  else\n"
462e5c31af7Sopenharmony_ci					<< "  {\n"
463e5c31af7Sopenharmony_ci					<< "    tempResult = imageLoad(tempImage, ivec2(id, 0)).x;\n"
464e5c31af7Sopenharmony_ci					<< "  }\n"
465e5c31af7Sopenharmony_ci					<< "  subgroupMemoryBarrierImage();\n";
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci				break;
468e5c31af7Sopenharmony_ci		}
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci		if (subgroups::SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
471e5c31af7Sopenharmony_ci		{
472e5c31af7Sopenharmony_ci			std::ostringstream	fragment;
473e5c31af7Sopenharmony_ci			fragment	<< "${VERSION_DECL}\n"
474e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
475e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
476e5c31af7Sopenharmony_ci				<< "precision highp int;\n"
477e5c31af7Sopenharmony_ci				<< "layout(location = 0) out highp vec4 out_color;\n"
478e5c31af7Sopenharmony_ci				<< "\n"
479e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std140) uniform Buffer1\n"
480e5c31af7Sopenharmony_ci				<< "{\n"
481e5c31af7Sopenharmony_ci				<< "  uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
482e5c31af7Sopenharmony_ci				<< "};\n"
483e5c31af7Sopenharmony_ci				<< "\n"
484e5c31af7Sopenharmony_ci				<< "layout(binding = 1, std140) uniform Buffer2\n"
485e5c31af7Sopenharmony_ci				<< "{\n"
486e5c31af7Sopenharmony_ci				<< "  uint value;\n"
487e5c31af7Sopenharmony_ci				<< "};\n"
488e5c31af7Sopenharmony_ci				<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
489e5c31af7Sopenharmony_ci				<< "void main (void)\n"
490e5c31af7Sopenharmony_ci				<< "{\n"
491e5c31af7Sopenharmony_ci				<< "  if (gl_HelperInvocation) return;\n"
492e5c31af7Sopenharmony_ci				<< "  uint id = 0u;\n"
493e5c31af7Sopenharmony_ci				<< "  if (subgroupElect())\n"
494e5c31af7Sopenharmony_ci				<< "  {\n"
495e5c31af7Sopenharmony_ci				<< "    id = uint(gl_FragCoord.x);\n"
496e5c31af7Sopenharmony_ci				<< "  }\n"
497e5c31af7Sopenharmony_ci				<< "  id = subgroupBroadcastFirst(id);\n"
498e5c31af7Sopenharmony_ci				<< "  uint localId = id;\n"
499e5c31af7Sopenharmony_ci				<< "  uint tempResult = 0u;\n"
500e5c31af7Sopenharmony_ci				<< "  uint tempResult2 = 0u;\n"
501e5c31af7Sopenharmony_ci				<< "  out_color.b = 0.0f;\n"
502e5c31af7Sopenharmony_ci				<< bdy.str()
503e5c31af7Sopenharmony_ci				<< "  out_color.r = float(tempResult);\n"
504e5c31af7Sopenharmony_ci				<< "  out_color.g = float(value);\n"
505e5c31af7Sopenharmony_ci				<< "  out_color.a = float(tempResult2);\n"
506e5c31af7Sopenharmony_ci				<< "}\n";
507e5c31af7Sopenharmony_ci			programCollection.add("fragment") << glu::FragmentSource(fragment.str());
508e5c31af7Sopenharmony_ci		}
509e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
510e5c31af7Sopenharmony_ci		{
511e5c31af7Sopenharmony_ci			std::ostringstream	vertex;
512e5c31af7Sopenharmony_ci			vertex	<< "${VERSION_DECL}\n"
513e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
514e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
515e5c31af7Sopenharmony_ci				<<"\n"
516e5c31af7Sopenharmony_ci				<< "layout(location = 0) out vec4 out_color;\n"
517e5c31af7Sopenharmony_ci				<< "layout(location = 0) in highp vec4 in_position;\n"
518e5c31af7Sopenharmony_ci				<< "\n"
519e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std140) uniform Buffer1\n"
520e5c31af7Sopenharmony_ci				<< "{\n"
521e5c31af7Sopenharmony_ci				<< "  uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
522e5c31af7Sopenharmony_ci				<< "};\n"
523e5c31af7Sopenharmony_ci				<< "\n"
524e5c31af7Sopenharmony_ci				<< "layout(binding = 1, std140) uniform Buffer2\n"
525e5c31af7Sopenharmony_ci				<< "{\n"
526e5c31af7Sopenharmony_ci				<< "  uint value;\n"
527e5c31af7Sopenharmony_ci				<< "};\n"
528e5c31af7Sopenharmony_ci				<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
529e5c31af7Sopenharmony_ci				<< "void main (void)\n"
530e5c31af7Sopenharmony_ci				<< "{\n"
531e5c31af7Sopenharmony_ci				<< "  uint id = 0u;\n"
532e5c31af7Sopenharmony_ci				<< "  if (subgroupElect())\n"
533e5c31af7Sopenharmony_ci				<< "  {\n"
534e5c31af7Sopenharmony_ci				<< "    id = uint(gl_VertexID);\n"
535e5c31af7Sopenharmony_ci				<< "  }\n"
536e5c31af7Sopenharmony_ci				<< "  id = subgroupBroadcastFirst(id);\n"
537e5c31af7Sopenharmony_ci				<< "  uint tempResult = 0u;\n"
538e5c31af7Sopenharmony_ci				<< "  uint tempResult2 = 0u;\n"
539e5c31af7Sopenharmony_ci				<< "  out_color.b = 0.0f;\n"
540e5c31af7Sopenharmony_ci				<< bdy.str()
541e5c31af7Sopenharmony_ci				<< "  out_color.r = float(tempResult);\n"
542e5c31af7Sopenharmony_ci				<< "  out_color.g = float(value);\n"
543e5c31af7Sopenharmony_ci				<< "  out_color.a = float(tempResult2);\n"
544e5c31af7Sopenharmony_ci				<< "  gl_Position = in_position;\n"
545e5c31af7Sopenharmony_ci				<< "  gl_PointSize = 1.0f;\n"
546e5c31af7Sopenharmony_ci				<< "}\n";
547e5c31af7Sopenharmony_ci			programCollection.add("vert") << glu::VertexSource(vertex.str());
548e5c31af7Sopenharmony_ci		}
549e5c31af7Sopenharmony_ci	else if (subgroups::SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
550e5c31af7Sopenharmony_ci		{
551e5c31af7Sopenharmony_ci			std::ostringstream geometry;
552e5c31af7Sopenharmony_ci
553e5c31af7Sopenharmony_ci			geometry << "${VERSION_DECL}\n"
554e5c31af7Sopenharmony_ci					<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
555e5c31af7Sopenharmony_ci					<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
556e5c31af7Sopenharmony_ci					<< "layout(points) in;\n"
557e5c31af7Sopenharmony_ci					<< "layout(points, max_vertices = 1) out;\n"
558e5c31af7Sopenharmony_ci					<< "layout(location = 0) out vec4 out_color;\n"
559e5c31af7Sopenharmony_ci					<< "layout(binding = 0, std140) uniform Buffer1\n"
560e5c31af7Sopenharmony_ci					<< "{\n"
561e5c31af7Sopenharmony_ci					<< "  uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
562e5c31af7Sopenharmony_ci					<< "};\n"
563e5c31af7Sopenharmony_ci					<< "\n"
564e5c31af7Sopenharmony_ci					<< "layout(binding = 1, std140) uniform Buffer2\n"
565e5c31af7Sopenharmony_ci					<< "{\n"
566e5c31af7Sopenharmony_ci					<< "  uint value;\n"
567e5c31af7Sopenharmony_ci					<< "};\n"
568e5c31af7Sopenharmony_ci					<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
569e5c31af7Sopenharmony_ci					<< "void main (void)\n"
570e5c31af7Sopenharmony_ci					<< "{\n"
571e5c31af7Sopenharmony_ci					<< "  uint id = 0u;\n"
572e5c31af7Sopenharmony_ci					<< "  if (subgroupElect())\n"
573e5c31af7Sopenharmony_ci					<< "  {\n"
574e5c31af7Sopenharmony_ci					<< "    id = uint(gl_InvocationID);\n"
575e5c31af7Sopenharmony_ci					<< "  }\n"
576e5c31af7Sopenharmony_ci					<< "  id = subgroupBroadcastFirst(id);\n"
577e5c31af7Sopenharmony_ci					<< "  uint tempResult = 0u;\n"
578e5c31af7Sopenharmony_ci					<< "  uint tempResult2 = 0u;\n"
579e5c31af7Sopenharmony_ci					<< "  out_color.b = 0.0f;\n"
580e5c31af7Sopenharmony_ci					<< bdy.str()
581e5c31af7Sopenharmony_ci					<< "  out_color.r = float(tempResult);\n"
582e5c31af7Sopenharmony_ci					<< "  out_color.g = float(value);\n"
583e5c31af7Sopenharmony_ci					<< "  out_color.a = float(tempResult2);\n"
584e5c31af7Sopenharmony_ci					<< "  gl_Position = gl_in[0].gl_Position;\n"
585e5c31af7Sopenharmony_ci					<< "  EmitVertex();\n"
586e5c31af7Sopenharmony_ci					<< "  EndPrimitive();\n"
587e5c31af7Sopenharmony_ci					<< "}\n";
588e5c31af7Sopenharmony_ci
589e5c31af7Sopenharmony_ci			programCollection.add("geometry") << glu::GeometrySource(geometry.str());
590e5c31af7Sopenharmony_ci		}
591e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
592e5c31af7Sopenharmony_ci		{
593e5c31af7Sopenharmony_ci			std::ostringstream controlSource;
594e5c31af7Sopenharmony_ci			std::ostringstream evaluationSource;
595e5c31af7Sopenharmony_ci
596e5c31af7Sopenharmony_ci			controlSource << "${VERSION_DECL}\n"
597e5c31af7Sopenharmony_ci				<< "${TESS_EXTENSION}\n"
598e5c31af7Sopenharmony_ci				<< "layout(vertices = 2) out;\n"
599e5c31af7Sopenharmony_ci				<< "void main (void)\n"
600e5c31af7Sopenharmony_ci				<< "{\n"
601e5c31af7Sopenharmony_ci				<< "  if (gl_InvocationID == 0)\n"
602e5c31af7Sopenharmony_ci				<<"  {\n"
603e5c31af7Sopenharmony_ci				<< "    gl_TessLevelOuter[0] = 1.0f;\n"
604e5c31af7Sopenharmony_ci				<< "    gl_TessLevelOuter[1] = 1.0f;\n"
605e5c31af7Sopenharmony_ci				<< "  }\n"
606e5c31af7Sopenharmony_ci				<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
607e5c31af7Sopenharmony_ci				<< "}\n";
608e5c31af7Sopenharmony_ci
609e5c31af7Sopenharmony_ci			evaluationSource << "${VERSION_DECL}\n"
610e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
611e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
612e5c31af7Sopenharmony_ci				<< "${TESS_EXTENSION}\n"
613e5c31af7Sopenharmony_ci				<< "layout(isolines, equal_spacing, ccw ) in;\n"
614e5c31af7Sopenharmony_ci				<< "layout(location = 0) out vec4 out_color;\n"
615e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std140) uniform Buffer1\n"
616e5c31af7Sopenharmony_ci				<< "{\n"
617e5c31af7Sopenharmony_ci				<< "  uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
618e5c31af7Sopenharmony_ci				<< "};\n"
619e5c31af7Sopenharmony_ci				<< "\n"
620e5c31af7Sopenharmony_ci				<< "layout(binding = 1, std140) uniform Buffer2\n"
621e5c31af7Sopenharmony_ci				<< "{\n"
622e5c31af7Sopenharmony_ci				<< "  uint value;\n"
623e5c31af7Sopenharmony_ci				<< "};\n"
624e5c31af7Sopenharmony_ci				<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
625e5c31af7Sopenharmony_ci				<< "void main (void)\n"
626e5c31af7Sopenharmony_ci				<< "{\n"
627e5c31af7Sopenharmony_ci				<< "  uint id = 0u;\n"
628e5c31af7Sopenharmony_ci				<< "  if (subgroupElect())\n"
629e5c31af7Sopenharmony_ci				<< "  {\n"
630e5c31af7Sopenharmony_ci				<< "    id = uint(gl_PrimitiveID);\n"
631e5c31af7Sopenharmony_ci				<< "  }\n"
632e5c31af7Sopenharmony_ci				<< "  id = subgroupBroadcastFirst(id);\n"
633e5c31af7Sopenharmony_ci				<< "  uint tempResult = 0u;\n"
634e5c31af7Sopenharmony_ci				<< "  uint tempResult2 = 0u;\n"
635e5c31af7Sopenharmony_ci				<< "  out_color.b = 0.0f;\n"
636e5c31af7Sopenharmony_ci				<< bdy.str()
637e5c31af7Sopenharmony_ci				<< "  out_color.r = float(tempResult);\n"
638e5c31af7Sopenharmony_ci				<< "  out_color.g = float(value);\n"
639e5c31af7Sopenharmony_ci				<< "  out_color.a = float(tempResult2);\n"
640e5c31af7Sopenharmony_ci				<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
641e5c31af7Sopenharmony_ci				<< "}\n";
642e5c31af7Sopenharmony_ci
643e5c31af7Sopenharmony_ci			programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str());
644e5c31af7Sopenharmony_ci			programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str());
645e5c31af7Sopenharmony_ci		}
646e5c31af7Sopenharmony_ci		else if (subgroups::SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
647e5c31af7Sopenharmony_ci		{
648e5c31af7Sopenharmony_ci			std::ostringstream controlSource;
649e5c31af7Sopenharmony_ci			std::ostringstream evaluationSource;
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ci			controlSource  << "${VERSION_DECL}\n"
652e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
653e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
654e5c31af7Sopenharmony_ci				<< "${TESS_EXTENSION}\n"
655e5c31af7Sopenharmony_ci				<< "layout(vertices = 2) out;\n"
656e5c31af7Sopenharmony_ci				<< "layout(location = 0) out vec4 out_color[];\n"
657e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std140) uniform Buffer1\n"
658e5c31af7Sopenharmony_ci				<< "{\n"
659e5c31af7Sopenharmony_ci				<< "  uint tempBuffer["<<SHADER_BUFFER_SIZE/4ull<<"];\n"
660e5c31af7Sopenharmony_ci				<< "};\n"
661e5c31af7Sopenharmony_ci				<< "\n"
662e5c31af7Sopenharmony_ci				<< "layout(binding = 1, std140) uniform Buffer2\n"
663e5c31af7Sopenharmony_ci				<< "{\n"
664e5c31af7Sopenharmony_ci				<< "  uint value;\n"
665e5c31af7Sopenharmony_ci				<< "};\n"
666e5c31af7Sopenharmony_ci				<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) readonly uniform highp uimage2D tempImage;\n" : "\n")
667e5c31af7Sopenharmony_ci				<< "void main (void)\n"
668e5c31af7Sopenharmony_ci				<< "{\n"
669e5c31af7Sopenharmony_ci				<< "  uint id = 0u;\n"
670e5c31af7Sopenharmony_ci				<< "  if (gl_InvocationID == 0)\n"
671e5c31af7Sopenharmony_ci				<<"  {\n"
672e5c31af7Sopenharmony_ci				<< "    gl_TessLevelOuter[0] = 1.0f;\n"
673e5c31af7Sopenharmony_ci				<< "    gl_TessLevelOuter[1] = 1.0f;\n"
674e5c31af7Sopenharmony_ci				<< "  }\n"
675e5c31af7Sopenharmony_ci				<< "  if (subgroupElect())\n"
676e5c31af7Sopenharmony_ci				<< "  {\n"
677e5c31af7Sopenharmony_ci				<< "    id = uint(gl_InvocationID);\n"
678e5c31af7Sopenharmony_ci				<< "  }\n"
679e5c31af7Sopenharmony_ci				<< "  id = subgroupBroadcastFirst(id);\n"
680e5c31af7Sopenharmony_ci				<< "  uint tempResult = 0u;\n"
681e5c31af7Sopenharmony_ci				<< "  uint tempResult2 = 0u;\n"
682e5c31af7Sopenharmony_ci				<< "  out_color[gl_InvocationID].b = 0.0f;\n"
683e5c31af7Sopenharmony_ci				<< bdy.str()
684e5c31af7Sopenharmony_ci				<< "  out_color[gl_InvocationID].r = float(tempResult);\n"
685e5c31af7Sopenharmony_ci				<< "  out_color[gl_InvocationID].g = float(value);\n"
686e5c31af7Sopenharmony_ci				<< "  out_color[gl_InvocationID].a = float(tempResult2);\n"
687e5c31af7Sopenharmony_ci				<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
688e5c31af7Sopenharmony_ci				<< "}\n";
689e5c31af7Sopenharmony_ci
690e5c31af7Sopenharmony_ci			evaluationSource << "${VERSION_DECL}\n"
691e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
692e5c31af7Sopenharmony_ci				<< "${TESS_EXTENSION}\n"
693e5c31af7Sopenharmony_ci				<< "layout(isolines, equal_spacing, ccw ) in;\n"
694e5c31af7Sopenharmony_ci				<< "layout(location = 0) in vec4 in_color[];\n"
695e5c31af7Sopenharmony_ci				<< "layout(location = 0) out vec4 out_color;\n"
696e5c31af7Sopenharmony_ci				<< "\n"
697e5c31af7Sopenharmony_ci				<< "void main (void)\n"
698e5c31af7Sopenharmony_ci				<< "{\n"
699e5c31af7Sopenharmony_ci				<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
700e5c31af7Sopenharmony_ci				<< "  out_color = in_color[0];\n"
701e5c31af7Sopenharmony_ci				<< "}\n";
702e5c31af7Sopenharmony_ci
703e5c31af7Sopenharmony_ci			programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str());
704e5c31af7Sopenharmony_ci			programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str());
705e5c31af7Sopenharmony_ci		}
706e5c31af7Sopenharmony_ci		else
707e5c31af7Sopenharmony_ci		{
708e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported shader stage");
709e5c31af7Sopenharmony_ci		}
710e5c31af7Sopenharmony_ci	}
711e5c31af7Sopenharmony_ci}
712e5c31af7Sopenharmony_ci
713e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
714e5c31af7Sopenharmony_ci{
715e5c31af7Sopenharmony_ci	if (OPTYPE_ELECT == caseDef.opType)
716e5c31af7Sopenharmony_ci	{
717e5c31af7Sopenharmony_ci		if (subgroups::SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
718e5c31af7Sopenharmony_ci		{
719e5c31af7Sopenharmony_ci			std::ostringstream src;
720e5c31af7Sopenharmony_ci
721e5c31af7Sopenharmony_ci			src << "${VERSION_DECL}\n"
722e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
723e5c31af7Sopenharmony_ci				<< "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n"
724e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std430) buffer Buffer1\n"
725e5c31af7Sopenharmony_ci				<< "{\n"
726e5c31af7Sopenharmony_ci				<< "  uint result[];\n"
727e5c31af7Sopenharmony_ci				<< "};\n"
728e5c31af7Sopenharmony_ci				<< "\n"
729e5c31af7Sopenharmony_ci				<< subgroups::getSharedMemoryBallotHelper()
730e5c31af7Sopenharmony_ci				<< "void main (void)\n"
731e5c31af7Sopenharmony_ci				<< "{\n"
732e5c31af7Sopenharmony_ci				<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
733e5c31af7Sopenharmony_ci				<< "  highp uint offset = globalSize.x * ((globalSize.y * "
734e5c31af7Sopenharmony_ci				"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
735e5c31af7Sopenharmony_ci				"gl_GlobalInvocationID.x;\n"
736e5c31af7Sopenharmony_ci				<< "  uint value = " << UNELECTED_VALUE << "u;\n"
737e5c31af7Sopenharmony_ci				<< "  if (subgroupElect())\n"
738e5c31af7Sopenharmony_ci				<< "  {\n"
739e5c31af7Sopenharmony_ci				<< "    value = " << ELECTED_VALUE << "u;\n"
740e5c31af7Sopenharmony_ci				<< "  }\n"
741e5c31af7Sopenharmony_ci				<< "  uvec4 bits = uvec4(bitCount(sharedMemoryBallot(value == " << ELECTED_VALUE << "u)));\n"
742e5c31af7Sopenharmony_ci				<< "  result[offset] = bits.x + bits.y + bits.z + bits.w;\n"
743e5c31af7Sopenharmony_ci				<< "}\n";
744e5c31af7Sopenharmony_ci
745e5c31af7Sopenharmony_ci			programCollection.add("comp") << glu::ComputeSource(src.str());
746e5c31af7Sopenharmony_ci		}
747e5c31af7Sopenharmony_ci		else
748e5c31af7Sopenharmony_ci		{
749e5c31af7Sopenharmony_ci			{
750e5c31af7Sopenharmony_ci				std::ostringstream  vertex;
751e5c31af7Sopenharmony_ci				vertex	<< "${VERSION_DECL}\n"
752e5c31af7Sopenharmony_ci						<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
753e5c31af7Sopenharmony_ci						<< "layout(binding = 0, std430) buffer Buffer0\n"
754e5c31af7Sopenharmony_ci						<< "{\n"
755e5c31af7Sopenharmony_ci						<< "  uint result[];\n"
756e5c31af7Sopenharmony_ci						<< "} b0;\n"
757e5c31af7Sopenharmony_ci						<< "layout(binding = 4, std430) buffer Buffer4\n"
758e5c31af7Sopenharmony_ci						<< "{\n"
759e5c31af7Sopenharmony_ci						<< "  uint numSubgroupsExecuted;\n"
760e5c31af7Sopenharmony_ci						<< "} b4;\n"
761e5c31af7Sopenharmony_ci						<< "\n"
762e5c31af7Sopenharmony_ci						<< "void main (void)\n"
763e5c31af7Sopenharmony_ci						<< "{\n"
764e5c31af7Sopenharmony_ci						<< "  if (subgroupElect())\n"
765e5c31af7Sopenharmony_ci						<< "  {\n"
766e5c31af7Sopenharmony_ci						<< "    b0.result[gl_VertexID] = " << ELECTED_VALUE << "u;\n"
767e5c31af7Sopenharmony_ci						<< "    atomicAdd(b4.numSubgroupsExecuted, 1u);\n"
768e5c31af7Sopenharmony_ci						<< "  }\n"
769e5c31af7Sopenharmony_ci						<< "  else\n"
770e5c31af7Sopenharmony_ci						<< "  {\n"
771e5c31af7Sopenharmony_ci						<< "    b0.result[gl_VertexID] = " << UNELECTED_VALUE << "u;\n"
772e5c31af7Sopenharmony_ci						<< "  }\n"
773e5c31af7Sopenharmony_ci						<< "  float pixelSize = 2.0f/1024.0f;\n"
774e5c31af7Sopenharmony_ci						<< "  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
775e5c31af7Sopenharmony_ci						<< "  gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
776e5c31af7Sopenharmony_ci						<< "  gl_PointSize = 1.0f;\n"
777e5c31af7Sopenharmony_ci						<< "}\n";
778e5c31af7Sopenharmony_ci				programCollection.add("vert") << glu::VertexSource(vertex.str());
779e5c31af7Sopenharmony_ci			}
780e5c31af7Sopenharmony_ci
781e5c31af7Sopenharmony_ci			{
782e5c31af7Sopenharmony_ci				std::ostringstream tesc;
783e5c31af7Sopenharmony_ci				tesc	<< "${VERSION_DECL}\n"
784e5c31af7Sopenharmony_ci						<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
785e5c31af7Sopenharmony_ci						<< "layout(vertices=1) out;\n"
786e5c31af7Sopenharmony_ci						<< "layout(binding = 1, std430) buffer Buffer1\n"
787e5c31af7Sopenharmony_ci						<< "{\n"
788e5c31af7Sopenharmony_ci						<< "  uint result[];\n"
789e5c31af7Sopenharmony_ci						<< "} b1;\n"
790e5c31af7Sopenharmony_ci						<< "layout(binding = 5, std430) buffer Buffer5\n"
791e5c31af7Sopenharmony_ci						<< "{\n"
792e5c31af7Sopenharmony_ci						<< "  uint numSubgroupsExecuted;\n"
793e5c31af7Sopenharmony_ci						<< "} b5;\n"
794e5c31af7Sopenharmony_ci						<< "\n"
795e5c31af7Sopenharmony_ci						<< "void main (void)\n"
796e5c31af7Sopenharmony_ci						<< "{\n"
797e5c31af7Sopenharmony_ci						<< "  if (subgroupElect())\n"
798e5c31af7Sopenharmony_ci						<< "  {\n"
799e5c31af7Sopenharmony_ci						<< "    b1.result[gl_PrimitiveID] = " << ELECTED_VALUE << "u;\n"
800e5c31af7Sopenharmony_ci						<< "    atomicAdd(b5.numSubgroupsExecuted, 1u);\n"
801e5c31af7Sopenharmony_ci						<< "  }\n"
802e5c31af7Sopenharmony_ci						<< "  else\n"
803e5c31af7Sopenharmony_ci						<< "  {\n"
804e5c31af7Sopenharmony_ci						<< "    b1.result[gl_PrimitiveID] = " << UNELECTED_VALUE << "u;\n"
805e5c31af7Sopenharmony_ci						<< "  }\n"
806e5c31af7Sopenharmony_ci						<< "  if (gl_InvocationID == 0)\n"
807e5c31af7Sopenharmony_ci						<< "  {\n"
808e5c31af7Sopenharmony_ci						<< "    gl_TessLevelOuter[0] = 1.0f;\n"
809e5c31af7Sopenharmony_ci						<< "    gl_TessLevelOuter[1] = 1.0f;\n"
810e5c31af7Sopenharmony_ci						<< "  }\n"
811e5c31af7Sopenharmony_ci						<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
812e5c31af7Sopenharmony_ci						<< "}\n";
813e5c31af7Sopenharmony_ci				programCollection.add("tesc") << glu::TessellationControlSource(tesc.str());
814e5c31af7Sopenharmony_ci			}
815e5c31af7Sopenharmony_ci
816e5c31af7Sopenharmony_ci			{
817e5c31af7Sopenharmony_ci				std::ostringstream tese;
818e5c31af7Sopenharmony_ci				tese	<< "${VERSION_DECL}\n"
819e5c31af7Sopenharmony_ci						<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
820e5c31af7Sopenharmony_ci						<< "layout(isolines) in;\n"
821e5c31af7Sopenharmony_ci						<< "layout(binding = 2, std430) buffer Buffer2\n"
822e5c31af7Sopenharmony_ci						<< "{\n"
823e5c31af7Sopenharmony_ci						<< "  uint result[];\n"
824e5c31af7Sopenharmony_ci						<< "} b2;\n"
825e5c31af7Sopenharmony_ci						<< "layout(binding = 6, std430) buffer Buffer6\n"
826e5c31af7Sopenharmony_ci						<< "{\n"
827e5c31af7Sopenharmony_ci						<< "  uint numSubgroupsExecuted;\n"
828e5c31af7Sopenharmony_ci						<< "} b6;\n"
829e5c31af7Sopenharmony_ci						<< "\n"
830e5c31af7Sopenharmony_ci						<< "void main (void)\n"
831e5c31af7Sopenharmony_ci						<< "{\n"
832e5c31af7Sopenharmony_ci						<< "  if (subgroupElect())\n"
833e5c31af7Sopenharmony_ci						<< "  {\n"
834e5c31af7Sopenharmony_ci						<< "    b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = " << ELECTED_VALUE << "u;\n"
835e5c31af7Sopenharmony_ci						<< "    atomicAdd(b6.numSubgroupsExecuted, 1u);\n"
836e5c31af7Sopenharmony_ci						<< "  }\n"
837e5c31af7Sopenharmony_ci						<< "  else\n"
838e5c31af7Sopenharmony_ci						<< "  {\n"
839e5c31af7Sopenharmony_ci						<< "    b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = " << UNELECTED_VALUE << "u;\n"
840e5c31af7Sopenharmony_ci						<< "  }\n"
841e5c31af7Sopenharmony_ci						<< "  float pixelSize = 2.0f/1024.0f;\n"
842e5c31af7Sopenharmony_ci						<< "  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
843e5c31af7Sopenharmony_ci						<< "}\n";
844e5c31af7Sopenharmony_ci				programCollection.add("tese") << glu::TessellationEvaluationSource(tese.str());
845e5c31af7Sopenharmony_ci			}
846e5c31af7Sopenharmony_ci			{
847e5c31af7Sopenharmony_ci				std::ostringstream geometry;
848e5c31af7Sopenharmony_ci				geometry	<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
849e5c31af7Sopenharmony_ci							<< "layout(${TOPOLOGY}) in;\n"
850e5c31af7Sopenharmony_ci							<< "layout(points, max_vertices = 1) out;\n"
851e5c31af7Sopenharmony_ci							<< "layout(binding = 3, std430) buffer Buffer3\n"
852e5c31af7Sopenharmony_ci							<< "{\n"
853e5c31af7Sopenharmony_ci							<< "  uint result[];\n"
854e5c31af7Sopenharmony_ci							<< "} b3;\n"
855e5c31af7Sopenharmony_ci							<< "layout(binding = 7, std430) buffer Buffer7\n"
856e5c31af7Sopenharmony_ci							<< "{\n"
857e5c31af7Sopenharmony_ci							<< "  uint numSubgroupsExecuted;\n"
858e5c31af7Sopenharmony_ci							<< "} b7;\n"
859e5c31af7Sopenharmony_ci							<< "\n"
860e5c31af7Sopenharmony_ci							<< "void main (void)\n"
861e5c31af7Sopenharmony_ci							<< "{\n"
862e5c31af7Sopenharmony_ci							<< "  if (subgroupElect())\n"
863e5c31af7Sopenharmony_ci							<< "  {\n"
864e5c31af7Sopenharmony_ci							<< "    b3.result[gl_PrimitiveIDIn] = " << ELECTED_VALUE << "u;\n"
865e5c31af7Sopenharmony_ci							<< "    atomicAdd(b7.numSubgroupsExecuted, 1u);\n"
866e5c31af7Sopenharmony_ci							<< "  }\n"
867e5c31af7Sopenharmony_ci							<< "  else\n"
868e5c31af7Sopenharmony_ci							<< "  {\n"
869e5c31af7Sopenharmony_ci							<< "    b3.result[gl_PrimitiveIDIn] = " << UNELECTED_VALUE << "u;\n"
870e5c31af7Sopenharmony_ci							<< "  }\n"
871e5c31af7Sopenharmony_ci							<< "  gl_Position = gl_in[0].gl_Position;\n"
872e5c31af7Sopenharmony_ci							<< "  EmitVertex();\n"
873e5c31af7Sopenharmony_ci							<< "  EndPrimitive();\n"
874e5c31af7Sopenharmony_ci							<< "}\n";
875e5c31af7Sopenharmony_ci				subgroups::addGeometryShadersFromTemplate(geometry.str(), programCollection);
876e5c31af7Sopenharmony_ci			}
877e5c31af7Sopenharmony_ci
878e5c31af7Sopenharmony_ci			{
879e5c31af7Sopenharmony_ci				std::ostringstream fragment;
880e5c31af7Sopenharmony_ci				fragment	<< "${VERSION_DECL}\n"
881e5c31af7Sopenharmony_ci							<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
882e5c31af7Sopenharmony_ci							<< "precision highp int;\n"
883e5c31af7Sopenharmony_ci							<< "layout(location = 0) out uint data;\n"
884e5c31af7Sopenharmony_ci							<< "layout(binding = 8, std430) buffer Buffer8\n"
885e5c31af7Sopenharmony_ci							<< "{\n"
886e5c31af7Sopenharmony_ci							<< "  uint numSubgroupsExecuted;\n"
887e5c31af7Sopenharmony_ci							<< "} b8;\n"
888e5c31af7Sopenharmony_ci							<< "void main (void)\n"
889e5c31af7Sopenharmony_ci							<< "{\n"
890e5c31af7Sopenharmony_ci							<< "  if (gl_HelperInvocation) return;\n"
891e5c31af7Sopenharmony_ci							<< "  if (subgroupElect())\n"
892e5c31af7Sopenharmony_ci							<< "  {\n"
893e5c31af7Sopenharmony_ci							<< "    data = " << ELECTED_VALUE << "u;\n"
894e5c31af7Sopenharmony_ci							<< "    atomicAdd(b8.numSubgroupsExecuted, 1u);\n"
895e5c31af7Sopenharmony_ci							<< "  }\n"
896e5c31af7Sopenharmony_ci							<< "  else\n"
897e5c31af7Sopenharmony_ci							<< "  {\n"
898e5c31af7Sopenharmony_ci							<< "    data = " << UNELECTED_VALUE << "u;\n"
899e5c31af7Sopenharmony_ci							<< "  }\n"
900e5c31af7Sopenharmony_ci							<< "}\n";
901e5c31af7Sopenharmony_ci				programCollection.add("fragment") << glu::FragmentSource(fragment.str());
902e5c31af7Sopenharmony_ci			}
903e5c31af7Sopenharmony_ci			subgroups::addNoSubgroupShader(programCollection);
904e5c31af7Sopenharmony_ci		}
905e5c31af7Sopenharmony_ci	}
906e5c31af7Sopenharmony_ci	else
907e5c31af7Sopenharmony_ci	{
908e5c31af7Sopenharmony_ci		std::ostringstream bdy;
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ci		switch (caseDef.opType)
911e5c31af7Sopenharmony_ci		{
912e5c31af7Sopenharmony_ci			default:
913e5c31af7Sopenharmony_ci				DE_FATAL("Unhandled op type!");
914e5c31af7Sopenharmony_ci				break;
915e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_BARRIER:
916e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER:
917e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER_BUFFER:
918e5c31af7Sopenharmony_ci				bdy << "  if (subgroupElect())\n"
919e5c31af7Sopenharmony_ci					<< "  {\n"
920e5c31af7Sopenharmony_ci					<< "    b${SSBO1}.tempBuffer[id] = b${SSBO1}.value;\n"
921e5c31af7Sopenharmony_ci					<< "  }\n"
922e5c31af7Sopenharmony_ci					<< "  " << getOpTypeName(caseDef.opType) << "();\n"
923e5c31af7Sopenharmony_ci					<< "  tempResult = b${SSBO1}.tempBuffer[id];\n";
924e5c31af7Sopenharmony_ci				break;
925e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED:
926e5c31af7Sopenharmony_ci				bdy << "  if (subgroupElect())\n"
927e5c31af7Sopenharmony_ci					<< "  {\n"
928e5c31af7Sopenharmony_ci					<< "    tempShared[localId] = b${SSBO1}.value;\n"
929e5c31af7Sopenharmony_ci					<< "  }\n"
930e5c31af7Sopenharmony_ci					<< "  subgroupMemoryBarrierShared();\n"
931e5c31af7Sopenharmony_ci					<< "  tempResult = tempShared[localId];\n";
932e5c31af7Sopenharmony_ci				break;
933e5c31af7Sopenharmony_ci			case OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE:
934e5c31af7Sopenharmony_ci				bdy << "  if (subgroupElect())\n"
935e5c31af7Sopenharmony_ci					<< "  {\n"
936e5c31af7Sopenharmony_ci					<< "    imageStore(tempImage${IMG1}, ivec2(id, 0), uvec4(b${SSBO1}.value));\n"
937e5c31af7Sopenharmony_ci					<< "  }\n"
938e5c31af7Sopenharmony_ci					<< "  subgroupMemoryBarrierImage();\n"
939e5c31af7Sopenharmony_ci					<< "  tempResult = imageLoad(tempImage${IMG1}, ivec2(id, 0)).x;\n";
940e5c31af7Sopenharmony_ci				break;
941e5c31af7Sopenharmony_ci		}
942e5c31af7Sopenharmony_ci
943e5c31af7Sopenharmony_ci		tcu::StringTemplate bdyTemplate(bdy.str());
944e5c31af7Sopenharmony_ci
945e5c31af7Sopenharmony_ci		if (subgroups::SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
946e5c31af7Sopenharmony_ci		{
947e5c31af7Sopenharmony_ci			std::ostringstream src;
948e5c31af7Sopenharmony_ci			map<string, string> bufferNameMapping;
949e5c31af7Sopenharmony_ci			bufferNameMapping.insert(pair<string, string>("SSBO1", "1"));
950e5c31af7Sopenharmony_ci			bufferNameMapping.insert(pair<string, string>("IMG1", "0"));
951e5c31af7Sopenharmony_ci
952e5c31af7Sopenharmony_ci			src << "${VERSION_DECL}\n"
953e5c31af7Sopenharmony_ci				<< "#extension GL_KHR_shader_subgroup_basic: enable\n"
954e5c31af7Sopenharmony_ci				<< "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n"
955e5c31af7Sopenharmony_ci				<< "layout(binding = 0, std430) buffer Buffer0\n"
956e5c31af7Sopenharmony_ci				<< "{\n"
957e5c31af7Sopenharmony_ci				<< "  uint result[];\n"
958e5c31af7Sopenharmony_ci				<< "} b0;\n"
959e5c31af7Sopenharmony_ci				<< "layout(binding = 1, std430) buffer Buffer1\n"
960e5c31af7Sopenharmony_ci				<< "{\n"
961e5c31af7Sopenharmony_ci				<< "  uint value;\n"
962e5c31af7Sopenharmony_ci				<< "  uint tempBuffer[];\n"
963e5c31af7Sopenharmony_ci				<< "} b1;\n"
964e5c31af7Sopenharmony_ci				<< (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) uniform highp uimage2D tempImage0;\n" : "\n")
965e5c31af7Sopenharmony_ci				<< "shared uint tempShared[gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z];\n"
966e5c31af7Sopenharmony_ci				<< "\n"
967e5c31af7Sopenharmony_ci				<< "void main (void)\n"
968e5c31af7Sopenharmony_ci				<< "{\n"
969e5c31af7Sopenharmony_ci				<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
970e5c31af7Sopenharmony_ci				<< "  highp uint offset = globalSize.x * ((globalSize.y * "
971e5c31af7Sopenharmony_ci						"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
972e5c31af7Sopenharmony_ci						"gl_GlobalInvocationID.x;\n"
973e5c31af7Sopenharmony_ci				<< "  uint localId = gl_SubgroupID;\n"
974e5c31af7Sopenharmony_ci				<< "  uint id = globalSize.x * ((globalSize.y * "
975e5c31af7Sopenharmony_ci						"gl_WorkGroupID.z) + gl_WorkGroupID.y) + "
976e5c31af7Sopenharmony_ci						"gl_WorkGroupID.x + localId;\n"
977e5c31af7Sopenharmony_ci				<< "  uint tempResult = 0u;\n"
978e5c31af7Sopenharmony_ci				<< bdyTemplate.specialize(bufferNameMapping)
979e5c31af7Sopenharmony_ci				<< "  b0.result[offset] = tempResult;\n"
980e5c31af7Sopenharmony_ci				<< "}\n";
981e5c31af7Sopenharmony_ci
982e5c31af7Sopenharmony_ci			programCollection.add("comp") << glu::ComputeSource(src.str());
983e5c31af7Sopenharmony_ci		}
984e5c31af7Sopenharmony_ci		else
985e5c31af7Sopenharmony_ci		{
986e5c31af7Sopenharmony_ci			{
987e5c31af7Sopenharmony_ci				map<string, string> bufferNameMapping;
988e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("SSBO1", "4"));
989e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("IMG1", "0"));
990e5c31af7Sopenharmony_ci
991e5c31af7Sopenharmony_ci				std::ostringstream vertex;
992e5c31af7Sopenharmony_ci				vertex <<
993e5c31af7Sopenharmony_ci					"${VERSION_DECL}\n"
994e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_basic: enable\n"
995e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_ballot: enable\n"
996e5c31af7Sopenharmony_ci					"layout(binding = 0, std430) buffer Buffer0\n"
997e5c31af7Sopenharmony_ci					"{\n"
998e5c31af7Sopenharmony_ci					"  uint result[];\n"
999e5c31af7Sopenharmony_ci					"} b0;\n"
1000e5c31af7Sopenharmony_ci					"layout(binding = 4, std430) buffer Buffer4\n"
1001e5c31af7Sopenharmony_ci					"{\n"
1002e5c31af7Sopenharmony_ci					"  uint value;\n"
1003e5c31af7Sopenharmony_ci					"  uint tempBuffer[];\n"
1004e5c31af7Sopenharmony_ci					"} b4;\n"
1005e5c31af7Sopenharmony_ci					"layout(binding = 5, std430) buffer Buffer5\n"
1006e5c31af7Sopenharmony_ci					"{\n"
1007e5c31af7Sopenharmony_ci					"  uint subgroupID;\n"
1008e5c31af7Sopenharmony_ci					"} b5;\n"
1009e5c31af7Sopenharmony_ci				<<	(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 0, r32ui) uniform highp uimage2D tempImage0;\n" : "")
1010e5c31af7Sopenharmony_ci				<<	"void main (void)\n"
1011e5c31af7Sopenharmony_ci					"{\n"
1012e5c31af7Sopenharmony_ci					"  uint id = 0u;\n"
1013e5c31af7Sopenharmony_ci					"  if (subgroupElect())\n"
1014e5c31af7Sopenharmony_ci					"  {\n"
1015e5c31af7Sopenharmony_ci					"    id = atomicAdd(b5.subgroupID, 1u);\n"
1016e5c31af7Sopenharmony_ci					"  }\n"
1017e5c31af7Sopenharmony_ci					"  id = subgroupBroadcastFirst(id);\n"
1018e5c31af7Sopenharmony_ci					"  uint localId = id;\n"
1019e5c31af7Sopenharmony_ci					"  uint tempResult = 0u;\n"
1020e5c31af7Sopenharmony_ci					+ bdyTemplate.specialize(bufferNameMapping) +
1021e5c31af7Sopenharmony_ci					"  b0.result[gl_VertexID] = tempResult;\n"
1022e5c31af7Sopenharmony_ci					"  float pixelSize = 2.0f/1024.0f;\n"
1023e5c31af7Sopenharmony_ci					"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
1024e5c31af7Sopenharmony_ci					"  gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
1025e5c31af7Sopenharmony_ci					"  gl_PointSize = 1.0f;\n"
1026e5c31af7Sopenharmony_ci					"}\n";
1027e5c31af7Sopenharmony_ci				programCollection.add("vert") << glu::VertexSource(vertex.str());
1028e5c31af7Sopenharmony_ci			}
1029e5c31af7Sopenharmony_ci
1030e5c31af7Sopenharmony_ci			{
1031e5c31af7Sopenharmony_ci				map<string, string> bufferNameMapping;
1032e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("SSBO1", "6"));
1033e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("IMG1", "1"));
1034e5c31af7Sopenharmony_ci
1035e5c31af7Sopenharmony_ci				std::ostringstream tesc;
1036e5c31af7Sopenharmony_ci				tesc <<
1037e5c31af7Sopenharmony_ci					"${VERSION_DECL}\n"
1038e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_basic: enable\n"
1039e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_ballot: enable\n"
1040e5c31af7Sopenharmony_ci					"layout(vertices=1) out;\n"
1041e5c31af7Sopenharmony_ci					"layout(binding = 1, std430) buffer Buffer1\n"
1042e5c31af7Sopenharmony_ci					"{\n"
1043e5c31af7Sopenharmony_ci					"  uint result[];\n"
1044e5c31af7Sopenharmony_ci					"} b1;\n"
1045e5c31af7Sopenharmony_ci					"layout(binding = 6, std430) buffer Buffer6\n"
1046e5c31af7Sopenharmony_ci					"{\n"
1047e5c31af7Sopenharmony_ci					"  uint value;\n"
1048e5c31af7Sopenharmony_ci					"  uint tempBuffer[];\n"
1049e5c31af7Sopenharmony_ci					"} b6;\n"
1050e5c31af7Sopenharmony_ci					"layout(binding = 7, std430) buffer Buffer7\n"
1051e5c31af7Sopenharmony_ci					"{\n"
1052e5c31af7Sopenharmony_ci					"  uint subgroupID;\n"
1053e5c31af7Sopenharmony_ci					"} b7;\n"
1054e5c31af7Sopenharmony_ci				<<	(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 1, r32ui) uniform highp uimage2D tempImage1;\n" : "")
1055e5c31af7Sopenharmony_ci				<<	"void main (void)\n"
1056e5c31af7Sopenharmony_ci					"{\n"
1057e5c31af7Sopenharmony_ci					"  uint id = 0u;\n"
1058e5c31af7Sopenharmony_ci					"  if (subgroupElect())\n"
1059e5c31af7Sopenharmony_ci					"  {\n"
1060e5c31af7Sopenharmony_ci					"    id = atomicAdd(b7.subgroupID, 1u);\n"
1061e5c31af7Sopenharmony_ci					"  }\n"
1062e5c31af7Sopenharmony_ci					"  id = subgroupBroadcastFirst(id);\n"
1063e5c31af7Sopenharmony_ci					"  uint localId = id;\n"
1064e5c31af7Sopenharmony_ci					"  uint tempResult = 0u;\n"
1065e5c31af7Sopenharmony_ci					+ bdyTemplate.specialize(bufferNameMapping) +
1066e5c31af7Sopenharmony_ci					"  b1.result[gl_PrimitiveID] = tempResult;\n"
1067e5c31af7Sopenharmony_ci					"  if (gl_InvocationID == 0)\n"
1068e5c31af7Sopenharmony_ci					"  {\n"
1069e5c31af7Sopenharmony_ci					"    gl_TessLevelOuter[0] = 1.0f;\n"
1070e5c31af7Sopenharmony_ci					"    gl_TessLevelOuter[1] = 1.0f;\n"
1071e5c31af7Sopenharmony_ci					"  }\n"
1072e5c31af7Sopenharmony_ci					"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1073e5c31af7Sopenharmony_ci					"}\n";
1074e5c31af7Sopenharmony_ci				programCollection.add("tesc") << glu::TessellationControlSource(tesc.str());
1075e5c31af7Sopenharmony_ci			}
1076e5c31af7Sopenharmony_ci
1077e5c31af7Sopenharmony_ci			{
1078e5c31af7Sopenharmony_ci				map<string, string> bufferNameMapping;
1079e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("SSBO1", "8"));
1080e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("IMG1", "2"));
1081e5c31af7Sopenharmony_ci
1082e5c31af7Sopenharmony_ci				std::ostringstream tese;
1083e5c31af7Sopenharmony_ci				tese <<
1084e5c31af7Sopenharmony_ci					"${VERSION_DECL}\n"
1085e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_basic: enable\n"
1086e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_ballot: enable\n"
1087e5c31af7Sopenharmony_ci					"layout(isolines) in;\n"
1088e5c31af7Sopenharmony_ci					"layout(binding = 2, std430) buffer Buffer2\n"
1089e5c31af7Sopenharmony_ci					"{\n"
1090e5c31af7Sopenharmony_ci					"  uint result[];\n"
1091e5c31af7Sopenharmony_ci					"} b2;\n"
1092e5c31af7Sopenharmony_ci					"layout(binding = 8, std430) buffer Buffer8\n"
1093e5c31af7Sopenharmony_ci					"{\n"
1094e5c31af7Sopenharmony_ci					"  uint value;\n"
1095e5c31af7Sopenharmony_ci					"  uint tempBuffer[];\n"
1096e5c31af7Sopenharmony_ci					"} b8;\n"
1097e5c31af7Sopenharmony_ci					"layout(binding = 9, std430) buffer Buffer9\n"
1098e5c31af7Sopenharmony_ci					"{\n"
1099e5c31af7Sopenharmony_ci					"  uint subgroupID;\n"
1100e5c31af7Sopenharmony_ci					"} b9;\n"
1101e5c31af7Sopenharmony_ci				<<	(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 2, r32ui) uniform highp uimage2D tempImage2;\n" : "")
1102e5c31af7Sopenharmony_ci				<<	"void main (void)\n"
1103e5c31af7Sopenharmony_ci					"{\n"
1104e5c31af7Sopenharmony_ci					"  uint id = 0u;\n"
1105e5c31af7Sopenharmony_ci					"  if (subgroupElect())\n"
1106e5c31af7Sopenharmony_ci					"  {\n"
1107e5c31af7Sopenharmony_ci					"    id = atomicAdd(b9.subgroupID, 1u);\n"
1108e5c31af7Sopenharmony_ci					"  }\n"
1109e5c31af7Sopenharmony_ci					"  id = subgroupBroadcastFirst(id);\n"
1110e5c31af7Sopenharmony_ci					"  uint localId = id;\n"
1111e5c31af7Sopenharmony_ci					"  uint tempResult = 0u;\n"
1112e5c31af7Sopenharmony_ci					+ bdyTemplate.specialize(bufferNameMapping) +
1113e5c31af7Sopenharmony_ci					"  b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = tempResult;\n"
1114e5c31af7Sopenharmony_ci					"  float pixelSize = 2.0f/1024.0f;\n""  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
1115e5c31af7Sopenharmony_ci					"}\n";
1116e5c31af7Sopenharmony_ci				programCollection.add("tese") << glu::TessellationEvaluationSource(tese.str());
1117e5c31af7Sopenharmony_ci			}
1118e5c31af7Sopenharmony_ci			{
1119e5c31af7Sopenharmony_ci				map<string, string> bufferNameMapping;
1120e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("SSBO1", "10"));
1121e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("IMG1", "3"));
1122e5c31af7Sopenharmony_ci
1123e5c31af7Sopenharmony_ci				std::ostringstream geometry;
1124e5c31af7Sopenharmony_ci				geometry <<
1125e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_basic: enable\n"
1126e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_ballot: enable\n"
1127e5c31af7Sopenharmony_ci					"layout(${TOPOLOGY}) in;\n"
1128e5c31af7Sopenharmony_ci					"layout(points, max_vertices = 1) out;\n"
1129e5c31af7Sopenharmony_ci					"layout(binding = 3, std430) buffer Buffer3\n"
1130e5c31af7Sopenharmony_ci					"{\n"
1131e5c31af7Sopenharmony_ci					"  uint result[];\n"
1132e5c31af7Sopenharmony_ci					"} b3;\n"
1133e5c31af7Sopenharmony_ci					"layout(binding = 10, std430) buffer Buffer10\n"
1134e5c31af7Sopenharmony_ci					"{\n"
1135e5c31af7Sopenharmony_ci					"  uint value;\n"
1136e5c31af7Sopenharmony_ci					"  uint tempBuffer[];\n"
1137e5c31af7Sopenharmony_ci					"} b10;\n"
1138e5c31af7Sopenharmony_ci					"layout(binding = 11, std430) buffer Buffer11\n"
1139e5c31af7Sopenharmony_ci					"{\n"
1140e5c31af7Sopenharmony_ci					"  uint subgroupID;\n"
1141e5c31af7Sopenharmony_ci					"} b11;\n"
1142e5c31af7Sopenharmony_ci				<<	(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 3, r32ui) uniform highp uimage2D tempImage3;\n" : "")
1143e5c31af7Sopenharmony_ci				<<	"void main (void)\n"
1144e5c31af7Sopenharmony_ci					"{\n"
1145e5c31af7Sopenharmony_ci					"  uint id = 0u;\n"
1146e5c31af7Sopenharmony_ci					"  if (subgroupElect())\n"
1147e5c31af7Sopenharmony_ci					"  {\n"
1148e5c31af7Sopenharmony_ci					"    id = atomicAdd(b11.subgroupID, 1u);\n"
1149e5c31af7Sopenharmony_ci					"  }\n"
1150e5c31af7Sopenharmony_ci					"  id = subgroupBroadcastFirst(id);\n"
1151e5c31af7Sopenharmony_ci					"  uint localId = id;\n"
1152e5c31af7Sopenharmony_ci					"  uint tempResult = 0u;\n"
1153e5c31af7Sopenharmony_ci					 + bdyTemplate.specialize(bufferNameMapping) +
1154e5c31af7Sopenharmony_ci					"  b3.result[gl_PrimitiveIDIn] = tempResult;\n"
1155e5c31af7Sopenharmony_ci					"  gl_Position = gl_in[0].gl_Position;\n"
1156e5c31af7Sopenharmony_ci					"  EmitVertex();\n"
1157e5c31af7Sopenharmony_ci					"  EndPrimitive();\n"
1158e5c31af7Sopenharmony_ci					"}\n";
1159e5c31af7Sopenharmony_ci				subgroups::addGeometryShadersFromTemplate(geometry.str(), programCollection);
1160e5c31af7Sopenharmony_ci			}
1161e5c31af7Sopenharmony_ci
1162e5c31af7Sopenharmony_ci			{
1163e5c31af7Sopenharmony_ci				map<string, string> bufferNameMapping;
1164e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("SSBO1", "12"));
1165e5c31af7Sopenharmony_ci				bufferNameMapping.insert(pair<string, string>("IMG1", "4"));
1166e5c31af7Sopenharmony_ci
1167e5c31af7Sopenharmony_ci				std::ostringstream fragment;
1168e5c31af7Sopenharmony_ci				fragment <<
1169e5c31af7Sopenharmony_ci					"${VERSION_DECL}\n"
1170e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_basic: enable\n"
1171e5c31af7Sopenharmony_ci					"#extension GL_KHR_shader_subgroup_ballot: enable\n"
1172e5c31af7Sopenharmony_ci					"precision highp int;\n"
1173e5c31af7Sopenharmony_ci					"layout(location = 0) out uint result;\n"
1174e5c31af7Sopenharmony_ci					"layout(binding = 12, std430) buffer Buffer12\n"
1175e5c31af7Sopenharmony_ci					"{\n"
1176e5c31af7Sopenharmony_ci					"  uint value;\n"
1177e5c31af7Sopenharmony_ci					"  uint tempBuffer[];\n"
1178e5c31af7Sopenharmony_ci					"} b12;\n"
1179e5c31af7Sopenharmony_ci					"layout(binding = 13, std430) buffer Buffer13\n"
1180e5c31af7Sopenharmony_ci					"{\n"
1181e5c31af7Sopenharmony_ci					"  uint subgroupID;\n"
1182e5c31af7Sopenharmony_ci					"} b13;\n"
1183e5c31af7Sopenharmony_ci				<<	(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? "layout(binding = 4, r32ui) uniform highp uimage2D tempImage4;\n" : "")
1184e5c31af7Sopenharmony_ci				<<	"void main (void)\n"
1185e5c31af7Sopenharmony_ci					"{\n"
1186e5c31af7Sopenharmony_ci					"  if (gl_HelperInvocation) return;\n"
1187e5c31af7Sopenharmony_ci					"  uint id = 0u;\n"
1188e5c31af7Sopenharmony_ci					"  if (subgroupElect())\n"
1189e5c31af7Sopenharmony_ci					"  {\n"
1190e5c31af7Sopenharmony_ci					"    id = atomicAdd(b13.subgroupID, 1u);\n"
1191e5c31af7Sopenharmony_ci					"  }\n"
1192e5c31af7Sopenharmony_ci					"  id = subgroupBroadcastFirst(id);\n"
1193e5c31af7Sopenharmony_ci					"  uint localId = id;\n"
1194e5c31af7Sopenharmony_ci					"  uint tempResult = 0u;\n"
1195e5c31af7Sopenharmony_ci					+ bdyTemplate.specialize(bufferNameMapping) +
1196e5c31af7Sopenharmony_ci					"  result = tempResult;\n"
1197e5c31af7Sopenharmony_ci					"}\n";
1198e5c31af7Sopenharmony_ci				programCollection.add("fragment") << glu::FragmentSource(fragment.str());
1199e5c31af7Sopenharmony_ci			}
1200e5c31af7Sopenharmony_ci
1201e5c31af7Sopenharmony_ci		subgroups::addNoSubgroupShader(programCollection);
1202e5c31af7Sopenharmony_ci		}
1203e5c31af7Sopenharmony_ci	}
1204e5c31af7Sopenharmony_ci}
1205e5c31af7Sopenharmony_ci
1206e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef)
1207e5c31af7Sopenharmony_ci{
1208e5c31af7Sopenharmony_ci	DE_UNREF(caseDef);
1209e5c31af7Sopenharmony_ci	if (!subgroups::isSubgroupSupported(context))
1210e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
1211e5c31af7Sopenharmony_ci}
1212e5c31af7Sopenharmony_ci
1213e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
1214e5c31af7Sopenharmony_ci{
1215e5c31af7Sopenharmony_ci	if (!subgroups::areSubgroupOperationsSupportedForStage(
1216e5c31af7Sopenharmony_ci				context, caseDef.shaderStage))
1217e5c31af7Sopenharmony_ci	{
1218e5c31af7Sopenharmony_ci		if (subgroups::areSubgroupOperationsRequiredForStage(
1219e5c31af7Sopenharmony_ci					caseDef.shaderStage))
1220e5c31af7Sopenharmony_ci		{
1221e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail(
1222e5c31af7Sopenharmony_ci					   "Shader stage " +
1223e5c31af7Sopenharmony_ci					   subgroups::getShaderStageName(caseDef.shaderStage) +
1224e5c31af7Sopenharmony_ci					   " is required to support subgroup operations!");
1225e5c31af7Sopenharmony_ci		}
1226e5c31af7Sopenharmony_ci		else
1227e5c31af7Sopenharmony_ci		{
1228e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
1229e5c31af7Sopenharmony_ci		}
1230e5c31af7Sopenharmony_ci	}
1231e5c31af7Sopenharmony_ci
1232e5c31af7Sopenharmony_ci	if (!subgroups::isSubgroupFeatureSupportedForDevice(context, subgroups::SUBGROUP_FEATURE_BASIC_BIT))
1233e5c31af7Sopenharmony_ci	{
1234e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail(
1235e5c31af7Sopenharmony_ci				   "Subgroup feature " +
1236e5c31af7Sopenharmony_ci				   subgroups::getSubgroupFeatureName(subgroups::SUBGROUP_FEATURE_BASIC_BIT) +
1237e5c31af7Sopenharmony_ci				   " is a required capability!");
1238e5c31af7Sopenharmony_ci	}
1239e5c31af7Sopenharmony_ci
1240e5c31af7Sopenharmony_ci	if (OPTYPE_ELECT != caseDef.opType && subgroups::SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1241e5c31af7Sopenharmony_ci	{
1242e5c31af7Sopenharmony_ci		if (!subgroups::isSubgroupFeatureSupportedForDevice(context, subgroups::SUBGROUP_FEATURE_BALLOT_BIT))
1243e5c31af7Sopenharmony_ci		{
1244e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1245e5c31af7Sopenharmony_ci		}
1246e5c31af7Sopenharmony_ci	}
1247e5c31af7Sopenharmony_ci
1248e5c31af7Sopenharmony_ci	if (OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType)
1249e5c31af7Sopenharmony_ci	{
1250e5c31af7Sopenharmony_ci		if (!subgroups::isImageSupportedForStageOnDevice(context, caseDef.shaderStage))
1251e5c31af7Sopenharmony_ci		{
1252e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup basic memory barrier image test for " +
1253e5c31af7Sopenharmony_ci										 subgroups::getShaderStageName(caseDef.shaderStage) +
1254e5c31af7Sopenharmony_ci										 " stage requires that image uniforms be supported on this stage");
1255e5c31af7Sopenharmony_ci		}
1256e5c31af7Sopenharmony_ci	}
1257e5c31af7Sopenharmony_ci
1258e5c31af7Sopenharmony_ci	const deUint32						inputDatasCount	= OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType ? 3u : 2u;
1259e5c31af7Sopenharmony_ci	std::vector<subgroups::SSBOData>	inputDatas		(inputDatasCount);
1260e5c31af7Sopenharmony_ci
1261e5c31af7Sopenharmony_ci	inputDatas[0].format = subgroups::FORMAT_R32_UINT;
1262e5c31af7Sopenharmony_ci	inputDatas[0].layout = subgroups::SSBOData::LayoutStd140;
1263e5c31af7Sopenharmony_ci	inputDatas[0].numElements = SHADER_BUFFER_SIZE/4ull;
1264e5c31af7Sopenharmony_ci	inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1265e5c31af7Sopenharmony_ci	inputDatas[0].binding = 0u;
1266e5c31af7Sopenharmony_ci
1267e5c31af7Sopenharmony_ci	inputDatas[1].format = subgroups::FORMAT_R32_UINT;
1268e5c31af7Sopenharmony_ci	inputDatas[1].layout = subgroups::SSBOData::LayoutStd140;
1269e5c31af7Sopenharmony_ci	inputDatas[1].numElements = 1ull;
1270e5c31af7Sopenharmony_ci	inputDatas[1].initializeType = subgroups::SSBOData::InitializeNonZero;
1271e5c31af7Sopenharmony_ci	inputDatas[1].binding = 1u;
1272e5c31af7Sopenharmony_ci
1273e5c31af7Sopenharmony_ci	if(OPTYPE_SUBGROUP_MEMORY_BARRIER_IMAGE == caseDef.opType )
1274e5c31af7Sopenharmony_ci	{
1275e5c31af7Sopenharmony_ci		inputDatas[2].format = subgroups::FORMAT_R32_UINT;
1276e5c31af7Sopenharmony_ci		inputDatas[2].layout = subgroups::SSBOData::LayoutPacked;
1277e5c31af7Sopenharmony_ci		inputDatas[2].numElements = SHADER_BUFFER_SIZE;
1278e5c31af7Sopenharmony_ci		inputDatas[2].initializeType = subgroups::SSBOData::InitializeNone;
1279e5c31af7Sopenharmony_ci		inputDatas[2].isImage = true;
1280e5c31af7Sopenharmony_ci		inputDatas[2].binding = 0u;
1281e5c31af7Sopenharmony_ci	}
1282e5c31af7Sopenharmony_ci
1283e5c31af7Sopenharmony_ci	if (subgroups::SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
1284e5c31af7Sopenharmony_ci	{
1285e5c31af7Sopenharmony_ci		if (OPTYPE_ELECT == caseDef.opType)
1286e5c31af7Sopenharmony_ci			return subgroups::makeVertexFrameBufferTest(context, subgroups::FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1287e5c31af7Sopenharmony_ci		else
1288e5c31af7Sopenharmony_ci			return subgroups::makeVertexFrameBufferTest(context, subgroups::FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1289e5c31af7Sopenharmony_ci	}
1290e5c31af7Sopenharmony_ci	else if (subgroups::SHADER_STAGE_FRAGMENT_BIT == caseDef.shaderStage)
1291e5c31af7Sopenharmony_ci	{
1292e5c31af7Sopenharmony_ci		return subgroups::makeFragmentFrameBufferTest(context, subgroups::FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkFragmentSubgroupBarriersNoSSBO);
1293e5c31af7Sopenharmony_ci	}
1294e5c31af7Sopenharmony_ci	else if (subgroups::SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
1295e5c31af7Sopenharmony_ci	{
1296e5c31af7Sopenharmony_ci		if (OPTYPE_ELECT == caseDef.opType)
1297e5c31af7Sopenharmony_ci			return subgroups::makeGeometryFrameBufferTest(context, subgroups::FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO);
1298e5c31af7Sopenharmony_ci		else
1299e5c31af7Sopenharmony_ci			return subgroups::makeGeometryFrameBufferTest(context, subgroups::FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount, checkVertexPipelineStagesSubgroupBarriersNoSSBO);
1300e5c31af7Sopenharmony_ci	}
1301e5c31af7Sopenharmony_ci
1302e5c31af7Sopenharmony_ci	if (OPTYPE_ELECT == caseDef.opType)
1303e5c31af7Sopenharmony_ci		return subgroups::makeTessellationEvaluationFrameBufferTest(context, subgroups::FORMAT_R32G32_SFLOAT, DE_NULL, 0u, checkVertexPipelineStagesSubgroupElectNoSSBO, caseDef.shaderStage);
1304e5c31af7Sopenharmony_ci
1305e5c31af7Sopenharmony_ci	return subgroups::makeTessellationEvaluationFrameBufferTest(context, subgroups::FORMAT_R32G32B32A32_SFLOAT, &inputDatas[0], inputDatasCount,
1306e5c31af7Sopenharmony_ci		(subgroups::SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)? checkVertexPipelineStagesSubgroupBarriersNoSSBO : checkTessellationEvaluationSubgroupBarriersNoSSBO,
1307e5c31af7Sopenharmony_ci		caseDef.shaderStage);
1308e5c31af7Sopenharmony_ci}
1309e5c31af7Sopenharmony_ci
1310e5c31af7Sopenharmony_citcu::TestStatus test(Context& context, const CaseDefinition caseDef)
1311e5c31af7Sopenharmony_ci{
1312e5c31af7Sopenharmony_ci	if (!subgroups::isSubgroupFeatureSupportedForDevice(context, subgroups::SUBGROUP_FEATURE_BASIC_BIT))
1313e5c31af7Sopenharmony_ci	{
1314e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail(
1315e5c31af7Sopenharmony_ci					"Subgroup feature " +
1316e5c31af7Sopenharmony_ci					subgroups::getSubgroupFeatureName(subgroups::SUBGROUP_FEATURE_BASIC_BIT) +
1317e5c31af7Sopenharmony_ci					" is a required capability!");
1318e5c31af7Sopenharmony_ci	}
1319e5c31af7Sopenharmony_ci
1320e5c31af7Sopenharmony_ci	if (OPTYPE_ELECT != caseDef.opType && subgroups::SHADER_STAGE_COMPUTE_BIT != caseDef.shaderStage)
1321e5c31af7Sopenharmony_ci	{
1322e5c31af7Sopenharmony_ci		if (!subgroups::isSubgroupFeatureSupportedForDevice(context, subgroups::SUBGROUP_FEATURE_BALLOT_BIT))
1323e5c31af7Sopenharmony_ci		{
1324e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup basic operation non-compute stage test required that ballot operations are supported!");
1325e5c31af7Sopenharmony_ci		}
1326e5c31af7Sopenharmony_ci	}
1327e5c31af7Sopenharmony_ci
1328e5c31af7Sopenharmony_ci	if (subgroups::SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
1329e5c31af7Sopenharmony_ci	{
1330e5c31af7Sopenharmony_ci		if (!subgroups::areSubgroupOperationsSupportedForStage(context, caseDef.shaderStage))
1331e5c31af7Sopenharmony_ci		{
1332e5c31af7Sopenharmony_ci				return tcu::TestStatus::fail("Shader stage " +
1333e5c31af7Sopenharmony_ci										subgroups::getShaderStageName(caseDef.shaderStage) +
1334e5c31af7Sopenharmony_ci										" is required to support subgroup operations!");
1335e5c31af7Sopenharmony_ci		}
1336e5c31af7Sopenharmony_ci
1337e5c31af7Sopenharmony_ci		if (OPTYPE_ELECT == caseDef.opType)
1338e5c31af7Sopenharmony_ci		{
1339e5c31af7Sopenharmony_ci			return subgroups::makeComputeTest(context, subgroups::FORMAT_R32_UINT, DE_NULL, 0, checkComputeSubgroupElect);
1340e5c31af7Sopenharmony_ci		}
1341e5c31af7Sopenharmony_ci		else
1342e5c31af7Sopenharmony_ci		{
1343e5c31af7Sopenharmony_ci			const deUint32 inputDatasCount = 2;
1344e5c31af7Sopenharmony_ci			subgroups::SSBOData inputDatas[inputDatasCount];
1345e5c31af7Sopenharmony_ci			inputDatas[0].format = subgroups::FORMAT_R32_UINT;
1346e5c31af7Sopenharmony_ci			inputDatas[0].layout = subgroups::SSBOData::LayoutStd430;
1347e5c31af7Sopenharmony_ci			inputDatas[0].numElements = 1 + SHADER_BUFFER_SIZE;
1348e5c31af7Sopenharmony_ci			inputDatas[0].initializeType = subgroups::SSBOData::InitializeNonZero;
1349e5c31af7Sopenharmony_ci			inputDatas[0].binding = 1u;
1350e5c31af7Sopenharmony_ci
1351e5c31af7Sopenharmony_ci			inputDatas[1].format = subgroups::FORMAT_R32_UINT;
1352e5c31af7Sopenharmony_ci			inputDatas[1].layout = subgroups::SSBOData::LayoutPacked;
1353e5c31af7Sopenharmony_ci			inputDatas[1].numElements = SHADER_BUFFER_SIZE;
1354e5c31af7Sopenharmony_ci			inputDatas[1].initializeType = subgroups::SSBOData::InitializeNone;
1355e5c31af7Sopenharmony_ci			inputDatas[1].isImage = true;
1356e5c31af7Sopenharmony_ci			inputDatas[1].binding = 0u;
1357e5c31af7Sopenharmony_ci
1358e5c31af7Sopenharmony_ci			return subgroups::makeComputeTest(context, subgroups::FORMAT_R32_UINT, inputDatas, inputDatasCount, checkComputeSubgroupBarriers);
1359e5c31af7Sopenharmony_ci		}
1360e5c31af7Sopenharmony_ci	}
1361e5c31af7Sopenharmony_ci	else
1362e5c31af7Sopenharmony_ci	{
1363e5c31af7Sopenharmony_ci		if (!subgroups::isFragmentSSBOSupportedForDevice(context))
1364e5c31af7Sopenharmony_ci		{
1365e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup basic operation require that the fragment stage be able to write to SSBOs!");
1366e5c31af7Sopenharmony_ci		}
1367e5c31af7Sopenharmony_ci
1368e5c31af7Sopenharmony_ci		int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR);
1369e5c31af7Sopenharmony_ci		int combinedSSBOs = context.getDeqpContext().getContextInfo().getInt(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
1370e5c31af7Sopenharmony_ci
1371e5c31af7Sopenharmony_ci		subgroups::ShaderStageFlags stages = (subgroups::ShaderStageFlags)(caseDef.shaderStage & supportedStages);
1372e5c31af7Sopenharmony_ci
1373e5c31af7Sopenharmony_ci		if ( subgroups::SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
1374e5c31af7Sopenharmony_ci		{
1375e5c31af7Sopenharmony_ci			if ( (stages & subgroups::SHADER_STAGE_FRAGMENT_BIT) == 0)
1376e5c31af7Sopenharmony_ci				TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
1377e5c31af7Sopenharmony_ci			else
1378e5c31af7Sopenharmony_ci				stages = subgroups::SHADER_STAGE_FRAGMENT_BIT;
1379e5c31af7Sopenharmony_ci		}
1380e5c31af7Sopenharmony_ci
1381e5c31af7Sopenharmony_ci		if ((subgroups::ShaderStageFlags)0u == stages)
1382e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
1383e5c31af7Sopenharmony_ci
1384e5c31af7Sopenharmony_ci		// with sufficient effort we could dynamically assign the binding points
1385e5c31af7Sopenharmony_ci		// based on the number of stages actually supported, etc, but we already
1386e5c31af7Sopenharmony_ci		// have the framebuffer tests which cover those cases, so there doesn't seem
1387e5c31af7Sopenharmony_ci		// to be much benefit in doing that right now.
1388e5c31af7Sopenharmony_ci		if (combinedSSBOs < 14)
1389e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Device does not support enough combined SSBOs for this test (14)");
1390e5c31af7Sopenharmony_ci
1391e5c31af7Sopenharmony_ci		if (OPTYPE_ELECT == caseDef.opType)
1392e5c31af7Sopenharmony_ci		{
1393e5c31af7Sopenharmony_ci			const deUint32 inputCount = 5u;
1394e5c31af7Sopenharmony_ci			subgroups::SSBOData inputData[inputCount];
1395e5c31af7Sopenharmony_ci
1396e5c31af7Sopenharmony_ci			inputData[0].format			= subgroups::FORMAT_R32_UINT;
1397e5c31af7Sopenharmony_ci			inputData[0].layout			= subgroups::SSBOData::LayoutStd430;
1398e5c31af7Sopenharmony_ci			inputData[0].numElements	= 1;
1399e5c31af7Sopenharmony_ci			inputData[0].initializeType	= subgroups::SSBOData::InitializeZero;
1400e5c31af7Sopenharmony_ci			inputData[0].binding		= 4u;
1401e5c31af7Sopenharmony_ci			inputData[0].stages			= subgroups::SHADER_STAGE_VERTEX_BIT;
1402e5c31af7Sopenharmony_ci
1403e5c31af7Sopenharmony_ci			inputData[1].format			= subgroups::FORMAT_R32_UINT;
1404e5c31af7Sopenharmony_ci			inputData[1].layout			= subgroups::SSBOData::LayoutStd430;
1405e5c31af7Sopenharmony_ci			inputData[1].numElements	= 1;
1406e5c31af7Sopenharmony_ci			inputData[1].initializeType	= subgroups::SSBOData::InitializeZero;
1407e5c31af7Sopenharmony_ci			inputData[1].binding		= 5u;
1408e5c31af7Sopenharmony_ci			inputData[1].stages			= subgroups::SHADER_STAGE_TESS_CONTROL_BIT;
1409e5c31af7Sopenharmony_ci
1410e5c31af7Sopenharmony_ci			inputData[2].format			= subgroups::FORMAT_R32_UINT;
1411e5c31af7Sopenharmony_ci			inputData[2].layout			= subgroups::SSBOData::LayoutStd430;
1412e5c31af7Sopenharmony_ci			inputData[2].numElements	= 1;
1413e5c31af7Sopenharmony_ci			inputData[2].initializeType	= subgroups::SSBOData::InitializeZero;
1414e5c31af7Sopenharmony_ci			inputData[2].binding		= 6u;
1415e5c31af7Sopenharmony_ci			inputData[2].stages			= subgroups::SHADER_STAGE_TESS_EVALUATION_BIT;
1416e5c31af7Sopenharmony_ci
1417e5c31af7Sopenharmony_ci			inputData[3].format			= subgroups::FORMAT_R32_UINT;
1418e5c31af7Sopenharmony_ci			inputData[3].layout			= subgroups::SSBOData::LayoutStd430;
1419e5c31af7Sopenharmony_ci			inputData[3].numElements	= 1;
1420e5c31af7Sopenharmony_ci			inputData[3].initializeType	= subgroups::SSBOData::InitializeZero;
1421e5c31af7Sopenharmony_ci			inputData[3].binding		= 7u;
1422e5c31af7Sopenharmony_ci			inputData[3].stages			= subgroups::SHADER_STAGE_GEOMETRY_BIT;
1423e5c31af7Sopenharmony_ci
1424e5c31af7Sopenharmony_ci			inputData[4].format			= subgroups::FORMAT_R32_UINT;
1425e5c31af7Sopenharmony_ci			inputData[4].layout			= subgroups::SSBOData::LayoutStd430;
1426e5c31af7Sopenharmony_ci			inputData[4].numElements	= 1;
1427e5c31af7Sopenharmony_ci			inputData[4].initializeType	= subgroups::SSBOData::InitializeZero;
1428e5c31af7Sopenharmony_ci			inputData[4].binding		= 8u;
1429e5c31af7Sopenharmony_ci			inputData[4].stages			= subgroups::SHADER_STAGE_FRAGMENT_BIT;
1430e5c31af7Sopenharmony_ci
1431e5c31af7Sopenharmony_ci			return subgroups::allStages(context, subgroups::FORMAT_R32_UINT, inputData, inputCount, checkVertexPipelineStagesSubgroupElect, stages);
1432e5c31af7Sopenharmony_ci		}
1433e5c31af7Sopenharmony_ci		else
1434e5c31af7Sopenharmony_ci		{
1435e5c31af7Sopenharmony_ci			const subgroups::ShaderStageFlags stagesBits[] =
1436e5c31af7Sopenharmony_ci			{
1437e5c31af7Sopenharmony_ci				subgroups::SHADER_STAGE_VERTEX_BIT,
1438e5c31af7Sopenharmony_ci				subgroups::SHADER_STAGE_TESS_CONTROL_BIT,
1439e5c31af7Sopenharmony_ci				subgroups::SHADER_STAGE_TESS_EVALUATION_BIT,
1440e5c31af7Sopenharmony_ci				subgroups::SHADER_STAGE_GEOMETRY_BIT,
1441e5c31af7Sopenharmony_ci				subgroups::SHADER_STAGE_FRAGMENT_BIT,
1442e5c31af7Sopenharmony_ci			};
1443e5c31af7Sopenharmony_ci
1444e5c31af7Sopenharmony_ci			const deUint32 inputDatasCount = DE_LENGTH_OF_ARRAY(stagesBits) * 3u;
1445e5c31af7Sopenharmony_ci			subgroups::SSBOData inputDatas[inputDatasCount];
1446e5c31af7Sopenharmony_ci
1447e5c31af7Sopenharmony_ci			for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stagesBits); ++ndx)
1448e5c31af7Sopenharmony_ci			{
1449e5c31af7Sopenharmony_ci				const deUint32 index = ndx*3;
1450e5c31af7Sopenharmony_ci				const deUint32 ssboIndex = ndx*2;
1451e5c31af7Sopenharmony_ci				const deUint32 imgIndex = ndx;
1452e5c31af7Sopenharmony_ci				inputDatas[index].format				= subgroups::FORMAT_R32_UINT;
1453e5c31af7Sopenharmony_ci				inputDatas[index].layout				= subgroups::SSBOData::LayoutStd430;
1454e5c31af7Sopenharmony_ci				inputDatas[index].numElements			= 1 + SHADER_BUFFER_SIZE;
1455e5c31af7Sopenharmony_ci				inputDatas[index].initializeType		= subgroups::SSBOData::InitializeNonZero;
1456e5c31af7Sopenharmony_ci				inputDatas[index].binding				= ssboIndex + 4u;
1457e5c31af7Sopenharmony_ci				inputDatas[index].stages				= stagesBits[ndx];
1458e5c31af7Sopenharmony_ci
1459e5c31af7Sopenharmony_ci				inputDatas[index + 1].format			= subgroups::FORMAT_R32_UINT;
1460e5c31af7Sopenharmony_ci				inputDatas[index + 1].layout			= subgroups::SSBOData::LayoutStd430;
1461e5c31af7Sopenharmony_ci				inputDatas[index + 1].numElements		= 1;
1462e5c31af7Sopenharmony_ci				inputDatas[index + 1].initializeType	= subgroups::SSBOData::InitializeZero;
1463e5c31af7Sopenharmony_ci				inputDatas[index + 1].binding			= ssboIndex + 5u;
1464e5c31af7Sopenharmony_ci				inputDatas[index + 1].stages			= stagesBits[ndx];
1465e5c31af7Sopenharmony_ci
1466e5c31af7Sopenharmony_ci				inputDatas[index + 2].format			= subgroups::FORMAT_R32_UINT;
1467e5c31af7Sopenharmony_ci				inputDatas[index + 2].layout			= subgroups::SSBOData::LayoutPacked;
1468e5c31af7Sopenharmony_ci				inputDatas[index + 2].numElements		= SHADER_BUFFER_SIZE;
1469e5c31af7Sopenharmony_ci				inputDatas[index + 2].initializeType	= subgroups::SSBOData::InitializeNone;
1470e5c31af7Sopenharmony_ci				inputDatas[index + 2].isImage			= true;
1471e5c31af7Sopenharmony_ci				inputDatas[index + 2].binding			= imgIndex;
1472e5c31af7Sopenharmony_ci				inputDatas[index + 2].stages			= stagesBits[ndx];
1473e5c31af7Sopenharmony_ci			}
1474e5c31af7Sopenharmony_ci
1475e5c31af7Sopenharmony_ci			return subgroups::allStages(context, subgroups::FORMAT_R32_UINT, inputDatas, inputDatasCount, checkVertexPipelineStagesSubgroupBarriers, stages);
1476e5c31af7Sopenharmony_ci		}
1477e5c31af7Sopenharmony_ci	}
1478e5c31af7Sopenharmony_ci}
1479e5c31af7Sopenharmony_ci}
1480e5c31af7Sopenharmony_ci
1481e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsBasicTests(deqp::Context& testCtx)
1482e5c31af7Sopenharmony_ci{
1483e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup(
1484e5c31af7Sopenharmony_ci		testCtx, "graphics", "Subgroup basic category tests: graphics"));
1485e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup(
1486e5c31af7Sopenharmony_ci		testCtx, "compute", "Subgroup basic category tests: compute"));
1487e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup(
1488e5c31af7Sopenharmony_ci		testCtx, "framebuffer", "Subgroup basic category tests: framebuffer"));
1489e5c31af7Sopenharmony_ci
1490e5c31af7Sopenharmony_ci	const subgroups::ShaderStageFlags stages[] =
1491e5c31af7Sopenharmony_ci	{
1492e5c31af7Sopenharmony_ci		SHADER_STAGE_FRAGMENT_BIT,
1493e5c31af7Sopenharmony_ci		SHADER_STAGE_VERTEX_BIT,
1494e5c31af7Sopenharmony_ci		SHADER_STAGE_TESS_EVALUATION_BIT,
1495e5c31af7Sopenharmony_ci		SHADER_STAGE_TESS_CONTROL_BIT,
1496e5c31af7Sopenharmony_ci		SHADER_STAGE_GEOMETRY_BIT,
1497e5c31af7Sopenharmony_ci	};
1498e5c31af7Sopenharmony_ci
1499e5c31af7Sopenharmony_ci	for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
1500e5c31af7Sopenharmony_ci	{
1501e5c31af7Sopenharmony_ci		const std::string op = de::toLower(getOpTypeName(opTypeIndex));
1502e5c31af7Sopenharmony_ci
1503e5c31af7Sopenharmony_ci		{
1504e5c31af7Sopenharmony_ci			const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT};
1505e5c31af7Sopenharmony_ci			SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(), op, "",
1506e5c31af7Sopenharmony_ci										supportedCheck, initPrograms, test, caseDef);
1507e5c31af7Sopenharmony_ci		}
1508e5c31af7Sopenharmony_ci
1509e5c31af7Sopenharmony_ci		if (OPTYPE_SUBGROUP_MEMORY_BARRIER_SHARED == opTypeIndex)
1510e5c31af7Sopenharmony_ci		{
1511e5c31af7Sopenharmony_ci			// Shared isn't available in non compute shaders.
1512e5c31af7Sopenharmony_ci			continue;
1513e5c31af7Sopenharmony_ci		}
1514e5c31af7Sopenharmony_ci
1515e5c31af7Sopenharmony_ci		{
1516e5c31af7Sopenharmony_ci			const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_ALL_GRAPHICS};
1517e5c31af7Sopenharmony_ci			SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(),
1518e5c31af7Sopenharmony_ci										op, "",
1519e5c31af7Sopenharmony_ci										supportedCheck, initPrograms, test, caseDef);
1520e5c31af7Sopenharmony_ci		}
1521e5c31af7Sopenharmony_ci
1522e5c31af7Sopenharmony_ci		for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
1523e5c31af7Sopenharmony_ci		{
1524e5c31af7Sopenharmony_ci			if (opTypeIndex == OPTYPE_ELECT && stageIndex == 0)
1525e5c31af7Sopenharmony_ci				continue;		// This is not tested. I don't know why.
1526e5c31af7Sopenharmony_ci
1527e5c31af7Sopenharmony_ci			const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex]};
1528e5c31af7Sopenharmony_ci			SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(),
1529e5c31af7Sopenharmony_ci						op + "_" + getShaderStageName(caseDef.shaderStage), "",
1530e5c31af7Sopenharmony_ci						supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
1531e5c31af7Sopenharmony_ci		}
1532e5c31af7Sopenharmony_ci	}
1533e5c31af7Sopenharmony_ci
1534e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup(
1535e5c31af7Sopenharmony_ci		testCtx, "basic", "Subgroup basic category tests"));
1536e5c31af7Sopenharmony_ci
1537e5c31af7Sopenharmony_ci	group->addChild(graphicGroup.release());
1538e5c31af7Sopenharmony_ci	group->addChild(computeGroup.release());
1539e5c31af7Sopenharmony_ci	group->addChild(framebufferGroup.release());
1540e5c31af7Sopenharmony_ci
1541e5c31af7Sopenharmony_ci	return group.release();
1542e5c31af7Sopenharmony_ci}
1543e5c31af7Sopenharmony_ci
1544e5c31af7Sopenharmony_ci} // subgroups
1545e5c31af7Sopenharmony_ci} // glc
1546