1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2016-2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
26 * \file glcParallelShaderCompileTests.cpp
27 * \brief Conformance tests for the GL_KHR_parallel_shader_compile functionality.
28 */ /*-------------------------------------------------------------------*/
30 #include "glcParallelShaderCompileTests.hpp"
32 #include "gluContextInfo.hpp"
33 #include "gluDefs.hpp"
34 #include "gluShaderProgram.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuTestLog.hpp"
45 static const char* shaderVersionES = "#version 300 es\n";
46 static const char* shaderVersionGL = "#version 450\n";
47 static const char* vShader = "\n"
51 " gl_Position = vec4(vertex, 1);\n"
54 static const char* fShader = "\n"
55 "out ver4 fragColor;\n"
58 " fragColor = vec4(1, 1, 1, 1);\n"
63 * @param context Rendering context
64 * @param name Test name
65 * @param description Test description
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>")
71 /* Left blank intentionally */
74 /** Executes test iteration.
76 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
78 tcu::TestNode::IterateResult SimpleQueriesTest::iterate()
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");
88 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
92 const Functions& gl = m_context.getRenderContext().getFunctions();
100 bool supportsInt64 = isGL || glu::contextSupports(contextType, glu::ApiType::es(3, 0));
101 bool supportsDouble = isGL;
103 gl.getBooleanv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &boolValue);
104 GLU_EXPECT_NO_ERROR(gl.getError(), "getBooleanv");
106 gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
107 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
111 gl.getInteger64v(GL_MAX_SHADER_COMPILER_THREADS_KHR, &int64Value);
112 GLU_EXPECT_NO_ERROR(gl.getError(), "getInteger64v");
115 gl.getFloatv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &floatValue);
116 GLU_EXPECT_NO_ERROR(gl.getError(), "getFloatv");
120 gl.getDoublev(GL_MAX_SHADER_COMPILER_THREADS_KHR, &doubleValue);
121 GLU_EXPECT_NO_ERROR(gl.getError(), "getDoublev");
124 if (boolValue != (intValue != 0) || intValue != (GLint)floatValue ||
125 (supportsInt64 && intValue != (GLint)int64Value) || (supportsDouble && intValue != (GLint)doubleValue))
127 tcu::MessageBuilder message = m_testCtx.getLog() << tcu::TestLog::Message;
129 message << "Simple queries returned different values: "
130 << "bool(" << (int)boolValue << "), "
131 << "int(" << intValue << "), ";
134 message << "int64(" << int64Value << "), ";
136 message << "float(" << floatValue << ")";
139 message << ", double(" << doubleValue << ")";
141 message << tcu::TestLog::EndMessage;
143 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
147 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
153 * @param context Rendering context
154 * @param name Test name
155 * @param description Test description
157 MaxShaderCompileThreadsTest::MaxShaderCompileThreadsTest(deqp::Context& context)
158 : TestCase(context, "max_shader_compile_threads",
159 "Tests verifies if MaxShaderCompileThreadsKHR function works as expected")
161 /* Left blank intentionally */
164 /** Executes test iteration.
166 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
168 tcu::TestNode::IterateResult MaxShaderCompileThreadsTest::iterate()
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");
176 if (!supportParallel)
178 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
182 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
186 gl.maxShaderCompilerThreadsKHR(0);
187 GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
189 gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
190 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
194 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Failed to disable parallel shader compilation.");
198 gl.maxShaderCompilerThreadsKHR(0xFFFFFFFF);
199 GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
201 gl.getIntegerv(GL_MAX_SHADER_COMPILER_THREADS_KHR, &intValue);
202 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
204 if (intValue != GLint(0xFFFFFFFF))
206 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Failed to set maximum shader compiler threads.");
210 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
216 * @param context Rendering context
217 * @param name Test name
218 * @param description Test description
220 CompilationCompletionNonParallelTest::CompilationCompletionNonParallelTest(deqp::Context& context)
221 : TestCase(context, "compilation_completion_non_parallel",
222 "Tests verifies if shader COMPLETION_STATUS query works as expected for non parallel compilation")
224 /* Left blank intentionally */
227 /** Executes test iteration.
229 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
231 tcu::TestNode::IterateResult CompilationCompletionNonParallelTest::iterate()
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");
239 if (!supportParallel)
241 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
245 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
247 GLint completionStatus;
249 gl.maxShaderCompilerThreadsKHR(0);
250 GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
254 Shader vertexShader(gl, SHADERTYPE_VERTEX);
255 Shader fragmentShader(gl, SHADERTYPE_FRAGMENT);
257 bool isContextES = (glu::isContextTypeES(m_context.getRenderContext().getType()));
258 const char* shaderVersion = isContextES ? shaderVersionES : shaderVersionGL;
260 const char* vSources[] = { shaderVersion, vShader };
261 const int vLengths[] = { int(strlen(shaderVersion)), int(strlen(vShader)) };
262 vertexShader.setSources(2, vSources, vLengths);
264 const char* fSources[] = { shaderVersion, fShader };
265 const int fLengths[] = { int(strlen(shaderVersion)), int(strlen(fShader)) };
266 fragmentShader.setSources(2, fSources, fLengths);
268 gl.compileShader(vertexShader.getShader());
269 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
270 gl.compileShader(fragmentShader.getShader());
271 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
273 gl.getShaderiv(fragmentShader.getShader(), GL_COMPLETION_STATUS_KHR, &completionStatus);
274 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
275 if (!completionStatus)
277 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
278 "Failed reading completion status for non parallel shader compiling");
282 program.attachShader(vertexShader.getShader());
283 program.attachShader(fragmentShader.getShader());
284 gl.linkProgram(program.getProgram());
286 gl.getProgramiv(program.getProgram(), GL_COMPLETION_STATUS_KHR, &completionStatus);
287 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
288 if (!completionStatus)
290 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
291 "Failed reading completion status for non parallel program linking");
296 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
302 * @param context Rendering context
303 * @param name Test name
304 * @param description Test description
306 CompilationCompletionParallelTest::CompilationCompletionParallelTest(deqp::Context& context)
307 : TestCase(context, "compilation_completion_parallel",
308 "Tests verifies if shader COMPLETION_STATUS query works as expected for parallel compilation")
310 /* Left blank intentionally */
313 /** Executes test iteration.
315 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
317 tcu::TestNode::IterateResult CompilationCompletionParallelTest::iterate()
319 const glu::ContextInfo& contextInfo = m_context.getContextInfo();
320 const glu::ContextType& contextType = m_context.getRenderContext().getType();
321 const bool isGL = glu::isContextTypeGLCore(contextType);
322 const bool supportParallel = (isGL && contextInfo.isExtensionSupported("GL_ARB_parallel_shader_compile")) ||
323 contextInfo.isExtensionSupported("GL_KHR_parallel_shader_compile");
325 if (!supportParallel)
327 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
331 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
333 GLint completionStatus;
335 gl.maxShaderCompilerThreadsKHR(8);
336 GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
339 Shader vertexShader(gl, SHADERTYPE_VERTEX);
340 deUint32 fragmentShader[8];
343 bool isContextES = (glu::isContextTypeES(m_context.getRenderContext().getType()));
344 const char* shaderVersion = isContextES ? shaderVersionES : shaderVersionGL;
346 for (int i = 0; i < 8; ++i)
348 fragmentShader[i] = gl.createShader(GL_FRAGMENT_SHADER);
349 program[i] = gl.createProgram();
352 const char* vSources[] = { shaderVersion, vShader };
353 const int vLengths[] = { int(strlen(shaderVersion)), int(strlen(vShader)) };
354 vertexShader.setSources(2, vSources, vLengths);
357 for (int i = 0; i < 8; ++i)
359 const char* fSources[] = { shaderVersion, fShader };
360 const int fLengths[] = { int(strlen(shaderVersion)), int(strlen(fShader)) };
361 gl.shaderSource(fragmentShader[i], 2, fSources, fLengths);
364 gl.compileShader(vertexShader.getShader());
365 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
366 for (int i = 0; i < 8; ++i)
368 gl.compileShader(fragmentShader[i]);
369 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
374 deUint64 shLoopStart = deGetMicroseconds();
375 while (completion != 8 && deGetMicroseconds() < shLoopStart + 1000000)
378 for (int i = 0; i < 8; ++i)
380 gl.getShaderiv(fragmentShader[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
381 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
382 if (completionStatus)
388 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
389 "Failed reading completion status for parallel shader compiling");
390 for (int i = 0; i < 8; ++i)
392 gl.deleteProgram(program[i]);
393 gl.deleteShader(fragmentShader[i]);
399 for (int i = 0; i < 8; ++i)
401 gl.attachShader(program[i], vertexShader.getShader());
402 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
403 gl.attachShader(program[i], fragmentShader[i]);
404 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
408 for (int i = 0; i < 8; ++i)
410 gl.linkProgram(program[i]);
411 GLU_EXPECT_NO_ERROR(gl.getError(), "linkProgram");
416 deUint64 prLoopStart = deGetMicroseconds();
417 while (completion != 8 && deGetMicroseconds() < prLoopStart + 1000000)
420 for (int i = 0; i < 8; ++i)
422 gl.getProgramiv(program[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
423 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
424 if (completionStatus)
430 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
431 "Failed reading completion status for parallel program linking");
432 for (int i = 0; i < 8; ++i)
434 gl.deleteProgram(program[i]);
435 gl.deleteShader(fragmentShader[i]);
442 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
448 * @param context Rendering context.
450 ParallelShaderCompileTests::ParallelShaderCompileTests(deqp::Context& context)
451 : TestCaseGroup(context, "parallel_shader_compile",
452 "Verify conformance of KHR_parallel_shader_compile implementation")
456 /** Initializes the test group contents. */
457 void ParallelShaderCompileTests::init()
459 addChild(new SimpleQueriesTest(m_context));
460 addChild(new MaxShaderCompileThreadsTest(m_context));
461 addChild(new CompilationCompletionNonParallelTest(m_context));
462 addChild(new CompilationCompletionParallelTest(m_context));
465 } /* glcts namespace */