• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-2016 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  * \file  gl3GPUShader5Tests.cpp
26  * \brief Implements conformance tests for "GPU Shader 5" functionality.
27  */ /*-------------------------------------------------------------------*/
28 
29 #include "gl3cGPUShader5Tests.hpp"
30 #include "gluContextInfo.hpp"
31 #include "glwFunctions.hpp"
32 #include "tcuMatrix.hpp"
33 #include "tcuTestLog.hpp"
34 
35 #include <iomanip>
36 
37 #include <deMath.h>
38 #include <tcuMatrixUtil.hpp>
39 #include <tcuVectorUtil.hpp>
40 
41 #include <cstdlib>
42 #include <cstring>
43 #include <limits>
44 #include <memory>
45 
46 namespace gl3cts
47 {
48 
49 /** Constructor
50  *
51  * @param context Test context
52  **/
programInfo(deqp::Context & context)53 Utils::programInfo::programInfo(deqp::Context& context)
54 	: m_context(context), m_fragment_shader_id(0), m_program_object_id(0), m_vertex_shader_id(0)
55 {
56 	/* Nothing to be done here */
57 }
58 
59 /** Destructor
60  *
61  **/
~programInfo()62 Utils::programInfo::~programInfo()
63 {
64 	/* GL entry points */
65 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
66 
67 	/* Make sure program object is no longer used by GL */
68 	gl.useProgram(0);
69 
70 	/* Clean program object */
71 	if (0 != m_program_object_id)
72 	{
73 		gl.deleteProgram(m_program_object_id);
74 		m_program_object_id = 0;
75 	}
76 
77 	/* Clean shaders */
78 	if (0 != m_fragment_shader_id)
79 	{
80 		gl.deleteShader(m_fragment_shader_id);
81 		m_fragment_shader_id = 0;
82 	}
83 
84 	if (0 != m_vertex_shader_id)
85 	{
86 		gl.deleteShader(m_vertex_shader_id);
87 		m_vertex_shader_id = 0;
88 	}
89 }
90 
91 /** Build program
92  *
93  * @param fragment_shader_code               Fragment shader source code
94  * @param vertex_shader_code                 Vertex shader source code
95  * @param varying_names                      Array of strings containing names of varyings to be captured with transfrom feedback
96  * @param n_varying_names                    Number of varyings to be captured with transfrom feedback
97  **/
build(const glw::GLchar * fragment_shader_code,const glw::GLchar * vertex_shader_code)98 void Utils::programInfo::build(const glw::GLchar* fragment_shader_code, const glw::GLchar* vertex_shader_code)
99 {
100 	/* GL entry points */
101 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
102 
103 	/* Create shader objects and compile */
104 	if (0 != fragment_shader_code)
105 	{
106 		m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
107 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
108 
109 		compile(m_fragment_shader_id, fragment_shader_code);
110 	}
111 
112 	if (0 != vertex_shader_code)
113 	{
114 		m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
115 		GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
116 
117 		compile(m_vertex_shader_id, vertex_shader_code);
118 	}
119 
120 	/* Create program object */
121 	m_program_object_id = gl.createProgram();
122 	GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
123 
124 	/* Link program */
125 	link();
126 }
127 
128 /** Compile shader
129  *
130  * @param shader_id   Shader object id
131  * @param shader_code Shader source code
132  **/
compile(glw::GLuint shader_id,const glw::GLchar * shader_code) const133 void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
134 {
135 	/* GL entry points */
136 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
137 
138 	/* Compilation status */
139 	glw::GLint status = GL_FALSE;
140 
141 	/* Set source code */
142 	gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
143 	GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
144 
145 	/* Compile */
146 	gl.compileShader(shader_id);
147 	GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
148 
149 	/* Get compilation status */
150 	gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
151 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
152 
153 	/* Log compilation error */
154 	if (GL_TRUE != status)
155 	{
156 		glw::GLint				 length = 0;
157 		std::vector<glw::GLchar> message;
158 
159 		/* Error log length */
160 		gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
161 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
162 
163 		/* Prepare storage */
164 		message.resize(length);
165 
166 		/* Get error log */
167 		gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
168 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
169 
170 		/* Log */
171 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
172 											<< &message[0] << "\nShader source\n"
173 											<< shader_code << tcu::TestLog::EndMessage;
174 
175 		TCU_FAIL("Failed to compile shader");
176 	}
177 }
178 
179 /** Attach shaders and link program
180  *
181  **/
link() const182 void Utils::programInfo::link() const
183 {
184 	/* GL entry points */
185 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
186 
187 	/* Link status */
188 	glw::GLint status = GL_FALSE;
189 
190 	/* Attach shaders */
191 	if (0 != m_fragment_shader_id)
192 	{
193 		gl.attachShader(m_program_object_id, m_fragment_shader_id);
194 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
195 	}
196 
197 	if (0 != m_vertex_shader_id)
198 	{
199 		gl.attachShader(m_program_object_id, m_vertex_shader_id);
200 		GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
201 	}
202 
203 	/* Link */
204 	gl.linkProgram(m_program_object_id);
205 	GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
206 
207 	/* Get link status */
208 	gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
209 	GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
210 
211 	/* Log link error */
212 	if (GL_TRUE != status)
213 	{
214 		glw::GLint				 length = 0;
215 		std::vector<glw::GLchar> message;
216 
217 		/* Get error log length */
218 		gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
219 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
220 
221 		message.resize(length);
222 
223 		/* Get error log */
224 		gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
225 		GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
226 
227 		/* Log */
228 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
229 											<< &message[0] << tcu::TestLog::EndMessage;
230 
231 		TCU_FAIL("Failed to link program");
232 	}
233 }
234 
235 /** Set the uniform variable with provided data.
236  *
237  * @param type       Type of variable
238  * @param name       Name of variable
239  * @param data       Data
240  */
setUniform(Utils::_variable_type type,const glw::GLchar * name,const glw::GLvoid * data)241 void Utils::programInfo::setUniform(Utils::_variable_type type, const glw::GLchar* name, const glw::GLvoid* data)
242 {
243 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
244 
245 	const glw::GLfloat* f_data = (glw::GLfloat*)data;
246 	const glw::GLint*   i_data = (glw::GLint*)data;
247 	const glw::GLuint*  u_data = (glw::GLuint*)data;
248 
249 	/* Get location */
250 	glw::GLint location = gl.getUniformLocation(m_program_object_id, name);
251 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
252 
253 	if (-1 == location)
254 	{
255 		TCU_FAIL("Uniform variable is unavailable");
256 	}
257 
258 	/* Set data */
259 	switch (type)
260 	{
261 	case Utils::VARIABLE_TYPE_FLOAT:
262 		gl.uniform1fv(location, 1, f_data);
263 		break;
264 	case Utils::VARIABLE_TYPE_INT:
265 		gl.uniform1iv(location, 1, i_data);
266 		break;
267 	case Utils::VARIABLE_TYPE_IVEC2:
268 		gl.uniform2iv(location, 1, i_data);
269 		break;
270 	case Utils::VARIABLE_TYPE_IVEC3:
271 		gl.uniform3iv(location, 1, i_data);
272 		break;
273 	case Utils::VARIABLE_TYPE_IVEC4:
274 		gl.uniform4iv(location, 1, i_data);
275 		break;
276 	case Utils::VARIABLE_TYPE_UINT:
277 		gl.uniform1uiv(location, 1, u_data);
278 		break;
279 	case Utils::VARIABLE_TYPE_UVEC2:
280 		gl.uniform2uiv(location, 1, u_data);
281 		break;
282 	case Utils::VARIABLE_TYPE_UVEC3:
283 		gl.uniform3uiv(location, 1, u_data);
284 		break;
285 	case Utils::VARIABLE_TYPE_UVEC4:
286 		gl.uniform4uiv(location, 1, u_data);
287 		break;
288 	case Utils::VARIABLE_TYPE_VEC2:
289 		gl.uniform2fv(location, 1, f_data);
290 		break;
291 	case Utils::VARIABLE_TYPE_VEC3:
292 		gl.uniform3fv(location, 1, f_data);
293 		break;
294 	case Utils::VARIABLE_TYPE_VEC4:
295 		gl.uniform4fv(location, 1, f_data);
296 		break;
297 	default:
298 		TCU_FAIL("Invalid enum");
299 	}
300 
301 	GLU_EXPECT_NO_ERROR(gl.getError(), "Uniform");
302 }
303 
304 /** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
305  *
306  * @param token           Token string
307  * @param search_position Position at which find will start, it is updated to position at which replaced text ends
308  * @param text            String that will be used as replacement for <token>
309  * @param string          String to work on
310  **/
replaceToken(const glw::GLchar * token,size_t & search_position,const glw::GLchar * text,std::string & string)311 void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
312 						 std::string& string)
313 {
314 	const size_t text_length	= strlen(text);
315 	const size_t token_length   = strlen(token);
316 	const size_t token_position = string.find(token, search_position);
317 
318 	string.replace(token_position, token_length, text, text_length);
319 
320 	search_position = token_position + text_length;
321 }
322 
323 /* Constants used by GPUShader5ImplicitConversionsTest */
324 const glw::GLsizei GPUShader5ImplicitConversionsTest::m_width  = 8;
325 const glw::GLsizei GPUShader5ImplicitConversionsTest::m_height = 8;
326 
327 /** Constructor.
328  *
329  * @param context Rendering context.
330  **/
GPUShader5ImplicitConversionsTest(deqp::Context & context)331 GPUShader5ImplicitConversionsTest::GPUShader5ImplicitConversionsTest(deqp::Context& context)
332 	: TestCase(context, "implicit_conversions",
333 			   "Verifies that implicit conversions are accepted and executed as explicit ones")
334 	, m_fbo_id(0)
335 	, m_tex_id(0)
336 	, m_vao_id(0)
337 
338 {
339 	/* Left blank intentionally */
340 }
341 
342 /** Constructor.
343  *
344  * @param context     Rendering context.
345  * @param name        Name of test
346  * @param description Describes test
347  **/
GPUShader5ImplicitConversionsTest(deqp::Context & context,const char * name,const char * description)348 GPUShader5ImplicitConversionsTest::GPUShader5ImplicitConversionsTest(deqp::Context& context, const char* name,
349 																	 const char* description)
350 	: TestCase(context, name, description), m_fbo_id(0), m_tex_id(0), m_vao_id(0)
351 
352 {
353 	/* Left blank intentionally */
354 }
355 
356 /** Deinitializes all GL objects that may have been created during
357  *  test execution.
358  **/
deinit()359 void GPUShader5ImplicitConversionsTest::deinit()
360 {
361 	if (m_fbo_id != 0)
362 	{
363 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
364 		gl.deleteFramebuffers(1, &m_fbo_id);
365 
366 		m_fbo_id = 0;
367 	}
368 
369 	if (m_tex_id != 0)
370 	{
371 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
372 		gl.deleteTextures(1, &m_tex_id);
373 
374 		m_tex_id = 0;
375 	}
376 
377 	if (m_vao_id != 0)
378 	{
379 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
380 		gl.deleteVertexArrays(1, &m_vao_id);
381 
382 		m_vao_id = 0;
383 	}
384 }
385 
386 /** Executes test iteration.
387  *
388  *  @return Returns STOP.
389  */
iterate()390 tcu::TestNode::IterateResult GPUShader5ImplicitConversionsTest::iterate()
391 {
392 	/* Defines data used as u1 and u2 uniforms */
393 	static const glw::GLint  uni_data_int_1[4]  = { 112, -1122, 111222, -1222111222 };
394 	static const glw::GLint  uni_data_int_2[4]  = { -112, 1122, -111222, 1222111222 };
395 	static const glw::GLuint uni_data_uint_1[4] = { 0xffff0000, 0x0000ffff, 0x00ffffff, 0xffffffff };
396 	static const glw::GLuint uni_data_uint_2[4] = { 0xfff70000, 0x00007fff, 0x007fffff, 0xfffffff7 };
397 
398 	/* Defines test cases */
399 	static const testCase test_cases[] = {
400 		{ "uint", false, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_2 } /* int >> uint */,
401 		{ "uint", true, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_1 },
402 		{ "float", false, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_1, uni_data_int_2 } /* int >> float */,
403 		{ "float", true, "int", Utils::VARIABLE_TYPE_INT, uni_data_int_2, uni_data_int_2 },
404 		{ "uvec2", false, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_2 } /* ivec2 >> uvec2 */,
405 		{ "uvec2", true, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_1 },
406 		{ "vec2", false, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_2 } /* ivec2 >> vec2 */,
407 		{ "vec2", true, "ivec2", Utils::VARIABLE_TYPE_IVEC2, uni_data_int_1, uni_data_int_1 },
408 		{ "uvec3", false, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_1, uni_data_int_2 } /* ivec3 >> uvec3 */,
409 		{ "uvec3", true, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_2, uni_data_int_2 },
410 		{ "vec3", false, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_1, uni_data_int_2 } /* ivec3 >> vec3 */,
411 		{ "vec3", true, "ivec3", Utils::VARIABLE_TYPE_IVEC3, uni_data_int_2, uni_data_int_2 },
412 		{ "uvec4", false, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_2 } /* ivec4 >> uvec4 */,
413 		{ "uvec4", true, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_1 },
414 		{ "vec4", false, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_2 } /* ivec4 >> vec4 */,
415 		{ "vec4", true, "ivec4", Utils::VARIABLE_TYPE_IVEC4, uni_data_int_1, uni_data_int_1 },
416 		{ "float", false, "uint", Utils::VARIABLE_TYPE_UINT, uni_data_uint_1, uni_data_uint_2 } /* uint >> float */,
417 		{ "float", true, "uint", Utils::VARIABLE_TYPE_UINT, uni_data_uint_2, uni_data_uint_2 },
418 		{ "vec2", false, "uvec2", Utils::VARIABLE_TYPE_UVEC2, uni_data_uint_1, uni_data_uint_2 } /* uvec2 >> vec2 */,
419 		{ "vec2", true, "uvec2", Utils::VARIABLE_TYPE_UVEC2, uni_data_uint_1, uni_data_uint_1 },
420 		{ "vec3", false, "uvec3", Utils::VARIABLE_TYPE_UVEC3, uni_data_uint_1, uni_data_uint_2 } /* uvec3 >> vec3 */,
421 		{ "vec3", true, "uvec3", Utils::VARIABLE_TYPE_UVEC3, uni_data_uint_2, uni_data_uint_2 },
422 		{ "vec4", false, "uvec4", Utils::VARIABLE_TYPE_UVEC4, uni_data_uint_1, uni_data_uint_2 } /* uvec4 >> vec4 */,
423 		{ "vec4", true, "uvec4", Utils::VARIABLE_TYPE_UVEC4, uni_data_uint_1, uni_data_uint_1 },
424 	};
425 	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
426 
427 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5"))
428 	{
429 		throw tcu::NotSupportedError("GL_ARB_gpu_shader5 is not supported.");
430 	}
431 
432 	testInit();
433 
434 	/* Execute test cases */
435 	for (size_t i = 0; i < n_test_cases; ++i)
436 	{
437 		const testCase& test_case = test_cases[i];
438 
439 		executeTestCase(test_case);
440 	}
441 
442 	/* Set result - exceptions are thrown in case of any error */
443 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
444 
445 	/* Done */
446 	return STOP;
447 }
448 
449 /** Initializes frame buffer and vertex array
450  *
451  **/
testInit()452 void GPUShader5ImplicitConversionsTest::testInit()
453 {
454 	/*  */
455 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
456 
457 	/* Prepare texture for color attachment 0 */
458 	gl.genTextures(1, &m_tex_id);
459 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenTextures");
460 
461 	gl.bindTexture(GL_TEXTURE_2D, m_tex_id);
462 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindTexture");
463 
464 	gl.texStorage2D(GL_TEXTURE_2D, 1 /* levels */, GL_RGBA8, m_width, m_height);
465 	GLU_EXPECT_NO_ERROR(gl.getError(), "TexStorage2D");
466 
467 	/* Prepare FBO with color attachment 0 */
468 	gl.genFramebuffers(1, &m_fbo_id);
469 	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");
470 
471 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
472 	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFramebuffer");
473 
474 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex_id, 0 /* level */);
475 	GLU_EXPECT_NO_ERROR(gl.getError(), "FramebufferTexture2D");
476 
477 	/* Set Viewport */
478 	gl.viewport(0 /* x */, 0 /* y */, m_width, m_height);
479 	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
480 
481 	/* Prepare blank VAO */
482 	gl.genVertexArrays(1, &m_vao_id);
483 	GLU_EXPECT_NO_ERROR(gl.getError(), "genVertexArrays");
484 
485 	gl.bindVertexArray(m_vao_id);
486 	GLU_EXPECT_NO_ERROR(gl.getError(), "bindVertexArray");
487 }
488 
489 /** Verifies if image is filled with <color>
490  *
491  * @param color       Color to be checked
492  * @param is_expected Selects if image is expected to be filled with given color or not
493  **/
verifyImage(glw::GLuint color,bool is_expected) const494 void GPUShader5ImplicitConversionsTest::verifyImage(glw::GLuint color, bool is_expected) const
495 {
496 	/*  */
497 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
498 
499 	/* Storage for image data */
500 	glw::GLuint result_image[m_width * m_height];
501 
502 	/* Get image data */
503 	gl.getTexImage(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
504 	GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
505 
506 	/* Inspect data */
507 	if (true == is_expected)
508 	{
509 		for (size_t i = 0; i < m_width * m_height; ++i)
510 		{
511 			const glw::GLuint pixel_data = result_image[i];
512 
513 			if (color != pixel_data)
514 			{
515 				TCU_FAIL("Found invalid pixel during verification of drawn image");
516 			}
517 		}
518 	}
519 	else
520 	{
521 		for (size_t i = 0; i < m_width * m_height; ++i)
522 		{
523 			const glw::GLuint pixel_data = result_image[i];
524 
525 			if (color == pixel_data)
526 			{
527 				TCU_FAIL("Found invalid pixel during verification of drawn image");
528 			}
529 		}
530 	}
531 }
532 
533 /** Executes test case
534  *
535  * @param test_case Defines test case parameters
536  */
executeTestCase(const testCase & test_case)537 void GPUShader5ImplicitConversionsTest::executeTestCase(const testCase& test_case)
538 {
539 	static const glw::GLuint white_color = 0xffffffff;
540 
541 	/*  */
542 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
543 
544 	/* Run test case */
545 	{
546 		/* Get shaders */
547 		const std::string& fs = getFragmentShader();
548 		const std::string& vs = getVertexShader(test_case.m_destination_type, test_case.m_source_type);
549 
550 		/* Prepare program */
551 		Utils::programInfo program(m_context);
552 
553 		program.build(fs.c_str(), vs.c_str());
554 
555 		gl.useProgram(program.m_program_object_id);
556 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
557 
558 		program.setUniform(test_case.m_source_variable_type, "u1", test_case.m_u1_data);
559 		program.setUniform(test_case.m_source_variable_type, "u2", test_case.m_u2_data);
560 
561 		/* Clear FBO */
562 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
563 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
564 
565 		gl.clear(GL_COLOR_BUFFER_BIT);
566 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
567 
568 		/* Draw a triangle strip */
569 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
570 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
571 	}
572 
573 	/* Verification */
574 	verifyImage(white_color, test_case.m_is_white_expected);
575 }
576 
577 /** Get vertex shader source.
578  *
579  * @param destination_type Name of type
580  * @param source_type      Name of type
581  *
582  * @return String with source of shader
583  */
getVertexShader(const glw::GLchar * destination_type,const glw::GLchar * source_type)584 std::string GPUShader5ImplicitConversionsTest::getVertexShader(const glw::GLchar* destination_type,
585 															   const glw::GLchar* source_type)
586 {
587 	/* Vertex shader template */
588 	const char* vs_body_template = "#version 150\n"
589 								   "#extension GL_ARB_gpu_shader5 : require\n"
590 								   "\n"
591 								   "uniform SOURCE_TYPE u1;\n"
592 								   "uniform SOURCE_TYPE u2;\n"
593 								   "\n"
594 								   "out     vec4 result;\n"
595 								   "\n"
596 								   "void main()\n"
597 								   "{\n"
598 								   "    DESTINATION_TYPE v = ZERO;\n"
599 								   "\n"
600 								   "    v = DESTINATION_TYPE(u2) - u1;\n"
601 								   "\n"
602 								   "    result = vec4(0.0, 0.0, 0.0, 0.0);\n"
603 								   "    if (ZERO == v)\n"
604 								   "    {\n"
605 								   "      result = vec4(1.0, 1.0, 1.0, 1.0);\n"
606 								   "    }\n"
607 								   "\n"
608 								   "    switch (gl_VertexID)\n"
609 								   "    {\n"
610 								   "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
611 								   "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
612 								   "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
613 								   "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
614 								   "    }\n"
615 								   "}\n"
616 								   "\n";
617 
618 	std::string vs_body = vs_body_template;
619 
620 	/* Tokens */
621 	size_t search_position = 0;
622 
623 	Utils::replaceToken("SOURCE_TYPE", search_position, source_type, vs_body);
624 	Utils::replaceToken("SOURCE_TYPE", search_position, source_type, vs_body);
625 
626 	search_position = 0;
627 	Utils::replaceToken("DESTINATION_TYPE", search_position, destination_type, vs_body);
628 	Utils::replaceToken("DESTINATION_TYPE", search_position, destination_type, vs_body);
629 
630 	search_position = 0;
631 	if (!strcmp(destination_type, "int") || !strcmp(destination_type, "uint"))
632 	{
633 		Utils::replaceToken("ZERO", search_position, "0", vs_body);
634 		Utils::replaceToken("ZERO", search_position, "0", vs_body);
635 	}
636 	else if (!strcmp(destination_type, "float"))
637 	{
638 		Utils::replaceToken("ZERO", search_position, "0.0", vs_body);
639 		Utils::replaceToken("ZERO", search_position, "0.0", vs_body);
640 	}
641 	else if (!strcmp(destination_type, "ivec2"))
642 	{
643 		Utils::replaceToken("ZERO", search_position, "ivec2(0,0)", vs_body);
644 		Utils::replaceToken("ZERO", search_position, "ivec2(0,0)", vs_body);
645 	}
646 	else if (!strcmp(destination_type, "ivec3"))
647 	{
648 		Utils::replaceToken("ZERO", search_position, "ivec3(0,0,0)", vs_body);
649 		Utils::replaceToken("ZERO", search_position, "ivec3(0,0,0)", vs_body);
650 	}
651 	else if (!strcmp(destination_type, "ivec4"))
652 	{
653 		Utils::replaceToken("ZERO", search_position, "ivec4(0,0,0,0)", vs_body);
654 		Utils::replaceToken("ZERO", search_position, "ivec4(0,0,0,0)", vs_body);
655 	}
656 	else if (!strcmp(destination_type, "uvec2"))
657 	{
658 		Utils::replaceToken("ZERO", search_position, "uvec2(0,0)", vs_body);
659 		Utils::replaceToken("ZERO", search_position, "uvec2(0,0)", vs_body);
660 	}
661 	else if (!strcmp(destination_type, "uvec3"))
662 	{
663 		Utils::replaceToken("ZERO", search_position, "uvec3(0,0,0)", vs_body);
664 		Utils::replaceToken("ZERO", search_position, "uvec3(0,0,0)", vs_body);
665 	}
666 	else if (!strcmp(destination_type, "uvec4"))
667 	{
668 		Utils::replaceToken("ZERO", search_position, "uvec4(0,0,0,0)", vs_body);
669 		Utils::replaceToken("ZERO", search_position, "uvec4(0,0,0,0)", vs_body);
670 	}
671 	else if (!strcmp(destination_type, "vec2"))
672 	{
673 		Utils::replaceToken("ZERO", search_position, "vec2(0,0)", vs_body);
674 		Utils::replaceToken("ZERO", search_position, "vec2(0,0)", vs_body);
675 	}
676 	else if (!strcmp(destination_type, "vec3"))
677 	{
678 		Utils::replaceToken("ZERO", search_position, "vec3(0,0,0)", vs_body);
679 		Utils::replaceToken("ZERO", search_position, "vec3(0,0,0)", vs_body);
680 	}
681 	else if (!strcmp(destination_type, "vec4"))
682 	{
683 		Utils::replaceToken("ZERO", search_position, "vec4(0,0,0,0)", vs_body);
684 		Utils::replaceToken("ZERO", search_position, "vec4(0,0,0,0)", vs_body);
685 	}
686 
687 	return vs_body;
688 }
689 
690 /** Get fragment shader source.
691  *
692  * @return String with source of shader
693  */
getFragmentShader()694 std::string GPUShader5ImplicitConversionsTest::getFragmentShader()
695 {
696 	const char* fs_body_template = "#version 150\n"
697 								   "\n"
698 								   "in  vec4 result;\n"
699 								   "out vec4 color;\n"
700 								   "\n"
701 								   "void main()\n"
702 								   "{\n"
703 								   "    color = result;\n"
704 								   "}\n"
705 								   "\n";
706 
707 	std::string fs_body = fs_body_template;
708 
709 	return fs_body;
710 }
711 
712 /** Constructor.
713  *
714  *  @param context Rendering context.
715  *
716  **/
GPUShader5FunctionOverloadingTest(deqp::Context & context)717 GPUShader5FunctionOverloadingTest::GPUShader5FunctionOverloadingTest(deqp::Context& context)
718 	: GPUShader5ImplicitConversionsTest(context, "function_overloading",
719 										"Verifies that function overloading is accepted")
720 {
721 	/* Left blank intentionally */
722 }
723 
724 /** Executes test iteration.
725  *
726  *  @return Returns STOP.
727  */
iterate()728 tcu::TestNode::IterateResult GPUShader5FunctionOverloadingTest::iterate()
729 {
730 	/* Defines data used as u1 and u2 uniforms */
731 	static const glw::GLint  u1_data_1[4] = { (glw::GLint)0xffff0000, 0x0000ffff, 0x00ffffff, (glw::GLint)0xffffffff };
732 	static const glw::GLint  u1_data_2[4] = { -112, 1122, -111222, 1222111222 };
733 	static const glw::GLuint u2_data_1[4] = { 0xffff0000, 0x0000ffff, 0x00ffffff, 0xffffffff };
734 	static const glw::GLuint u2_data_2[4] = { 0xfff70000, 0x00007fff, 0x007fffff, 0xfffffff7 };
735 
736 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5"))
737 	{
738 		throw tcu::NotSupportedError("GL_ARB_gpu_shader5 is not supported.");
739 	}
740 
741 	testInit();
742 
743 	/* Execute test case */
744 	execute(u1_data_1, u2_data_1, true);
745 	execute(u1_data_2, u2_data_2, false);
746 
747 	/* Set result - exceptions are thrown in case of any error */
748 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
749 
750 	/* Done */
751 	return STOP;
752 }
753 
754 /** Executes test case
755  *
756  * @param u1_data   Pointer to data that will used as u1 uniform
757  * @param u2_data   Pointer to data that will used as u2 uniform
758  * @param test_case Defines test case parameters
759  */
execute(const glw::GLint * u1_data,const glw::GLuint * u2_data,bool is_black_expected)760 void GPUShader5FunctionOverloadingTest::execute(const glw::GLint* u1_data, const glw::GLuint* u2_data,
761 												bool is_black_expected)
762 {
763 	static const glw::GLuint black_color = 0x00000000;
764 
765 	/*  */
766 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
767 
768 	/* Run test case */
769 	{
770 		/* Shaders */
771 		const char* fs = "#version 150\n"
772 						 "\n"
773 						 "in  vec4 result;\n"
774 						 "out vec4 color;\n"
775 						 "\n"
776 						 "void main()\n"
777 						 "{\n"
778 						 "    color = result;\n"
779 						 "}\n"
780 						 "\n";
781 
782 		const char* vs = "#version 150\n"
783 						 "#extension GL_ARB_gpu_shader5 : require\n"
784 						 "\n"
785 						 "uniform ivec4 u1;\n"
786 						 "uniform uvec4 u2;\n"
787 						 "\n"
788 						 "out     vec4  result;\n"
789 						 "\n"
790 						 "vec4 f(in vec4 a, in vec4 b)\n"
791 						 "{\n"
792 						 "    return a * b;\n"
793 						 "}\n"
794 						 "\n"
795 						 "vec4 f(in uvec4 a, in uvec4 b)\n"
796 						 "{\n"
797 						 "    return vec4(a - b);\n"
798 						 "}\n"
799 						 "\n"
800 						 "void main()\n"
801 						 "{\n"
802 						 "    result = f(u1, u2);\n"
803 						 "\n"
804 						 "    switch (gl_VertexID)\n"
805 						 "    {\n"
806 						 "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
807 						 "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
808 						 "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
809 						 "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
810 						 "    }\n"
811 						 "}\n"
812 						 "\n";
813 
814 		/* Prepare program */
815 		Utils::programInfo program(m_context);
816 
817 		program.build(fs, vs);
818 
819 		gl.useProgram(program.m_program_object_id);
820 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
821 
822 		program.setUniform(Utils::VARIABLE_TYPE_IVEC4, "u1", u1_data);
823 		program.setUniform(Utils::VARIABLE_TYPE_UVEC4, "u2", u2_data);
824 
825 		/* Clear FBO */
826 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
827 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
828 
829 		gl.clear(GL_COLOR_BUFFER_BIT);
830 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
831 
832 		/* Draw a triangle strip */
833 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
834 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
835 	}
836 
837 	/* Verification */
838 	verifyImage(black_color, is_black_expected);
839 }
840 
841 /** Constructor.
842  *
843  *  @param context Rendering context.
844  *
845  **/
GPUShader5FloatEncodingTest(deqp::Context & context)846 GPUShader5FloatEncodingTest::GPUShader5FloatEncodingTest(deqp::Context& context)
847 	: GPUShader5ImplicitConversionsTest(context, "float_encoding",
848 										"Verifies that functions encoding floats as bits work as expected")
849 {
850 	/* Left blank intentionally */
851 }
852 
853 /** Executes test iteration.
854  *
855  *  @return Returns STOP.
856  */
iterate()857 tcu::TestNode::IterateResult GPUShader5FloatEncodingTest::iterate()
858 {
859 	/* Defines data used as u1 and u2 uniforms */
860 	static const glw::GLfloat floats[4] = { -1.0f, -1234.0f, 1.0f, 1234.0f };
861 	static const glw::GLint   ints[4]   = { -1, -1234, 1, 1234 };
862 	static const glw::GLuint  uints[4]  = { 0xffffffff, 0xfffffb2e, 1, 0x4d2 };
863 
864 	/* Defines tested cases */
865 	static const testCase test_cases[] = {
866 		{ /* float >> int - invalid */
867 		  { Utils::VARIABLE_TYPE_INT, "int", ints },
868 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
869 		  "floatBitsToInt",
870 		  false },
871 		{ /* float >> int - valid */
872 		  { Utils::VARIABLE_TYPE_INT, "int", floats },
873 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
874 		  "floatBitsToInt",
875 		  true },
876 		{ /* vec2 >> ivec2 - invalid */
877 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", ints },
878 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
879 		  "floatBitsToInt",
880 		  false },
881 		{ /* vec2 >> ivec2 - valid */
882 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", floats },
883 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
884 		  "floatBitsToInt",
885 		  true },
886 		{ /* vec3 >> ivec3 - invalid */
887 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", ints },
888 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
889 		  "floatBitsToInt",
890 		  false },
891 		{ /* vec3 >> ivec3 - valid */
892 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", floats },
893 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
894 		  "floatBitsToInt",
895 		  true },
896 		{ /* vec4 >> ivec4 - invalid */
897 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", ints },
898 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
899 		  "floatBitsToInt",
900 		  false },
901 		{ /* vec4 >> ivec4 - valid */
902 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", floats },
903 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
904 		  "floatBitsToInt",
905 		  true },
906 		{ /* float >> uint - invalid */
907 		  { Utils::VARIABLE_TYPE_UINT, "uint", uints },
908 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
909 		  "floatBitsToUint",
910 		  false },
911 		{ /* float >> uint - valid */
912 		  { Utils::VARIABLE_TYPE_UINT, "uint", floats },
913 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
914 		  "floatBitsToUint",
915 		  true },
916 		{ /* vec2 >> uvec2 - invalid */
917 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", uints },
918 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
919 		  "floatBitsToUint",
920 		  false },
921 		{ /* vec2 >> uvec2 - valid */
922 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", floats },
923 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
924 		  "floatBitsToUint",
925 		  true },
926 		{ /* vec3 >> uvec3 - invalid */
927 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", uints },
928 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
929 		  "floatBitsToUint",
930 		  false },
931 		{ /* vec3 >> uvec3 - valid */
932 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", floats },
933 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
934 		  "floatBitsToUint",
935 		  true },
936 		{ /* vec4 >> ivec4 - invalid */
937 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", uints },
938 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
939 		  "floatBitsToUint",
940 		  false },
941 		{ /* vec4 >> uvec4 - valid */
942 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", floats },
943 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
944 		  "floatBitsToUint",
945 		  true },
946 		{ /* int >> float - invalid */
947 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
948 		  { Utils::VARIABLE_TYPE_INT, "int", ints },
949 		  "intBitsToFloat",
950 		  false },
951 		{ /* int >> float - valid */
952 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
953 		  { Utils::VARIABLE_TYPE_INT, "int", floats },
954 		  "intBitsToFloat",
955 		  true },
956 		{ /* ivec2 >> vec2 - invalid */
957 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
958 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", ints },
959 		  "intBitsToFloat",
960 		  false },
961 		{ /* ivec2 >> vec2 - valid */
962 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
963 		  { Utils::VARIABLE_TYPE_IVEC2, "ivec2", floats },
964 		  "intBitsToFloat",
965 		  true },
966 		{ /* ivec3 >> vec3 - invalid */
967 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
968 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", ints },
969 		  "intBitsToFloat",
970 		  false },
971 		{ /* ivec3 >> vec3 - valid */
972 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
973 		  { Utils::VARIABLE_TYPE_IVEC3, "ivec3", floats },
974 		  "intBitsToFloat",
975 		  true },
976 		{ /* ivec4 >> vec4 - invalid */
977 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
978 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", ints },
979 		  "intBitsToFloat",
980 		  false },
981 		{ /* ivec4 >> vec4 - valid */
982 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
983 		  { Utils::VARIABLE_TYPE_IVEC4, "ivec4", floats },
984 		  "intBitsToFloat",
985 		  true },
986 		{ /* uint >> float - invalid */
987 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
988 		  { Utils::VARIABLE_TYPE_UINT, "uint", uints },
989 		  "uintBitsToFloat",
990 		  false },
991 		{ /* uint >> float - valid */
992 		  { Utils::VARIABLE_TYPE_FLOAT, "float", floats },
993 		  { Utils::VARIABLE_TYPE_UINT, "uint", floats },
994 		  "uintBitsToFloat",
995 		  true },
996 		{ /* uvec2 >> vec2 - invalid */
997 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
998 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", uints },
999 		  "uintBitsToFloat",
1000 		  false },
1001 		{ /* uvec2 >> vec2 - valid */
1002 		  { Utils::VARIABLE_TYPE_VEC2, "vec2", floats },
1003 		  { Utils::VARIABLE_TYPE_UVEC2, "uvec2", floats },
1004 		  "uintBitsToFloat",
1005 		  true },
1006 		{ /* uvec3 >> vec3 - invalid */
1007 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
1008 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", uints },
1009 		  "uintBitsToFloat",
1010 		  false },
1011 		{ /* uvec3 >> vec3 - valid */
1012 		  { Utils::VARIABLE_TYPE_VEC3, "vec3", floats },
1013 		  { Utils::VARIABLE_TYPE_UVEC3, "uvec3", floats },
1014 		  "uintBitsToFloat",
1015 		  true },
1016 		{ /* uvec4 >> vec4 - invalid */
1017 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
1018 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", uints },
1019 		  "uintBitsToFloat",
1020 		  false },
1021 		{ /* uvec4 >> vec4 - valid */
1022 		  { Utils::VARIABLE_TYPE_VEC4, "vec4", floats },
1023 		  { Utils::VARIABLE_TYPE_UVEC4, "uvec4", floats },
1024 		  "uintBitsToFloat",
1025 		  true },
1026 	};
1027 	static const size_t n_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
1028 
1029 	if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5"))
1030 	{
1031 		throw tcu::NotSupportedError("GL_ARB_gpu_shader5 is not supported.");
1032 	}
1033 
1034 	testInit();
1035 
1036 	/* Execute test case */
1037 	for (size_t i = 0; i < n_test_cases; ++i)
1038 	{
1039 		const testCase& test_case = test_cases[i];
1040 
1041 		execute(test_case);
1042 	}
1043 
1044 	/* Set result - exceptions are thrown in case of any error */
1045 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1046 
1047 	/* Done */
1048 	return STOP;
1049 }
1050 
1051 /** Executes test case
1052  *
1053  * @param test_case Tested case
1054  *
1055  * @param test_case Defines test case parameters
1056  */
execute(const testCase & test_case)1057 void GPUShader5FloatEncodingTest::execute(const testCase& test_case)
1058 {
1059 	static const glw::GLuint white_color = 0xffffffff;
1060 
1061 	/*  */
1062 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1063 
1064 	/* Run test case */
1065 	{
1066 		/* Shaders */
1067 		const char* fs = "#version 150\n"
1068 						 "\n"
1069 						 "in  vec4 result;\n"
1070 						 "out vec4 color;\n"
1071 						 "\n"
1072 						 "void main()\n"
1073 						 "{\n"
1074 						 "    color = result;\n"
1075 						 "}\n"
1076 						 "\n";
1077 
1078 		const std::string& vs = getVertexShader(test_case);
1079 
1080 		/* Prepare program */
1081 		Utils::programInfo program(m_context);
1082 
1083 		program.build(fs, vs.c_str());
1084 
1085 		gl.useProgram(program.m_program_object_id);
1086 		GLU_EXPECT_NO_ERROR(gl.getError(), "UseProgram");
1087 
1088 		program.setUniform(test_case.m_expected_value.m_type, "expected_value", test_case.m_expected_value.m_data);
1089 		program.setUniform(test_case.m_value.m_type, "value", test_case.m_value.m_data);
1090 
1091 		/* Clear FBO */
1092 		gl.clearColor(0.5f, 0.5f, 0.5f, 0.5f);
1093 		GLU_EXPECT_NO_ERROR(gl.getError(), "clearColor");
1094 
1095 		gl.clear(GL_COLOR_BUFFER_BIT);
1096 		GLU_EXPECT_NO_ERROR(gl.getError(), "clear");
1097 
1098 		/* Draw a triangle strip */
1099 		gl.drawArrays(GL_TRIANGLE_STRIP, 0 /* first */, 4 /* count */);
1100 		GLU_EXPECT_NO_ERROR(gl.getError(), "drawArrays");
1101 	}
1102 
1103 	/* Verification */
1104 	verifyImage(white_color, test_case.m_is_white_expected);
1105 }
1106 
1107 /** Get vertex shader source.
1108  *
1109  * @param test_case Tested case
1110  *
1111  * @return String with source of shader
1112  */
getVertexShader(const testCase & test_case) const1113 std::string GPUShader5FloatEncodingTest::getVertexShader(const testCase& test_case) const
1114 {
1115 	/* Vertex shader template */
1116 	const char* vs_body_template = "#version 150\n"
1117 								   "#extension GL_ARB_gpu_shader5 : require\n"
1118 								   "\n"
1119 								   "uniform EXPECTED_VALUE_TYPE expected_value;\n"
1120 								   "uniform VALUE_TYPE value;\n"
1121 								   "\n"
1122 								   "out     vec4 result;\n"
1123 								   "\n"
1124 								   "void main()\n"
1125 								   "{\n"
1126 								   "    result = vec4(1.0, 1.0, 1.0, 1.0);\n"
1127 								   "\n"
1128 								   "    EXPECTED_VALUE_TYPE ret_val = TESTED_FUNCTION(value);\n"
1129 								   "\n"
1130 								   "    if (expected_value != ret_val)\n"
1131 								   "    {\n"
1132 								   "        result = vec4(0.0, 0.0, 0.0, 0.0);\n"
1133 								   "    }\n"
1134 								   "\n"
1135 								   "    switch (gl_VertexID)\n"
1136 								   "    {\n"
1137 								   "      case 0: gl_Position = vec4(-1.0, 1.0, 0.0, 1.0); break; \n"
1138 								   "      case 1: gl_Position = vec4( 1.0, 1.0, 0.0, 1.0); break; \n"
1139 								   "      case 2: gl_Position = vec4(-1.0,-1.0, 0.0, 1.0); break; \n"
1140 								   "      case 3: gl_Position = vec4( 1.0,-1.0, 0.0, 1.0); break; \n"
1141 								   "    }\n"
1142 								   "}\n"
1143 								   "\n";
1144 
1145 	std::string vs_body = vs_body_template;
1146 
1147 	/* Tokens */
1148 	size_t search_position = 0;
1149 
1150 	Utils::replaceToken("EXPECTED_VALUE_TYPE", search_position, test_case.m_expected_value.m_type_name, vs_body);
1151 	Utils::replaceToken("VALUE_TYPE", search_position, test_case.m_value.m_type_name, vs_body);
1152 	Utils::replaceToken("EXPECTED_VALUE_TYPE", search_position, test_case.m_expected_value.m_type_name, vs_body);
1153 	Utils::replaceToken("TESTED_FUNCTION", search_position, test_case.m_function_name, vs_body);
1154 
1155 	return vs_body;
1156 }
1157 
1158 /** Constructor.
1159  *
1160  *  @param context Rendering context.
1161  **/
GPUShader5Tests(deqp::Context & context)1162 GPUShader5Tests::GPUShader5Tests(deqp::Context& context)
1163 	: TestCaseGroup(context, "gpu_shader5_gl", "Verifies \"gpu_shader5\" functionality")
1164 {
1165 	/* Left blank on purpose */
1166 }
1167 
1168 /** Initializes a texture_storage_multisample test group.
1169  *
1170  **/
init(void)1171 void GPUShader5Tests::init(void)
1172 {
1173 	addChild(new GPUShader5ImplicitConversionsTest(m_context));
1174 	addChild(new GPUShader5FunctionOverloadingTest(m_context));
1175 	addChild(new GPUShader5FloatEncodingTest(m_context));
1176 }
1177 } /* glcts namespace */
1178