1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2016-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
21e5c31af7Sopenharmony_ci * \brief
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci/**
25e5c31af7Sopenharmony_ci */ /*!
26e5c31af7Sopenharmony_ci * \file  glcParallelShaderCompileTests.cpp
27e5c31af7Sopenharmony_ci * \brief Conformance tests for the GL_KHR_parallel_shader_compile functionality.
28e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_ci#include "glcParallelShaderCompileTests.hpp"
31e5c31af7Sopenharmony_ci#include "deClock.h"
32e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
33e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
34e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
35e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
36e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
37e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ciusing namespace glu;
40e5c31af7Sopenharmony_ciusing namespace glw;
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_cinamespace glcts
43e5c31af7Sopenharmony_ci{
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_cistatic const char* shaderVersionES = "#version 300 es\n";
46e5c31af7Sopenharmony_cistatic const char* shaderVersionGL = "#version 450\n";
47e5c31af7Sopenharmony_cistatic const char* vShader		   = "\n"
48e5c31af7Sopenharmony_ci							 "in vec3 vertex;\n"
49e5c31af7Sopenharmony_ci							 "\n"
50e5c31af7Sopenharmony_ci							 "void main() {\n"
51e5c31af7Sopenharmony_ci							 "    gl_Position = vec4(vertex, 1);\n"
52e5c31af7Sopenharmony_ci							 "}\n";
53e5c31af7Sopenharmony_ci
54e5c31af7Sopenharmony_cistatic const char* fShader = "\n"
55e5c31af7Sopenharmony_ci							 "out vec4 fragColor;\n"
56e5c31af7Sopenharmony_ci							 "\n"
57e5c31af7Sopenharmony_ci							 "void main() {\n"
58e5c31af7Sopenharmony_ci							 "    fragColor = vec4(1, 1, 1, 1);\n"
59e5c31af7Sopenharmony_ci							 "}\n";
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ci/** Constructor.
62e5c31af7Sopenharmony_ci *
63e5c31af7Sopenharmony_ci *  @param context     Rendering context
64e5c31af7Sopenharmony_ci *  @param name        Test name
65e5c31af7Sopenharmony_ci *  @param description Test description
66e5c31af7Sopenharmony_ci */
67e5c31af7Sopenharmony_ciSimpleQueriesTest::SimpleQueriesTest(deqp::Context& context)
68e5c31af7Sopenharmony_ci	: TestCase(context, "simple_queries",
69e5c31af7Sopenharmony_ci			   "Tests verifies if simple queries works as expected for MAX_SHADER_COMPILER_THREADS_KHR <pname>")
70e5c31af7Sopenharmony_ci{
71e5c31af7Sopenharmony_ci	/* Left blank intentionally */
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci/** Executes test iteration.
75e5c31af7Sopenharmony_ci *
76e5c31af7Sopenharmony_ci *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
77e5c31af7Sopenharmony_ci */
78e5c31af7Sopenharmony_citcu::TestNode::IterateResult SimpleQueriesTest::iterate()
79e5c31af7Sopenharmony_ci{
80e5c31af7Sopenharmony_ci	const glu::ContextInfo& contextInfo		= m_context.getContextInfo();
81e5c31af7Sopenharmony_ci	const glu::ContextType& contextType		= m_context.getRenderContext().getType();
82e5c31af7Sopenharmony_ci	const bool				isGL			= glu::isContextTypeGLCore(contextType);
83e5c31af7Sopenharmony_ci	const bool				supportParallel	= (isGL && contextInfo.isExtensionSupported("GL_ARB_parallel_shader_compile")) ||
84e5c31af7Sopenharmony_ci												contextInfo.isExtensionSupported("GL_KHR_parallel_shader_compile");
85e5c31af7Sopenharmony_ci
86e5c31af7Sopenharmony_ci	if (!supportParallel)
87e5c31af7Sopenharmony_ci	{
88e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
89e5c31af7Sopenharmony_ci		return STOP;
90e5c31af7Sopenharmony_ci	}
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ci	const Functions&		gl			 = m_context.getRenderContext().getFunctions();
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	GLboolean boolValue;
95e5c31af7Sopenharmony_ci	GLint	 intValue;
96e5c31af7Sopenharmony_ci	GLint64   int64Value;
97e5c31af7Sopenharmony_ci	GLfloat   floatValue;
98e5c31af7Sopenharmony_ci	GLdouble  doubleValue;
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_ci	bool supportsInt64  = isGL || glu::contextSupports(contextType, glu::ApiType::es(3, 0));
101e5c31af7Sopenharmony_ci	bool supportsDouble = isGL;
102e5c31af7Sopenharmony_ci
103e5c31af7Sopenharmony_ci	gl.getBooleanv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &boolValue);
104e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv");
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_ci	gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
107e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
108e5c31af7Sopenharmony_ci
109e5c31af7Sopenharmony_ci	if (supportsInt64)
110e5c31af7Sopenharmony_ci	{
111e5c31af7Sopenharmony_ci		gl.getInteger64v(GL_MAX_SHADER_COMPILER_THREADS_KHR, &int64Value);
112e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "getInteger64v");
113e5c31af7Sopenharmony_ci	}
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ci	gl.getFloatv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &floatValue);
116e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_ci	if (supportsDouble)
119e5c31af7Sopenharmony_ci	{
120e5c31af7Sopenharmony_ci		gl.getDoublev(GL_MAX_SHADER_COMPILER_THREADS_KHR, &doubleValue);
121e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublev");
122e5c31af7Sopenharmony_ci	}
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	if (boolValue != (intValue != 0) || intValue != (GLint)floatValue ||
125e5c31af7Sopenharmony_ci		(supportsInt64 && intValue != (GLint)int64Value) || (supportsDouble && intValue != (GLint)doubleValue))
126e5c31af7Sopenharmony_ci	{
127e5c31af7Sopenharmony_ci		tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci		message << "Simple queries returned different values: "
130e5c31af7Sopenharmony_ci				<< "bool(" << (int)boolValue << "), "
131e5c31af7Sopenharmony_ci				<< "int(" << intValue << "), ";
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_ci		if (supportsInt64)
134e5c31af7Sopenharmony_ci			message << "int64(" << int64Value << "), ";
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci		message << "float(" << floatValue << ")";
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_ci		if (supportsDouble)
139e5c31af7Sopenharmony_ci			message << ", double(" << doubleValue << ")";
140e5c31af7Sopenharmony_ci
141e5c31af7Sopenharmony_ci		message << tcu::TestLog::EndMessage;
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
144e5c31af7Sopenharmony_ci		return STOP;
145e5c31af7Sopenharmony_ci	}
146e5c31af7Sopenharmony_ci
147e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
148e5c31af7Sopenharmony_ci	return STOP;
149e5c31af7Sopenharmony_ci}
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_ci/** Constructor.
152e5c31af7Sopenharmony_ci *
153e5c31af7Sopenharmony_ci *  @param context     Rendering context
154e5c31af7Sopenharmony_ci *  @param name        Test name
155e5c31af7Sopenharmony_ci *  @param description Test description
156e5c31af7Sopenharmony_ci */
157e5c31af7Sopenharmony_ciMaxShaderCompileThreadsTest::MaxShaderCompileThreadsTest(deqp::Context& context)
158e5c31af7Sopenharmony_ci	: TestCase(context, "max_shader_compile_threads",
159e5c31af7Sopenharmony_ci			   "Tests verifies if MaxShaderCompileThreadsKHR function works as expected")
160e5c31af7Sopenharmony_ci{
161e5c31af7Sopenharmony_ci	/* Left blank intentionally */
162e5c31af7Sopenharmony_ci}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ci/** Executes test iteration.
165e5c31af7Sopenharmony_ci *
166e5c31af7Sopenharmony_ci *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
167e5c31af7Sopenharmony_ci */
168e5c31af7Sopenharmony_citcu::TestNode::IterateResult MaxShaderCompileThreadsTest::iterate()
169e5c31af7Sopenharmony_ci{
170e5c31af7Sopenharmony_ci	const glu::ContextInfo& contextInfo		= m_context.getContextInfo();
171e5c31af7Sopenharmony_ci	const glu::ContextType& contextType		= m_context.getRenderContext().getType();
172e5c31af7Sopenharmony_ci	const bool				isGL			= glu::isContextTypeGLCore(contextType);
173e5c31af7Sopenharmony_ci	const bool				supportParallel	= (isGL && contextInfo.isExtensionSupported("GL_ARB_parallel_shader_compile")) ||
174e5c31af7Sopenharmony_ci												contextInfo.isExtensionSupported("GL_KHR_parallel_shader_compile");
175e5c31af7Sopenharmony_ci
176e5c31af7Sopenharmony_ci	if (!supportParallel)
177e5c31af7Sopenharmony_ci	{
178e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
179e5c31af7Sopenharmony_ci		return STOP;
180e5c31af7Sopenharmony_ci	}
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	GLint intValue;
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci	gl.maxShaderCompilerThreadsKHR(0);
187e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_ci	gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
190e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci	if (intValue != 0)
193e5c31af7Sopenharmony_ci	{
194e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Failed to disable parallel shader compilation.");
195e5c31af7Sopenharmony_ci		return STOP;
196e5c31af7Sopenharmony_ci	}
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci	gl.maxShaderCompilerThreadsKHR(0xFFFFFFFF);
199e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci	gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
202e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
203e5c31af7Sopenharmony_ci
204e5c31af7Sopenharmony_ci	if (intValue != GLint(0xFFFFFFFF))
205e5c31af7Sopenharmony_ci	{
206e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Failed to set maximum shader compiler threads.");
207e5c31af7Sopenharmony_ci		return STOP;
208e5c31af7Sopenharmony_ci	}
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
211e5c31af7Sopenharmony_ci	return STOP;
212e5c31af7Sopenharmony_ci}
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ci/** Constructor.
215e5c31af7Sopenharmony_ci *
216e5c31af7Sopenharmony_ci *  @param context     Rendering context
217e5c31af7Sopenharmony_ci *  @param name        Test name
218e5c31af7Sopenharmony_ci *  @param description Test description
219e5c31af7Sopenharmony_ci */
220e5c31af7Sopenharmony_ciCompilationCompletionParallelTest::CompilationCompletionParallelTest(deqp::Context& context)
221e5c31af7Sopenharmony_ci	: TestCase(context, "compilation_completion_parallel",
222e5c31af7Sopenharmony_ci			   "Tests verifies if shader COMPLETION_STATUS query works as expected for parallel compilation")
223e5c31af7Sopenharmony_ci{
224e5c31af7Sopenharmony_ci	/* Left blank intentionally */
225e5c31af7Sopenharmony_ci}
226e5c31af7Sopenharmony_ci
227e5c31af7Sopenharmony_ci/** Executes test iteration.
228e5c31af7Sopenharmony_ci *
229e5c31af7Sopenharmony_ci *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
230e5c31af7Sopenharmony_ci */
231e5c31af7Sopenharmony_citcu::TestNode::IterateResult CompilationCompletionParallelTest::iterate()
232e5c31af7Sopenharmony_ci{
233e5c31af7Sopenharmony_ci	const glu::ContextInfo& contextInfo		= m_context.getContextInfo();
234e5c31af7Sopenharmony_ci	const glu::ContextType& contextType		= m_context.getRenderContext().getType();
235e5c31af7Sopenharmony_ci	const bool				isGL			= glu::isContextTypeGLCore(contextType);
236e5c31af7Sopenharmony_ci	const bool				supportParallel	= (isGL && contextInfo.isExtensionSupported("GL_ARB_parallel_shader_compile")) ||
237e5c31af7Sopenharmony_ci												contextInfo.isExtensionSupported("GL_KHR_parallel_shader_compile");
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ci	if (!supportParallel)
240e5c31af7Sopenharmony_ci	{
241e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
242e5c31af7Sopenharmony_ci		return STOP;
243e5c31af7Sopenharmony_ci	}
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci	GLint completionStatus;
248e5c31af7Sopenharmony_ci
249e5c31af7Sopenharmony_ci	gl.maxShaderCompilerThreadsKHR(8);
250e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
251e5c31af7Sopenharmony_ci
252e5c31af7Sopenharmony_ci	{
253e5c31af7Sopenharmony_ci		Shader   vertexShader(gl, SHADERTYPE_VERTEX);
254e5c31af7Sopenharmony_ci		deUint32 fragmentShader[8];
255e5c31af7Sopenharmony_ci		deUint32 program[8];
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci		bool		isContextES   = (glu::isContextTypeES(m_context.getRenderContext().getType()));
258e5c31af7Sopenharmony_ci		const char* shaderVersion = isContextES ? shaderVersionES : shaderVersionGL;
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ci		for (int i = 0; i < 8; ++i)
261e5c31af7Sopenharmony_ci		{
262e5c31af7Sopenharmony_ci			fragmentShader[i] = gl.createShader(GL_FRAGMENT_SHADER);
263e5c31af7Sopenharmony_ci			program[i]		  = gl.createProgram();
264e5c31af7Sopenharmony_ci		}
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci		const char* vSources[] = { shaderVersion, vShader };
267e5c31af7Sopenharmony_ci		const int   vLengths[] = { int(strlen(shaderVersion)), int(strlen(vShader)) };
268e5c31af7Sopenharmony_ci		vertexShader.setSources(2, vSources, vLengths);
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci		//Compilation test
271e5c31af7Sopenharmony_ci		for (int i = 0; i < 8; ++i)
272e5c31af7Sopenharmony_ci		{
273e5c31af7Sopenharmony_ci			const char* fSources[] = { shaderVersion, fShader };
274e5c31af7Sopenharmony_ci			const int   fLengths[] = { int(strlen(shaderVersion)), int(strlen(fShader)) };
275e5c31af7Sopenharmony_ci			gl.shaderSource(fragmentShader[i], 2, fSources, fLengths);
276e5c31af7Sopenharmony_ci		}
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ci		gl.compileShader(vertexShader.getShader());
279e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
280e5c31af7Sopenharmony_ci		for (int i = 0; i < 8; ++i)
281e5c31af7Sopenharmony_ci		{
282e5c31af7Sopenharmony_ci			gl.compileShader(fragmentShader[i]);
283e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
284e5c31af7Sopenharmony_ci		}
285e5c31af7Sopenharmony_ci
286e5c31af7Sopenharmony_ci		{
287e5c31af7Sopenharmony_ci			int		 completion  = 0;
288e5c31af7Sopenharmony_ci			deUint64 shLoopStart = deGetMicroseconds();
289e5c31af7Sopenharmony_ci			while (completion != 8 && deGetMicroseconds() < shLoopStart + 1000000)
290e5c31af7Sopenharmony_ci			{
291e5c31af7Sopenharmony_ci				completion = 0;
292e5c31af7Sopenharmony_ci				for (int i = 0; i < 8; ++i)
293e5c31af7Sopenharmony_ci				{
294e5c31af7Sopenharmony_ci					gl.getShaderiv(fragmentShader[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
295e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
296e5c31af7Sopenharmony_ci					if (completionStatus)
297e5c31af7Sopenharmony_ci						completion++;
298e5c31af7Sopenharmony_ci				}
299e5c31af7Sopenharmony_ci			}
300e5c31af7Sopenharmony_ci			if (completion != 8)
301e5c31af7Sopenharmony_ci			{
302e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
303e5c31af7Sopenharmony_ci										"Failed reading completion status for parallel shader compiling");
304e5c31af7Sopenharmony_ci				for (int i = 0; i < 8; ++i)
305e5c31af7Sopenharmony_ci				{
306e5c31af7Sopenharmony_ci					gl.deleteProgram(program[i]);
307e5c31af7Sopenharmony_ci					gl.deleteShader(fragmentShader[i]);
308e5c31af7Sopenharmony_ci				}
309e5c31af7Sopenharmony_ci				return STOP;
310e5c31af7Sopenharmony_ci			}
311e5c31af7Sopenharmony_ci		}
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_ci		for (int i = 0; i < 8; ++i)
314e5c31af7Sopenharmony_ci		{
315e5c31af7Sopenharmony_ci			gl.attachShader(program[i], vertexShader.getShader());
316e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
317e5c31af7Sopenharmony_ci			gl.attachShader(program[i], fragmentShader[i]);
318e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
319e5c31af7Sopenharmony_ci		}
320e5c31af7Sopenharmony_ci
321e5c31af7Sopenharmony_ci		//Linking test
322e5c31af7Sopenharmony_ci		for (int i = 0; i < 8; ++i)
323e5c31af7Sopenharmony_ci		{
324e5c31af7Sopenharmony_ci			gl.linkProgram(program[i]);
325e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "linkProgram");
326e5c31af7Sopenharmony_ci		}
327e5c31af7Sopenharmony_ci
328e5c31af7Sopenharmony_ci		{
329e5c31af7Sopenharmony_ci			int		 completion  = 0;
330e5c31af7Sopenharmony_ci			deUint64 prLoopStart = deGetMicroseconds();
331e5c31af7Sopenharmony_ci			while (completion != 8 && deGetMicroseconds() < prLoopStart + 1000000)
332e5c31af7Sopenharmony_ci			{
333e5c31af7Sopenharmony_ci				completion = 0;
334e5c31af7Sopenharmony_ci				for (int i = 0; i < 8; ++i)
335e5c31af7Sopenharmony_ci				{
336e5c31af7Sopenharmony_ci					gl.getProgramiv(program[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
337e5c31af7Sopenharmony_ci					GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
338e5c31af7Sopenharmony_ci					if (completionStatus)
339e5c31af7Sopenharmony_ci						completion++;
340e5c31af7Sopenharmony_ci				}
341e5c31af7Sopenharmony_ci			}
342e5c31af7Sopenharmony_ci			if (completion != 8)
343e5c31af7Sopenharmony_ci			{
344e5c31af7Sopenharmony_ci				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
345e5c31af7Sopenharmony_ci										"Failed reading completion status for parallel program linking");
346e5c31af7Sopenharmony_ci				for (int i = 0; i < 8; ++i)
347e5c31af7Sopenharmony_ci				{
348e5c31af7Sopenharmony_ci					gl.deleteProgram(program[i]);
349e5c31af7Sopenharmony_ci					gl.deleteShader(fragmentShader[i]);
350e5c31af7Sopenharmony_ci				}
351e5c31af7Sopenharmony_ci				return STOP;
352e5c31af7Sopenharmony_ci			}
353e5c31af7Sopenharmony_ci		}
354e5c31af7Sopenharmony_ci	}
355e5c31af7Sopenharmony_ci
356e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
357e5c31af7Sopenharmony_ci	return STOP;
358e5c31af7Sopenharmony_ci}
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci/** Constructor.
361e5c31af7Sopenharmony_ci *
362e5c31af7Sopenharmony_ci *  @param context Rendering context.
363e5c31af7Sopenharmony_ci */
364e5c31af7Sopenharmony_ciParallelShaderCompileTests::ParallelShaderCompileTests(deqp::Context& context)
365e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "parallel_shader_compile",
366e5c31af7Sopenharmony_ci					"Verify conformance of KHR_parallel_shader_compile implementation")
367e5c31af7Sopenharmony_ci{
368e5c31af7Sopenharmony_ci}
369e5c31af7Sopenharmony_ci
370e5c31af7Sopenharmony_ci/** Initializes the test group contents. */
371e5c31af7Sopenharmony_civoid ParallelShaderCompileTests::init()
372e5c31af7Sopenharmony_ci{
373e5c31af7Sopenharmony_ci	addChild(new SimpleQueriesTest(m_context));
374e5c31af7Sopenharmony_ci	addChild(new MaxShaderCompileThreadsTest(m_context));
375e5c31af7Sopenharmony_ci	addChild(new CompilationCompletionParallelTest(m_context));
376e5c31af7Sopenharmony_ci}
377e5c31af7Sopenharmony_ci
378e5c31af7Sopenharmony_ci} /* glcts namespace */
379