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