xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcParallelShaderCompileTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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         uint32_t fragmentShader[8];
255         uint32_t 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             uint64_t 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             uint64_t 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 } // namespace glcts
379