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