xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcShaderIntegerMixTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014 Intel Corporation
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21  * \file
22  * \brief
23  */ /*-------------------------------------------------------------------*/
24 
25 #include "glcShaderIntegerMixTests.hpp"
26 #include "deMath.h"
27 #include "deRandom.hpp"
28 #include "deString.h"
29 #include "deStringUtil.hpp"
30 #include "gluContextInfo.hpp"
31 #include "gluDrawUtil.hpp"
32 #include "gluPixelTransfer.hpp"
33 #include "gluShaderProgram.hpp"
34 #include "glw.h"
35 #include "glwFunctions.hpp"
36 #include "tcuCommandLine.hpp"
37 #include "tcuStringTemplate.hpp"
38 #include "tcuSurface.hpp"
39 #include "tcuTestLog.hpp"
40 
41 namespace deqp
42 {
43 
44 using tcu::TestLog;
45 
46 class ShaderIntegerMixCase : public TestCase
47 {
48 public:
ShaderIntegerMixCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion)49     ShaderIntegerMixCase(Context &context, const char *name, const char *description, glu::GLSLVersion glslVersion)
50         : TestCase(context, name, description)
51         , m_glslVersion(glslVersion)
52     {
53     }
54 
~ShaderIntegerMixCase()55     ~ShaderIntegerMixCase()
56     {
57         // empty
58     }
59 
iterate()60     IterateResult iterate()
61     {
62         qpTestResult result = test();
63 
64         m_testCtx.setTestResult(result, qpGetTestResultName(result));
65 
66         return STOP;
67     }
68 
69 protected:
70     glu::GLSLVersion m_glslVersion;
71 
72     virtual qpTestResult test() = 0;
73 };
74 
75 class ShaderIntegerMixDefineCase : public ShaderIntegerMixCase
76 {
77 public:
ShaderIntegerMixDefineCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion)78     ShaderIntegerMixDefineCase(Context &context, const char *name, const char *description,
79                                glu::GLSLVersion glslVersion)
80         : ShaderIntegerMixCase(context, name, description, glslVersion)
81     {
82         // empty
83     }
84 
~ShaderIntegerMixDefineCase()85     ~ShaderIntegerMixDefineCase()
86     {
87         // empty
88     }
89 
90 protected:
test()91     virtual qpTestResult test()
92     {
93         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
94         bool pass                = true;
95 
96         static const char source_template[] = "${VERSION_DECL}\n"
97                                               "#extension GL_EXT_shader_integer_mix: require\n"
98                                               "\n"
99                                               "#if !defined GL_EXT_shader_integer_mix\n"
100                                               "#  error GL_EXT_shader_integer_mix is not defined\n"
101                                               "#elif GL_EXT_shader_integer_mix != 1\n"
102                                               "#  error GL_EXT_shader_integer_mix is not equal to 1\n"
103                                               "#endif\n"
104                                               "\n"
105                                               "void main(void) { ${BODY} }\n";
106 
107         static const struct
108         {
109             GLenum target;
110             const char *body;
111         } shader_targets[] = {
112             {GL_VERTEX_SHADER, "gl_Position = vec4(0);"},
113             {GL_FRAGMENT_SHADER, ""},
114         };
115 
116         const glu::GLSLVersion v = glslVersionIsES(m_glslVersion) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;
117 
118         if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_integer_mix"))
119             return QP_TEST_RESULT_NOT_SUPPORTED;
120 
121         for (int i = 0; i < DE_LENGTH_OF_ARRAY(shader_targets); i++)
122         {
123             std::map<std::string, std::string> args;
124 
125             args["VERSION_DECL"] = glu::getGLSLVersionDeclaration(v);
126             args["BODY"]         = shader_targets[i].body;
127 
128             std::string code = tcu::StringTemplate(source_template).specialize(args);
129 
130             GLuint shader          = gl.createShader(shader_targets[i].target);
131             char const *strings[1] = {code.c_str()};
132             gl.shaderSource(shader, 1, strings, 0);
133             gl.compileShader(shader);
134 
135             GLint compileSuccess = 0;
136             gl.getShaderiv(shader, GL_COMPILE_STATUS, &compileSuccess);
137             gl.deleteShader(shader);
138 
139             if (!compileSuccess)
140                 pass = false;
141         }
142 
143         return pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
144     }
145 };
146 
147 class ShaderIntegerMixPrototypesCase : public ShaderIntegerMixCase
148 {
149 public:
ShaderIntegerMixPrototypesCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion,bool _use_extension,bool _is_negative_testing)150     ShaderIntegerMixPrototypesCase(Context &context, const char *name, const char *description,
151                                    glu::GLSLVersion glslVersion, bool _use_extension, bool _is_negative_testing)
152         : ShaderIntegerMixCase(context, name, description, glslVersion)
153         , use_extension(_use_extension)
154         , is_negative_testing(_is_negative_testing)
155     {
156         // empty
157     }
158 
~ShaderIntegerMixPrototypesCase()159     ~ShaderIntegerMixPrototypesCase()
160     {
161         // empty
162     }
163 
164 protected:
165     bool use_extension;
166     bool is_negative_testing;
167 
test()168     virtual qpTestResult test()
169     {
170         TestLog &log             = m_testCtx.getLog();
171         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
172         bool pass                = true;
173 
174         static const char source_template[] = "${VERSION_DECL}\n"
175                                               "${EXTENSION_ENABLE}\n"
176                                               "\n"
177                                               "void main()\n"
178                                               "{\n"
179                                               "    mix(ivec2(1), ivec2(2), bvec2(true));\n"
180                                               "    mix(ivec3(1), ivec3(2), bvec3(true));\n"
181                                               "    mix(ivec4(1), ivec4(2), bvec4(true));\n"
182                                               "    mix(uvec2(1), uvec2(2), bvec2(true));\n"
183                                               "    mix(uvec3(1), uvec3(2), bvec3(true));\n"
184                                               "    mix(uvec4(1), uvec4(2), bvec4(true));\n"
185                                               "    mix(bvec2(1), bvec2(0), bvec2(true));\n"
186                                               "    mix(bvec3(1), bvec3(0), bvec3(true));\n"
187                                               "    mix(bvec4(1), bvec4(0), bvec4(true));\n"
188                                               "    ${BODY}\n"
189                                               "}\n";
190 
191         static const struct
192         {
193             GLenum target;
194             const char *body;
195         } shader_targets[] = {
196             {GL_VERTEX_SHADER, "gl_Position = vec4(0);"},
197             {GL_FRAGMENT_SHADER, ""},
198         };
199 
200         glu::GLSLVersion v;
201         const char *extension_enable;
202 
203         if (use_extension)
204         {
205             v                = glslVersionIsES(m_glslVersion) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;
206             extension_enable = "#extension GL_EXT_shader_integer_mix: enable";
207 
208             if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_integer_mix"))
209                 return QP_TEST_RESULT_NOT_SUPPORTED;
210         }
211         else if (is_negative_testing)
212         {
213             v                = glslVersionIsES(m_glslVersion) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;
214             extension_enable = "";
215         }
216         else
217         {
218             v                = m_glslVersion;
219             extension_enable = "";
220             if (glslVersionIsES(m_glslVersion))
221             {
222                 if (m_glslVersion < glu::GLSL_VERSION_310_ES)
223                     return QP_TEST_RESULT_NOT_SUPPORTED;
224             }
225             else
226             {
227                 if (m_glslVersion < glu::GLSL_VERSION_450)
228                     return QP_TEST_RESULT_NOT_SUPPORTED;
229             }
230         }
231 
232         for (int i = 0; i < DE_LENGTH_OF_ARRAY(shader_targets); i++)
233         {
234             std::map<std::string, std::string> args;
235 
236             args["VERSION_DECL"]     = glu::getGLSLVersionDeclaration(v);
237             args["EXTENSION_ENABLE"] = extension_enable;
238             args["BODY"]             = shader_targets[i].body;
239 
240             std::string code = tcu::StringTemplate(source_template).specialize(args);
241 
242             GLuint shader          = gl.createShader(shader_targets[i].target);
243             char const *strings[1] = {code.c_str()};
244             gl.shaderSource(shader, 1, strings, 0);
245             gl.compileShader(shader);
246 
247             GLint compileSuccess = 0;
248             gl.getShaderiv(shader, GL_COMPILE_STATUS, &compileSuccess);
249 
250             if (is_negative_testing)
251             {
252                 if (compileSuccess)
253                 {
254                     TCU_FAIL("The shader compilation was expected to fail, but it was successful.");
255                     pass = false;
256                 }
257             }
258             else if (!compileSuccess)
259             {
260                 GLchar infoLog[1000];
261 
262                 gl.getShaderInfoLog(shader, sizeof(infoLog), NULL, infoLog);
263                 log.writeKernelSource(strings[0]);
264                 log.writeCompileInfo("shader", "", false, infoLog);
265 
266                 pass = false;
267             }
268 
269             gl.deleteShader(shader);
270         }
271 
272         return pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
273     }
274 };
275 
276 class ShaderIntegerMixRenderCase : public ShaderIntegerMixCase
277 {
278 public:
ShaderIntegerMixRenderCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion,const char * _type)279     ShaderIntegerMixRenderCase(Context &context, const char *name, const char *description,
280                                glu::GLSLVersion glslVersion, const char *_type)
281         : ShaderIntegerMixCase(context, name, description, glslVersion)
282         , type(_type)
283     {
284         // empty
285     }
286 
~ShaderIntegerMixRenderCase()287     ~ShaderIntegerMixRenderCase()
288     {
289         // empty
290     }
291 
292 protected:
293     // Type used for mix() parameters in this test case.
294     const char *type;
295 
296     static const unsigned width  = 8 * 8;
297     static const unsigned height = 8 * 8;
298 
test()299     virtual qpTestResult test()
300     {
301         static const char vs_template[] = "${VERSION_DECL}\n"
302                                           "${EXTENSION_ENABLE}\n"
303                                           "\n"
304                                           "in vec2 vertex;\n"
305                                           "in ivec4 vs_in_a;\n"
306                                           "in ivec4 vs_in_b;\n"
307                                           "in ivec4 vs_in_sel;\n"
308                                           "\n"
309                                           "flat out ivec4 fs_in_a;\n"
310                                           "flat out ivec4 fs_in_b;\n"
311                                           "flat out ivec4 fs_in_sel;\n"
312                                           "flat out ivec4 fs_in_result;\n"
313                                           "\n"
314                                           "void main()\n"
315                                           "{\n"
316                                           "    fs_in_a = vs_in_a;\n"
317                                           "    fs_in_b = vs_in_b;\n"
318                                           "    fs_in_sel = vs_in_sel;\n"
319                                           "\n"
320                                           "    ${TYPE} a = ${TYPE}(vs_in_a);\n"
321                                           "    ${TYPE} b = ${TYPE}(vs_in_b);\n"
322                                           "    bvec4 sel = bvec4(vs_in_sel);\n"
323                                           "    fs_in_result = ivec4(mix(a, b, sel));\n"
324                                           "\n"
325                                           "    gl_Position = vec4(vertex, 0, 1);\n"
326                                           "    gl_PointSize = 4.;\n"
327                                           "}\n";
328 
329         static const char fs_template[] = "${VERSION_DECL}\n"
330                                           "${EXTENSION_ENABLE}\n"
331                                           "\n"
332                                           "out ivec4 o;\n"
333                                           "\n"
334                                           "flat in ivec4 fs_in_a;\n"
335                                           "flat in ivec4 fs_in_b;\n"
336                                           "flat in ivec4 fs_in_sel;\n"
337                                           "flat in ivec4 fs_in_result;\n"
338                                           "\n"
339                                           "uniform bool use_vs_data;\n"
340                                           "\n"
341                                           "void main()\n"
342                                           "{\n"
343                                           "    if (use_vs_data)\n"
344                                           "        o = fs_in_result;\n"
345                                           "    else {\n"
346                                           "        ${TYPE} a = ${TYPE}(fs_in_a);\n"
347                                           "        ${TYPE} b = ${TYPE}(fs_in_b);\n"
348                                           "        bvec4 sel = bvec4(fs_in_sel);\n"
349                                           "        o = ivec4(mix(a, b, sel));\n"
350                                           "    }\n"
351                                           "}\n";
352 
353         TestLog &log             = m_testCtx.getLog();
354         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
355         bool pass                = true;
356         const char *extension_enable;
357         bool is_es = glslVersionIsES(m_glslVersion);
358 
359         if ((is_es && (m_glslVersion < glu::GLSL_VERSION_310_ES)) || !is_es)
360         {
361             /* For versions that do not support this feature in Core it must be exposed via an extension. */
362             if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_integer_mix"))
363             {
364                 return QP_TEST_RESULT_NOT_SUPPORTED;
365             }
366 
367             extension_enable = "#extension GL_EXT_shader_integer_mix: enable";
368         }
369         else
370         {
371             extension_enable = "";
372         }
373 
374         /* Generate the specialization of the shader for the specific
375          * type being tested.
376          */
377         std::map<std::string, std::string> args;
378 
379         args["VERSION_DECL"]     = glu::getGLSLVersionDeclaration(m_glslVersion);
380         args["EXTENSION_ENABLE"] = extension_enable;
381         args["TYPE"]             = type;
382 
383         std::string vs_code = tcu::StringTemplate(vs_template).specialize(args);
384 
385         std::string fs_code = tcu::StringTemplate(fs_template).specialize(args);
386 
387         glu::ShaderProgram prog(m_context.getRenderContext(),
388                                 glu::makeVtxFragSources(vs_code.c_str(), fs_code.c_str()));
389 
390         if (!prog.isOk())
391         {
392             log << prog;
393             TCU_FAIL("Compile failed");
394         }
395 
396         if (!glslVersionIsES(m_glslVersion))
397             glEnable(GL_PROGRAM_POINT_SIZE);
398 
399         /* Generate an integer FBO for rendering.
400          */
401         GLuint fbo;
402         GLuint tex;
403 
404         glGenTextures(1, &tex);
405         glBindTexture(GL_TEXTURE_2D, tex);
406         glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA32I, width, height, 0 /* border */, GL_RGBA_INTEGER, GL_INT,
407                      NULL /* data */);
408         glBindTexture(GL_TEXTURE_2D, 0);
409 
410         glGenFramebuffers(1, &fbo);
411         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
412         glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
413         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0 /* level */);
414 
415         GLU_EXPECT_NO_ERROR(gl.getError(), "Creation of rendering FBO failed.");
416 
417         if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
418             TCU_FAIL("Framebuffer not complete.");
419 
420         glViewport(0, 0, width, height);
421 
422         /* Fill a VBO with some vertex data.
423          */
424         uint32_t pointIndices[256];
425         float vertex[DE_LENGTH_OF_ARRAY(pointIndices) * 2];
426         int32_t a[DE_LENGTH_OF_ARRAY(pointIndices) * 4];
427         int32_t b[DE_LENGTH_OF_ARRAY(a)];
428         int32_t sel[DE_LENGTH_OF_ARRAY(a)];
429         tcu::IVec4 expected[DE_LENGTH_OF_ARRAY(pointIndices)];
430 
431         for (int i = 0; i < DE_LENGTH_OF_ARRAY(pointIndices); i++)
432         {
433             pointIndices[i] = uint16_t(i);
434 
435             const int x = (i / 16) * (width / 16) + (4 / 2);
436             const int y = (i % 16) * (height / 16) + (4 / 2);
437 
438             vertex[(i * 2) + 0] = float(x) * 2.0f / float(width) - 1.0f;
439             vertex[(i * 2) + 1] = float(y) * 2.0f / float(height) - 1.0f;
440 
441             a[(i * 4) + 0] = i;
442             a[(i * 4) + 1] = i * 5;
443             a[(i * 4) + 2] = i * 7;
444             a[(i * 4) + 3] = i * 11;
445 
446             b[(i * 4) + 0] = ~a[(i * 4) + 3];
447             b[(i * 4) + 1] = ~a[(i * 4) + 2];
448             b[(i * 4) + 2] = ~a[(i * 4) + 1];
449             b[(i * 4) + 3] = ~a[(i * 4) + 0];
450 
451             sel[(i * 4) + 0] = (i >> 0) & 1;
452             sel[(i * 4) + 1] = (i >> 1) & 1;
453             sel[(i * 4) + 2] = (i >> 2) & 1;
454             sel[(i * 4) + 3] = (i >> 3) & 1;
455 
456             expected[i] = tcu::IVec4(
457                 sel[(i * 4) + 0] ? b[(i * 4) + 0] : a[(i * 4) + 0], sel[(i * 4) + 1] ? b[(i * 4) + 1] : a[(i * 4) + 1],
458                 sel[(i * 4) + 2] ? b[(i * 4) + 2] : a[(i * 4) + 2], sel[(i * 4) + 3] ? b[(i * 4) + 3] : a[(i * 4) + 3]);
459         }
460 
461         /* Mask off all but the least significant bit for boolean
462          * types.
463          */
464         if (type[0] == 'b')
465         {
466             for (int i = 0; i < DE_LENGTH_OF_ARRAY(a); i++)
467             {
468                 a[i] &= 1;
469                 b[i] &= 1;
470 
471                 expected[i / 4][0] &= 1;
472                 expected[i / 4][1] &= 1;
473                 expected[i / 4][2] &= 1;
474                 expected[i / 4][3] &= 1;
475             }
476         }
477 
478         glu::VertexArrayBinding vertexArrays[] = {
479             glu::va::Float("vertex", 2, DE_LENGTH_OF_ARRAY(pointIndices), 0, vertex),
480             glu::va::Int32("vs_in_a", 4, DE_LENGTH_OF_ARRAY(pointIndices), 0, a),
481             glu::va::Int32("vs_in_b", 4, DE_LENGTH_OF_ARRAY(pointIndices), 0, b),
482             glu::va::Int32("vs_in_sel", 4, DE_LENGTH_OF_ARRAY(pointIndices), 0, sel)};
483 
484         /* Render and verify the results.  Rendering happens twice.
485          * The first time, use_vs_data is false, and the mix() result
486          * from the fragment shader is used.  The second time,
487          * use_vs_data is true, and the mix() result from the vertex
488          * shader is used.
489          */
490         const GLint loc = gl.getUniformLocation(prog.getProgram(), "use_vs_data");
491         gl.useProgram(prog.getProgram());
492 
493         static const GLint clear[] = {1, 2, 3, 4};
494         glClearBufferiv(GL_COLOR, 0, clear);
495 
496         gl.uniform1i(loc, 0);
497         glu::draw(m_context.getRenderContext(), prog.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
498                   glu::pr::Points(DE_LENGTH_OF_ARRAY(pointIndices), pointIndices));
499 
500         for (int i = 0; i < DE_LENGTH_OF_ARRAY(pointIndices); i++)
501         {
502             const int x = int((vertex[(i * 2) + 0] + 1.0f) * float(width) / 2.0f);
503             const int y = int((vertex[(i * 2) + 1] + 1.0f) * float(height) / 2.0f);
504 
505             pass = probe_pixel(log, "Fragment", x, y, expected[i]) && pass;
506         }
507 
508         gl.uniform1i(loc, 1);
509         glu::draw(m_context.getRenderContext(), prog.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays,
510                   glu::pr::Points(DE_LENGTH_OF_ARRAY(pointIndices), pointIndices));
511 
512         for (int i = 0; i < DE_LENGTH_OF_ARRAY(pointIndices); i++)
513         {
514             const int x = int((vertex[(i * 2) + 0] + 1.0f) * float(width) / 2.0f);
515             const int y = int((vertex[(i * 2) + 1] + 1.0f) * float(height) / 2.0f);
516 
517             pass = probe_pixel(log, "Vertex", x, y, expected[i]) && pass;
518         }
519 
520         glDeleteFramebuffers(1, &fbo);
521         glDeleteTextures(1, &tex);
522 
523         return pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL;
524     }
525 
probe_pixel(TestLog & log,const char * stage,int x,int y,const tcu::IVec4 & expected)526     bool probe_pixel(TestLog &log, const char *stage, int x, int y, const tcu::IVec4 &expected)
527     {
528         tcu::IVec4 pixel;
529 
530         glReadPixels(x, y, 1, 1, GL_RGBA_INTEGER, GL_INT, &pixel);
531 
532         if (expected != pixel)
533         {
534             log << TestLog::Message << stage << " shader failed at pixel (" << x << ", " << y << ").  "
535                 << "Got " << pixel << ", expected " << expected << ")." << TestLog::EndMessage;
536             return false;
537         }
538 
539         return true;
540     }
541 };
542 
ShaderIntegerMixTests(Context & context,glu::GLSLVersion glslVersion)543 ShaderIntegerMixTests::ShaderIntegerMixTests(Context &context, glu::GLSLVersion glslVersion)
544     : TestCaseGroup(context, "shader_integer_mix", "Shader Integer Mix tests")
545     , m_glslVersion(glslVersion)
546 {
547     // empty
548 }
549 
~ShaderIntegerMixTests()550 ShaderIntegerMixTests::~ShaderIntegerMixTests()
551 {
552     // empty
553 }
554 
init(void)555 void ShaderIntegerMixTests::init(void)
556 {
557     addChild(new ShaderIntegerMixDefineCase(m_context, "define", "Verify GL_EXT_shader_integer_mix is defined to 1.",
558                                             m_glslVersion));
559     addChild(new ShaderIntegerMixPrototypesCase(m_context, "prototypes-extension",
560                                                 "Verify availability of all function signatures with the extension.",
561                                                 m_glslVersion, true, false));
562     addChild(new ShaderIntegerMixPrototypesCase(
563         m_context, "prototypes", "Verify availability of all function signatures with the proper GLSL version.",
564         m_glslVersion, false, false));
565     addChild(new ShaderIntegerMixPrototypesCase(
566         m_context, "prototypes-negative",
567         "Verify compilation fails if the GLSL version does not support shader_integer_mix", m_glslVersion, false,
568         true));
569 
570     static const char *types_to_test[] = {"ivec4", "uvec4", "bvec4"};
571 
572     for (int i = 0; i < DE_LENGTH_OF_ARRAY(types_to_test); i++)
573     {
574         std::stringstream name;
575 
576         name << "mix-" << types_to_test[i];
577 
578         std::stringstream description;
579 
580         description << "Verify functionality of mix() with " << types_to_test[i] << " parameters.";
581 
582         addChild(new ShaderIntegerMixRenderCase(m_context, name.str().c_str(), description.str().c_str(), m_glslVersion,
583                                                 types_to_test[i]));
584     }
585 }
586 
587 } // namespace deqp
588