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) 2018-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 "glcSubgroupsPartitionedTests.hpp"
27e5c31af7Sopenharmony_ci#include "glcSubgroupsTestsUtils.hpp"
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_ci#include <string>
30e5c31af7Sopenharmony_ci#include <vector>
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_ciusing namespace tcu;
33e5c31af7Sopenharmony_ciusing namespace std;
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cinamespace glc
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cinamespace subgroups
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_cinamespace
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_cienum OpType
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_ci	OPTYPE_ADD = 0,
44e5c31af7Sopenharmony_ci	OPTYPE_MUL,
45e5c31af7Sopenharmony_ci	OPTYPE_MIN,
46e5c31af7Sopenharmony_ci	OPTYPE_MAX,
47e5c31af7Sopenharmony_ci	OPTYPE_AND,
48e5c31af7Sopenharmony_ci	OPTYPE_OR,
49e5c31af7Sopenharmony_ci	OPTYPE_XOR,
50e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_ADD,
51e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_MUL,
52e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_MIN,
53e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_MAX,
54e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_AND,
55e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_OR,
56e5c31af7Sopenharmony_ci	OPTYPE_INCLUSIVE_XOR,
57e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_ADD,
58e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_MUL,
59e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_MIN,
60e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_MAX,
61e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_AND,
62e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_OR,
63e5c31af7Sopenharmony_ci	OPTYPE_EXCLUSIVE_XOR,
64e5c31af7Sopenharmony_ci	OPTYPE_LAST
65e5c31af7Sopenharmony_ci};
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_cistatic bool checkVertexPipelineStages(std::vector<const void*> datas,
68e5c31af7Sopenharmony_ci									  deUint32 width, deUint32)
69e5c31af7Sopenharmony_ci{
70e5c31af7Sopenharmony_ci	return glc::subgroups::check(datas, width, 0xFFFFFF);
71e5c31af7Sopenharmony_ci}
72e5c31af7Sopenharmony_ci
73e5c31af7Sopenharmony_cistatic bool checkComputeStage(std::vector<const void*> datas,
74e5c31af7Sopenharmony_ci						 const deUint32 numWorkgroups[3], const deUint32 localSize[3],
75e5c31af7Sopenharmony_ci						 deUint32)
76e5c31af7Sopenharmony_ci{
77e5c31af7Sopenharmony_ci	return glc::subgroups::checkCompute(datas, numWorkgroups, localSize, 0xFFFFFF);
78e5c31af7Sopenharmony_ci}
79e5c31af7Sopenharmony_ci
80e5c31af7Sopenharmony_cistd::string getOpTypeName(int opType)
81e5c31af7Sopenharmony_ci{
82e5c31af7Sopenharmony_ci	switch (opType)
83e5c31af7Sopenharmony_ci	{
84e5c31af7Sopenharmony_ci		default:
85e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported op type");
86e5c31af7Sopenharmony_ci			return "";
87e5c31af7Sopenharmony_ci		case OPTYPE_ADD:
88e5c31af7Sopenharmony_ci			return "subgroupAdd";
89e5c31af7Sopenharmony_ci		case OPTYPE_MUL:
90e5c31af7Sopenharmony_ci			return "subgroupMul";
91e5c31af7Sopenharmony_ci		case OPTYPE_MIN:
92e5c31af7Sopenharmony_ci			return "subgroupMin";
93e5c31af7Sopenharmony_ci		case OPTYPE_MAX:
94e5c31af7Sopenharmony_ci			return "subgroupMax";
95e5c31af7Sopenharmony_ci		case OPTYPE_AND:
96e5c31af7Sopenharmony_ci			return "subgroupAnd";
97e5c31af7Sopenharmony_ci		case OPTYPE_OR:
98e5c31af7Sopenharmony_ci			return "subgroupOr";
99e5c31af7Sopenharmony_ci		case OPTYPE_XOR:
100e5c31af7Sopenharmony_ci			return "subgroupXor";
101e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_ADD:
102e5c31af7Sopenharmony_ci			return "subgroupInclusiveAdd";
103e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MUL:
104e5c31af7Sopenharmony_ci			return "subgroupInclusiveMul";
105e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MIN:
106e5c31af7Sopenharmony_ci			return "subgroupInclusiveMin";
107e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MAX:
108e5c31af7Sopenharmony_ci			return "subgroupInclusiveMax";
109e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_AND:
110e5c31af7Sopenharmony_ci			return "subgroupInclusiveAnd";
111e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_OR:
112e5c31af7Sopenharmony_ci			return "subgroupInclusiveOr";
113e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_XOR:
114e5c31af7Sopenharmony_ci			return "subgroupInclusiveXor";
115e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_ADD:
116e5c31af7Sopenharmony_ci			return "subgroupExclusiveAdd";
117e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MUL:
118e5c31af7Sopenharmony_ci			return "subgroupExclusiveMul";
119e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MIN:
120e5c31af7Sopenharmony_ci			return "subgroupExclusiveMin";
121e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MAX:
122e5c31af7Sopenharmony_ci			return "subgroupExclusiveMax";
123e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_AND:
124e5c31af7Sopenharmony_ci			return "subgroupExclusiveAnd";
125e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_OR:
126e5c31af7Sopenharmony_ci			return "subgroupExclusiveOr";
127e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_XOR:
128e5c31af7Sopenharmony_ci			return "subgroupExclusiveXor";
129e5c31af7Sopenharmony_ci	}
130e5c31af7Sopenharmony_ci}
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_cistd::string getOpTypeNamePartitioned(int opType)
133e5c31af7Sopenharmony_ci{
134e5c31af7Sopenharmony_ci	switch (opType)
135e5c31af7Sopenharmony_ci	{
136e5c31af7Sopenharmony_ci		default:
137e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported op type");
138e5c31af7Sopenharmony_ci			return "";
139e5c31af7Sopenharmony_ci		case OPTYPE_ADD:
140e5c31af7Sopenharmony_ci			return "subgroupPartitionedAddNV";
141e5c31af7Sopenharmony_ci		case OPTYPE_MUL:
142e5c31af7Sopenharmony_ci			return "subgroupPartitionedMulNV";
143e5c31af7Sopenharmony_ci		case OPTYPE_MIN:
144e5c31af7Sopenharmony_ci			return "subgroupPartitionedMinNV";
145e5c31af7Sopenharmony_ci		case OPTYPE_MAX:
146e5c31af7Sopenharmony_ci			return "subgroupPartitionedMaxNV";
147e5c31af7Sopenharmony_ci		case OPTYPE_AND:
148e5c31af7Sopenharmony_ci			return "subgroupPartitionedAndNV";
149e5c31af7Sopenharmony_ci		case OPTYPE_OR:
150e5c31af7Sopenharmony_ci			return "subgroupPartitionedOrNV";
151e5c31af7Sopenharmony_ci		case OPTYPE_XOR:
152e5c31af7Sopenharmony_ci			return "subgroupPartitionedXorNV";
153e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_ADD:
154e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveAddNV";
155e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MUL:
156e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveMulNV";
157e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MIN:
158e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveMinNV";
159e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MAX:
160e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveMaxNV";
161e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_AND:
162e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveAndNV";
163e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_OR:
164e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveOrNV";
165e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_XOR:
166e5c31af7Sopenharmony_ci			return "subgroupPartitionedInclusiveXorNV";
167e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_ADD:
168e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveAddNV";
169e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MUL:
170e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveMulNV";
171e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MIN:
172e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveMinNV";
173e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MAX:
174e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveMaxNV";
175e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_AND:
176e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveAndNV";
177e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_OR:
178e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveOrNV";
179e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_XOR:
180e5c31af7Sopenharmony_ci			return "subgroupPartitionedExclusiveXorNV";
181e5c31af7Sopenharmony_ci	}
182e5c31af7Sopenharmony_ci}
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_cistd::string getIdentity(int opType, Format format)
185e5c31af7Sopenharmony_ci{
186e5c31af7Sopenharmony_ci	bool isFloat = false;
187e5c31af7Sopenharmony_ci	bool isInt = false;
188e5c31af7Sopenharmony_ci	bool isUnsigned = false;
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci	switch (format)
191e5c31af7Sopenharmony_ci	{
192e5c31af7Sopenharmony_ci		default:
193e5c31af7Sopenharmony_ci			DE_FATAL("Unhandled format!");
194e5c31af7Sopenharmony_ci			return "";
195e5c31af7Sopenharmony_ci		case FORMAT_R32_SINT:
196e5c31af7Sopenharmony_ci		case FORMAT_R32G32_SINT:
197e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32_SINT:
198e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32A32_SINT:
199e5c31af7Sopenharmony_ci			isInt = true;
200e5c31af7Sopenharmony_ci			break;
201e5c31af7Sopenharmony_ci		case FORMAT_R32_UINT:
202e5c31af7Sopenharmony_ci		case FORMAT_R32G32_UINT:
203e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32_UINT:
204e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32A32_UINT:
205e5c31af7Sopenharmony_ci			isUnsigned = true;
206e5c31af7Sopenharmony_ci			break;
207e5c31af7Sopenharmony_ci		case FORMAT_R32_SFLOAT:
208e5c31af7Sopenharmony_ci		case FORMAT_R32G32_SFLOAT:
209e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32_SFLOAT:
210e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32A32_SFLOAT:
211e5c31af7Sopenharmony_ci		case FORMAT_R64_SFLOAT:
212e5c31af7Sopenharmony_ci		case FORMAT_R64G64_SFLOAT:
213e5c31af7Sopenharmony_ci		case FORMAT_R64G64B64_SFLOAT:
214e5c31af7Sopenharmony_ci		case FORMAT_R64G64B64A64_SFLOAT:
215e5c31af7Sopenharmony_ci			isFloat = true;
216e5c31af7Sopenharmony_ci			break;
217e5c31af7Sopenharmony_ci		case FORMAT_R32_BOOL:
218e5c31af7Sopenharmony_ci		case FORMAT_R32G32_BOOL:
219e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32_BOOL:
220e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32A32_BOOL:
221e5c31af7Sopenharmony_ci			break; // bool types are not anything
222e5c31af7Sopenharmony_ci	}
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	switch (opType)
225e5c31af7Sopenharmony_ci	{
226e5c31af7Sopenharmony_ci		default:
227e5c31af7Sopenharmony_ci			DE_FATAL("Unsupported op type");
228e5c31af7Sopenharmony_ci			return "";
229e5c31af7Sopenharmony_ci		case OPTYPE_ADD:
230e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_ADD:
231e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_ADD:
232e5c31af7Sopenharmony_ci			return subgroups::getFormatNameForGLSL(format) + "(0)";
233e5c31af7Sopenharmony_ci		case OPTYPE_MUL:
234e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MUL:
235e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MUL:
236e5c31af7Sopenharmony_ci			return subgroups::getFormatNameForGLSL(format) + "(1)";
237e5c31af7Sopenharmony_ci		case OPTYPE_MIN:
238e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MIN:
239e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MIN:
240e5c31af7Sopenharmony_ci			if (isFloat)
241e5c31af7Sopenharmony_ci			{
242e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0x7f800000))";
243e5c31af7Sopenharmony_ci			}
244e5c31af7Sopenharmony_ci			else if (isInt)
245e5c31af7Sopenharmony_ci			{
246e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(0x7fffffff)";
247e5c31af7Sopenharmony_ci			}
248e5c31af7Sopenharmony_ci			else if (isUnsigned)
249e5c31af7Sopenharmony_ci			{
250e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(0xffffffffu)";
251e5c31af7Sopenharmony_ci			}
252e5c31af7Sopenharmony_ci			else
253e5c31af7Sopenharmony_ci			{
254e5c31af7Sopenharmony_ci				DE_FATAL("Unhandled case");
255e5c31af7Sopenharmony_ci				return "";
256e5c31af7Sopenharmony_ci			}
257e5c31af7Sopenharmony_ci		case OPTYPE_MAX:
258e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_MAX:
259e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_MAX:
260e5c31af7Sopenharmony_ci			if (isFloat)
261e5c31af7Sopenharmony_ci			{
262e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0xff800000))";
263e5c31af7Sopenharmony_ci			}
264e5c31af7Sopenharmony_ci			else if (isInt)
265e5c31af7Sopenharmony_ci			{
266e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(0x80000000)";
267e5c31af7Sopenharmony_ci			}
268e5c31af7Sopenharmony_ci			else if (isUnsigned)
269e5c31af7Sopenharmony_ci			{
270e5c31af7Sopenharmony_ci				return subgroups::getFormatNameForGLSL(format) + "(0u)";
271e5c31af7Sopenharmony_ci			}
272e5c31af7Sopenharmony_ci			else
273e5c31af7Sopenharmony_ci			{
274e5c31af7Sopenharmony_ci				DE_FATAL("Unhandled case");
275e5c31af7Sopenharmony_ci				return "";
276e5c31af7Sopenharmony_ci			}
277e5c31af7Sopenharmony_ci		case OPTYPE_AND:
278e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_AND:
279e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_AND:
280e5c31af7Sopenharmony_ci			return subgroups::getFormatNameForGLSL(format) + "(~0)";
281e5c31af7Sopenharmony_ci		case OPTYPE_OR:
282e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_OR:
283e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_OR:
284e5c31af7Sopenharmony_ci			return subgroups::getFormatNameForGLSL(format) + "(0)";
285e5c31af7Sopenharmony_ci		case OPTYPE_XOR:
286e5c31af7Sopenharmony_ci		case OPTYPE_INCLUSIVE_XOR:
287e5c31af7Sopenharmony_ci		case OPTYPE_EXCLUSIVE_XOR:
288e5c31af7Sopenharmony_ci			return subgroups::getFormatNameForGLSL(format) + "(0)";
289e5c31af7Sopenharmony_ci	}
290e5c31af7Sopenharmony_ci}
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_cistd::string getCompare(int opType, Format format, std::string lhs, std::string rhs)
293e5c31af7Sopenharmony_ci{
294e5c31af7Sopenharmony_ci	std::string formatName = subgroups::getFormatNameForGLSL(format);
295e5c31af7Sopenharmony_ci	switch (format)
296e5c31af7Sopenharmony_ci	{
297e5c31af7Sopenharmony_ci		default:
298e5c31af7Sopenharmony_ci			return "all(equal(" + lhs + ", " + rhs + "))";
299e5c31af7Sopenharmony_ci		case FORMAT_R32_BOOL:
300e5c31af7Sopenharmony_ci		case FORMAT_R32_UINT:
301e5c31af7Sopenharmony_ci		case FORMAT_R32_SINT:
302e5c31af7Sopenharmony_ci			return "(" + lhs + " == " + rhs + ")";
303e5c31af7Sopenharmony_ci		case FORMAT_R32_SFLOAT:
304e5c31af7Sopenharmony_ci		case FORMAT_R64_SFLOAT:
305e5c31af7Sopenharmony_ci			switch (opType)
306e5c31af7Sopenharmony_ci			{
307e5c31af7Sopenharmony_ci				default:
308e5c31af7Sopenharmony_ci					return "(abs(" + lhs + " - " + rhs + ") < 0.00001)";
309e5c31af7Sopenharmony_ci				case OPTYPE_MIN:
310e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_MIN:
311e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_MIN:
312e5c31af7Sopenharmony_ci				case OPTYPE_MAX:
313e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_MAX:
314e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_MAX:
315e5c31af7Sopenharmony_ci					return "(" + lhs + " == " + rhs + ")";
316e5c31af7Sopenharmony_ci			}
317e5c31af7Sopenharmony_ci		case FORMAT_R32G32_SFLOAT:
318e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32_SFLOAT:
319e5c31af7Sopenharmony_ci		case FORMAT_R32G32B32A32_SFLOAT:
320e5c31af7Sopenharmony_ci		case FORMAT_R64G64_SFLOAT:
321e5c31af7Sopenharmony_ci		case FORMAT_R64G64B64_SFLOAT:
322e5c31af7Sopenharmony_ci		case FORMAT_R64G64B64A64_SFLOAT:
323e5c31af7Sopenharmony_ci			switch (opType)
324e5c31af7Sopenharmony_ci			{
325e5c31af7Sopenharmony_ci				default:
326e5c31af7Sopenharmony_ci					return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName + "(0.00001)))";
327e5c31af7Sopenharmony_ci				case OPTYPE_MIN:
328e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_MIN:
329e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_MIN:
330e5c31af7Sopenharmony_ci				case OPTYPE_MAX:
331e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_MAX:
332e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_MAX:
333e5c31af7Sopenharmony_ci					return "all(equal(" + lhs + ", " + rhs + "))";
334e5c31af7Sopenharmony_ci			}
335e5c31af7Sopenharmony_ci	}
336e5c31af7Sopenharmony_ci}
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_cistruct CaseDefinition
339e5c31af7Sopenharmony_ci{
340e5c31af7Sopenharmony_ci	int					opType;
341e5c31af7Sopenharmony_ci	ShaderStageFlags	shaderStage;
342e5c31af7Sopenharmony_ci	Format				format;
343e5c31af7Sopenharmony_ci};
344e5c31af7Sopenharmony_ci
345e5c31af7Sopenharmony_cistring getTestString(const CaseDefinition &caseDef)
346e5c31af7Sopenharmony_ci{
347e5c31af7Sopenharmony_ci    // NOTE: tempResult can't have anything in bits 31:24 to avoid int->float
348e5c31af7Sopenharmony_ci    // conversion overflow in framebuffer tests.
349e5c31af7Sopenharmony_ci    string fmt = subgroups::getFormatNameForGLSL(caseDef.format);
350e5c31af7Sopenharmony_ci	string bdy =
351e5c31af7Sopenharmony_ci		"  uint tempResult = 0u;\n"
352e5c31af7Sopenharmony_ci		"  uint id = gl_SubgroupInvocationID;\n";
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci    // Test the case where the partition has a single subset with all invocations in it.
355e5c31af7Sopenharmony_ci    // This should generate the same result as the non-partitioned function.
356e5c31af7Sopenharmony_ci    bdy +=
357e5c31af7Sopenharmony_ci        "  uvec4 allBallot = mask;\n"
358e5c31af7Sopenharmony_ci        "  " + fmt + " allResult = " + getOpTypeNamePartitioned(caseDef.opType) + "(data[gl_SubgroupInvocationID], allBallot);\n"
359e5c31af7Sopenharmony_ci        "  " + fmt + " refResult = " + getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID]);\n"
360e5c31af7Sopenharmony_ci        "  if (" + getCompare(caseDef.opType, caseDef.format, "allResult", "refResult") + ") {\n"
361e5c31af7Sopenharmony_ci        "      tempResult |= 0x1u;\n"
362e5c31af7Sopenharmony_ci        "  }\n";
363e5c31af7Sopenharmony_ci
364e5c31af7Sopenharmony_ci    // The definition of a partition doesn't forbid bits corresponding to inactive
365e5c31af7Sopenharmony_ci    // invocations being in the subset with active invocations. In other words, test that
366e5c31af7Sopenharmony_ci    // bits corresponding to inactive invocations are ignored.
367e5c31af7Sopenharmony_ci    bdy +=
368e5c31af7Sopenharmony_ci	    "  if (0u == (gl_SubgroupInvocationID % 2u)) {\n"
369e5c31af7Sopenharmony_ci        "    " + fmt + " allResult = " + getOpTypeNamePartitioned(caseDef.opType) + "(data[gl_SubgroupInvocationID], allBallot);\n"
370e5c31af7Sopenharmony_ci        "    " + fmt + " refResult = " + getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID]);\n"
371e5c31af7Sopenharmony_ci        "    if (" + getCompare(caseDef.opType, caseDef.format, "allResult", "refResult") + ") {\n"
372e5c31af7Sopenharmony_ci        "        tempResult |= 0x2u;\n"
373e5c31af7Sopenharmony_ci        "    }\n"
374e5c31af7Sopenharmony_ci        "  } else {\n"
375e5c31af7Sopenharmony_ci        "    tempResult |= 0x2u;\n"
376e5c31af7Sopenharmony_ci        "  }\n";
377e5c31af7Sopenharmony_ci
378e5c31af7Sopenharmony_ci    // Test the case where the partition has each invocation in a unique subset. For
379e5c31af7Sopenharmony_ci    // exclusive ops, the result is identity. For reduce/inclusive, it's the original value.
380e5c31af7Sopenharmony_ci    string expectedSelfResult = "data[gl_SubgroupInvocationID]";
381e5c31af7Sopenharmony_ci    if (caseDef.opType >= OPTYPE_EXCLUSIVE_ADD &&
382e5c31af7Sopenharmony_ci        caseDef.opType <= OPTYPE_EXCLUSIVE_XOR) {
383e5c31af7Sopenharmony_ci        expectedSelfResult = getIdentity(caseDef.opType, caseDef.format);
384e5c31af7Sopenharmony_ci    }
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_ci    bdy +=
387e5c31af7Sopenharmony_ci        "  uvec4 selfBallot = subgroupPartitionNV(gl_SubgroupInvocationID);\n"
388e5c31af7Sopenharmony_ci        "  " + fmt + " selfResult = " + getOpTypeNamePartitioned(caseDef.opType) + "(data[gl_SubgroupInvocationID], selfBallot);\n"
389e5c31af7Sopenharmony_ci        "  if (" + getCompare(caseDef.opType, caseDef.format, "selfResult", expectedSelfResult) + ") {\n"
390e5c31af7Sopenharmony_ci        "      tempResult |= 0x4u;\n"
391e5c31af7Sopenharmony_ci        "  }\n";
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ci    // Test "random" partitions based on a hash of the invocation id.
394e5c31af7Sopenharmony_ci    // This "hash" function produces interesting/randomish partitions.
395e5c31af7Sopenharmony_ci    static const char *idhash = "((id%N)+(id%(N+1u))-(id%2u)+(id/2u))%((N+1u)/2u)";
396e5c31af7Sopenharmony_ci
397e5c31af7Sopenharmony_ci    bdy +=
398e5c31af7Sopenharmony_ci		"  for (uint N = 1u; N < 16u; ++N) {\n"
399e5c31af7Sopenharmony_ci		"    " + fmt + " idhashFmt = " + fmt + "(" + idhash + ");\n"
400e5c31af7Sopenharmony_ci		"    uvec4 partitionBallot = subgroupPartitionNV(idhashFmt) & mask;\n"
401e5c31af7Sopenharmony_ci		"    " + fmt + " partitionedResult = " + getOpTypeNamePartitioned(caseDef.opType) + "(data[gl_SubgroupInvocationID], partitionBallot);\n"
402e5c31af7Sopenharmony_ci		"      for (uint i = 0u; i < N; ++i) {\n"
403e5c31af7Sopenharmony_ci		"        " + fmt + " iFmt = " + fmt + "(i);\n"
404e5c31af7Sopenharmony_ci        "        if (" + getCompare(caseDef.opType, caseDef.format, "idhashFmt", "iFmt") + ") {\n"
405e5c31af7Sopenharmony_ci        "          " + fmt + " subsetResult = " + getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID]);\n"
406e5c31af7Sopenharmony_ci        "          tempResult |= " + getCompare(caseDef.opType, caseDef.format, "partitionedResult", "subsetResult") + " ? (0x4u << N) : 0u;\n"
407e5c31af7Sopenharmony_ci        "        }\n"
408e5c31af7Sopenharmony_ci        "      }\n"
409e5c31af7Sopenharmony_ci        "  }\n"
410e5c31af7Sopenharmony_ci        // tests in flow control:
411e5c31af7Sopenharmony_ci		"  if (1u == (gl_SubgroupInvocationID % 2u)) {\n"
412e5c31af7Sopenharmony_ci        "    for (uint N = 1u; N < 7u; ++N) {\n"
413e5c31af7Sopenharmony_ci		"      " + fmt + " idhashFmt = " + fmt + "(" + idhash + ");\n"
414e5c31af7Sopenharmony_ci		"      uvec4 partitionBallot = subgroupPartitionNV(idhashFmt) & mask;\n"
415e5c31af7Sopenharmony_ci        "      " + fmt + " partitionedResult = " + getOpTypeNamePartitioned(caseDef.opType) + "(data[gl_SubgroupInvocationID], partitionBallot);\n"
416e5c31af7Sopenharmony_ci        "        for (uint i = 0u; i < N; ++i) {\n"
417e5c31af7Sopenharmony_ci		"          " + fmt + " iFmt = " + fmt + "(i);\n"
418e5c31af7Sopenharmony_ci        "          if (" + getCompare(caseDef.opType, caseDef.format, "idhashFmt", "iFmt") + ") {\n"
419e5c31af7Sopenharmony_ci        "            " + fmt + " subsetResult = " + getOpTypeName(caseDef.opType) + "(data[gl_SubgroupInvocationID]);\n"
420e5c31af7Sopenharmony_ci        "            tempResult |= " + getCompare(caseDef.opType, caseDef.format, "partitionedResult", "subsetResult") + " ? (0x20000u << N) : 0u;\n"
421e5c31af7Sopenharmony_ci        "          }\n"
422e5c31af7Sopenharmony_ci        "        }\n"
423e5c31af7Sopenharmony_ci        "    }\n"
424e5c31af7Sopenharmony_ci        "  } else {\n"
425e5c31af7Sopenharmony_ci        "    tempResult |= 0xFC0000u;\n"
426e5c31af7Sopenharmony_ci        "  }\n"
427e5c31af7Sopenharmony_ci        ;
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci    return bdy;
430e5c31af7Sopenharmony_ci}
431e5c31af7Sopenharmony_ci
432e5c31af7Sopenharmony_civoid initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef)
433e5c31af7Sopenharmony_ci{
434e5c31af7Sopenharmony_ci	std::ostringstream				bdy;
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_ci	subgroups::setFragmentShaderFrameBuffer(programCollection);
437e5c31af7Sopenharmony_ci
438e5c31af7Sopenharmony_ci	if (SHADER_STAGE_VERTEX_BIT != caseDef.shaderStage)
439e5c31af7Sopenharmony_ci		subgroups::setVertexShaderFrameBuffer(programCollection);
440e5c31af7Sopenharmony_ci
441e5c31af7Sopenharmony_ci	bdy << getTestString(caseDef);
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
444e5c31af7Sopenharmony_ci	{
445e5c31af7Sopenharmony_ci		std::ostringstream vertexSrc;
446e5c31af7Sopenharmony_ci		vertexSrc << "${VERSION_DECL}\n"
447e5c31af7Sopenharmony_ci			<< "#extension GL_NV_shader_subgroup_partitioned: enable\n"
448e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
449e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
450e5c31af7Sopenharmony_ci			<< "layout(location = 0) in highp vec4 in_position;\n"
451e5c31af7Sopenharmony_ci			<< "layout(location = 0) out float out_color;\n"
452e5c31af7Sopenharmony_ci			<< "layout(binding = 0, std140) uniform Buffer0\n"
453e5c31af7Sopenharmony_ci			<< "{\n"
454e5c31af7Sopenharmony_ci			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
455e5c31af7Sopenharmony_ci			<< "};\n"
456e5c31af7Sopenharmony_ci			<< "\n"
457e5c31af7Sopenharmony_ci			<< "void main (void)\n"
458e5c31af7Sopenharmony_ci			<< "{\n"
459e5c31af7Sopenharmony_ci			<< "  uvec4 mask = subgroupBallot(true);\n"
460e5c31af7Sopenharmony_ci			<< bdy.str()
461e5c31af7Sopenharmony_ci			<< "  out_color = float(tempResult);\n"
462e5c31af7Sopenharmony_ci			<< "  gl_Position = in_position;\n"
463e5c31af7Sopenharmony_ci			<< "  gl_PointSize = 1.0f;\n"
464e5c31af7Sopenharmony_ci			<< "}\n";
465e5c31af7Sopenharmony_ci		programCollection.add("vert") << glu::VertexSource(vertexSrc.str());
466e5c31af7Sopenharmony_ci	}
467e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
468e5c31af7Sopenharmony_ci	{
469e5c31af7Sopenharmony_ci		std::ostringstream geometry;
470e5c31af7Sopenharmony_ci
471e5c31af7Sopenharmony_ci		geometry << "${VERSION_DECL}\n"
472e5c31af7Sopenharmony_ci			<< "#extension GL_NV_shader_subgroup_partitioned: enable\n"
473e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
474e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
475e5c31af7Sopenharmony_ci			<< "layout(points) in;\n"
476e5c31af7Sopenharmony_ci			<< "layout(points, max_vertices = 1) out;\n"
477e5c31af7Sopenharmony_ci			<< "layout(location = 0) out float out_color;\n"
478e5c31af7Sopenharmony_ci			<< "layout(binding = 0, std140) uniform Buffer0\n"
479e5c31af7Sopenharmony_ci			<< "{\n"
480e5c31af7Sopenharmony_ci			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
481e5c31af7Sopenharmony_ci			<< "};\n"
482e5c31af7Sopenharmony_ci			<< "\n"
483e5c31af7Sopenharmony_ci			<< "void main (void)\n"
484e5c31af7Sopenharmony_ci			<< "{\n"
485e5c31af7Sopenharmony_ci			<< "  uvec4 mask = subgroupBallot(true);\n"
486e5c31af7Sopenharmony_ci			<< bdy.str()
487e5c31af7Sopenharmony_ci			<< "  out_color = float(tempResult);\n"
488e5c31af7Sopenharmony_ci			<< "  gl_Position = gl_in[0].gl_Position;\n"
489e5c31af7Sopenharmony_ci			<< "  EmitVertex();\n"
490e5c31af7Sopenharmony_ci			<< "  EndPrimitive();\n"
491e5c31af7Sopenharmony_ci			<< "}\n";
492e5c31af7Sopenharmony_ci
493e5c31af7Sopenharmony_ci		programCollection.add("geometry") << glu::GeometrySource(geometry.str());
494e5c31af7Sopenharmony_ci	}
495e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
496e5c31af7Sopenharmony_ci	{
497e5c31af7Sopenharmony_ci		std::ostringstream controlSource;
498e5c31af7Sopenharmony_ci		controlSource  << "${VERSION_DECL}\n"
499e5c31af7Sopenharmony_ci			<< "#extension GL_NV_shader_subgroup_partitioned: enable\n"
500e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
501e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
502e5c31af7Sopenharmony_ci			<< "layout(vertices = 2) out;\n"
503e5c31af7Sopenharmony_ci			<< "layout(location = 0) out float out_color[];\n"
504e5c31af7Sopenharmony_ci			<< "layout(binding = 0, std140) uniform Buffer0\n"
505e5c31af7Sopenharmony_ci			<< "{\n"
506e5c31af7Sopenharmony_ci			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
507e5c31af7Sopenharmony_ci			<< "};\n"
508e5c31af7Sopenharmony_ci			<< "\n"
509e5c31af7Sopenharmony_ci			<< "void main (void)\n"
510e5c31af7Sopenharmony_ci			<< "{\n"
511e5c31af7Sopenharmony_ci			<< "  if (gl_InvocationID == 0)\n"
512e5c31af7Sopenharmony_ci			<<"  {\n"
513e5c31af7Sopenharmony_ci			<< "    gl_TessLevelOuter[0] = 1.0f;\n"
514e5c31af7Sopenharmony_ci			<< "    gl_TessLevelOuter[1] = 1.0f;\n"
515e5c31af7Sopenharmony_ci			<< "  }\n"
516e5c31af7Sopenharmony_ci			<< "  uvec4 mask = subgroupBallot(true);\n"
517e5c31af7Sopenharmony_ci			<< bdy.str()
518e5c31af7Sopenharmony_ci			<< "  out_color[gl_InvocationID] = float(tempResult);"
519e5c31af7Sopenharmony_ci			<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
520e5c31af7Sopenharmony_ci			<< "}\n";
521e5c31af7Sopenharmony_ci
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_ci		programCollection.add("tesc") << glu::TessellationControlSource(controlSource.str());
524e5c31af7Sopenharmony_ci		subgroups::setTesEvalShaderFrameBuffer(programCollection);
525e5c31af7Sopenharmony_ci	}
526e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
527e5c31af7Sopenharmony_ci	{
528e5c31af7Sopenharmony_ci
529e5c31af7Sopenharmony_ci		std::ostringstream evaluationSource;
530e5c31af7Sopenharmony_ci		evaluationSource << "${VERSION_DECL}\n"
531e5c31af7Sopenharmony_ci			<< "#extension GL_NV_shader_subgroup_partitioned: enable\n"
532e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
533e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
534e5c31af7Sopenharmony_ci			<< "layout(isolines, equal_spacing, ccw ) in;\n"
535e5c31af7Sopenharmony_ci			<< "layout(location = 0) out float out_color;\n"
536e5c31af7Sopenharmony_ci			<< "layout(binding = 0, std140) uniform Buffer0\n"
537e5c31af7Sopenharmony_ci			<< "{\n"
538e5c31af7Sopenharmony_ci			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[" << subgroups::maxSupportedSubgroupSize() << "];\n"
539e5c31af7Sopenharmony_ci			<< "};\n"
540e5c31af7Sopenharmony_ci			<< "\n"
541e5c31af7Sopenharmony_ci			<< "void main (void)\n"
542e5c31af7Sopenharmony_ci			<< "{\n"
543e5c31af7Sopenharmony_ci			<< "  uvec4 mask = subgroupBallot(true);\n"
544e5c31af7Sopenharmony_ci			<< bdy.str()
545e5c31af7Sopenharmony_ci			<< "  out_color = float(tempResult);\n"
546e5c31af7Sopenharmony_ci			<< "  gl_Position = mix(gl_in[0].gl_Position, gl_in[1].gl_Position, gl_TessCoord.x);\n"
547e5c31af7Sopenharmony_ci			<< "}\n";
548e5c31af7Sopenharmony_ci
549e5c31af7Sopenharmony_ci		subgroups::setTesCtrlShaderFrameBuffer(programCollection);
550e5c31af7Sopenharmony_ci		programCollection.add("tese") << glu::TessellationEvaluationSource(evaluationSource.str());
551e5c31af7Sopenharmony_ci	}
552e5c31af7Sopenharmony_ci	else
553e5c31af7Sopenharmony_ci	{
554e5c31af7Sopenharmony_ci		DE_FATAL("Unsupported shader stage");
555e5c31af7Sopenharmony_ci	}
556e5c31af7Sopenharmony_ci}
557e5c31af7Sopenharmony_ci
558e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& programCollection, CaseDefinition caseDef)
559e5c31af7Sopenharmony_ci{
560e5c31af7Sopenharmony_ci	const string bdy = getTestString(caseDef);
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_ci	if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
563e5c31af7Sopenharmony_ci	{
564e5c31af7Sopenharmony_ci		std::ostringstream src;
565e5c31af7Sopenharmony_ci
566e5c31af7Sopenharmony_ci		src << "${VERSION_DECL}\n"
567e5c31af7Sopenharmony_ci			<< "#extension GL_NV_shader_subgroup_partitioned: enable\n"
568e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
569e5c31af7Sopenharmony_ci			<< "#extension GL_KHR_shader_subgroup_ballot: enable\n"
570e5c31af7Sopenharmony_ci			<< "layout (${LOCAL_SIZE_X}, ${LOCAL_SIZE_Y}, ${LOCAL_SIZE_Z}) in;\n"
571e5c31af7Sopenharmony_ci			<< "layout(binding = 0, std430) buffer Buffer0\n"
572e5c31af7Sopenharmony_ci			<< "{\n"
573e5c31af7Sopenharmony_ci			<< "  uint result[];\n"
574e5c31af7Sopenharmony_ci			<< "};\n"
575e5c31af7Sopenharmony_ci			<< "layout(binding = 1, std430) buffer Buffer1\n"
576e5c31af7Sopenharmony_ci			<< "{\n"
577e5c31af7Sopenharmony_ci			<< "  " << subgroups::getFormatNameForGLSL(caseDef.format) << " data[];\n"
578e5c31af7Sopenharmony_ci			<< "};\n"
579e5c31af7Sopenharmony_ci			<< "\n"
580e5c31af7Sopenharmony_ci			<< "void main (void)\n"
581e5c31af7Sopenharmony_ci			<< "{\n"
582e5c31af7Sopenharmony_ci			<< "  uvec3 globalSize = gl_NumWorkGroups * gl_WorkGroupSize;\n"
583e5c31af7Sopenharmony_ci			<< "  highp uint offset = globalSize.x * ((globalSize.y * "
584e5c31af7Sopenharmony_ci			"gl_GlobalInvocationID.z) + gl_GlobalInvocationID.y) + "
585e5c31af7Sopenharmony_ci			"gl_GlobalInvocationID.x;\n"
586e5c31af7Sopenharmony_ci			<< "  uvec4 mask = subgroupBallot(true);\n"
587e5c31af7Sopenharmony_ci			<< bdy
588e5c31af7Sopenharmony_ci			<< "  result[offset] = tempResult;\n"
589e5c31af7Sopenharmony_ci			<< "}\n";
590e5c31af7Sopenharmony_ci
591e5c31af7Sopenharmony_ci		programCollection.add("comp") << glu::ComputeSource(src.str());
592e5c31af7Sopenharmony_ci	}
593e5c31af7Sopenharmony_ci	else
594e5c31af7Sopenharmony_ci	{
595e5c31af7Sopenharmony_ci		{
596e5c31af7Sopenharmony_ci			const std::string vertex =
597e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
598e5c31af7Sopenharmony_ci				"#extension GL_NV_shader_subgroup_partitioned: enable\n"
599e5c31af7Sopenharmony_ci			    "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
600e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
601e5c31af7Sopenharmony_ci				"layout(binding = 0, std430) buffer Buffer0\n"
602e5c31af7Sopenharmony_ci				"{\n"
603e5c31af7Sopenharmony_ci				"  uint result[];\n"
604e5c31af7Sopenharmony_ci				"} b0;\n"
605e5c31af7Sopenharmony_ci				"layout(binding = 4, std430) readonly buffer Buffer4\n"
606e5c31af7Sopenharmony_ci				"{\n"
607e5c31af7Sopenharmony_ci				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
608e5c31af7Sopenharmony_ci				"};\n"
609e5c31af7Sopenharmony_ci				"\n"
610e5c31af7Sopenharmony_ci				"void main (void)\n"
611e5c31af7Sopenharmony_ci				"{\n"
612e5c31af7Sopenharmony_ci				"  uvec4 mask = subgroupBallot(true);\n"
613e5c31af7Sopenharmony_ci				+ bdy+
614e5c31af7Sopenharmony_ci				"  b0.result[gl_VertexID] = tempResult;\n"
615e5c31af7Sopenharmony_ci				"  float pixelSize = 2.0f/1024.0f;\n"
616e5c31af7Sopenharmony_ci				"  float pixelPosition = pixelSize/2.0f - 1.0f;\n"
617e5c31af7Sopenharmony_ci				"  gl_Position = vec4(float(gl_VertexID) * pixelSize + pixelPosition, 0.0f, 0.0f, 1.0f);\n"
618e5c31af7Sopenharmony_ci				"  gl_PointSize = 1.0f;\n"
619e5c31af7Sopenharmony_ci				"}\n";
620e5c31af7Sopenharmony_ci			programCollection.add("vert") << glu::VertexSource(vertex);
621e5c31af7Sopenharmony_ci		}
622e5c31af7Sopenharmony_ci
623e5c31af7Sopenharmony_ci		{
624e5c31af7Sopenharmony_ci			const std::string tesc =
625e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
626e5c31af7Sopenharmony_ci				"#extension GL_NV_shader_subgroup_partitioned: enable\n"
627e5c31af7Sopenharmony_ci			    "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
628e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
629e5c31af7Sopenharmony_ci				"layout(vertices=1) out;\n"
630e5c31af7Sopenharmony_ci				"layout(binding = 1, std430) buffer Buffer1\n"
631e5c31af7Sopenharmony_ci				"{\n"
632e5c31af7Sopenharmony_ci				"  uint result[];\n"
633e5c31af7Sopenharmony_ci				"} b1;\n"
634e5c31af7Sopenharmony_ci				"layout(binding = 4, std430) readonly buffer Buffer4\n"
635e5c31af7Sopenharmony_ci				"{\n"
636e5c31af7Sopenharmony_ci				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
637e5c31af7Sopenharmony_ci				"};\n"
638e5c31af7Sopenharmony_ci				"\n"
639e5c31af7Sopenharmony_ci				"void main (void)\n"
640e5c31af7Sopenharmony_ci				"{\n"
641e5c31af7Sopenharmony_ci				"  uvec4 mask = subgroupBallot(true);\n"
642e5c31af7Sopenharmony_ci				+ bdy +
643e5c31af7Sopenharmony_ci				"  b1.result[gl_PrimitiveID] = tempResult;\n"
644e5c31af7Sopenharmony_ci				"  if (gl_InvocationID == 0)\n"
645e5c31af7Sopenharmony_ci				"  {\n"
646e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[0] = 1.0f;\n"
647e5c31af7Sopenharmony_ci				"    gl_TessLevelOuter[1] = 1.0f;\n"
648e5c31af7Sopenharmony_ci				"  }\n"
649e5c31af7Sopenharmony_ci				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
650e5c31af7Sopenharmony_ci				"}\n";
651e5c31af7Sopenharmony_ci			programCollection.add("tesc") << glu::TessellationControlSource(tesc);
652e5c31af7Sopenharmony_ci		}
653e5c31af7Sopenharmony_ci
654e5c31af7Sopenharmony_ci		{
655e5c31af7Sopenharmony_ci			const std::string tese =
656e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
657e5c31af7Sopenharmony_ci				"#extension GL_NV_shader_subgroup_partitioned: enable\n"
658e5c31af7Sopenharmony_ci			    "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
659e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
660e5c31af7Sopenharmony_ci				"layout(isolines) in;\n"
661e5c31af7Sopenharmony_ci				"layout(binding = 2, std430) buffer Buffer2\n"
662e5c31af7Sopenharmony_ci				"{\n"
663e5c31af7Sopenharmony_ci				"  uint result[];\n"
664e5c31af7Sopenharmony_ci				"} b2;\n"
665e5c31af7Sopenharmony_ci				"layout(binding = 4, std430) readonly buffer Buffer4\n"
666e5c31af7Sopenharmony_ci				"{\n"
667e5c31af7Sopenharmony_ci				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
668e5c31af7Sopenharmony_ci				"};\n"
669e5c31af7Sopenharmony_ci				"\n"
670e5c31af7Sopenharmony_ci				"void main (void)\n"
671e5c31af7Sopenharmony_ci				"{\n"
672e5c31af7Sopenharmony_ci				"  uvec4 mask = subgroupBallot(true);\n"
673e5c31af7Sopenharmony_ci				+ bdy +
674e5c31af7Sopenharmony_ci				"  b2.result[gl_PrimitiveID * 2 + int(gl_TessCoord.x + 0.5)] = tempResult;\n"
675e5c31af7Sopenharmony_ci				"  float pixelSize = 2.0f/1024.0f;\n"
676e5c31af7Sopenharmony_ci				"  gl_Position = gl_in[0].gl_Position + gl_TessCoord.x * pixelSize / 2.0f;\n"
677e5c31af7Sopenharmony_ci				"}\n";
678e5c31af7Sopenharmony_ci			programCollection.add("tese") << glu::TessellationEvaluationSource(tese);
679e5c31af7Sopenharmony_ci		}
680e5c31af7Sopenharmony_ci
681e5c31af7Sopenharmony_ci		{
682e5c31af7Sopenharmony_ci			const std::string geometry =
683e5c31af7Sopenharmony_ci				// version added by addGeometryShadersFromTemplate
684e5c31af7Sopenharmony_ci				"#extension GL_NV_shader_subgroup_partitioned: enable\n"
685e5c31af7Sopenharmony_ci			    "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
686e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
687e5c31af7Sopenharmony_ci				"layout(${TOPOLOGY}) in;\n"
688e5c31af7Sopenharmony_ci				"layout(points, max_vertices = 1) out;\n"
689e5c31af7Sopenharmony_ci				"layout(binding = 3, std430) buffer Buffer3\n"
690e5c31af7Sopenharmony_ci				"{\n"
691e5c31af7Sopenharmony_ci				"  uint result[];\n"
692e5c31af7Sopenharmony_ci				"} b3;\n"
693e5c31af7Sopenharmony_ci				"layout(binding = 4, std430) readonly buffer Buffer4\n"
694e5c31af7Sopenharmony_ci				"{\n"
695e5c31af7Sopenharmony_ci				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
696e5c31af7Sopenharmony_ci				"};\n"
697e5c31af7Sopenharmony_ci				"\n"
698e5c31af7Sopenharmony_ci				"void main (void)\n"
699e5c31af7Sopenharmony_ci				"{\n"
700e5c31af7Sopenharmony_ci				"  uvec4 mask = subgroupBallot(true);\n"
701e5c31af7Sopenharmony_ci				 + bdy +
702e5c31af7Sopenharmony_ci				"  b3.result[gl_PrimitiveIDIn] = tempResult;\n"
703e5c31af7Sopenharmony_ci				"  gl_Position = gl_in[0].gl_Position;\n"
704e5c31af7Sopenharmony_ci				"  EmitVertex();\n"
705e5c31af7Sopenharmony_ci				"  EndPrimitive();\n"
706e5c31af7Sopenharmony_ci				"}\n";
707e5c31af7Sopenharmony_ci			subgroups::addGeometryShadersFromTemplate(geometry, programCollection);
708e5c31af7Sopenharmony_ci		}
709e5c31af7Sopenharmony_ci
710e5c31af7Sopenharmony_ci		{
711e5c31af7Sopenharmony_ci			const std::string fragment =
712e5c31af7Sopenharmony_ci				"${VERSION_DECL}\n"
713e5c31af7Sopenharmony_ci				"#extension GL_NV_shader_subgroup_partitioned: enable\n"
714e5c31af7Sopenharmony_ci			    "#extension GL_KHR_shader_subgroup_arithmetic: enable\n"
715e5c31af7Sopenharmony_ci				"#extension GL_KHR_shader_subgroup_ballot: enable\n"
716e5c31af7Sopenharmony_ci				"precision highp int;\n"
717e5c31af7Sopenharmony_ci				"precision highp float;\n"
718e5c31af7Sopenharmony_ci				"layout(location = 0) out uint result;\n"
719e5c31af7Sopenharmony_ci				"layout(binding = 4, std430) readonly buffer Buffer4\n"
720e5c31af7Sopenharmony_ci				"{\n"
721e5c31af7Sopenharmony_ci				"  " + subgroups::getFormatNameForGLSL(caseDef.format) + " data[];\n"
722e5c31af7Sopenharmony_ci				"};\n"
723e5c31af7Sopenharmony_ci				"void main (void)\n"
724e5c31af7Sopenharmony_ci				"{\n"
725e5c31af7Sopenharmony_ci				"  uvec4 mask = subgroupBallot(true);\n"
726e5c31af7Sopenharmony_ci				+ bdy +
727e5c31af7Sopenharmony_ci				"  result = tempResult;\n"
728e5c31af7Sopenharmony_ci				"}\n";
729e5c31af7Sopenharmony_ci			programCollection.add("fragment") << glu::FragmentSource(fragment);
730e5c31af7Sopenharmony_ci		}
731e5c31af7Sopenharmony_ci		subgroups::addNoSubgroupShader(programCollection);
732e5c31af7Sopenharmony_ci	}
733e5c31af7Sopenharmony_ci}
734e5c31af7Sopenharmony_ci
735e5c31af7Sopenharmony_civoid supportedCheck (Context& context, CaseDefinition caseDef)
736e5c31af7Sopenharmony_ci{
737e5c31af7Sopenharmony_ci	if (!subgroups::isSubgroupSupported(context))
738e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Subgroup operations are not supported");
739e5c31af7Sopenharmony_ci
740e5c31af7Sopenharmony_ci	if (!subgroups::isSubgroupFeatureSupportedForDevice(context, SUBGROUP_FEATURE_PARTITIONED_BIT_NV))
741e5c31af7Sopenharmony_ci	{
742e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Device does not support subgroup partitioned operations");
743e5c31af7Sopenharmony_ci	}
744e5c31af7Sopenharmony_ci
745e5c31af7Sopenharmony_ci	if (subgroups::isDoubleFormat(caseDef.format) &&
746e5c31af7Sopenharmony_ci			!subgroups::isDoubleSupportedForDevice(context))
747e5c31af7Sopenharmony_ci	{
748e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Device does not support subgroup double operations");
749e5c31af7Sopenharmony_ci	}
750e5c31af7Sopenharmony_ci}
751e5c31af7Sopenharmony_ci
752e5c31af7Sopenharmony_citcu::TestStatus noSSBOtest (Context& context, const CaseDefinition caseDef)
753e5c31af7Sopenharmony_ci{
754e5c31af7Sopenharmony_ci	if (!subgroups::areSubgroupOperationsSupportedForStage(
755e5c31af7Sopenharmony_ci				context, caseDef.shaderStage))
756e5c31af7Sopenharmony_ci	{
757e5c31af7Sopenharmony_ci		if (subgroups::areSubgroupOperationsRequiredForStage(
758e5c31af7Sopenharmony_ci					caseDef.shaderStage))
759e5c31af7Sopenharmony_ci		{
760e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail(
761e5c31af7Sopenharmony_ci					   "Shader stage " +
762e5c31af7Sopenharmony_ci					   subgroups::getShaderStageName(caseDef.shaderStage) +
763e5c31af7Sopenharmony_ci					   " is required to support subgroup operations!");
764e5c31af7Sopenharmony_ci		}
765e5c31af7Sopenharmony_ci		else
766e5c31af7Sopenharmony_ci		{
767e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
768e5c31af7Sopenharmony_ci		}
769e5c31af7Sopenharmony_ci	}
770e5c31af7Sopenharmony_ci
771e5c31af7Sopenharmony_ci	subgroups::SSBOData inputData;
772e5c31af7Sopenharmony_ci	inputData.format = caseDef.format;
773e5c31af7Sopenharmony_ci	inputData.layout = subgroups::SSBOData::LayoutStd140;
774e5c31af7Sopenharmony_ci	inputData.numElements = subgroups::maxSupportedSubgroupSize();
775e5c31af7Sopenharmony_ci	inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
776e5c31af7Sopenharmony_ci	inputData.binding = 0u;
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci	if (SHADER_STAGE_VERTEX_BIT == caseDef.shaderStage)
779e5c31af7Sopenharmony_ci		return subgroups::makeVertexFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
780e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_GEOMETRY_BIT == caseDef.shaderStage)
781e5c31af7Sopenharmony_ci		return subgroups::makeGeometryFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages);
782e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_TESS_CONTROL_BIT == caseDef.shaderStage)
783e5c31af7Sopenharmony_ci		return subgroups::makeTessellationEvaluationFrameBufferTest(context, FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_CONTROL_BIT);
784e5c31af7Sopenharmony_ci	else if (SHADER_STAGE_TESS_EVALUATION_BIT == caseDef.shaderStage)
785e5c31af7Sopenharmony_ci		return subgroups::makeTessellationEvaluationFrameBufferTest(context,  FORMAT_R32_UINT, &inputData, 1, checkVertexPipelineStages, SHADER_STAGE_TESS_EVALUATION_BIT);
786e5c31af7Sopenharmony_ci	else
787e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Unhandled shader stage");
788e5c31af7Sopenharmony_ci}
789e5c31af7Sopenharmony_ci
790e5c31af7Sopenharmony_cibool checkShaderStages (Context& context, const CaseDefinition& caseDef)
791e5c31af7Sopenharmony_ci{
792e5c31af7Sopenharmony_ci	if (!subgroups::areSubgroupOperationsSupportedForStage(
793e5c31af7Sopenharmony_ci				context, caseDef.shaderStage))
794e5c31af7Sopenharmony_ci	{
795e5c31af7Sopenharmony_ci		if (subgroups::areSubgroupOperationsRequiredForStage(
796e5c31af7Sopenharmony_ci					caseDef.shaderStage))
797e5c31af7Sopenharmony_ci		{
798e5c31af7Sopenharmony_ci			return false;
799e5c31af7Sopenharmony_ci		}
800e5c31af7Sopenharmony_ci		else
801e5c31af7Sopenharmony_ci		{
802e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Device does not support subgroup operations for this stage");
803e5c31af7Sopenharmony_ci		}
804e5c31af7Sopenharmony_ci	}
805e5c31af7Sopenharmony_ci	return true;
806e5c31af7Sopenharmony_ci}
807e5c31af7Sopenharmony_ci
808e5c31af7Sopenharmony_citcu::TestStatus test(Context& context, const CaseDefinition caseDef)
809e5c31af7Sopenharmony_ci{
810e5c31af7Sopenharmony_ci	if (SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage)
811e5c31af7Sopenharmony_ci	{
812e5c31af7Sopenharmony_ci		if(!checkShaderStages(context,caseDef))
813e5c31af7Sopenharmony_ci		{
814e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail(
815e5c31af7Sopenharmony_ci							"Shader stage " +
816e5c31af7Sopenharmony_ci							subgroups::getShaderStageName(caseDef.shaderStage) +
817e5c31af7Sopenharmony_ci							" is required to support subgroup operations!");
818e5c31af7Sopenharmony_ci		}
819e5c31af7Sopenharmony_ci		subgroups::SSBOData inputData;
820e5c31af7Sopenharmony_ci		inputData.format = caseDef.format;
821e5c31af7Sopenharmony_ci		inputData.layout = subgroups::SSBOData::LayoutStd430;
822e5c31af7Sopenharmony_ci		inputData.numElements = subgroups::maxSupportedSubgroupSize();
823e5c31af7Sopenharmony_ci		inputData.initializeType = subgroups::SSBOData::InitializeNonZero;
824e5c31af7Sopenharmony_ci		inputData.binding = 1u;
825e5c31af7Sopenharmony_ci
826e5c31af7Sopenharmony_ci		return subgroups::makeComputeTest(context, FORMAT_R32_UINT, &inputData, 1, checkComputeStage);
827e5c31af7Sopenharmony_ci	}
828e5c31af7Sopenharmony_ci	else
829e5c31af7Sopenharmony_ci	{
830e5c31af7Sopenharmony_ci		int supportedStages = context.getDeqpContext().getContextInfo().getInt(GL_SUBGROUP_SUPPORTED_STAGES_KHR);
831e5c31af7Sopenharmony_ci
832e5c31af7Sopenharmony_ci		ShaderStageFlags stages = (ShaderStageFlags)(caseDef.shaderStage & supportedStages);
833e5c31af7Sopenharmony_ci
834e5c31af7Sopenharmony_ci		if ( SHADER_STAGE_FRAGMENT_BIT != stages && !subgroups::isVertexSSBOSupportedForDevice(context))
835e5c31af7Sopenharmony_ci		{
836e5c31af7Sopenharmony_ci			if ( (stages & SHADER_STAGE_FRAGMENT_BIT) == 0)
837e5c31af7Sopenharmony_ci				TCU_THROW(NotSupportedError, "Device does not support vertex stage SSBO writes");
838e5c31af7Sopenharmony_ci			else
839e5c31af7Sopenharmony_ci				stages = SHADER_STAGE_FRAGMENT_BIT;
840e5c31af7Sopenharmony_ci		}
841e5c31af7Sopenharmony_ci
842e5c31af7Sopenharmony_ci		if ((ShaderStageFlags)0u == stages)
843e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Subgroup operations are not supported for any graphic shader");
844e5c31af7Sopenharmony_ci
845e5c31af7Sopenharmony_ci		subgroups::SSBOData inputData;
846e5c31af7Sopenharmony_ci		inputData.format			= caseDef.format;
847e5c31af7Sopenharmony_ci		inputData.layout			= subgroups::SSBOData::LayoutStd430;
848e5c31af7Sopenharmony_ci		inputData.numElements		= subgroups::maxSupportedSubgroupSize();
849e5c31af7Sopenharmony_ci		inputData.initializeType	= subgroups::SSBOData::InitializeNonZero;
850e5c31af7Sopenharmony_ci		inputData.binding			= 4u;
851e5c31af7Sopenharmony_ci		inputData.stages			= stages;
852e5c31af7Sopenharmony_ci
853e5c31af7Sopenharmony_ci		return subgroups::allStages(context, FORMAT_R32_UINT, &inputData,
854e5c31af7Sopenharmony_ci										 1, checkVertexPipelineStages, stages);
855e5c31af7Sopenharmony_ci	}
856e5c31af7Sopenharmony_ci}
857e5c31af7Sopenharmony_ci}
858e5c31af7Sopenharmony_ci
859e5c31af7Sopenharmony_cideqp::TestCaseGroup* createSubgroupsPartitionedTests(deqp::Context& testCtx)
860e5c31af7Sopenharmony_ci{
861e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> graphicGroup(new deqp::TestCaseGroup(
862e5c31af7Sopenharmony_ci		testCtx, "graphics", "Subgroup partitioned category tests: graphics"));
863e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> computeGroup(new deqp::TestCaseGroup(
864e5c31af7Sopenharmony_ci		testCtx, "compute", "Subgroup partitioned category tests: compute"));
865e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> framebufferGroup(new deqp::TestCaseGroup(
866e5c31af7Sopenharmony_ci		testCtx, "framebuffer", "Subgroup partitioned category tests: framebuffer"));
867e5c31af7Sopenharmony_ci
868e5c31af7Sopenharmony_ci
869e5c31af7Sopenharmony_ci	const ShaderStageFlags stages[] =
870e5c31af7Sopenharmony_ci	{
871e5c31af7Sopenharmony_ci		SHADER_STAGE_VERTEX_BIT,
872e5c31af7Sopenharmony_ci		SHADER_STAGE_TESS_EVALUATION_BIT,
873e5c31af7Sopenharmony_ci		SHADER_STAGE_TESS_CONTROL_BIT,
874e5c31af7Sopenharmony_ci		SHADER_STAGE_GEOMETRY_BIT,
875e5c31af7Sopenharmony_ci	};
876e5c31af7Sopenharmony_ci
877e5c31af7Sopenharmony_ci	const Format formats[] =
878e5c31af7Sopenharmony_ci	{
879e5c31af7Sopenharmony_ci		FORMAT_R32_SINT, FORMAT_R32G32_SINT, FORMAT_R32G32B32_SINT,
880e5c31af7Sopenharmony_ci		FORMAT_R32G32B32A32_SINT, FORMAT_R32_UINT, FORMAT_R32G32_UINT,
881e5c31af7Sopenharmony_ci		FORMAT_R32G32B32_UINT, FORMAT_R32G32B32A32_UINT,
882e5c31af7Sopenharmony_ci		FORMAT_R32_SFLOAT, FORMAT_R32G32_SFLOAT,
883e5c31af7Sopenharmony_ci		FORMAT_R32G32B32_SFLOAT, FORMAT_R32G32B32A32_SFLOAT,
884e5c31af7Sopenharmony_ci		FORMAT_R64_SFLOAT, FORMAT_R64G64_SFLOAT,
885e5c31af7Sopenharmony_ci		FORMAT_R64G64B64_SFLOAT, FORMAT_R64G64B64A64_SFLOAT,
886e5c31af7Sopenharmony_ci		FORMAT_R32_BOOL, FORMAT_R32G32_BOOL,
887e5c31af7Sopenharmony_ci		FORMAT_R32G32B32_BOOL, FORMAT_R32G32B32A32_BOOL,
888e5c31af7Sopenharmony_ci	};
889e5c31af7Sopenharmony_ci
890e5c31af7Sopenharmony_ci	for (int formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(formats); ++formatIndex)
891e5c31af7Sopenharmony_ci	{
892e5c31af7Sopenharmony_ci		const Format format = formats[formatIndex];
893e5c31af7Sopenharmony_ci
894e5c31af7Sopenharmony_ci		for (int opTypeIndex = 0; opTypeIndex < OPTYPE_LAST; ++opTypeIndex)
895e5c31af7Sopenharmony_ci		{
896e5c31af7Sopenharmony_ci			bool isBool = false;
897e5c31af7Sopenharmony_ci			bool isFloat = false;
898e5c31af7Sopenharmony_ci
899e5c31af7Sopenharmony_ci			switch (format)
900e5c31af7Sopenharmony_ci			{
901e5c31af7Sopenharmony_ci				default:
902e5c31af7Sopenharmony_ci					break;
903e5c31af7Sopenharmony_ci				case FORMAT_R32_SFLOAT:
904e5c31af7Sopenharmony_ci				case FORMAT_R32G32_SFLOAT:
905e5c31af7Sopenharmony_ci				case FORMAT_R32G32B32_SFLOAT:
906e5c31af7Sopenharmony_ci				case FORMAT_R32G32B32A32_SFLOAT:
907e5c31af7Sopenharmony_ci				case FORMAT_R64_SFLOAT:
908e5c31af7Sopenharmony_ci				case FORMAT_R64G64_SFLOAT:
909e5c31af7Sopenharmony_ci				case FORMAT_R64G64B64_SFLOAT:
910e5c31af7Sopenharmony_ci				case FORMAT_R64G64B64A64_SFLOAT:
911e5c31af7Sopenharmony_ci					isFloat = true;
912e5c31af7Sopenharmony_ci					break;
913e5c31af7Sopenharmony_ci				case FORMAT_R32_BOOL:
914e5c31af7Sopenharmony_ci				case FORMAT_R32G32_BOOL:
915e5c31af7Sopenharmony_ci				case FORMAT_R32G32B32_BOOL:
916e5c31af7Sopenharmony_ci				case FORMAT_R32G32B32A32_BOOL:
917e5c31af7Sopenharmony_ci					isBool = true;
918e5c31af7Sopenharmony_ci					break;
919e5c31af7Sopenharmony_ci			}
920e5c31af7Sopenharmony_ci
921e5c31af7Sopenharmony_ci			bool isBitwiseOp = false;
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ci			switch (opTypeIndex)
924e5c31af7Sopenharmony_ci			{
925e5c31af7Sopenharmony_ci				default:
926e5c31af7Sopenharmony_ci					break;
927e5c31af7Sopenharmony_ci				case OPTYPE_AND:
928e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_AND:
929e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_AND:
930e5c31af7Sopenharmony_ci				case OPTYPE_OR:
931e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_OR:
932e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_OR:
933e5c31af7Sopenharmony_ci				case OPTYPE_XOR:
934e5c31af7Sopenharmony_ci				case OPTYPE_INCLUSIVE_XOR:
935e5c31af7Sopenharmony_ci				case OPTYPE_EXCLUSIVE_XOR:
936e5c31af7Sopenharmony_ci					isBitwiseOp = true;
937e5c31af7Sopenharmony_ci					break;
938e5c31af7Sopenharmony_ci			}
939e5c31af7Sopenharmony_ci
940e5c31af7Sopenharmony_ci			if (isFloat && isBitwiseOp)
941e5c31af7Sopenharmony_ci			{
942e5c31af7Sopenharmony_ci				// Skip float with bitwise category.
943e5c31af7Sopenharmony_ci				continue;
944e5c31af7Sopenharmony_ci			}
945e5c31af7Sopenharmony_ci
946e5c31af7Sopenharmony_ci			if (isBool && !isBitwiseOp)
947e5c31af7Sopenharmony_ci			{
948e5c31af7Sopenharmony_ci				// Skip bool when its not the bitwise category.
949e5c31af7Sopenharmony_ci				continue;
950e5c31af7Sopenharmony_ci			}
951e5c31af7Sopenharmony_ci			const std::string name = de::toLower(getOpTypeName(opTypeIndex)) + "_" +
952e5c31af7Sopenharmony_ci				subgroups::getFormatNameForGLSL(format);
953e5c31af7Sopenharmony_ci
954e5c31af7Sopenharmony_ci			{
955e5c31af7Sopenharmony_ci				const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_COMPUTE_BIT, format};
956e5c31af7Sopenharmony_ci				SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(computeGroup.get(),
957e5c31af7Sopenharmony_ci											name, "", supportedCheck, initPrograms, test, caseDef);
958e5c31af7Sopenharmony_ci			}
959e5c31af7Sopenharmony_ci
960e5c31af7Sopenharmony_ci			{
961e5c31af7Sopenharmony_ci				const CaseDefinition caseDef = {opTypeIndex, SHADER_STAGE_ALL_GRAPHICS, format};
962e5c31af7Sopenharmony_ci				SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(graphicGroup.get(),
963e5c31af7Sopenharmony_ci											name, "", supportedCheck, initPrograms, test, caseDef);
964e5c31af7Sopenharmony_ci			}
965e5c31af7Sopenharmony_ci
966e5c31af7Sopenharmony_ci			for (int stageIndex = 0; stageIndex < DE_LENGTH_OF_ARRAY(stages); ++stageIndex)
967e5c31af7Sopenharmony_ci			{
968e5c31af7Sopenharmony_ci				const CaseDefinition caseDef = {opTypeIndex, stages[stageIndex], format};
969e5c31af7Sopenharmony_ci				SubgroupFactory<CaseDefinition>::addFunctionCaseWithPrograms(framebufferGroup.get(),
970e5c31af7Sopenharmony_ci											name + "_" + getShaderStageName(caseDef.shaderStage), "",
971e5c31af7Sopenharmony_ci											supportedCheck, initFrameBufferPrograms, noSSBOtest, caseDef);
972e5c31af7Sopenharmony_ci			}
973e5c31af7Sopenharmony_ci		}
974e5c31af7Sopenharmony_ci	}
975e5c31af7Sopenharmony_ci	de::MovePtr<deqp::TestCaseGroup> group(new deqp::TestCaseGroup(
976e5c31af7Sopenharmony_ci			testCtx, "partitioned", "NV_shader_subgroup_partitioned category tests"));
977e5c31af7Sopenharmony_ci
978e5c31af7Sopenharmony_ci	group->addChild(graphicGroup.release());
979e5c31af7Sopenharmony_ci	group->addChild(computeGroup.release());
980e5c31af7Sopenharmony_ci	group->addChild(framebufferGroup.release());
981e5c31af7Sopenharmony_ci
982e5c31af7Sopenharmony_ci	return group.release();
983e5c31af7Sopenharmony_ci}
984e5c31af7Sopenharmony_ci
985e5c31af7Sopenharmony_ci} // subgroups
986e5c31af7Sopenharmony_ci} // glc
987e5c31af7Sopenharmony_ci
988