1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci* OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci* -----------------------------
4e5c31af7Sopenharmony_ci*
5e5c31af7Sopenharmony_ci* Copyright (c) 2014-2017 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci*
7e5c31af7Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci* you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci* You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci*
11e5c31af7Sopenharmony_ci*      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci*
13e5c31af7Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci* See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci* limitations under the License.
18e5c31af7Sopenharmony_ci*
19e5c31af7Sopenharmony_ci*/ /*!
20e5c31af7Sopenharmony_ci* \file  gl4cShaderBallotTests.cpp
21e5c31af7Sopenharmony_ci* \brief Conformance tests for the ARB_shader_ballot functionality.
22e5c31af7Sopenharmony_ci*/ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "gl4cShaderBallotTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "glcContext.hpp"
27e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
28e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
29e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp"
30e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp"
31e5c31af7Sopenharmony_ci#include "gluProgramInterfaceQuery.hpp"
32e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
33e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
34e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
35e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
36e5c31af7Sopenharmony_ci
37e5c31af7Sopenharmony_cinamespace gl4cts
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ciShaderBallotBaseTestCase::ShaderPipeline::ShaderPipeline(glu::ShaderType	testedShader,
41e5c31af7Sopenharmony_ci														 const std::string& contentSnippet,
42e5c31af7Sopenharmony_ci														 std::map<std::string, std::string> specMap)
43e5c31af7Sopenharmony_ci	: m_programRender(NULL), m_programCompute(NULL), m_testedShader(testedShader), m_specializationMap(specMap)
44e5c31af7Sopenharmony_ci{
45e5c31af7Sopenharmony_ci	std::string testedHeadPart = "#extension GL_ARB_shader_ballot : enable\n"
46e5c31af7Sopenharmony_ci								 "#extension GL_ARB_gpu_shader_int64 : enable\n";
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_ci	std::string testedContentPart = contentSnippet;
49e5c31af7Sopenharmony_ci
50e5c31af7Sopenharmony_ci	// vertex shader parts
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_VERTEX].push_back("#version 450 core\n");
53e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_VERTEX].push_back(m_testedShader == glu::SHADERTYPE_VERTEX ? testedHeadPart : "");
54e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_VERTEX].push_back("in highp vec2 inPosition;\n"
55e5c31af7Sopenharmony_ci												"in highp vec4 inColor;\n"
56e5c31af7Sopenharmony_ci												"out highp vec3 vsPosition;\n"
57e5c31af7Sopenharmony_ci												"out highp vec4 vsColor;\n"
58e5c31af7Sopenharmony_ci												"void main()\n"
59e5c31af7Sopenharmony_ci												"{\n"
60e5c31af7Sopenharmony_ci												"	gl_Position = vec4(inPosition, 0.0, 1.0);\n"
61e5c31af7Sopenharmony_ci												"	vsPosition = vec3(inPosition, 0.0);\n"
62e5c31af7Sopenharmony_ci												"	vec4 outColor = vec4(0.0); \n");
63e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_VERTEX].push_back(m_testedShader == glu::SHADERTYPE_VERTEX ? testedContentPart :
64e5c31af7Sopenharmony_ci																						   "	outColor = inColor;\n");
65e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_VERTEX].push_back("	vsColor = outColor;\n"
66e5c31af7Sopenharmony_ci												"}\n");
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_ci	// fragment shader parts
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_FRAGMENT].push_back("#version 450 core\n");
71e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_FRAGMENT].push_back(m_testedShader == glu::SHADERTYPE_FRAGMENT ? testedHeadPart : "");
72e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_FRAGMENT].push_back("in highp vec4 gsColor;\n"
73e5c31af7Sopenharmony_ci												  "out highp vec4 fsColor;\n"
74e5c31af7Sopenharmony_ci												  "void main()\n"
75e5c31af7Sopenharmony_ci												  "{\n"
76e5c31af7Sopenharmony_ci												  "	vec4 outColor = vec4(0.0); \n");
77e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_FRAGMENT].push_back(
78e5c31af7Sopenharmony_ci		m_testedShader == glu::SHADERTYPE_FRAGMENT ? testedContentPart : "	outColor = gsColor;\n");
79e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_FRAGMENT].push_back("	fsColor = outColor;\n"
80e5c31af7Sopenharmony_ci												  "}\n");
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	// tessellation control shader parts
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back("#version 450 core\n");
85e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(
86e5c31af7Sopenharmony_ci		m_testedShader == glu::SHADERTYPE_TESSELLATION_CONTROL ? testedHeadPart : "");
87e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(
88e5c31af7Sopenharmony_ci		"layout(vertices = 3) out;\n"
89e5c31af7Sopenharmony_ci		"in highp vec4 vsColor[];\n"
90e5c31af7Sopenharmony_ci		"in highp vec3 vsPosition[];\n"
91e5c31af7Sopenharmony_ci		"out highp vec3 tcsPosition[];\n"
92e5c31af7Sopenharmony_ci		"out highp vec4 tcsColor[];\n"
93e5c31af7Sopenharmony_ci		"void main()\n"
94e5c31af7Sopenharmony_ci		"{\n"
95e5c31af7Sopenharmony_ci		"	tcsPosition[gl_InvocationID] = vsPosition[gl_InvocationID];\n"
96e5c31af7Sopenharmony_ci		"	vec4 outColor = vec4(0.0);\n");
97e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(m_testedShader == glu::SHADERTYPE_TESSELLATION_CONTROL ?
98e5c31af7Sopenharmony_ci																  testedContentPart :
99e5c31af7Sopenharmony_ci																  "	outColor = vsColor[gl_InvocationID];\n");
100e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back("	tcsColor[gl_InvocationID] = outColor;\n"
101e5c31af7Sopenharmony_ci															  "	gl_TessLevelInner[0] = 3;\n"
102e5c31af7Sopenharmony_ci															  "	gl_TessLevelOuter[0] = 3;\n"
103e5c31af7Sopenharmony_ci															  "	gl_TessLevelOuter[1] = 3;\n"
104e5c31af7Sopenharmony_ci															  "	gl_TessLevelOuter[2] = 3;\n"
105e5c31af7Sopenharmony_ci															  "}\n");
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_ci	// tessellation evaluation shader parts
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back("#version 450 core\n");
110e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(
111e5c31af7Sopenharmony_ci		m_testedShader == glu::SHADERTYPE_TESSELLATION_EVALUATION ? testedHeadPart : "");
112e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back("layout(triangles, equal_spacing, cw) in;\n"
113e5c31af7Sopenharmony_ci																 "in highp vec3 tcsPosition[];\n"
114e5c31af7Sopenharmony_ci																 "in highp vec4 tcsColor[];\n"
115e5c31af7Sopenharmony_ci																 "out highp vec4 tesColor;\n"
116e5c31af7Sopenharmony_ci																 "void main()\n"
117e5c31af7Sopenharmony_ci																 "{\n"
118e5c31af7Sopenharmony_ci																 "	vec3 p0 = gl_TessCoord.x * tcsPosition[0];\n"
119e5c31af7Sopenharmony_ci																 "	vec3 p1 = gl_TessCoord.y * tcsPosition[1];\n"
120e5c31af7Sopenharmony_ci																 "	vec3 p2 = gl_TessCoord.z * tcsPosition[2];\n"
121e5c31af7Sopenharmony_ci																 "	vec4 outColor = vec4(0.0);\n");
122e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(
123e5c31af7Sopenharmony_ci		m_testedShader == glu::SHADERTYPE_TESSELLATION_EVALUATION ? testedContentPart : "	outColor = tcsColor[0];\n");
124e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back("	tesColor = outColor;\n"
125e5c31af7Sopenharmony_ci																 "	gl_Position = vec4(normalize(p0 + p1 + p2), 1.0);\n"
126e5c31af7Sopenharmony_ci																 "}\n");
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_ci	// geometry shader parts
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_GEOMETRY].push_back("#version 450 core\n");
131e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_GEOMETRY].push_back(m_testedShader == glu::SHADERTYPE_GEOMETRY ? testedHeadPart : "");
132e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_GEOMETRY].push_back("layout(triangles) in;\n"
133e5c31af7Sopenharmony_ci												  "layout(triangle_strip, max_vertices = 3) out;\n"
134e5c31af7Sopenharmony_ci												  "in highp vec4 tesColor[];\n"
135e5c31af7Sopenharmony_ci												  "out highp vec4 gsColor;\n"
136e5c31af7Sopenharmony_ci												  "void main()\n"
137e5c31af7Sopenharmony_ci												  "{\n"
138e5c31af7Sopenharmony_ci												  "	for (int i = 0; i<3; i++)\n"
139e5c31af7Sopenharmony_ci												  "	{\n"
140e5c31af7Sopenharmony_ci												  "		gl_Position = gl_in[i].gl_Position;\n"
141e5c31af7Sopenharmony_ci												  "		vec4 outColor = vec4(0.0);\n");
142e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_GEOMETRY].push_back(
143e5c31af7Sopenharmony_ci		m_testedShader == glu::SHADERTYPE_GEOMETRY ? testedContentPart : "		outColor = tesColor[i];\n");
144e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_GEOMETRY].push_back("		gsColor = outColor;\n"
145e5c31af7Sopenharmony_ci												  "		EmitVertex();\n"
146e5c31af7Sopenharmony_ci												  "	}\n"
147e5c31af7Sopenharmony_ci												  "	EndPrimitive();\n"
148e5c31af7Sopenharmony_ci												  "}\n");
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ci	// compute shader parts
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_COMPUTE].push_back("#version 450 core\n");
153e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_COMPUTE].push_back(m_testedShader == glu::SHADERTYPE_COMPUTE ? testedHeadPart : "");
154e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_COMPUTE].push_back(
155e5c31af7Sopenharmony_ci		"layout(rgba32f, binding = 1) writeonly uniform highp image2D destImage;\n"
156e5c31af7Sopenharmony_ci		"layout (local_size_x = 16, local_size_y = 16) in;\n"
157e5c31af7Sopenharmony_ci		"void main (void)\n"
158e5c31af7Sopenharmony_ci		"{\n"
159e5c31af7Sopenharmony_ci		"vec4 outColor = vec4(0.0);\n");
160e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_COMPUTE].push_back(m_testedShader == glu::SHADERTYPE_COMPUTE ? testedContentPart : "");
161e5c31af7Sopenharmony_ci	m_shaders[glu::SHADERTYPE_COMPUTE].push_back("imageStore(destImage, ivec2(gl_GlobalInvocationID.xy), outColor);\n"
162e5c31af7Sopenharmony_ci												 "}\n");
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci	// create shader chunks
165e5c31af7Sopenharmony_ci
166e5c31af7Sopenharmony_ci	for (unsigned int shaderType = 0; shaderType <= glu::SHADERTYPE_COMPUTE; ++shaderType)
167e5c31af7Sopenharmony_ci	{
168e5c31af7Sopenharmony_ci		m_shaderChunks[shaderType] = new char*[m_shaders[shaderType].size()];
169e5c31af7Sopenharmony_ci		for (unsigned int i = 0; i < m_shaders[i].size(); ++i)
170e5c31af7Sopenharmony_ci		{
171e5c31af7Sopenharmony_ci			m_shaderChunks[shaderType][i] = (char*)m_shaders[shaderType][i].data();
172e5c31af7Sopenharmony_ci		}
173e5c31af7Sopenharmony_ci	}
174e5c31af7Sopenharmony_ci}
175e5c31af7Sopenharmony_ci
176e5c31af7Sopenharmony_ciShaderBallotBaseTestCase::ShaderPipeline::~ShaderPipeline()
177e5c31af7Sopenharmony_ci{
178e5c31af7Sopenharmony_ci	if (m_programRender)
179e5c31af7Sopenharmony_ci	{
180e5c31af7Sopenharmony_ci		delete m_programRender;
181e5c31af7Sopenharmony_ci	}
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ci	if (m_programCompute)
184e5c31af7Sopenharmony_ci	{
185e5c31af7Sopenharmony_ci		delete m_programCompute;
186e5c31af7Sopenharmony_ci	}
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_ci	for (unsigned int shaderType = 0; shaderType <= glu::SHADERTYPE_COMPUTE; ++shaderType)
189e5c31af7Sopenharmony_ci	{
190e5c31af7Sopenharmony_ci		delete[] m_shaderChunks[shaderType];
191e5c31af7Sopenharmony_ci	}
192e5c31af7Sopenharmony_ci}
193e5c31af7Sopenharmony_ci
194e5c31af7Sopenharmony_ciconst char* const* ShaderBallotBaseTestCase::ShaderPipeline::getShaderParts(glu::ShaderType shaderType) const
195e5c31af7Sopenharmony_ci{
196e5c31af7Sopenharmony_ci	return m_shaderChunks[shaderType];
197e5c31af7Sopenharmony_ci}
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ciunsigned int ShaderBallotBaseTestCase::ShaderPipeline::getShaderPartsCount(glu::ShaderType shaderType) const
200e5c31af7Sopenharmony_ci{
201e5c31af7Sopenharmony_ci	return static_cast<unsigned int>(m_shaders[shaderType].size());
202e5c31af7Sopenharmony_ci}
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_civoid ShaderBallotBaseTestCase::ShaderPipeline::renderQuad(deqp::Context& context)
205e5c31af7Sopenharmony_ci{
206e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getRenderContext().getFunctions();
207e5c31af7Sopenharmony_ci
208e5c31af7Sopenharmony_ci	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
211e5c31af7Sopenharmony_ci
212e5c31af7Sopenharmony_ci	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("inPosition", 2, 4, 0, position) };
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ci	this->use(context);
215e5c31af7Sopenharmony_ci
216e5c31af7Sopenharmony_ci	glu::PrimitiveList primitiveList = glu::pr::Patches(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_ci	glu::draw(context.getRenderContext(), m_programRender->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
219e5c31af7Sopenharmony_ci			  primitiveList);
220e5c31af7Sopenharmony_ci
221e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
222e5c31af7Sopenharmony_ci}
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_civoid ShaderBallotBaseTestCase::ShaderPipeline::executeComputeShader(deqp::Context& context)
225e5c31af7Sopenharmony_ci{
226e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getRenderContext().getFunctions();
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_ci	const glu::Texture outputTexture(context.getRenderContext());
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci	gl.useProgram(m_programCompute->getProgram());
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci	// output image
233e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
234e5c31af7Sopenharmony_ci	gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 16, 16);
235e5c31af7Sopenharmony_ci	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
236e5c31af7Sopenharmony_ci	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
237e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading image data failed");
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ci	// bind image
240e5c31af7Sopenharmony_ci	gl.bindImageTexture(1, *outputTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
241e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Image setup failed");
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_ci	// dispatch compute
244e5c31af7Sopenharmony_ci	gl.dispatchCompute(1, 1, 1);
245e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glDispatchCompute()");
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci	gl.memoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
248e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glMemoryBarrier()");
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	// render output texture
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ci	std::string vs = "#version 450 core\n"
253e5c31af7Sopenharmony_ci					 "in highp vec2 position;\n"
254e5c31af7Sopenharmony_ci					 "in vec2 inTexcoord;\n"
255e5c31af7Sopenharmony_ci					 "out vec2 texcoord;\n"
256e5c31af7Sopenharmony_ci					 "void main()\n"
257e5c31af7Sopenharmony_ci					 "{\n"
258e5c31af7Sopenharmony_ci					 "	texcoord = inTexcoord;\n"
259e5c31af7Sopenharmony_ci					 "	gl_Position = vec4(position, 0.0, 1.0);\n"
260e5c31af7Sopenharmony_ci					 "}\n";
261e5c31af7Sopenharmony_ci
262e5c31af7Sopenharmony_ci	std::string fs = "#version 450 core\n"
263e5c31af7Sopenharmony_ci					 "uniform sampler2D sampler;\n"
264e5c31af7Sopenharmony_ci					 "in vec2 texcoord;\n"
265e5c31af7Sopenharmony_ci					 "out vec4 color;\n"
266e5c31af7Sopenharmony_ci					 "void main()\n"
267e5c31af7Sopenharmony_ci					 "{\n"
268e5c31af7Sopenharmony_ci					 "	color = texture(sampler, texcoord);\n"
269e5c31af7Sopenharmony_ci					 "}\n";
270e5c31af7Sopenharmony_ci
271e5c31af7Sopenharmony_ci	glu::ProgramSources sources;
272e5c31af7Sopenharmony_ci	sources.sources[glu::SHADERTYPE_VERTEX].push_back(vs);
273e5c31af7Sopenharmony_ci	sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(fs);
274e5c31af7Sopenharmony_ci	glu::ShaderProgram renderShader(context.getRenderContext(), sources);
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ci	if (!m_programRender->isOk())
277e5c31af7Sopenharmony_ci	{
278e5c31af7Sopenharmony_ci		TCU_FAIL("Shader compilation failed");
279e5c31af7Sopenharmony_ci	}
280e5c31af7Sopenharmony_ci
281e5c31af7Sopenharmony_ci	gl.bindTexture(GL_TEXTURE_2D, *outputTexture);
282e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
283e5c31af7Sopenharmony_ci
284e5c31af7Sopenharmony_ci	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
285e5c31af7Sopenharmony_ci	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ci	gl.useProgram(renderShader.getProgram());
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ci	gl.uniform1i(gl.getUniformLocation(renderShader.getProgram(), "sampler"), 0);
290e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i failed");
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ci	deUint16 const quadIndices[] = { 0, 1, 2, 2, 1, 3 };
293e5c31af7Sopenharmony_ci
294e5c31af7Sopenharmony_ci	float const position[] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f };
295e5c31af7Sopenharmony_ci
296e5c31af7Sopenharmony_ci	float const texCoord[] = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
297e5c31af7Sopenharmony_ci
298e5c31af7Sopenharmony_ci	glu::VertexArrayBinding vertexArrays[] = { glu::va::Float("position", 2, 4, 0, position),
299e5c31af7Sopenharmony_ci											   glu::va::Float("inTexcoord", 2, 4, 0, texCoord) };
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ci	glu::draw(context.getRenderContext(), renderShader.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
302e5c31af7Sopenharmony_ci			  glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices));
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glu::draw error");
305e5c31af7Sopenharmony_ci}
306e5c31af7Sopenharmony_ci
307e5c31af7Sopenharmony_civoid ShaderBallotBaseTestCase::ShaderPipeline::use(deqp::Context& context)
308e5c31af7Sopenharmony_ci{
309e5c31af7Sopenharmony_ci	const glw::Functions& gl = context.getRenderContext().getFunctions();
310e5c31af7Sopenharmony_ci	gl.useProgram(m_programRender->getProgram());
311e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");
312e5c31af7Sopenharmony_ci}
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_civoid ShaderBallotBaseTestCase::ShaderPipeline::test(deqp::Context& context)
315e5c31af7Sopenharmony_ci{
316e5c31af7Sopenharmony_ci	if (m_testedShader == glu::SHADERTYPE_COMPUTE)
317e5c31af7Sopenharmony_ci	{
318e5c31af7Sopenharmony_ci		executeComputeShader(context);
319e5c31af7Sopenharmony_ci	}
320e5c31af7Sopenharmony_ci	else
321e5c31af7Sopenharmony_ci	{
322e5c31af7Sopenharmony_ci		renderQuad(context);
323e5c31af7Sopenharmony_ci	}
324e5c31af7Sopenharmony_ci}
325e5c31af7Sopenharmony_ci
326e5c31af7Sopenharmony_civoid ShaderBallotBaseTestCase::createShaderPrograms(ShaderPipeline& pipeline)
327e5c31af7Sopenharmony_ci{
328e5c31af7Sopenharmony_ci	glu::ProgramSources sourcesRender;
329e5c31af7Sopenharmony_ci
330e5c31af7Sopenharmony_ci	for (unsigned int i = 0; i < glu::SHADERTYPE_COMPUTE; ++i)
331e5c31af7Sopenharmony_ci	{
332e5c31af7Sopenharmony_ci		glu::ShaderType shaderType = (glu::ShaderType)i;
333e5c31af7Sopenharmony_ci
334e5c31af7Sopenharmony_ci		std::map<std::string, std::string>::const_iterator mapIter;
335e5c31af7Sopenharmony_ci		for (mapIter = pipeline.getSpecializationMap().begin(); mapIter != pipeline.getSpecializationMap().end();
336e5c31af7Sopenharmony_ci			 mapIter++)
337e5c31af7Sopenharmony_ci			m_specializationMap[mapIter->first] = mapIter->second;
338e5c31af7Sopenharmony_ci
339e5c31af7Sopenharmony_ci		std::string shader =
340e5c31af7Sopenharmony_ci			specializeShader(pipeline.getShaderPartsCount(shaderType), pipeline.getShaderParts(shaderType));
341e5c31af7Sopenharmony_ci		sourcesRender.sources[i].push_back(shader);
342e5c31af7Sopenharmony_ci	}
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci	glu::ShaderProgram* programRender = new glu::ShaderProgram(m_context.getRenderContext(), sourcesRender);
345e5c31af7Sopenharmony_ci
346e5c31af7Sopenharmony_ci	if (!programRender->isOk())
347e5c31af7Sopenharmony_ci	{
348e5c31af7Sopenharmony_ci		TCU_FAIL("Shader compilation failed");
349e5c31af7Sopenharmony_ci	}
350e5c31af7Sopenharmony_ci
351e5c31af7Sopenharmony_ci	glu::ProgramSources sourcesCompute;
352e5c31af7Sopenharmony_ci
353e5c31af7Sopenharmony_ci	m_specializationMap.insert(pipeline.getSpecializationMap().begin(), pipeline.getSpecializationMap().end());
354e5c31af7Sopenharmony_ci	std::string shaderCompute = specializeShader(pipeline.getShaderPartsCount(glu::SHADERTYPE_COMPUTE),
355e5c31af7Sopenharmony_ci												 pipeline.getShaderParts(glu::SHADERTYPE_COMPUTE));
356e5c31af7Sopenharmony_ci	sourcesCompute.sources[glu::SHADERTYPE_COMPUTE].push_back(shaderCompute);
357e5c31af7Sopenharmony_ci
358e5c31af7Sopenharmony_ci	glu::ShaderProgram* programCompute = new glu::ShaderProgram(m_context.getRenderContext(), sourcesCompute);
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci	if (!programCompute->isOk())
361e5c31af7Sopenharmony_ci	{
362e5c31af7Sopenharmony_ci		TCU_FAIL("Shader compilation failed");
363e5c31af7Sopenharmony_ci	}
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci	pipeline.setShaderPrograms(programRender, programCompute);
366e5c31af7Sopenharmony_ci}
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ciShaderBallotBaseTestCase::~ShaderBallotBaseTestCase()
369e5c31af7Sopenharmony_ci{
370e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
371e5c31af7Sopenharmony_ci	{
372e5c31af7Sopenharmony_ci		delete *iter;
373e5c31af7Sopenharmony_ci	}
374e5c31af7Sopenharmony_ci}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_cibool ShaderBallotBaseTestCase::validateScreenPixels(deqp::Context& context, tcu::Vec4 desiredColor,
377e5c31af7Sopenharmony_ci													tcu::Vec4 ignoredColor)
378e5c31af7Sopenharmony_ci{
379e5c31af7Sopenharmony_ci	const glw::Functions&   gl			 = context.getRenderContext().getFunctions();
380e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = context.getRenderContext().getRenderTarget();
381e5c31af7Sopenharmony_ci	tcu::IVec2				size(renderTarget.getWidth(), renderTarget.getHeight());
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ci	glw::GLfloat* pixels = new glw::GLfloat[size.x() * size.y() * 4];
384e5c31af7Sopenharmony_ci
385e5c31af7Sopenharmony_ci	// clear buffer
386e5c31af7Sopenharmony_ci	for (int x = 0; x < size.x(); ++x)
387e5c31af7Sopenharmony_ci	{
388e5c31af7Sopenharmony_ci		for (int y = 0; y < size.y(); ++y)
389e5c31af7Sopenharmony_ci		{
390e5c31af7Sopenharmony_ci			int mappedPixelPosition = y * size.x() + x;
391e5c31af7Sopenharmony_ci
392e5c31af7Sopenharmony_ci			pixels[mappedPixelPosition * 4 + 0] = -1.0f;
393e5c31af7Sopenharmony_ci			pixels[mappedPixelPosition * 4 + 1] = -1.0f;
394e5c31af7Sopenharmony_ci			pixels[mappedPixelPosition * 4 + 2] = -1.0f;
395e5c31af7Sopenharmony_ci			pixels[mappedPixelPosition * 4 + 3] = -1.0f;
396e5c31af7Sopenharmony_ci		}
397e5c31af7Sopenharmony_ci	}
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_ci	// read pixels
400e5c31af7Sopenharmony_ci	gl.readPixels(0, 0, size.x(), size.y(), GL_RGBA, GL_FLOAT, pixels);
401e5c31af7Sopenharmony_ci
402e5c31af7Sopenharmony_ci	// validate pixels
403e5c31af7Sopenharmony_ci	bool rendered = false;
404e5c31af7Sopenharmony_ci	for (int x = 0; x < size.x(); ++x)
405e5c31af7Sopenharmony_ci	{
406e5c31af7Sopenharmony_ci		for (int y = 0; y < size.y(); ++y)
407e5c31af7Sopenharmony_ci		{
408e5c31af7Sopenharmony_ci			int mappedPixelPosition = y * size.x() + x;
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci			tcu::Vec4 color(pixels[mappedPixelPosition * 4 + 0], pixels[mappedPixelPosition * 4 + 1],
411e5c31af7Sopenharmony_ci							pixels[mappedPixelPosition * 4 + 2], pixels[mappedPixelPosition * 4 + 3]);
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ci			if (!ShaderBallotBaseTestCase::validateColor(color, ignoredColor))
414e5c31af7Sopenharmony_ci			{
415e5c31af7Sopenharmony_ci				rendered = true;
416e5c31af7Sopenharmony_ci				if (!ShaderBallotBaseTestCase::validateColor(color, desiredColor))
417e5c31af7Sopenharmony_ci				{
418e5c31af7Sopenharmony_ci					return false;
419e5c31af7Sopenharmony_ci				}
420e5c31af7Sopenharmony_ci			}
421e5c31af7Sopenharmony_ci		}
422e5c31af7Sopenharmony_ci	}
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	delete[] pixels;
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ci	return rendered;
427e5c31af7Sopenharmony_ci}
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_cibool ShaderBallotBaseTestCase::validateScreenPixelsSameColor(deqp::Context& context, tcu::Vec4 ignoredColor)
430e5c31af7Sopenharmony_ci{
431e5c31af7Sopenharmony_ci	const glw::Functions&   gl			 = context.getRenderContext().getFunctions();
432e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = context.getRenderContext().getRenderTarget();
433e5c31af7Sopenharmony_ci
434e5c31af7Sopenharmony_ci	glw::GLfloat* topLeftPixel = new glw::GLfloat[4];
435e5c31af7Sopenharmony_ci	topLeftPixel[0]			  = -1.0f;
436e5c31af7Sopenharmony_ci	topLeftPixel[1]			  = -1.0f;
437e5c31af7Sopenharmony_ci	topLeftPixel[2]			  = -1.0f;
438e5c31af7Sopenharmony_ci	topLeftPixel[3]			  = -1.0f;
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_ci	// read pixel
441e5c31af7Sopenharmony_ci	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, topLeftPixel);
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	tcu::Vec4 desiredColor(topLeftPixel[0], topLeftPixel[1], topLeftPixel[2], topLeftPixel[3]);
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_ci	delete[] topLeftPixel;
446e5c31af7Sopenharmony_ci
447e5c31af7Sopenharmony_ci	// validation
448e5c31af7Sopenharmony_ci	return ShaderBallotBaseTestCase::validateScreenPixels(context, desiredColor, ignoredColor);
449e5c31af7Sopenharmony_ci}
450e5c31af7Sopenharmony_ci
451e5c31af7Sopenharmony_cibool ShaderBallotBaseTestCase::validateColor(tcu::Vec4 testedColor, tcu::Vec4 desiredColor)
452e5c31af7Sopenharmony_ci{
453e5c31af7Sopenharmony_ci	const float epsilon = 0.008f;
454e5c31af7Sopenharmony_ci	return de::abs(testedColor.x() - desiredColor.x()) < epsilon &&
455e5c31af7Sopenharmony_ci		   de::abs(testedColor.y() - desiredColor.y()) < epsilon &&
456e5c31af7Sopenharmony_ci		   de::abs(testedColor.z() - desiredColor.z()) < epsilon &&
457e5c31af7Sopenharmony_ci		   de::abs(testedColor.w() - desiredColor.w()) < epsilon;
458e5c31af7Sopenharmony_ci}
459e5c31af7Sopenharmony_ci
460e5c31af7Sopenharmony_ci/** Constructor.
461e5c31af7Sopenharmony_ci*
462e5c31af7Sopenharmony_ci*  @param context Rendering context
463e5c31af7Sopenharmony_ci*/
464e5c31af7Sopenharmony_ciShaderBallotAvailabilityTestCase::ShaderBallotAvailabilityTestCase(deqp::Context& context)
465e5c31af7Sopenharmony_ci	: ShaderBallotBaseTestCase(context, "ShaderBallotAvailability",
466e5c31af7Sopenharmony_ci							   "Implements verification of availability for new build-in features")
467e5c31af7Sopenharmony_ci{
468e5c31af7Sopenharmony_ci	std::string colorShaderSnippet =
469e5c31af7Sopenharmony_ci		"	float red = gl_SubGroupSizeARB / 64.0f;\n"
470e5c31af7Sopenharmony_ci		"	float green = 1.0f - (gl_SubGroupInvocationARB / float(gl_SubGroupSizeARB));\n"
471e5c31af7Sopenharmony_ci		"	float blue = float(ballotARB(true) % 256) / 256.0f;\n"
472e5c31af7Sopenharmony_ci		"	outColor = readInvocationARB(vec4(red, green, blue, 1.0f), gl_SubGroupInvocationARB);\n";
473e5c31af7Sopenharmony_ci
474e5c31af7Sopenharmony_ci	for (unsigned int i = 0; i <= glu::SHADERTYPE_COMPUTE; ++i)
475e5c31af7Sopenharmony_ci	{
476e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, colorShaderSnippet));
477e5c31af7Sopenharmony_ci	}
478e5c31af7Sopenharmony_ci}
479e5c31af7Sopenharmony_ci
480e5c31af7Sopenharmony_ci/** Initializes the test
481e5c31af7Sopenharmony_ci*/
482e5c31af7Sopenharmony_civoid ShaderBallotAvailabilityTestCase::init()
483e5c31af7Sopenharmony_ci{
484e5c31af7Sopenharmony_ci}
485e5c31af7Sopenharmony_ci
486e5c31af7Sopenharmony_ci/** Executes test iteration.
487e5c31af7Sopenharmony_ci*
488e5c31af7Sopenharmony_ci*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
489e5c31af7Sopenharmony_ci*/
490e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderBallotAvailabilityTestCase::iterate()
491e5c31af7Sopenharmony_ci{
492e5c31af7Sopenharmony_ci	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_ballot") ||
493e5c31af7Sopenharmony_ci		!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
494e5c31af7Sopenharmony_ci	{
495e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
496e5c31af7Sopenharmony_ci		return STOP;
497e5c31af7Sopenharmony_ci	}
498e5c31af7Sopenharmony_ci
499e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
500e5c31af7Sopenharmony_ci	{
501e5c31af7Sopenharmony_ci		createShaderPrograms(**iter);
502e5c31af7Sopenharmony_ci	}
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
505e5c31af7Sopenharmony_ci
506e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
507e5c31af7Sopenharmony_ci		 ++pipelineIter)
508e5c31af7Sopenharmony_ci	{
509e5c31af7Sopenharmony_ci		gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
510e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
511e5c31af7Sopenharmony_ci
512e5c31af7Sopenharmony_ci		(*pipelineIter)->test(m_context);
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci		gl.flush();
515e5c31af7Sopenharmony_ci	}
516e5c31af7Sopenharmony_ci
517e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
518e5c31af7Sopenharmony_ci	return STOP;
519e5c31af7Sopenharmony_ci}
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci/** Constructor.
522e5c31af7Sopenharmony_ci*
523e5c31af7Sopenharmony_ci*  @param context Rendering context
524e5c31af7Sopenharmony_ci*/
525e5c31af7Sopenharmony_ciShaderBallotBitmasksTestCase::ShaderBallotBitmasksTestCase(deqp::Context& context)
526e5c31af7Sopenharmony_ci	: ShaderBallotBaseTestCase(context, "ShaderBallotBitmasks",
527e5c31af7Sopenharmony_ci							   "Implements verification of values of gl_SubGroup*MaskARB variables")
528e5c31af7Sopenharmony_ci{
529e5c31af7Sopenharmony_ci	m_maskVars["gl_SubGroupEqMaskARB"] = "==";
530e5c31af7Sopenharmony_ci	m_maskVars["gl_SubGroupGeMaskARB"] = ">=";
531e5c31af7Sopenharmony_ci	m_maskVars["gl_SubGroupGtMaskARB"] = ">";
532e5c31af7Sopenharmony_ci	m_maskVars["gl_SubGroupLeMaskARB"] = "<=";
533e5c31af7Sopenharmony_ci	m_maskVars["gl_SubGroupLtMaskARB"] = "<";
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ci	std::string colorShaderSnippet = "	uint64_t mask = 0;\n"
536e5c31af7Sopenharmony_ci									 "	for(uint i = 0; i < gl_SubGroupSizeARB; ++i)\n"
537e5c31af7Sopenharmony_ci									 "	{\n"
538e5c31af7Sopenharmony_ci									 "		if(i ${MASK_OPERATOR} gl_SubGroupInvocationARB)\n"
539e5c31af7Sopenharmony_ci									 "			mask = mask | (1ul << i);\n"
540e5c31af7Sopenharmony_ci									 "	}\n"
541e5c31af7Sopenharmony_ci									 "	float color = (${MASK_VAR} ^ mask) == 0ul ? 1.0 : 0.0;\n"
542e5c31af7Sopenharmony_ci									 "	outColor = vec4(color, color, color, 1.0);\n";
543e5c31af7Sopenharmony_ci
544e5c31af7Sopenharmony_ci	for (MaskVarIter maskIter = m_maskVars.begin(); maskIter != m_maskVars.end(); maskIter++)
545e5c31af7Sopenharmony_ci	{
546e5c31af7Sopenharmony_ci		for (unsigned int i = 0; i <= glu::SHADERTYPE_COMPUTE; ++i)
547e5c31af7Sopenharmony_ci		{
548e5c31af7Sopenharmony_ci			std::map<std::string, std::string> specMap;
549e5c31af7Sopenharmony_ci			specMap["MASK_VAR"]		 = maskIter->first;
550e5c31af7Sopenharmony_ci			specMap["MASK_OPERATOR"] = maskIter->second;
551e5c31af7Sopenharmony_ci			m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, colorShaderSnippet, specMap));
552e5c31af7Sopenharmony_ci		}
553e5c31af7Sopenharmony_ci	}
554e5c31af7Sopenharmony_ci}
555e5c31af7Sopenharmony_ci
556e5c31af7Sopenharmony_ci/** Initializes the test
557e5c31af7Sopenharmony_ci*/
558e5c31af7Sopenharmony_civoid ShaderBallotBitmasksTestCase::init()
559e5c31af7Sopenharmony_ci{
560e5c31af7Sopenharmony_ci}
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_ci/** Executes test iteration.
563e5c31af7Sopenharmony_ci*
564e5c31af7Sopenharmony_ci*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
565e5c31af7Sopenharmony_ci*/
566e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderBallotBitmasksTestCase::iterate()
567e5c31af7Sopenharmony_ci{
568e5c31af7Sopenharmony_ci	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_ballot") ||
569e5c31af7Sopenharmony_ci		!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
570e5c31af7Sopenharmony_ci	{
571e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
572e5c31af7Sopenharmony_ci		return STOP;
573e5c31af7Sopenharmony_ci	}
574e5c31af7Sopenharmony_ci
575e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
576e5c31af7Sopenharmony_ci	{
577e5c31af7Sopenharmony_ci		createShaderPrograms(**iter);
578e5c31af7Sopenharmony_ci	}
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
581e5c31af7Sopenharmony_ci
582e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
583e5c31af7Sopenharmony_ci		 ++pipelineIter)
584e5c31af7Sopenharmony_ci	{
585e5c31af7Sopenharmony_ci		gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
586e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
587e5c31af7Sopenharmony_ci
588e5c31af7Sopenharmony_ci		(*pipelineIter)->test(m_context);
589e5c31af7Sopenharmony_ci
590e5c31af7Sopenharmony_ci		gl.flush();
591e5c31af7Sopenharmony_ci
592e5c31af7Sopenharmony_ci		bool validationResult = ShaderBallotBaseTestCase::validateScreenPixels(
593e5c31af7Sopenharmony_ci			m_context, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
594e5c31af7Sopenharmony_ci		TCU_CHECK_MSG(validationResult, "Bitmask value is not correct");
595e5c31af7Sopenharmony_ci	}
596e5c31af7Sopenharmony_ci
597e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
598e5c31af7Sopenharmony_ci	return STOP;
599e5c31af7Sopenharmony_ci}
600e5c31af7Sopenharmony_ci
601e5c31af7Sopenharmony_ci/** Constructor.
602e5c31af7Sopenharmony_ci*
603e5c31af7Sopenharmony_ci*  @param context Rendering context
604e5c31af7Sopenharmony_ci*/
605e5c31af7Sopenharmony_ciShaderBallotFunctionBallotTestCase::ShaderBallotFunctionBallotTestCase(deqp::Context& context)
606e5c31af7Sopenharmony_ci	: ShaderBallotBaseTestCase(context, "ShaderBallotFunctionBallot",
607e5c31af7Sopenharmony_ci							   "Implements verification of ballotARB calls and returned results")
608e5c31af7Sopenharmony_ci{
609e5c31af7Sopenharmony_ci	std::string ballotFalseSnippet = "	uint64_t result = ballotARB(false);\n"
610e5c31af7Sopenharmony_ci									 "	float color = result == 0ul ? 1.0 : 0.0;\n"
611e5c31af7Sopenharmony_ci									 "	outColor = vec4(color, color, color, 1.0);\n";
612e5c31af7Sopenharmony_ci
613e5c31af7Sopenharmony_ci	std::string ballotTrueSnippet = "	uint64_t result = ballotARB(true);\n"
614e5c31af7Sopenharmony_ci									"	float color = result != 0ul ? 1.0 : 0.0;\n"
615e5c31af7Sopenharmony_ci									"	uint64_t invocationBit = 1ul << gl_SubGroupInvocationARB;\n"
616e5c31af7Sopenharmony_ci									"	color *= float(invocationBit & result);\n"
617e5c31af7Sopenharmony_ci									"	outColor = vec4(color, color, color, 1.0);\n";
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci	std::string ballotMixedSnippet = "	bool param = (gl_SubGroupInvocationARB % 2) == 0ul;\n"
620e5c31af7Sopenharmony_ci									 "	uint64_t result = ballotARB(param);\n"
621e5c31af7Sopenharmony_ci									 "	float color = (param && result != 0ul) || !param ? 1.0 : 0.0;\n"
622e5c31af7Sopenharmony_ci									 "	outColor = vec4(color, color, color, 1.0);\n";
623e5c31af7Sopenharmony_ci
624e5c31af7Sopenharmony_ci	for (unsigned int i = 0; i <= glu::SHADERTYPE_COMPUTE; ++i)
625e5c31af7Sopenharmony_ci	{
626e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, ballotFalseSnippet));
627e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, ballotTrueSnippet));
628e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, ballotMixedSnippet));
629e5c31af7Sopenharmony_ci	}
630e5c31af7Sopenharmony_ci}
631e5c31af7Sopenharmony_ci
632e5c31af7Sopenharmony_ci/** Initializes the test
633e5c31af7Sopenharmony_ci*/
634e5c31af7Sopenharmony_civoid ShaderBallotFunctionBallotTestCase::init()
635e5c31af7Sopenharmony_ci{
636e5c31af7Sopenharmony_ci}
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci/** Executes test iteration.
639e5c31af7Sopenharmony_ci*
640e5c31af7Sopenharmony_ci*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
641e5c31af7Sopenharmony_ci*/
642e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderBallotFunctionBallotTestCase::iterate()
643e5c31af7Sopenharmony_ci{
644e5c31af7Sopenharmony_ci	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_ballot") ||
645e5c31af7Sopenharmony_ci		!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
646e5c31af7Sopenharmony_ci	{
647e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
648e5c31af7Sopenharmony_ci		return STOP;
649e5c31af7Sopenharmony_ci	}
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
652e5c31af7Sopenharmony_ci	{
653e5c31af7Sopenharmony_ci		createShaderPrograms(**iter);
654e5c31af7Sopenharmony_ci	}
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
657e5c31af7Sopenharmony_ci
658e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
659e5c31af7Sopenharmony_ci		 ++pipelineIter)
660e5c31af7Sopenharmony_ci	{
661e5c31af7Sopenharmony_ci		gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
662e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
663e5c31af7Sopenharmony_ci
664e5c31af7Sopenharmony_ci		(*pipelineIter)->test(m_context);
665e5c31af7Sopenharmony_ci
666e5c31af7Sopenharmony_ci		gl.flush();
667e5c31af7Sopenharmony_ci
668e5c31af7Sopenharmony_ci		bool validationResult = ShaderBallotBaseTestCase::validateScreenPixels(
669e5c31af7Sopenharmony_ci			m_context, tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
670e5c31af7Sopenharmony_ci		TCU_CHECK_MSG(validationResult, "Value returned from ballotARB function is not correct");
671e5c31af7Sopenharmony_ci	}
672e5c31af7Sopenharmony_ci
673e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
674e5c31af7Sopenharmony_ci	return STOP;
675e5c31af7Sopenharmony_ci}
676e5c31af7Sopenharmony_ci
677e5c31af7Sopenharmony_ci/** Constructor.
678e5c31af7Sopenharmony_ci*
679e5c31af7Sopenharmony_ci*  @param context Rendering context
680e5c31af7Sopenharmony_ci*/
681e5c31af7Sopenharmony_ciShaderBallotFunctionReadTestCase::ShaderBallotFunctionReadTestCase(deqp::Context& context)
682e5c31af7Sopenharmony_ci	: ShaderBallotBaseTestCase(context, "ShaderBallotFunctionRead",
683e5c31af7Sopenharmony_ci							   "Implements verification of readInvocationARB and readFirstInvocationARB function calls")
684e5c31af7Sopenharmony_ci{
685e5c31af7Sopenharmony_ci	std::string readFirstInvSnippet = "float color = 1.0f - (gl_SubGroupInvocationARB / float(gl_SubGroupSizeARB));\n"
686e5c31af7Sopenharmony_ci									  "outColor = readFirstInvocationARB(vec4(color, color, color, 1.0f));\n";
687e5c31af7Sopenharmony_ci
688e5c31af7Sopenharmony_ci	std::string readInvSnippet = "float color = 1.0 - (gl_SubGroupInvocationARB / float(gl_SubGroupSizeARB));\n"
689e5c31af7Sopenharmony_ci								 "uvec2 parts = unpackUint2x32(ballotARB(true));\n"
690e5c31af7Sopenharmony_ci								 "uint invocation;\n"
691e5c31af7Sopenharmony_ci								 "if (parts.x != 0) {\n"
692e5c31af7Sopenharmony_ci								 "    invocation = findLSB(parts.x);\n"
693e5c31af7Sopenharmony_ci								 "} else {\n"
694e5c31af7Sopenharmony_ci								 "    invocation = findLSB(parts.y) + 32;\n"
695e5c31af7Sopenharmony_ci								 "}\n"
696e5c31af7Sopenharmony_ci								 "outColor = readInvocationARB(vec4(color, color, color, 1.0f), invocation);\n";
697e5c31af7Sopenharmony_ci
698e5c31af7Sopenharmony_ci	for (unsigned int i = 0; i <= glu::SHADERTYPE_COMPUTE; ++i)
699e5c31af7Sopenharmony_ci	{
700e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, readFirstInvSnippet));
701e5c31af7Sopenharmony_ci		m_shaderPipelines.push_back(new ShaderPipeline((glu::ShaderType)i, readInvSnippet));
702e5c31af7Sopenharmony_ci	}
703e5c31af7Sopenharmony_ci}
704e5c31af7Sopenharmony_ci
705e5c31af7Sopenharmony_ci/** Initializes the test
706e5c31af7Sopenharmony_ci*/
707e5c31af7Sopenharmony_civoid ShaderBallotFunctionReadTestCase::init()
708e5c31af7Sopenharmony_ci{
709e5c31af7Sopenharmony_ci}
710e5c31af7Sopenharmony_ci
711e5c31af7Sopenharmony_ci/** Executes test iteration.
712e5c31af7Sopenharmony_ci*
713e5c31af7Sopenharmony_ci*  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
714e5c31af7Sopenharmony_ci*/
715e5c31af7Sopenharmony_citcu::TestNode::IterateResult ShaderBallotFunctionReadTestCase::iterate()
716e5c31af7Sopenharmony_ci{
717e5c31af7Sopenharmony_ci	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_shader_ballot") ||
718e5c31af7Sopenharmony_ci		!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
719e5c31af7Sopenharmony_ci	{
720e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
721e5c31af7Sopenharmony_ci		return STOP;
722e5c31af7Sopenharmony_ci	}
723e5c31af7Sopenharmony_ci
724e5c31af7Sopenharmony_ci	for (ShaderPipelineIter iter = m_shaderPipelines.begin(); iter != m_shaderPipelines.end(); ++iter)
725e5c31af7Sopenharmony_ci	{
726e5c31af7Sopenharmony_ci		createShaderPrograms(**iter);
727e5c31af7Sopenharmony_ci	}
728e5c31af7Sopenharmony_ci
729e5c31af7Sopenharmony_ci	const glw::Functions&   gl			 = m_context.getRenderContext().getFunctions();
730e5c31af7Sopenharmony_ci	const tcu::RenderTarget renderTarget = m_context.getRenderContext().getRenderTarget();
731e5c31af7Sopenharmony_ci
732e5c31af7Sopenharmony_ci	gl.clearColor(1.0f, 0.0f, 0.0f, 1.0f);
733e5c31af7Sopenharmony_ci	gl.viewport(0, 0, 2, 2);
734e5c31af7Sopenharmony_ci
735e5c31af7Sopenharmony_ci	for (ShaderPipelineIter pipelineIter = m_shaderPipelines.begin(); pipelineIter != m_shaderPipelines.end();
736e5c31af7Sopenharmony_ci		 ++pipelineIter)
737e5c31af7Sopenharmony_ci	{
738e5c31af7Sopenharmony_ci		gl.clear(GL_COLOR_BUFFER_BIT);
739e5c31af7Sopenharmony_ci
740e5c31af7Sopenharmony_ci		(*pipelineIter)->test(m_context);
741e5c31af7Sopenharmony_ci
742e5c31af7Sopenharmony_ci		gl.flush();
743e5c31af7Sopenharmony_ci
744e5c31af7Sopenharmony_ci		bool validationResult =
745e5c31af7Sopenharmony_ci			ShaderBallotBaseTestCase::validateScreenPixelsSameColor(m_context, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
746e5c31af7Sopenharmony_ci		TCU_CHECK_MSG(validationResult, "Read functions result is not correct");
747e5c31af7Sopenharmony_ci	}
748e5c31af7Sopenharmony_ci
749e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
750e5c31af7Sopenharmony_ci	return STOP;
751e5c31af7Sopenharmony_ci}
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci/** Constructor.
754e5c31af7Sopenharmony_ci*
755e5c31af7Sopenharmony_ci*  @param context Rendering context.
756e5c31af7Sopenharmony_ci**/
757e5c31af7Sopenharmony_ciShaderBallotTests::ShaderBallotTests(deqp::Context& context)
758e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "shader_ballot_tests", "Verify conformance of CTS_ARB_shader_ballot implementation")
759e5c31af7Sopenharmony_ci{
760e5c31af7Sopenharmony_ci}
761e5c31af7Sopenharmony_ci
762e5c31af7Sopenharmony_ci/** Initializes the shader_ballot test group.
763e5c31af7Sopenharmony_ci*
764e5c31af7Sopenharmony_ci**/
765e5c31af7Sopenharmony_civoid ShaderBallotTests::init(void)
766e5c31af7Sopenharmony_ci{
767e5c31af7Sopenharmony_ci	addChild(new ShaderBallotAvailabilityTestCase(m_context));
768e5c31af7Sopenharmony_ci	addChild(new ShaderBallotBitmasksTestCase(m_context));
769e5c31af7Sopenharmony_ci	addChild(new ShaderBallotFunctionBallotTestCase(m_context));
770e5c31af7Sopenharmony_ci	addChild(new ShaderBallotFunctionReadTestCase(m_context));
771e5c31af7Sopenharmony_ci}
772e5c31af7Sopenharmony_ci} /* glcts namespace */
773