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 46namespace gl3cts 47{ 48 49/** Constructor 50 * 51 * @param context Test context 52 **/ 53Utils::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 **/ 62Utils::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 **/ 98void 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 **/ 133void 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 **/ 182void 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 */ 241void 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 **/ 311void 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 */ 324const glw::GLsizei GPUShader5ImplicitConversionsTest::m_width = 8; 325const glw::GLsizei GPUShader5ImplicitConversionsTest::m_height = 8; 326 327/** Constructor. 328 * 329 * @param context Rendering context. 330 **/ 331GPUShader5ImplicitConversionsTest::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 **/ 348GPUShader5ImplicitConversionsTest::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 **/ 359void 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 */ 390tcu::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 **/ 452void 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 **/ 494void 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 */ 537void 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 */ 584std::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 */ 694std::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 **/ 717GPUShader5FunctionOverloadingTest::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 */ 728tcu::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 */ 760void 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 **/ 846GPUShader5FloatEncodingTest::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 */ 857tcu::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 */ 1057void 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 */ 1113std::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 **/ 1162GPUShader5Tests::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 **/ 1171void 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