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