1 #ifndef _GL4CSHADERSUBROUTINETESTS_HPP 2 #define _GL4CSHADERSUBROUTINETESTS_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2014-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 /** 27 * \file gl4cShaderSubroutineTests.hpp 28 * \brief Declares test classes for "Shader Subroutine" functionality. 29 */ /*-------------------------------------------------------------------*/ 30 31 #include "glcTestCase.hpp" 32 #include "glwDefs.hpp" 33 #include <queue> 34 35 #include "tcuTestLog.hpp" 36 37 namespace gl4cts 38 { 39 namespace ShaderSubroutine 40 { 41 class Utils 42 { 43 public: 44 /* Public type definitions */ 45 46 struct buffer 47 { 48 buffer(deqp::Context& context); 49 ~buffer(); 50 51 void bindRange(glw::GLenum target, glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size); 52 53 void generate(); 54 55 void update(glw::GLenum target, glw::GLsizeiptr size, glw::GLvoid* data, glw::GLenum usage); 56 57 glw::GLuint m_id; 58 59 private: 60 deqp::Context& m_context; 61 }; 62 63 struct framebuffer 64 { 65 framebuffer(deqp::Context& context); 66 ~framebuffer(); 67 68 void attachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width, glw::GLuint height); 69 70 void bind(); 71 void clear(glw::GLenum mask); 72 73 void clearColor(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat alpha); 74 void generate(); 75 76 glw::GLuint m_id; 77 78 private: 79 deqp::Context& m_context; 80 }; 81 82 /** Store information about program object 83 * 84 **/ 85 struct program 86 { 87 program(deqp::Context& context); 88 ~program(); 89 90 void build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code, 91 const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code, 92 const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code, 93 const glw::GLchar* const* varying_names, glw::GLuint n_varying_names, bool is_separable = false); 94 95 void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const; 96 97 bool isProgramBinarySupported() const; 98 99 void createFromBinary(const std::vector<glw::GLubyte>& binary, glw::GLenum binary_format); 100 101 void getBinary(std::vector<glw::GLubyte>& binary, glw::GLenum& binary_format) const; 102 103 glw::GLuint getSubroutineIndex(const glw::GLchar* subroutine_name, glw::GLenum shader_stage) const; 104 105 glw::GLint getSubroutineUniformLocation(const glw::GLchar* uniform_name, glw::GLenum shader_stage) const; 106 107 glw::GLint getUniformLocation(const glw::GLchar* uniform_name) const; 108 void link() const; 109 void remove(); 110 void use() const; 111 112 static const glw::GLenum ARB_COMPUTE_SHADER; 113 114 glw::GLuint m_compute_shader_id; 115 glw::GLuint m_fragment_shader_id; 116 glw::GLuint m_geometry_shader_id; 117 glw::GLuint m_program_object_id; 118 glw::GLuint m_tesselation_control_shader_id; 119 glw::GLuint m_tesselation_evaluation_shader_id; 120 glw::GLuint m_vertex_shader_id; 121 122 private: 123 deqp::Context& m_context; 124 }; 125 126 struct texture 127 { 128 texture(deqp::Context& context); 129 ~texture(); 130 131 void bind(); 132 133 void create(glw::GLuint width, glw::GLuint height, glw::GLenum internal_format); 134 135 void get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data); 136 137 void update(glw::GLuint width, glw::GLuint height, glw::GLenum format, glw::GLenum type, glw::GLvoid* data); 138 139 glw::GLuint m_id; 140 141 private: 142 deqp::Context& m_context; 143 }; 144 145 struct vertexArray 146 { 147 vertexArray(deqp::Context& Context); 148 ~vertexArray(); 149 150 void generate(); 151 void bind(); 152 153 glw::GLuint m_id; 154 155 private: 156 deqp::Context& m_context; 157 }; 158 159 /** Storage for 4 element vector of T 160 * 161 **/ 162 template <typename T> 163 struct vec4 164 { vec4gl4cts::ShaderSubroutine::Utils::vec4165 vec4() 166 { 167 } 168 vec4gl4cts::ShaderSubroutine::Utils::vec4169 vec4(T x, T y, T z, T w) : m_x(x), m_y(y), m_z(z), m_w(w) 170 { 171 } 172 operator ==gl4cts::ShaderSubroutine::Utils::vec4173 bool operator==(const vec4& val) const 174 { 175 bool result = true; 176 177 result = result && compare(m_x, val.m_x); 178 result = result && compare(m_y, val.m_y); 179 result = result && compare(m_z, val.m_z); 180 result = result && compare(m_w, val.m_w); 181 182 return result; 183 } 184 loggl4cts::ShaderSubroutine::Utils::vec4185 void log(tcu::MessageBuilder& message) const 186 { 187 message << "[ " << m_x << ", " << m_y << ", " << m_z << ", " << m_w << " ]"; 188 } 189 190 T m_x; 191 T m_y; 192 T m_z; 193 T m_w; 194 }; 195 196 enum _shader_stage 197 { 198 SHADER_STAGE_FIRST, 199 200 SHADER_STAGE_VERTEX = SHADER_STAGE_FIRST, 201 SHADER_STAGE_TESSELLATION_CONTROL, 202 SHADER_STAGE_TESSELLATION_EVALUATION, 203 SHADER_STAGE_GEOMETRY, 204 SHADER_STAGE_FRAGMENT, 205 206 SHADER_STAGE_COUNT 207 }; 208 209 enum _variable_type 210 { 211 VARIABLE_TYPE_BOOL, 212 VARIABLE_TYPE_BVEC2, 213 VARIABLE_TYPE_BVEC3, 214 VARIABLE_TYPE_BVEC4, 215 VARIABLE_TYPE_DOUBLE, 216 VARIABLE_TYPE_DVEC2, 217 VARIABLE_TYPE_DVEC3, 218 VARIABLE_TYPE_DVEC4, 219 VARIABLE_TYPE_FLOAT, 220 VARIABLE_TYPE_INT, 221 VARIABLE_TYPE_IVEC2, 222 VARIABLE_TYPE_IVEC3, 223 VARIABLE_TYPE_IVEC4, 224 VARIABLE_TYPE_MAT2, 225 VARIABLE_TYPE_MAT2X3, 226 VARIABLE_TYPE_MAT2X4, 227 VARIABLE_TYPE_MAT3, 228 VARIABLE_TYPE_MAT3X2, 229 VARIABLE_TYPE_MAT3X4, 230 VARIABLE_TYPE_MAT4, 231 VARIABLE_TYPE_MAT4X2, 232 VARIABLE_TYPE_MAT4X3, 233 VARIABLE_TYPE_UINT, 234 VARIABLE_TYPE_UVEC2, 235 VARIABLE_TYPE_UVEC3, 236 VARIABLE_TYPE_UVEC4, 237 VARIABLE_TYPE_VEC2, 238 VARIABLE_TYPE_VEC3, 239 VARIABLE_TYPE_VEC4, 240 241 /* Always last */ 242 VARIABLE_TYPE_UNKNOWN 243 }; 244 245 /* Public methods */ 246 static bool buildProgram(const glw::Functions& gl, const std::string& vs_body, const std::string& tc_body, 247 const std::string& te_body, const std::string& gs_body, const std::string& fs_body, 248 const glw::GLchar** xfb_varyings, const unsigned int& n_xfb_varyings, 249 glw::GLuint* out_vs_id, glw::GLuint* out_tc_id, glw::GLuint* out_te_id, 250 glw::GLuint* out_gs_id, glw::GLuint* out_fs_id, glw::GLuint* out_po_id); 251 252 static _variable_type getBaseVariableType(const _variable_type& variable_type); 253 254 static unsigned int getComponentSizeForVariableType(const _variable_type& variable_type); 255 256 static glw::GLenum getGLenumForShaderStage(const _shader_stage& shader_stage); 257 258 static unsigned int getNumberOfComponentsForVariableType(const _variable_type& variable_type); 259 260 static std::string getShaderStageString(const _shader_stage& shader_stage); 261 262 static std::string getShaderStageStringFromGLEnum(const glw::GLenum shader_stage_glenum); 263 264 static _variable_type getVariableTypeFromProperties(const _variable_type& base_variable_type, 265 const unsigned int& n_components); 266 267 static std::string getVariableTypeGLSLString(const _variable_type& variable_type); 268 269 static const glw::GLchar* programInterfaceToStr(glw::GLenum program_interface); 270 static const glw::GLchar* pnameToStr(glw::GLenum pname); 271 272 private: 273 /* Private methods */ 274 template <typename T> compare(const T & left,const T & right)275 static bool compare(const T& left, const T& right) 276 { 277 return left == right; 278 } 279 280 static bool compare(const glw::GLfloat& left, const glw::GLfloat& right); 281 }; 282 283 /** Verify that Get* commands accept MAX_SUBROUTINES and 284 * MAX_SUBROUTINE_UNIFORM_LOCATIONS tokens and that the returned values 285 * are not lower than required by the specification. 286 **/ 287 class APITest1 : public deqp::TestCase 288 { 289 public: 290 /* Public methods */ 291 APITest1(deqp::Context& context); 292 293 virtual tcu::TestNode::IterateResult iterate(); 294 295 private: 296 /* Private type definitions */ 297 /* Private methods */ 298 299 /* Private fields */ 300 bool m_has_test_passed; 301 }; 302 303 /** Check if <bufsize> and <length> parameters behave correctly in 304 * GetActiveSubroutineName and GetActiveSubroutineUniformName functions. 305 **/ 306 class APITest2 : public deqp::TestCase 307 { 308 public: 309 /* Public methods */ 310 APITest2(deqp::Context& context); 311 312 virtual void deinit(); 313 virtual tcu::TestNode::IterateResult iterate(); 314 315 private: 316 /* Private type definitions */ 317 318 /* Private methods */ 319 std::string getVertexShaderBody(); 320 void initTest(); 321 void verifyGLGetActiveSubroutineNameFunctionality(); 322 void verifyGLGetActiveSubroutineUniformNameFunctionality(); 323 324 /* Private fields */ 325 glw::GLchar* m_buffer; 326 bool m_has_test_passed; 327 glw::GLuint m_po_id; 328 const char* m_subroutine_name1; 329 const char* m_subroutine_name2; 330 const char* m_subroutine_uniform_name; 331 glw::GLuint m_vs_id; 332 }; 333 334 /** * Create program with 2 subroutines taking one parameter and 1 subroutine 335 * uniform. Select the first subroutine and make a draw. Verify the result 336 * and draw again with second subroutine selected then verify result again. 337 * Repeat for following subroutines return and argument types: bool, float, 338 * int, uint, double, *vec*, *mat*. 339 * 340 * * Same as above, but with return and argument types as arrays. 341 * 342 ***/ 343 class FunctionalTest1_2 : public deqp::TestCase 344 { 345 public: 346 /* Public methods */ 347 FunctionalTest1_2(deqp::Context& context); 348 349 virtual void deinit(); 350 virtual tcu::TestNode::IterateResult iterate(); 351 352 private: 353 /* Private type definitions */ 354 struct _test_case 355 { 356 unsigned int array_size; 357 Utils::_variable_type variable_type; 358 }; 359 360 typedef std::vector<_test_case> _test_cases; 361 typedef _test_cases::const_iterator _test_cases_const_iterator; 362 363 /* Private methods */ 364 void deinitTestIteration(); 365 bool executeTestIteration(const _test_case& test_case); 366 367 std::string getVertexShaderBody(const Utils::_variable_type& variable_type, unsigned int array_size); 368 369 void initTest(); 370 371 bool verifyXFBData(const void* xfb_data, const Utils::_variable_type& variable_type); 372 373 /* Private fields */ 374 bool m_has_test_passed; 375 glw::GLuint m_po_id; 376 glw::GLuint m_po_getter0_subroutine_index; 377 glw::GLuint m_po_getter1_subroutine_index; 378 glw::GLint m_po_subroutine_uniform_index; 379 _test_cases m_test_cases; 380 glw::GLuint m_xfb_bo_id; 381 glw::GLuint m_vao_id; 382 glw::GLuint m_vs_id; 383 }; 384 385 /** * Create a program with 4 subroutines and 2 subroutine uniforms and query 386 * it using: GetProgramStageiv, GetActiveSubroutineUniformiv, 387 * GetActiveSubroutineUniformName, GetActiveSubroutineName, 388 * GetUniformSubroutineuiv, GetSubroutineIndex and 389 * GetSubroutineUniformLocation. Verify the results and use them to select 390 * subroutines, then make a draw and select different set of subroutines. 391 * Draw again and verify the results. 392 * 393 * OpenGL 4.3 or ARB_program_interface_query support required 394 * * Same as above, but query the program using calls introduced in 395 * ARB_program_interface_query extension. 396 **/ 397 class FunctionalTest3_4 : public deqp::TestCase 398 { 399 public: 400 /* Public methods */ 401 FunctionalTest3_4(deqp::Context& context); 402 403 virtual tcu::TestNode::IterateResult iterate(); 404 405 private: 406 /* Private types */ 407 /** Connect pname with expected value. Used to check Get* API. 408 * 409 **/ 410 struct inspectionDetails 411 { 412 glw::GLenum pname; 413 glw::GLint expected_value; 414 }; 415 416 /* Private types */ 417 /** Connect program_interface, pname and expected value. Used to check GetProgramInterface. 418 * 419 **/ 420 struct inspectionDetailsForProgramInterface 421 { 422 glw::GLenum program_interface; 423 glw::GLenum pname; 424 glw::GLint expected_value; 425 }; 426 427 /* Private methods */ 428 bool checkProgramStageiv(glw::GLuint program_id, glw::GLenum pname, glw::GLint expected) const; 429 430 bool checkProgramResourceiv(glw::GLuint program_id, glw::GLenum program_interface, glw::GLenum prop, 431 const glw::GLchar* resource_name, glw::GLint expected) const; 432 433 bool checkProgramInterfaceiv(glw::GLuint program_id, glw::GLenum program_interface, glw::GLenum pname, 434 glw::GLint expected) const; 435 436 bool checkActiveSubroutineUniformiv(glw::GLuint program_id, glw::GLuint index, glw::GLenum pname, 437 glw::GLint expected) const; 438 439 glw::GLuint getProgramResourceIndex(glw::GLuint program_id, glw::GLenum program_interface, 440 const glw::GLchar* resource_name) const; 441 442 glw::GLuint getSubroutineIndex(glw::GLuint program_id, const glw::GLchar* subroutine_name, 443 bool use_program_query) const; 444 445 glw::GLint getSubroutineUniformLocation(glw::GLuint program_id, const glw::GLchar* uniform_name, 446 bool use_program_query) const; 447 448 bool inspectProgramStageiv(glw::GLuint program_id) const; 449 bool inspectProgramInterfaceiv(glw::GLuint program_id) const; 450 451 bool inspectProgramResourceiv(glw::GLuint program_id, const glw::GLchar** subroutine_names, 452 const glw::GLchar** uniform_names) const; 453 454 bool inspectActiveSubroutineUniformiv(glw::GLuint program_id, const glw::GLchar** uniform_names) const; 455 456 bool inspectActiveSubroutineUniformName(glw::GLuint program_id, const glw::GLchar** uniform_names) const; 457 458 bool inspectActiveSubroutineName(glw::GLuint program_id, const glw::GLchar** subroutine_names) const; 459 460 bool inspectSubroutineBinding(glw::GLuint program_id, const glw::GLchar** subroutine_names, 461 const glw::GLchar** uniform_names, bool use_program_query) const; 462 463 bool testDraw(glw::GLuint program_id, const glw::GLchar* first_routine_name, const glw::GLchar* second_routine_name, 464 const glw::GLchar** uniform_names, const Utils::vec4<glw::GLfloat> data[5], 465 bool use_program_query) const; 466 467 /* Private fields */ 468 glw::GLint m_n_active_subroutine_uniforms; 469 glw::GLint m_n_active_subroutine_uniform_locations; 470 glw::GLint m_n_active_subroutines; 471 glw::GLint m_n_active_subroutine_uniform_name_length; 472 glw::GLint m_n_active_subroutine_name_length; 473 glw::GLint m_n_active_subroutine_uniform_size; 474 }; 475 476 /** 477 * * Create a program with 8 subroutines and 4 subroutine uniforms. Each 478 * subroutine uniform should have different signature that should match 2 479 * subroutines. Go through all possible combinations of subroutine uniforms 480 * values and for each combination verify that it works as expected. 481 **/ 482 class FunctionalTest5 : public deqp::TestCase 483 { 484 public: 485 /* Public methods */ 486 FunctionalTest5(deqp::Context& context); 487 488 virtual tcu::TestNode::IterateResult iterate(); 489 490 private: 491 /* Private methods */ 492 void logError(const glw::GLchar* subroutine_names[4][2], const glw::GLuint subroutine_combination[4], 493 const Utils::vec4<glw::GLfloat> input_data[3], const Utils::vec4<glw::GLfloat>& first_routine_result, 494 const Utils::vec4<glw::GLfloat>& second_routine_result, 495 const Utils::vec4<glw::GLfloat>& third_routine_result, 496 const Utils::vec4<glw::GLuint>& fourth_routine_result, 497 const Utils::vec4<glw::GLfloat>& first_routine_expected_result, 498 const Utils::vec4<glw::GLfloat>& second_routine_expected_result, 499 const Utils::vec4<glw::GLfloat>& third_routine_expected_result, 500 const Utils::vec4<glw::GLuint>& fourth_routine_expected_result) const; 501 502 void testDraw(const glw::GLuint subroutine_combination[4], const Utils::vec4<glw::GLfloat> input_data[3], 503 Utils::vec4<glw::GLfloat>& out_first_routine_result, 504 Utils::vec4<glw::GLfloat>& out_second_routine_result, 505 Utils::vec4<glw::GLfloat>& out_third_routine_result, 506 Utils::vec4<glw::GLuint>& out_fourth_routine_result) const; 507 508 bool verify(const Utils::vec4<glw::GLfloat>& first_routine_result, 509 const Utils::vec4<glw::GLfloat>& second_routine_result, 510 const Utils::vec4<glw::GLfloat>& third_routine_result, 511 const Utils::vec4<glw::GLuint>& fourth_routine_result, 512 const Utils::vec4<glw::GLfloat>& first_routine_expected_result, 513 const Utils::vec4<glw::GLfloat>& second_routine_expected_result, 514 const Utils::vec4<glw::GLfloat>& third_routine_expected_result, 515 const Utils::vec4<glw::GLuint>& fourth_routine_expected_result) const; 516 517 /* Private fields */ 518 glw::GLuint m_subroutine_uniform_locations[4][1]; 519 glw::GLuint m_subroutine_indices[4][2]; 520 glw::GLuint m_uniform_locations[3]; 521 }; 522 523 /** 524 * * Create a program with a subroutine and a subroutine uniform. Verify that 525 * subroutine can be called directly with a static use of subroutine's 526 * function name, as is done with non-subroutine function declarations and 527 * calls. 528 **/ 529 class FunctionalTest6 : public deqp::TestCase 530 { 531 public: 532 /* Public methods */ 533 FunctionalTest6(deqp::Context& context); 534 535 virtual tcu::TestNode::IterateResult iterate(); 536 }; 537 538 /** 539 * * Create a program with 2 subroutines and an array of 4 subroutine 540 * uniforms. Go through all possible combinations of subroutine uniforms 541 * values and for each combination verify that it works as expected by 542 * performing draw or dispatch call. Also verify that length() function 543 * works correctly when used on array of subroutine uniforms. 544 * 545 * * Verify that program which uses uniforms, constant expressions and 546 * dynamically uniform loop index to access subroutine uniform array 547 * compiles and works as expected. 548 **/ 549 class FunctionalTest7_8 : public deqp::TestCase 550 { 551 public: 552 /* Public methods */ 553 FunctionalTest7_8(deqp::Context& context); 554 555 virtual tcu::TestNode::IterateResult iterate(); 556 557 private: 558 /* Private methods */ 559 void calculate(glw::GLuint function, const Utils::vec4<glw::GLfloat>& left, const Utils::vec4<glw::GLfloat>& right, 560 Utils::vec4<glw::GLfloat>& out) const; 561 562 void calculate(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, 563 const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices, 564 Utils::vec4<glw::GLfloat>& out_combined, Utils::vec4<glw::GLfloat>& out_combined_inversed, 565 Utils::vec4<glw::GLfloat>& out_constant, Utils::vec4<glw::GLfloat>& out_constant_inversed, 566 Utils::vec4<glw::GLfloat>& out_dynamic, Utils::vec4<glw::GLfloat>& out_dynamic_inversed, 567 Utils::vec4<glw::GLfloat>& out_loop) const; 568 569 void logError(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, 570 const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices, 571 const Utils::vec4<glw::GLfloat> vec4_expected[7], const Utils::vec4<glw::GLfloat> vec4_result[7], 572 glw::GLuint array_length, bool result[7]) const; 573 574 bool testDraw(const glw::GLuint combination[4], const Utils::vec4<glw::GLfloat>& left, 575 const Utils::vec4<glw::GLfloat>& right, const Utils::vec4<glw::GLuint>& indices) const; 576 577 /* Private fields */ 578 glw::GLuint m_subroutine_uniform_locations[4]; 579 glw::GLuint m_subroutine_indices[2]; 580 glw::GLuint m_uniform_locations[3]; 581 }; 582 583 /** 584 * Make sure that program with one function associated with 3 different 585 * subroutine types and 3 subroutine uniforms using that function compiles 586 * and works as expected. 587 * 588 **/ 589 class FunctionalTest9 : public deqp::TestCase 590 { 591 public: 592 /* Public methods */ 593 FunctionalTest9(deqp::Context& context); 594 595 virtual void deinit(); 596 virtual tcu::TestNode::IterateResult iterate(); 597 598 private: 599 /* Private methods */ 600 std::string getVertexShaderBody() const; 601 void initTest(); 602 void verifyXFBData(const glw::GLvoid* data_ptr); 603 604 /* Private fields */ 605 bool m_has_test_passed; 606 const unsigned int m_n_points_to_draw; 607 glw::GLuint m_po_id; 608 glw::GLuint m_vao_id; 609 glw::GLuint m_vs_id; 610 glw::GLuint m_xfb_bo_id; 611 }; 612 613 /** 614 * OpenGL 4.3 or ARB_arrays_of_arrays support required 615 * * Create a program that uses array of arrays for subroutine uniform type 616 * and verify that it works as expected. 617 **/ 618 class FunctionalTest10 : public deqp::TestCase 619 { 620 public: 621 FunctionalTest10(deqp::Context& context); 622 623 virtual tcu::TestNode::IterateResult iterate(); 624 625 private: 626 /* Private methods */ 627 glw::GLint testDraw(const glw::GLuint routine_indices[16]) const; 628 629 /* Private fields */ 630 glw::GLuint m_subroutine_uniform_locations[16]; 631 glw::GLuint m_subroutine_indices[2]; 632 }; 633 634 /** 635 * * Verify that following operations work correctly when performed inside 636 * subroutine body: setting global variable, texture sampling, writing 637 * to fragment shader outputs, using discard function (fragment shader 638 * only), calling other functions and subroutines. 639 **/ 640 class FunctionalTest11 : public deqp::TestCase 641 { 642 public: 643 /* Public methods */ 644 FunctionalTest11(deqp::Context& context); 645 646 virtual tcu::TestNode::IterateResult iterate(); 647 648 private: 649 /* Private types */ 650 struct testConfiguration 651 { testConfigurationgl4cts::ShaderSubroutine::FunctionalTest11::testConfiguration652 testConfiguration(const glw::GLchar* description, const glw::GLubyte expected_color[4], 653 glw::GLuint discard_fragment, glw::GLuint set_global_colors, glw::GLuint sample_texture, 654 glw::GLuint compare, glw::GLuint test, glw::GLuint first_sampler, glw::GLuint second_sampler) 655 { 656 m_description = description; 657 658 m_expected_color[0] = expected_color[0]; 659 m_expected_color[1] = expected_color[1]; 660 m_expected_color[2] = expected_color[2]; 661 m_expected_color[3] = expected_color[3]; 662 663 m_routines[0] = discard_fragment; 664 m_routines[1] = set_global_colors; 665 m_routines[2] = sample_texture; 666 m_routines[3] = compare; 667 m_routines[4] = test; 668 669 m_samplers[0] = first_sampler; 670 m_samplers[1] = second_sampler; 671 } 672 673 const glw::GLchar* m_description; 674 glw::GLubyte m_expected_color[4]; 675 glw::GLuint m_routines[5]; 676 glw::GLuint m_samplers[2]; 677 }; 678 679 /* Private methods */ 680 void fillTexture(Utils::texture& texture, const glw::GLubyte color[4]) const; 681 682 bool testDraw(const glw::GLuint routine_configuration[5], const glw::GLuint sampler_configuration[2], 683 const glw::GLubyte expected_color[4], Utils::texture& color_texture) const; 684 685 /* Private fields */ 686 /* Constants */ 687 static const glw::GLuint m_texture_height; 688 static const glw::GLuint m_texture_width; 689 690 /* Locations and indices */ 691 glw::GLuint m_subroutine_uniform_locations[5]; 692 glw::GLuint m_subroutine_indices[5][2]; 693 glw::GLuint m_uniform_locations[2]; 694 glw::GLuint m_source_textures[2]; 695 }; 696 697 /** 698 * OpenGL 4.3 or ARB_shader_storage_buffer_object, ARB_atomic_counters 699 * and ARB_shader_image_load_store support required 700 * * Same as above, but check writing/reading from storage buffer, performing 701 * operations on atomic counters and writing/reading from an image. This 702 * should be tested in a program stage which supports operations of these 703 * kind. 704 **/ 705 class FunctionalTest12 : public deqp::TestCase 706 { 707 public: 708 FunctionalTest12(deqp::Context& context); 709 710 virtual tcu::TestNode::IterateResult iterate(); 711 712 private: 713 /* Private methods */ 714 void fillTexture(Utils::texture& texture, const glw::GLuint color[4]) const; 715 716 bool verifyTexture(Utils::texture& texture, const glw::GLuint color[4]) const; 717 718 bool testAtomic(); 719 720 bool testAtomicDraw(glw::GLuint subourinte_index, const glw::GLuint expected_results[3]) const; 721 722 bool testImage(); 723 724 bool testImageDraw(glw::GLuint subroutine_index, Utils::texture& left, Utils::texture& right, 725 const glw::GLuint expected_left_color[4], const glw::GLuint expected_right_color[4]) const; 726 727 bool testSSBO(); 728 729 bool testSSBODraw(glw::GLuint subourinte_index, const glw::GLuint expected_results[4]) const; 730 731 /* Private fields */ 732 /* Constatnts */ 733 static const glw::GLuint m_texture_height; 734 static const glw::GLuint m_texture_width; 735 736 /* Locations */ 737 glw::GLuint m_left_image; 738 glw::GLuint m_right_image; 739 }; 740 741 /** 742 * Verify that subroutines work correctly when used in separate shader 743 * objects. 744 * 745 **/ 746 class FunctionalTest13 : public deqp::TestCase 747 { 748 public: 749 /* Public methods */ 750 FunctionalTest13(deqp::Context& context); 751 752 virtual void deinit(); 753 virtual tcu::TestNode::IterateResult iterate(); 754 755 private: 756 /* Private methods */ 757 std::string getFragmentShaderBody(unsigned int n_id); 758 std::string getGeometryShaderBody(unsigned int n_id); 759 std::string getTessellationControlShaderBody(unsigned int n_id); 760 std::string getTessellationEvaluationShaderBody(unsigned int n_id); 761 std::string getVertexShaderBody(unsigned int n_id); 762 void initTest(); 763 764 void verifyReadBuffer(unsigned int n_fs_id, unsigned int n_fs_subroutine, unsigned int n_gs_id, 765 unsigned int n_gs_subroutine, unsigned int n_tc_id, unsigned int n_tc_subroutine, 766 unsigned int n_te_id, unsigned int n_te_subroutine, unsigned int n_vs_id, 767 unsigned int n_vs_subroutine); 768 769 /* Private fields */ 770 glw::GLuint m_fbo_id; 771 glw::GLuint m_fs_po_ids[2]; 772 glw::GLuint m_gs_po_ids[2]; 773 glw::GLuint m_pipeline_id; 774 unsigned char* m_read_buffer; 775 glw::GLuint m_tc_po_ids[2]; 776 glw::GLuint m_te_po_ids[2]; 777 const unsigned int m_to_height; 778 glw::GLuint m_to_id; 779 const unsigned int m_to_width; 780 glw::GLuint m_vao_id; 781 glw::GLuint m_vs_po_ids[2]; 782 783 bool m_has_test_passed; 784 }; 785 786 /** 787 * * Create program with subroutines that use structures as parameters and 788 * make sure it works correctly. 789 * 790 * OpenGL 4.1 or ARB_get_program_binary support required 791 * * Create a program with 4 subroutines and 2 subroutine uniforms. Query 792 * names and indices of all active subroutines and query names and 793 * locations of all active subroutine uniforms. Call GetProgramBinary on 794 * this program and delete it. Create new program from the binary using 795 * ProgramBinary. Verify that all active subroutine names and indices in 796 * this program match ones from the original program. Also verify that 797 * all active subroutine uniform names and locations match ones from 798 * original program. Make a draw, expect random but valid set of selected 799 * subroutines, then select arbitrary set of subroutines, make a draw and 800 * verify the results. 801 **/ 802 class FunctionalTest14_15 : public deqp::TestCase 803 { 804 public: 805 FunctionalTest14_15(deqp::Context& context); 806 807 virtual tcu::TestNode::IterateResult iterate(); 808 809 private: 810 /* Private methods */ 811 bool testDefaultSubroutineSet(const Utils::vec4<glw::GLuint>& uni_input, 812 const Utils::vec4<glw::GLuint> expected_routine_1_result[2], 813 const Utils::vec4<glw::GLuint> expected_routine_2_result[2]) const; 814 815 bool testDraw(glw::GLuint routine_configuration, const Utils::vec4<glw::GLuint>& uni_input, 816 const Utils::vec4<glw::GLuint>& expected_routine_1_result, 817 const Utils::vec4<glw::GLuint>& expected_routine_2_result) const; 818 819 bool testIndicesAndLocations() const; 820 821 /* Private fields */ 822 /* Locations and indices */ 823 glw::GLuint m_subroutine_uniform_locations[2]; 824 glw::GLuint m_subroutine_indices[2][2]; 825 glw::GLuint m_uniform_location; 826 glw::GLuint m_initial_subroutine_uniform_locations[2]; 827 glw::GLuint m_initial_subroutine_indices[2][2]; 828 }; 829 830 /** 831 * Check that when the active program for a shader stage is re-linked or 832 * changed by a call to UseProgram, BindProgramPipeline, or 833 * UseProgramStages, subroutine uniforms for that stage are reset to 834 * arbitrarily chosen default functions with compatible subroutine types. 835 * 836 **/ 837 class FunctionalTest16 : public deqp::TestCase 838 { 839 public: 840 /* Public methods */ 841 FunctionalTest16(deqp::Context& context); 842 843 virtual void deinit(); 844 virtual tcu::TestNode::IterateResult iterate(); 845 846 private: 847 /* Private type definitions */ 848 /* Defines a specific use case that should be checked during particular 849 * test iteration. 850 */ 851 enum _test_case 852 { 853 TEST_CASE_FIRST, 854 855 TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_OBJECT = TEST_CASE_FIRST, 856 TEST_CASE_SWITCH_TO_DIFFERENT_PROGRAM_PIPELINE_OBJECT, 857 TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_FRAGMENT_STAGE, 858 TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_GEOMETRY_STAGE, 859 TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_CONTROL_STAGE, 860 TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_TESS_EVALUATION_STAGE, 861 TEST_CASE_SWITCH_TO_DIFFERENT_PIPELINE_VERTEX_STAGE, 862 863 /* Always last */ 864 TEST_CASE_COUNT 865 }; 866 867 /** Defines a number of different subroutine-specific properties 868 * for a single shader stage. 869 **/ 870 struct _shader_stage 871 { 872 glw::GLuint default_subroutine1_value; 873 glw::GLuint default_subroutine2_value; 874 glw::GLuint default_subroutine3_value; 875 glw::GLuint default_subroutine4_value; 876 glw::GLint subroutine1_uniform_location; 877 glw::GLint subroutine2_uniform_location; 878 glw::GLint subroutine3_uniform_location; 879 glw::GLint subroutine4_uniform_location; 880 glw::GLuint function1_index; 881 glw::GLuint function2_index; 882 glw::GLuint function3_index; 883 glw::GLuint function4_index; 884 885 glw::GLenum gl_stage; 886 }; 887 888 /** Describes subroutine-specific properties for a program object */ 889 struct _program 890 { 891 _shader_stage fragment; 892 _shader_stage geometry; 893 _shader_stage tess_control; 894 _shader_stage tess_evaluation; 895 _shader_stage vertex; 896 }; 897 898 /** Describes modes that verify*() functions can run in */ 899 enum _subroutine_uniform_value_verification 900 { 901 SUBROUTINE_UNIFORMS_SET_TO_DEFAULT_VALUES, 902 SUBROUTINE_UNIFORMS_SET_TO_NONDEFAULT_VALUES, 903 SUBROUTINE_UNIFORMS_SET_TO_VALID_VALUES, 904 }; 905 906 /* Private methods */ 907 std::string getShaderBody(const Utils::_shader_stage& shader_stage, const unsigned int& n_id) const; 908 909 void getShaderStages(bool retrieve_program_object_shader_ids, const unsigned int& n_id, 910 const _shader_stage** out_shader_stages) const; 911 912 void initTest(); 913 914 void verifySubroutineUniformValues(const _test_case& test_case, const unsigned int& n_id, 915 const _subroutine_uniform_value_verification& verification); 916 917 void verifySubroutineUniformValuesForShaderStage(const _shader_stage& shader_stage, 918 const _subroutine_uniform_value_verification& verification); 919 920 /* Private fields */ 921 bool m_are_pipeline_objects_supported; 922 bool m_has_test_passed; 923 924 glw::GLuint m_fs_ids[2]; 925 glw::GLuint m_gs_ids[2]; 926 glw::GLuint m_po_ids[2]; 927 glw::GLuint m_tc_ids[2]; 928 glw::GLuint m_te_ids[2]; 929 glw::GLuint m_vs_ids[2]; 930 931 glw::GLuint m_fs_po_ids[2]; 932 glw::GLuint m_gs_po_ids[2]; 933 glw::GLuint m_pipeline_object_ids[2]; 934 glw::GLuint m_tc_po_ids[2]; 935 glw::GLuint m_te_po_ids[2]; 936 glw::GLuint m_vs_po_ids[2]; 937 938 _shader_stage m_fs_po_descriptors[2]; 939 _shader_stage m_gs_po_descriptors[2]; 940 _shader_stage m_tc_po_descriptors[2]; 941 _shader_stage m_te_po_descriptors[2]; 942 _shader_stage m_vs_po_descriptors[2]; 943 944 _program m_po_descriptors[2]; 945 }; 946 947 /** 948 * Create a program which uses the same subroutine and subroutine uniform 949 * names for every stage. Types of subroutines should be different in each 950 * stage. Make sure that such program compiles and works as expected. 951 **/ 952 class FunctionalTest17 : public deqp::TestCase 953 { 954 public: 955 /* Public methods */ 956 FunctionalTest17(deqp::Context& context); 957 958 virtual void deinit(); 959 virtual tcu::TestNode::IterateResult iterate(); 960 961 private: 962 /* Private methods */ 963 std::string getFragmentShaderBody() const; 964 std::string getGeometryShaderBody() const; 965 std::string getTessellationControlShaderBody() const; 966 std::string getTessellationEvaluationShaderBody() const; 967 std::string getVertexShaderBody() const; 968 void initTest(); 969 void verifyRenderedData(); 970 971 /* Private fields */ 972 glw::GLuint m_fbo_id; 973 glw::GLuint m_fs_id; 974 glw::GLuint m_gs_id; 975 bool m_has_test_passed; 976 glw::GLuint m_po_id; 977 glw::GLuint m_tc_id; 978 glw::GLuint m_te_id; 979 float* m_to_data; 980 const unsigned int m_to_height; 981 glw::GLuint m_to_id; 982 const unsigned int m_to_width; 983 glw::GLuint m_vao_id; 984 glw::GLuint m_vs_id; 985 }; 986 987 /** 988 * Make sure that calling a subroutine with argument value returned by 989 * another subroutine works correctly. 990 * 991 * Verify that subroutines and subroutine uniforms work as expected when 992 * they are used in connection with control flow functions 993 * (if/else/case/while/for/break/continue). 994 * 995 **/ 996 class FunctionalTest18_19 : public deqp::TestCase 997 { 998 public: 999 /* Public methods */ 1000 FunctionalTest18_19(deqp::Context& context); 1001 1002 virtual void deinit(); 1003 virtual tcu::TestNode::IterateResult iterate(); 1004 1005 private: 1006 /* Private type definitions */ 1007 typedef tcu::Vec4 (*PFNVEC4OPERATORPROC)(tcu::Vec4); 1008 1009 /* Private methods */ 1010 void executeTest(glw::GLuint bool_operator1_subroutine_location, glw::GLuint bool_operator2_subroutine_location, 1011 glw::GLuint vec4_operator1_subroutine_location, glw::GLuint vec4_operator2_subroutine_location); 1012 1013 std::string getVertexShaderBody() const; 1014 1015 void initTest(); 1016 void verifyXFBData(const glw::GLvoid* data, glw::GLuint bool_operator1_subroutine_location, 1017 glw::GLuint bool_operator2_subroutine_location, glw::GLuint vec4_operator1_subroutine_location, 1018 glw::GLuint vec4_operator2_subroutine_location); 1019 1020 static tcu::Vec4 vec4operator_div2(tcu::Vec4 data); 1021 static tcu::Vec4 vec4operator_mul4(tcu::Vec4 data); 1022 1023 /* Private fields */ 1024 bool m_has_test_passed; 1025 const unsigned int m_n_points_to_draw; 1026 glw::GLuint m_po_id; 1027 glw::GLuint m_po_subroutine_divide_by_two_location; 1028 glw::GLuint m_po_subroutine_multiply_by_four_location; 1029 glw::GLuint m_po_subroutine_returns_false_location; 1030 glw::GLuint m_po_subroutine_returns_true_location; 1031 glw::GLint m_po_subroutine_uniform_bool_operator1; 1032 glw::GLint m_po_subroutine_uniform_bool_operator2; 1033 glw::GLint m_po_subroutine_uniform_vec4_processor1; 1034 glw::GLint m_po_subroutine_uniform_vec4_processor2; 1035 glw::GLuint m_xfb_bo_id; 1036 glw::GLuint m_vao_id; 1037 glw::GLuint m_vs_id; 1038 }; 1039 1040 /** 1041 * Test whether all INVALID_OPERATION, INVALID_VALUE and INVALID_ENUM 1042 * errors related to subroutines usage are properly generated. 1043 **/ 1044 class NegativeTest1 : public deqp::TestCase 1045 { 1046 public: 1047 /* Public methods */ 1048 NegativeTest1(deqp::Context& context); 1049 1050 virtual void deinit(); 1051 virtual tcu::TestNode::IterateResult iterate(); 1052 1053 private: 1054 /* Private methods */ 1055 void initTest(); 1056 1057 /* Private fields */ 1058 bool m_has_test_passed; 1059 glw::GLint m_po_active_subroutine_uniform_locations; 1060 glw::GLint m_po_active_subroutine_uniforms; 1061 glw::GLint m_po_active_subroutines; 1062 glw::GLint m_po_subroutine_uniform_function_index; 1063 glw::GLint m_po_subroutine_uniform_function2_index; 1064 glw::GLuint m_po_subroutine_test1_index; 1065 glw::GLuint m_po_subroutine_test2_index; 1066 glw::GLuint m_po_subroutine_test3_index; 1067 glw::GLuint m_po_not_linked_id; 1068 glw::GLuint m_po_id; 1069 glw::GLuint m_vs_id; 1070 }; 1071 1072 /** Make sure that subroutine uniform variables are scoped to the shader 1073 * execution stage the variable is declared in. Referencing subroutine 1074 * uniform from different stage should cause compile or link error 1075 **/ 1076 class NegativeTest2 : public deqp::TestCase 1077 { 1078 public: 1079 /* Public methods */ 1080 NegativeTest2(deqp::Context& context); 1081 1082 virtual void deinit(); 1083 virtual tcu::TestNode::IterateResult iterate(); 1084 1085 private: 1086 /* Private type definitions */ 1087 1088 /* Private methods */ 1089 void deinitGLObjects(); 1090 void executeTestCase(const Utils::_shader_stage& referencing_stage); 1091 std::string getFragmentShaderBody(const Utils::_shader_stage& referencing_stage) const; 1092 std::string getGeometryShaderBody(const Utils::_shader_stage& referencing_stage) const; 1093 std::string getSubroutineUniformName(const Utils::_shader_stage& stage) const; 1094 std::string getTessellationControlShaderBody(const Utils::_shader_stage& referencing_stage) const; 1095 std::string getTessellationEvaluationShaderBody(const Utils::_shader_stage& referencing_stage) const; 1096 std::string getVertexShaderBody(const Utils::_shader_stage& referencing_stage) const; 1097 1098 /* Private fields */ 1099 glw::GLuint m_fs_id; 1100 glw::GLuint m_gs_id; 1101 bool m_has_test_passed; 1102 glw::GLuint m_po_id; 1103 glw::GLuint m_tc_id; 1104 glw::GLuint m_te_id; 1105 glw::GLuint m_vs_id; 1106 }; 1107 1108 /** Verify that "subroutine" keyword is necessary when declaring a 1109 * subroutine uniform and a compilation error occurs without it. 1110 **/ 1111 class NegativeTest3 : public deqp::TestCase 1112 { 1113 public: 1114 /* Public methods */ 1115 NegativeTest3(deqp::Context& context); 1116 1117 virtual void deinit(); 1118 virtual tcu::TestNode::IterateResult iterate(); 1119 1120 private: 1121 /* Private methods */ 1122 void executeTest(const Utils::_shader_stage& shader_stage); 1123 std::string getFragmentShaderBody() const; 1124 std::string getGeometryShaderBody() const; 1125 std::string getTessellationControlShaderBody() const; 1126 std::string getTessellationEvaluationShaderBody() const; 1127 std::string getVertexShaderBody() const; 1128 1129 /* Private fields */ 1130 bool m_has_test_passed; 1131 glw::GLuint m_so_id; 1132 }; 1133 1134 /** 1135 * Verify that compile-time error is present when arguments and return type 1136 * do not match between the function and each associated subroutine type. 1137 * In particular make sure that applies when there are multiple associated 1138 * subroutine types and only one of them does not match. 1139 * 1140 **/ 1141 class NegativeTest4 : public deqp::TestCase 1142 { 1143 public: 1144 /* Public methods */ 1145 NegativeTest4(deqp::Context& context); 1146 1147 virtual void deinit(); 1148 virtual tcu::TestNode::IterateResult iterate(); 1149 1150 private: 1151 /* Private type declarations */ 1152 enum _test_case 1153 { 1154 TEST_CASE_FIRST, 1155 1156 TEST_CASE_INCOMPATIBLE_RETURN_TYPE = TEST_CASE_FIRST, 1157 TEST_CASE_INCOMPATIBLE_ARGUMENT_LIST, 1158 1159 /* Always last */ 1160 TEST_CASE_COUNT 1161 }; 1162 1163 /* Private methods */ 1164 std::string getShaderBody(const Utils::_shader_stage& shader_stage, const unsigned int& n_subroutine_types, 1165 const _test_case& test_case) const; 1166 1167 /* Private fields */ 1168 bool m_has_test_passed; 1169 glw::GLint m_so_id; 1170 }; 1171 1172 /** Verify that link or compile error occurs when trying to link a program 1173 * with no subroutine for subroutine uniform variable. 1174 **/ 1175 class NegativeTest5 : public deqp::TestCase 1176 { 1177 public: 1178 /* Public methods */ 1179 NegativeTest5(deqp::Context& context); 1180 1181 virtual void deinit(); 1182 virtual tcu::TestNode::IterateResult iterate(); 1183 1184 private: 1185 /* Private type definitions */ 1186 /* Private methods */ 1187 void deinitIteration(); 1188 void executeIteration(const Utils::_shader_stage& shader_stage); 1189 std::string getFragmentShaderBody(bool include_invalid_subroutine_uniform_declaration) const; 1190 std::string getGeometryShaderBody(bool include_invalid_subroutine_uniform_declaration) const; 1191 std::string getTessellationControlShaderBody(bool include_invalid_subroutine_uniform_declaration) const; 1192 std::string getTessellationEvaluationShaderBody(bool include_invalid_subroutine_uniform_declaration) const; 1193 std::string getVertexShaderBody(bool include_invalid_subroutine_uniform_declaration) const; 1194 1195 /* Private fields */ 1196 glw::GLuint m_fs_id; 1197 glw::GLuint m_gs_id; 1198 bool m_has_test_passed; 1199 glw::GLuint m_po_id; 1200 glw::GLuint m_tc_id; 1201 glw::GLuint m_te_id; 1202 glw::GLuint m_vs_id; 1203 }; 1204 1205 /** Check that link or compile error occurs if any shader in a program 1206 * includes two or more functions with the same name and at least one of 1207 * which is associated with a subroutine type. 1208 **/ 1209 class NegativeTest6 : public deqp::TestCase 1210 { 1211 public: 1212 /* Public methods */ 1213 NegativeTest6(deqp::Context& context); 1214 1215 virtual void deinit(); 1216 virtual tcu::TestNode::IterateResult iterate(); 1217 1218 private: 1219 /* Private type definitions */ 1220 /* Private methods */ 1221 void deinitIteration(); 1222 void executeIteration(const Utils::_shader_stage& shader_stage); 1223 std::string getFragmentShaderBody(bool include_invalid_declaration) const; 1224 std::string getGeometryShaderBody(bool include_invalid_declaration) const; 1225 std::string getTessellationControlShaderBody(bool include_invalid_declaration) const; 1226 std::string getTessellationEvaluationShaderBody(bool include_invalid_declaration) const; 1227 std::string getVertexShaderBody(bool include_invalid_declaration) const; 1228 1229 /* Private fields */ 1230 glw::GLuint m_fs_id; 1231 glw::GLuint m_gs_id; 1232 bool m_has_test_passed; 1233 glw::GLuint m_po_id; 1234 glw::GLuint m_tc_id; 1235 glw::GLuint m_te_id; 1236 glw::GLuint m_vs_id; 1237 }; 1238 1239 /** 1240 * * Verify that program fails to link if there is any possible combination 1241 * of subroutine uniform values that would result in recursion. 1242 **/ 1243 class NegativeTest7 : public deqp::TestCase 1244 { 1245 public: 1246 NegativeTest7(deqp::Context& contex); 1247 1248 virtual void deinit(); 1249 virtual tcu::TestNode::IterateResult iterate(); 1250 1251 private: 1252 /* Private methods */ 1253 bool test(const glw::GLchar* vertex_shader_code, const glw::GLchar* name_of_recursive_routine); 1254 1255 /* Private fields */ 1256 glw::GLuint m_program_id; 1257 glw::GLuint m_vertex_shader_id; 1258 }; 1259 1260 /** Test that either compile or link error occurs when function declared 1261 * with subroutine does not include a body. 1262 **/ 1263 class NegativeTest8 : public deqp::TestCase 1264 { 1265 public: 1266 /* Public methods */ 1267 NegativeTest8(deqp::Context& context); 1268 1269 virtual void deinit(); 1270 virtual tcu::TestNode::IterateResult iterate(); 1271 1272 private: 1273 /* Private type definitions */ 1274 /* Private methods */ 1275 void deinitIteration(); 1276 void executeIteration(const Utils::_shader_stage& shader_stage); 1277 std::string getFragmentShaderBody(bool include_invalid_declaration) const; 1278 std::string getGeometryShaderBody(bool include_invalid_declaration) const; 1279 std::string getTessellationControlShaderBody(bool include_invalid_declaration) const; 1280 std::string getTessellationEvaluationShaderBody(bool include_invalid_declaration) const; 1281 std::string getVertexShaderBody(bool include_invalid_declaration) const; 1282 1283 /* Private fields */ 1284 glw::GLuint m_fs_id; 1285 glw::GLuint m_gs_id; 1286 bool m_has_test_passed; 1287 glw::GLuint m_po_id; 1288 glw::GLuint m_tc_id; 1289 glw::GLuint m_te_id; 1290 glw::GLuint m_vs_id; 1291 }; 1292 1293 /** 1294 * Make sure that it is not possible to assign float/int to subroutine 1295 * uniform and that subroutine uniform values cannot be compared. 1296 * 1297 **/ 1298 class NegativeTest9 : public deqp::TestCase 1299 { 1300 public: 1301 /* Public methods */ 1302 NegativeTest9(deqp::Context& context); 1303 1304 virtual void deinit(); 1305 virtual tcu::TestNode::IterateResult iterate(); 1306 1307 private: 1308 /* Private type definitions */ 1309 enum _test_case 1310 { 1311 TEST_CASE_FIRST, 1312 1313 TEST_CASE_INVALID_FLOAT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT = TEST_CASE_FIRST, 1314 TEST_CASE_INVALID_INT_TO_SUBROUTINE_UNIFORM_ASSIGNMENT, 1315 TEST_CASE_INVALID_SUBROUTINE_UNIFORM_VALUE_COMPARISON, 1316 1317 /* Always last */ 1318 TEST_CASE_COUNT 1319 }; 1320 1321 /* Private methods */ 1322 std::string getTestCaseString(const _test_case& test_case); 1323 std::string getVertexShader(const _test_case& test_case); 1324 1325 /* Private fields */ 1326 bool m_has_test_passed; 1327 glw::GLuint m_po_id; 1328 glw::GLuint m_vs_id; 1329 }; 1330 1331 /** 1332 * Check that an overloaded function cannot be declared with subroutine and 1333 * a program will fail to compile or link if any shader or stage contains 1334 * two or more functions with the same name if the name is associated with 1335 * a subroutine type. 1336 * 1337 **/ 1338 class NegativeTest10 : public deqp::TestCase 1339 { 1340 public: 1341 /* Public methods */ 1342 NegativeTest10(deqp::Context& context); 1343 1344 virtual void deinit(); 1345 virtual tcu::TestNode::IterateResult iterate(); 1346 1347 private: 1348 /* Private type definitions */ 1349 struct _test_case 1350 { 1351 std::string name; 1352 1353 std::string fs_body; 1354 std::string gs_body; 1355 std::string tc_body; 1356 std::string te_body; 1357 std::string vs_body; 1358 }; 1359 1360 typedef std::vector<_test_case> _test_cases; 1361 typedef _test_cases::const_iterator _test_cases_const_iterator; 1362 1363 /* Private methods */ 1364 std::string getFragmentShader(bool include_duplicate_function); 1365 std::string getGeometryShader(bool include_duplicate_function); 1366 std::string getTessellationControlShader(bool include_duplicate_function); 1367 std::string getTessellationEvaluationShader(bool include_duplicate_function); 1368 std::string getVertexShader(bool include_duplicate_function); 1369 void initTestCases(); 1370 1371 /* Private fields */ 1372 bool m_has_test_passed; 1373 glw::GLuint m_fs_id; 1374 glw::GLuint m_gs_id; 1375 glw::GLuint m_po_id; 1376 glw::GLuint m_tc_id; 1377 glw::GLuint m_te_id; 1378 _test_cases m_test_cases; 1379 glw::GLuint m_vs_id; 1380 }; 1381 1382 /** 1383 * Try to use subroutine uniform in invalid way in sampling, atomic and 1384 * image functions. Verify that compile or link time error occurs. 1385 * 1386 **/ 1387 class NegativeTest11 : public deqp::TestCase 1388 { 1389 public: 1390 /* Public methods */ 1391 NegativeTest11(deqp::Context& context); 1392 1393 virtual void deinit(); 1394 virtual tcu::TestNode::IterateResult iterate(); 1395 1396 private: 1397 /* Private type definitions */ 1398 enum _test_case 1399 { 1400 TEST_CASE_FIRST, 1401 1402 TEST_CASE_INVALID_TEXTURE_SAMPLING_ATTEMPT = TEST_CASE_FIRST, 1403 TEST_CASE_INVALID_ATOMIC_COUNTER_USAGE_ATTEMPT, 1404 TEST_CASE_INVALID_IMAGE_FUNCTION_USAGE_ATTEMPT, 1405 1406 /* Always last */ 1407 TEST_CASE_COUNT 1408 }; 1409 1410 /* Private methods */ 1411 std::string getTestCaseString(const _test_case& test_case); 1412 std::string getVertexShader(const _test_case& test_case); 1413 1414 /* Private fields */ 1415 bool m_has_test_passed; 1416 glw::GLuint m_po_id; 1417 glw::GLuint m_vs_id; 1418 }; 1419 1420 /** 1421 * Verify that it is not allowed to use subroutine type for local/global 1422 * variables, constructors or argument/return type. 1423 * 1424 **/ 1425 class NegativeTest12 : public deqp::TestCase 1426 { 1427 public: 1428 /* Public methods */ 1429 NegativeTest12(deqp::Context& context); 1430 1431 virtual void deinit(); 1432 virtual tcu::TestNode::IterateResult iterate(); 1433 1434 private: 1435 /* Private type definitions */ 1436 enum _test_case 1437 { 1438 TEST_CASE_FIRST, 1439 1440 TEST_CASE_INVALID_LOCAL_SUBROUTINE_VARIABLE = TEST_CASE_FIRST, 1441 TEST_CASE_INVALID_GLOBAL_SUBROUTINE_VARIABLE, 1442 TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR, 1443 TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_ARGUMENT, 1444 TEST_CASE_SUBROUTINE_USED_AS_CONSTRUCTOR_RETURN_TYPE, 1445 1446 /* Always last */ 1447 TEST_CASE_COUNT 1448 }; 1449 1450 /* Private methods */ 1451 std::string getTestCaseString(const _test_case& test_case); 1452 std::string getVertexShader(const _test_case& test_case); 1453 1454 /* Private fields */ 1455 bool m_has_test_passed; 1456 glw::GLuint m_po_id; 1457 glw::GLuint m_vs_id; 1458 }; 1459 } /* ShaderSubroutine */ 1460 1461 /** Group class for Shader Subroutine conformance tests */ 1462 class ShaderSubroutineTests : public deqp::TestCaseGroup 1463 { 1464 public: 1465 /* Public methods */ 1466 ShaderSubroutineTests(deqp::Context& context); ~ShaderSubroutineTests()1467 virtual ~ShaderSubroutineTests() 1468 { 1469 } 1470 1471 virtual void init(void); 1472 1473 private: 1474 /* Private methods */ 1475 ShaderSubroutineTests(const ShaderSubroutineTests&); 1476 ShaderSubroutineTests& operator=(const ShaderSubroutineTests&); 1477 }; 1478 1479 } /* gl4cts namespace */ 1480 1481 #endif // _GL4CSHADERSUBROUTINETESTS_HPP 1482