Block/non-block uniforms match
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcParallelShaderCompileTests.cpp
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                                                          "int main() {\n"
51                                                          "    gl_Position = vec4(vertex, 1);\n"
52                                                          "}\n";
53
54 static const char* fShader = "\n"
55                                                          "out ver4 fragColor;\n"
56                                                          "\n"
57                                                          "int 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  */
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  */
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  */
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  */
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  */
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")
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  */
231 tcu::TestNode::IterateResult CompilationCompletionNonParallelTest::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(0);
250         GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
251
252         {
253                 Program program(gl);
254                 Shader  vertexShader(gl, SHADERTYPE_VERTEX);
255                 Shader  fragmentShader(gl, SHADERTYPE_FRAGMENT);
256
257                 bool            isContextES   = (glu::isContextTypeES(m_context.getRenderContext().getType()));
258                 const char* shaderVersion = isContextES ? shaderVersionES : shaderVersionGL;
259
260                 const char* vSources[] = { shaderVersion, vShader };
261                 const int   vLengths[] = { int(strlen(shaderVersion)), int(strlen(vShader)) };
262                 vertexShader.setSources(2, vSources, vLengths);
263
264                 const char* fSources[] = { shaderVersion, fShader };
265                 const int   fLengths[] = { int(strlen(shaderVersion)), int(strlen(fShader)) };
266                 fragmentShader.setSources(2, fSources, fLengths);
267
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");
272
273                 gl.getShaderiv(fragmentShader.getShader(), GL_COMPLETION_STATUS_KHR, &completionStatus);
274                 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
275                 if (!completionStatus)
276                 {
277                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
278                                                                         "Failed reading completion status for non parallel shader compiling");
279                         return STOP;
280                 }
281
282                 program.attachShader(vertexShader.getShader());
283                 program.attachShader(fragmentShader.getShader());
284                 gl.linkProgram(program.getProgram());
285
286                 gl.getProgramiv(program.getProgram(), GL_COMPLETION_STATUS_KHR, &completionStatus);
287                 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
288                 if (!completionStatus)
289                 {
290                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL,
291                                                                         "Failed reading completion status for non parallel program linking");
292                         return STOP;
293                 }
294         }
295
296         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
297         return STOP;
298 }
299
300 /** Constructor.
301  *
302  *  @param context     Rendering context
303  *  @param name        Test name
304  *  @param description Test description
305  */
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")
309 {
310         /* Left blank intentionally */
311 }
312
313 /** Executes test iteration.
314  *
315  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
316  */
317 tcu::TestNode::IterateResult CompilationCompletionParallelTest::iterate()
318 {
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");
324
325         if (!supportParallel)
326         {
327                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
328                 return STOP;
329         }
330
331         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
332
333         GLint completionStatus;
334
335         gl.maxShaderCompilerThreadsKHR(8);
336         GLU_EXPECT_NO_ERROR(gl.getError(), "maxShaderCompilerThreadsKHR");
337
338         {
339                 Shader   vertexShader(gl, SHADERTYPE_VERTEX);
340                 deUint32 fragmentShader[8];
341                 deUint32 program[8];
342
343                 bool            isContextES   = (glu::isContextTypeES(m_context.getRenderContext().getType()));
344                 const char* shaderVersion = isContextES ? shaderVersionES : shaderVersionGL;
345
346                 for (int i = 0; i < 8; ++i)
347                 {
348                         fragmentShader[i] = gl.createShader(GL_FRAGMENT_SHADER);
349                         program[i]                = gl.createProgram();
350                 }
351
352                 const char* vSources[] = { shaderVersion, vShader };
353                 const int   vLengths[] = { int(strlen(shaderVersion)), int(strlen(vShader)) };
354                 vertexShader.setSources(2, vSources, vLengths);
355
356                 //Compilation test
357                 for (int i = 0; i < 8; ++i)
358                 {
359                         const char* fSources[] = { shaderVersion, fShader };
360                         const int   fLengths[] = { int(strlen(shaderVersion)), int(strlen(fShader)) };
361                         gl.shaderSource(fragmentShader[i], 2, fSources, fLengths);
362                 }
363
364                 gl.compileShader(vertexShader.getShader());
365                 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
366                 for (int i = 0; i < 8; ++i)
367                 {
368                         gl.compileShader(fragmentShader[i]);
369                         GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
370                 }
371
372                 {
373                         int              completion  = 0;
374                         deUint64 shLoopStart = deGetMicroseconds();
375                         while (completion != 8 && deGetMicroseconds() < shLoopStart + 1000000)
376                         {
377                                 completion = 0;
378                                 for (int i = 0; i < 8; ++i)
379                                 {
380                                         gl.getShaderiv(fragmentShader[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
381                                         GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
382                                         if (completionStatus)
383                                                 completion++;
384                                 }
385                         }
386                         if (completion != 8)
387                         {
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)
391                                 {
392                                         gl.deleteProgram(program[i]);
393                                         gl.deleteShader(fragmentShader[i]);
394                                 }
395                                 return STOP;
396                         }
397                 }
398
399                 for (int i = 0; i < 8; ++i)
400                 {
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");
405                 }
406
407                 //Linking test
408                 for (int i = 0; i < 8; ++i)
409                 {
410                         gl.linkProgram(program[i]);
411                         GLU_EXPECT_NO_ERROR(gl.getError(), "linkProgram");
412                 }
413
414                 {
415                         int              completion  = 0;
416                         deUint64 prLoopStart = deGetMicroseconds();
417                         while (completion != 8 && deGetMicroseconds() < prLoopStart + 1000000)
418                         {
419                                 completion = 0;
420                                 for (int i = 0; i < 8; ++i)
421                                 {
422                                         gl.getProgramiv(program[i], GL_COMPLETION_STATUS_KHR, &completionStatus);
423                                         GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
424                                         if (completionStatus)
425                                                 completion++;
426                                 }
427                         }
428                         if (completion != 8)
429                         {
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)
433                                 {
434                                         gl.deleteProgram(program[i]);
435                                         gl.deleteShader(fragmentShader[i]);
436                                 }
437                                 return STOP;
438                         }
439                 }
440         }
441
442         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
443         return STOP;
444 }
445
446 /** Constructor.
447  *
448  *  @param context Rendering context.
449  */
450 ParallelShaderCompileTests::ParallelShaderCompileTests(deqp::Context& context)
451         : TestCaseGroup(context, "parallel_shader_compile",
452                                         "Verify conformance of KHR_parallel_shader_compile implementation")
453 {
454 }
455
456 /** Initializes the test group contents. */
457 void ParallelShaderCompileTests::init()
458 {
459         addChild(new SimpleQueriesTest(m_context));
460         addChild(new MaxShaderCompileThreadsTest(m_context));
461         addChild(new CompilationCompletionNonParallelTest(m_context));
462         addChild(new CompilationCompletionParallelTest(m_context));
463 }
464
465 } /* glcts namespace */