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