1 #ifndef _GL4CGPUSHADERFP64TESTS_HPP 2 #define _GL4CGPUSHADERFP64TESTS_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 gl4cGPUShaderFP64Tests.hpp 28 * \brief Declares test classes for "GPU Shader FP64" functionality. 29 */ /*-------------------------------------------------------------------*/ 30 31 #include "glcTestCase.hpp" 32 #include "glwDefs.hpp" 33 #include "glwEnums.hpp" 34 #include "tcuDefs.hpp" 35 #include "tcuVector.hpp" 36 #include <queue> 37 38 namespace gl4cts 39 { 40 class Utils 41 { 42 public: 43 /* Public type definitions */ 44 45 /** Store information about program object 46 * 47 **/ 48 struct programInfo 49 { 50 programInfo(deqp::Context &context); 51 ~programInfo(); 52 53 void build(const glw::GLchar *compute_shader_code, const glw::GLchar *fragment_shader_code, 54 const glw::GLchar *geometry_shader_code, const glw::GLchar *tesselation_control_shader_code, 55 const glw::GLchar *tesselation_evaluation_shader_code, const glw::GLchar *vertex_shader_code, 56 const glw::GLchar *const *varying_names, glw::GLuint n_varying_names); 57 58 void compile(glw::GLuint shader_id, const glw::GLchar *shader_code) const; 59 60 void link() const; 61 62 static const glw::GLenum ARB_COMPUTE_SHADER; 63 64 deqp::Context &m_context; 65 66 glw::GLuint m_compute_shader_id; 67 glw::GLuint m_fragment_shader_id; 68 glw::GLuint m_geometry_shader_id; 69 glw::GLuint m_program_object_id; 70 glw::GLuint m_tesselation_control_shader_id; 71 glw::GLuint m_tesselation_evaluation_shader_id; 72 glw::GLuint m_vertex_shader_id; 73 }; 74 75 /* Defines GLSL variable type */ 76 enum _variable_type 77 { 78 VARIABLE_TYPE_BOOL, 79 VARIABLE_TYPE_BVEC2, 80 VARIABLE_TYPE_BVEC3, 81 VARIABLE_TYPE_BVEC4, 82 VARIABLE_TYPE_DOUBLE, 83 VARIABLE_TYPE_DMAT2, 84 VARIABLE_TYPE_DMAT2X3, 85 VARIABLE_TYPE_DMAT2X4, 86 VARIABLE_TYPE_DMAT3, 87 VARIABLE_TYPE_DMAT3X2, 88 VARIABLE_TYPE_DMAT3X4, 89 VARIABLE_TYPE_DMAT4, 90 VARIABLE_TYPE_DMAT4X2, 91 VARIABLE_TYPE_DMAT4X3, 92 VARIABLE_TYPE_DVEC2, 93 VARIABLE_TYPE_DVEC3, 94 VARIABLE_TYPE_DVEC4, 95 VARIABLE_TYPE_FLOAT, 96 VARIABLE_TYPE_INT, 97 VARIABLE_TYPE_IVEC2, 98 VARIABLE_TYPE_IVEC3, 99 VARIABLE_TYPE_IVEC4, 100 VARIABLE_TYPE_MAT2, 101 VARIABLE_TYPE_MAT2X3, 102 VARIABLE_TYPE_MAT2X4, 103 VARIABLE_TYPE_MAT3, 104 VARIABLE_TYPE_MAT3X2, 105 VARIABLE_TYPE_MAT3X4, 106 VARIABLE_TYPE_MAT4, 107 VARIABLE_TYPE_MAT4X2, 108 VARIABLE_TYPE_MAT4X3, 109 VARIABLE_TYPE_UINT, 110 VARIABLE_TYPE_UVEC2, 111 VARIABLE_TYPE_UVEC3, 112 VARIABLE_TYPE_UVEC4, 113 VARIABLE_TYPE_VEC2, 114 VARIABLE_TYPE_VEC3, 115 VARIABLE_TYPE_VEC4, 116 117 /* Always last */ 118 VARIABLE_TYPE_UNKNOWN 119 }; 120 121 /* Public static methods */ 122 static _variable_type getBaseVariableType(_variable_type type); 123 static unsigned int getBaseVariableTypeComponentSize(_variable_type type); 124 static unsigned char getComponentAtIndex(unsigned int index); 125 126 static _variable_type getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows); 127 128 static std::string getFPVariableTypeStringForVariableType(_variable_type type); 129 static glw::GLenum getGLDataTypeOfBaseVariableType(_variable_type type); 130 static glw::GLenum getGLDataTypeOfVariableType(_variable_type type); 131 132 static _variable_type getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows); 133 134 static unsigned int getNumberOfColumnsForVariableType(_variable_type type); 135 static unsigned int getNumberOfComponentsForVariableType(_variable_type type); 136 static unsigned int getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type); 137 static unsigned int getNumberOfRowsForVariableType(_variable_type type); 138 139 static _variable_type getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a, 140 _variable_type type_matrix_b); 141 142 static std::string getStringForVariableTypeValue(_variable_type type, const unsigned char *data_ptr); 143 144 static _variable_type getTransposedMatrixVariableType(_variable_type type); 145 146 static _variable_type getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows); 147 148 static std::string getVariableTypeString(_variable_type type); 149 150 static bool isGLVersionAtLeast(const glw::Functions &gl, glw::GLint required_major, glw::GLint required_minor); 151 152 static bool isMatrixVariableType(_variable_type type); 153 static bool isScalarVariableType(_variable_type type); 154 155 static void replaceToken(const glw::GLchar *token, size_t &search_position, const glw::GLchar *text, 156 std::string &string); 157 }; 158 159 /** Make sure errors as per spec are generated for new entry-points. 160 * 161 * a) Make sure GL_INVALID_OPERATION is generated by glUniform*() and 162 * glUniformMatrix*() functions if there is no current program object. 163 * b) Make sure GL_INVALID_OPERATION is generated by glUniform*() if 164 * the size of the uniform variable declared in the shader does not 165 * match the size indicated by the command. 166 * c) Make sure GL_INVALID_OPERATION is generated if glUniform*() and 167 * glUniformMatrix*() are used to load a uniform variable of type 168 * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4, 169 * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array 170 * of these. 171 * d) Make sure GL_INVALID_OPERATION is generated if glUniform*() and 172 * glUniformMatrix*() are used to load incompatible double-typed 173 * uniforms, as presented below: 174 * 175 * I. double-typed uniform configured by glUniform2d(); 176 * II. double-typed uniform configured by glUniform3d(); 177 * III. double-typed uniform configured by glUniform4d(); 178 * IV. double-typed uniform configured by glUniformMatrix*(); 179 * V. dvec2-typed uniform configured by glUniform1d(); 180 * VI. dvec2-typed uniform configured by glUniform3d(); 181 * VII. dvec2-typed uniform configured by glUniform4d(); 182 * VIII. dvec2-typed uniform configured by glUniformMatrix*(); 183 * 184 * (etc.) 185 * 186 * e) Make sure GL_INVALID_OPERATION is generated if <location> of 187 * glUniform*() and glUniformMatrix*() is an invalid uniform 188 * location for the current program object and location is not 189 * equal to -1. 190 * f) Make sure GL_INVALID_VALUE is generated if <count> of 191 * glUniform*() (*dv() functions only) and glUniformMatrix*() is 192 * negative. 193 * g) Make sure GL_INVALID_OPERATION is generated if <count> of 194 * glUniform*() (*dv() functions only) and glUniformMatrix*() is 195 * greater than 1 and the indicated uniform variable is not an 196 * array variable. 197 * h) Make sure GL_INVALID_OPERATION is generated if a sampler is 198 * loaded by glUniform*() and glUniformMatrix*(). 199 * i) Make sure GL_INVALID_OPERATION is generated if glUniform*() and 200 * glUniformMatrix*() is used to load values for uniforms of 201 * boolean types. 202 */ 203 class GPUShaderFP64Test1 : public deqp::TestCase 204 { 205 public: 206 /* Public methods */ 207 GPUShaderFP64Test1(deqp::Context &context); 208 209 void deinit(); 210 virtual tcu::TestNode::IterateResult iterate(); 211 212 /* Private type definitions */ 213 private: 214 typedef enum 215 { 216 UNIFORM_FUNCTION_FIRST, 217 218 UNIFORM_FUNCTION_1D = UNIFORM_FUNCTION_FIRST, 219 UNIFORM_FUNCTION_1DV, 220 UNIFORM_FUNCTION_2D, 221 UNIFORM_FUNCTION_2DV, 222 UNIFORM_FUNCTION_3D, 223 UNIFORM_FUNCTION_3DV, 224 UNIFORM_FUNCTION_4D, 225 UNIFORM_FUNCTION_4DV, 226 227 UNIFORM_FUNCTION_MATRIX2DV, 228 UNIFORM_FUNCTION_MATRIX2X3DV, 229 UNIFORM_FUNCTION_MATRIX2X4DV, 230 UNIFORM_FUNCTION_MATRIX3DV, 231 UNIFORM_FUNCTION_MATRIX3X2DV, 232 UNIFORM_FUNCTION_MATRIX3X4DV, 233 UNIFORM_FUNCTION_MATRIX4DV, 234 UNIFORM_FUNCTION_MATRIX4X2DV, 235 UNIFORM_FUNCTION_MATRIX4X3DV, 236 237 /* Always last */ 238 UNIFORM_FUNCTION_COUNT 239 } _uniform_function; 240 241 /* Private methods */ 242 const char *getUniformFunctionString(_uniform_function func); 243 const char *getUniformNameForLocation(glw::GLint location); 244 void initTest(); 245 bool isMatrixUniform(glw::GLint uniform_location); 246 bool isMatrixUniformFunction(_uniform_function func); 247 bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans(); 248 bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers(); 249 bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount(); 250 bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation(); 251 bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount(); 252 bool verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions(); 253 bool verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions(); 254 bool verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions(); 255 bool verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO(); 256 257 /* Private fields */ 258 bool m_has_test_passed; 259 glw::GLint m_po_bool_arr_uniform_location; 260 glw::GLint m_po_bool_uniform_location; 261 glw::GLint m_po_bvec2_arr_uniform_location; 262 glw::GLint m_po_bvec2_uniform_location; 263 glw::GLint m_po_bvec3_arr_uniform_location; 264 glw::GLint m_po_bvec3_uniform_location; 265 glw::GLint m_po_bvec4_arr_uniform_location; 266 glw::GLint m_po_bvec4_uniform_location; 267 glw::GLint m_po_dmat2_arr_uniform_location; 268 glw::GLint m_po_dmat2_uniform_location; 269 glw::GLint m_po_dmat2x3_arr_uniform_location; 270 glw::GLint m_po_dmat2x3_uniform_location; 271 glw::GLint m_po_dmat2x4_arr_uniform_location; 272 glw::GLint m_po_dmat2x4_uniform_location; 273 glw::GLint m_po_dmat3_arr_uniform_location; 274 glw::GLint m_po_dmat3_uniform_location; 275 glw::GLint m_po_dmat3x2_arr_uniform_location; 276 glw::GLint m_po_dmat3x2_uniform_location; 277 glw::GLint m_po_dmat3x4_arr_uniform_location; 278 glw::GLint m_po_dmat3x4_uniform_location; 279 glw::GLint m_po_dmat4_arr_uniform_location; 280 glw::GLint m_po_dmat4_uniform_location; 281 glw::GLint m_po_dmat4x2_arr_uniform_location; 282 glw::GLint m_po_dmat4x2_uniform_location; 283 glw::GLint m_po_dmat4x3_arr_uniform_location; 284 glw::GLint m_po_dmat4x3_uniform_location; 285 glw::GLint m_po_double_arr_uniform_location; 286 glw::GLint m_po_double_uniform_location; 287 glw::GLint m_po_dvec2_arr_uniform_location; 288 glw::GLint m_po_dvec2_uniform_location; 289 glw::GLint m_po_dvec3_arr_uniform_location; 290 glw::GLint m_po_dvec3_uniform_location; 291 glw::GLint m_po_dvec4_arr_uniform_location; 292 glw::GLint m_po_dvec4_uniform_location; 293 glw::GLint m_po_float_arr_uniform_location; 294 glw::GLint m_po_float_uniform_location; 295 glw::GLint m_po_int_arr_uniform_location; 296 glw::GLint m_po_int_uniform_location; 297 glw::GLint m_po_ivec2_arr_uniform_location; 298 glw::GLint m_po_ivec2_uniform_location; 299 glw::GLint m_po_ivec3_arr_uniform_location; 300 glw::GLint m_po_ivec3_uniform_location; 301 glw::GLint m_po_ivec4_arr_uniform_location; 302 glw::GLint m_po_ivec4_uniform_location; 303 glw::GLint m_po_sampler_uniform_location; 304 glw::GLint m_po_uint_arr_uniform_location; 305 glw::GLint m_po_uint_uniform_location; 306 glw::GLint m_po_uvec2_arr_uniform_location; 307 glw::GLint m_po_uvec2_uniform_location; 308 glw::GLint m_po_uvec3_arr_uniform_location; 309 glw::GLint m_po_uvec3_uniform_location; 310 glw::GLint m_po_uvec4_arr_uniform_location; 311 glw::GLint m_po_uvec4_uniform_location; 312 glw::GLint m_po_vec2_arr_uniform_location; 313 glw::GLint m_po_vec2_uniform_location; 314 glw::GLint m_po_vec3_arr_uniform_location; 315 glw::GLint m_po_vec3_uniform_location; 316 glw::GLint m_po_vec4_arr_uniform_location; 317 glw::GLint m_po_vec4_uniform_location; 318 glw::GLuint m_po_id; 319 glw::GLuint m_vs_id; 320 }; 321 322 /** Implements "Subtest 2" from CTS_ARB_gpu_shader_fp64, description follows: 323 * Make sure that it is possible to use: 324 * 325 * a) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 2) double uniforms 326 * in a default uniform block of a vertex shader; 327 * b) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4) dvec2 uniforms 328 * in a default uniform block of a vertex shader; 329 * c) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 6) dvec3 uniforms 330 * in a default uniform block of a vertex shader; 331 * d) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 8) dvec4 uniforms 332 * in a default uniform block of a vertex shader; 333 * e) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 16) dmat2, dmat2x3, 334 * dmat2x4, dmat3x2, dmat4x2 uniforms in a default uniform block 335 * of a vertex shader; (each type tested in a separate shader) 336 * f) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 24) dmat3, dmat3x4, 337 * dmat4x3 uniforms in a default uniform block of a vertex shader; 338 * (each type tested in a separate shader) 339 * g) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 32) dmat4 uniforms 340 * in a default uniform block of a vertex shader; 341 * h) arrayed cases of a)-g), where the array size is 3 and the 342 * amount of uniforms that can be supported should be divided 343 * by three as well. 344 * i) cases a)-h), where "vertex shader" is replaced by "fragment 345 * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to 346 * GL_MAX_FRAGMENT_UNIFORM_COMPONENTS; 347 * j) cases a)-h) where "vertex shader" is replaced by "geometry 348 * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to 349 * GL_MAX_GEOMETRY_UNIFORM_COMPONENTS; 350 * k) cases a)-h) where "vertex shader" is replaced by "compute 351 * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to 352 * GL_MAX_COMPUTE_UNIFORM_COMPONENTS; 353 * l) cases a)-h) where "vertex shader" is replaced by "tessellation 354 * control shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed 355 * to GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS; 356 * m) cases a)-h) where "vertex shader" is replaced by "tessellation 357 * evaluation shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is 358 * changed to GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS; 359 * 360 * For each case considered, the test should only define uniforms 361 * for the stage the test is dealing with. 362 * 363 * All uniform components considered as a whole should be assigned 364 * unique values, where the very first uniform component is set to 365 * a value of 1, the one following set to 2, the one afterward set 366 * to 3, and so on. 367 * 368 * For "vertex shader" cases, the test should work by creating 369 * a program object, to which a vertex shader (as per test case) 370 * would be attached. The shader would then read all the uniforms, 371 * verify their values are correct and then set an output bool 372 * variable to true if the validation passed, false otherwise. 373 * The test should draw 1024 points, XFB the contents of the output 374 * variable and verify the result. 375 * 376 * For "geometry shader" cases, the test should create a program object 377 * and attach vertex and geometry shaders to it. The vertex shader 378 * should set gl_Position to (1, 0, 0, 1). The geometry shader 379 * should accept points on input and emit 1 point, read all the 380 * uniforms, verify their values are correct and then set an output 381 * bool variable to true if the validation passed, false otherwise. 382 * The test should draw 1024 points, XFB the contents of the output 383 * variable and verify the result. 384 * 385 * For "tessellation control shader" cases, the test should create 386 * a program object and attach vertex and tessellation control shaders 387 * to the program object. The vertex shader should set gl_Position 388 * to (1, 0, 0, 1). The tessellation control shader should output 389 * a single vertex per patch and set all inner/outer tessellation. 390 * levels to 1. The shader should read all the uniforms, verify 391 * their values are correct and then set an output per-vertex bool 392 * variable to true if the validation passed, false otherwise. The 393 * test should draw 1024 patches, XFB the contents of the output 394 * variable and verify the result. 395 * 396 * For "tessellation evaluation shader" cases, the test should create 397 * a program object and attach vertex, tessellation control and 398 * tessellation evaluation shaders to the program object. The vertex 399 * shader should set gl_Position to (1, 0, 0, 1). The tessellation 400 * control shader should behave as in "tessellation control shader" 401 * case. The tessellation evaluation shader should accept isolines 402 * and work in point mode. The shader should read all the uniforms, 403 * verify their values are correct and then set an output 404 * bool variable to true if the validation passed, false otherwise. 405 * The test should draw 1024 patches, XFB the contents of the output 406 * variable and verify the result. 407 * 408 * For "fragment shader" cases, the test should create a program object 409 * and attach vertex and fragment shaders to the program object. The 410 * vertex shader should set gl_Position to 4 different values 411 * (depending on gl_VertexID value), defining screen-space corners 412 * for a GL_TRIANGLE_FAN-based draw call. The fragment shader should 413 * read all the uniforms, verify their values are correct and then 414 * set the output color to vec4(1) if the validation passed, vec4(0) 415 * otherwise. The test should draw 4 vertices making up a triangle fan, 416 * read the rasterized image and confirm the result. 417 * 418 * For all cases apart from "fragment shader", the test should also 419 * verify that glGetTransformFeedbackVarying() reports correct 420 * properties for the uniforms. 421 * 422 * The test should also verify that in all cases glGetActiveUniform() 423 * reports correct properties for all the defined uniforms. 424 **/ 425 class GPUShaderFP64Test2 : public deqp::TestCase 426 { 427 public: 428 /* Public methods */ 429 GPUShaderFP64Test2(deqp::Context &context); 430 431 virtual void deinit(); 432 virtual tcu::TestNode::IterateResult iterate(); 433 434 private: 435 /* Private types */ 436 typedef glw::GLint captured_varying_type; 437 typedef void(GLW_APIENTRY *arbDispatchComputeFunc)(glw::GLuint num_groups_x, glw::GLuint num_groups_y, 438 glw::GLuint num_groups_z); 439 440 /** Shader stage enumeration 441 * 442 */ 443 enum shaderStage 444 { 445 COMPUTE_SHADER, 446 FRAGMENT_SHADER, 447 GEOMETRY_SHADER, 448 TESS_CTRL_SHADER, 449 TESS_EVAL_SHADER, 450 VERTEX_SHADER, 451 }; 452 453 /** Store details about uniform type 454 * 455 **/ 456 struct uniformTypeDetails 457 { 458 uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows); 459 460 glw::GLuint m_n_columns; 461 glw::GLuint m_n_rows; 462 glw::GLenum m_type; 463 std::string m_type_name; 464 }; 465 466 /** Store details about uniform 467 * 468 **/ 469 struct uniformDetails 470 { 471 glw::GLuint m_array_stride; 472 glw::GLuint m_matrix_stride; 473 glw::GLuint m_offset; 474 }; 475 476 /* Provate methods */ 477 glw::GLenum getCapturedPrimitiveType(shaderStage shader_stage) const; 478 glw::GLenum getDrawPrimitiveType(shaderStage shader_stage) const; 479 glw::GLuint getMaxUniformComponents(shaderStage shader_stage) const; 480 glw::GLuint getMaxUniformBlockSize() const; 481 glw::GLuint getRequiredComponentsNumber(const uniformTypeDetails &uniform_type) const; 482 glw::GLuint getUniformTypeMemberSize(const uniformTypeDetails &uniform_type) const; 483 glw::GLuint getAmountUniforms(shaderStage shader_stage, const uniformTypeDetails &uniform_type) const; 484 const glw::GLchar *getShaderStageName(shaderStage shader_stage) const; 485 486 void inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms, const uniformTypeDetails &uniform_type, 487 glw::GLint &out_buffer_size, uniformDetails &out_offsets, 488 glw::GLuint &uniform_block_index) const; 489 490 void prepareBoilerplateShader(const glw::GLchar *stage_specific_layout, const glw::GLchar *stage_specific_main_body, 491 std::string &out_source_code) const; 492 493 void prepareProgram(shaderStage shader_stage, const uniformTypeDetails &uniform_type, 494 Utils::programInfo &out_program_info) const; 495 496 void prepareShaderStages(); 497 498 void prepareTestShader(const glw::GLchar *stage_specific_layout, const glw::GLchar *uniform_definitions, 499 const glw::GLchar *in_variable_definitions, const glw::GLchar *out_variable_definitions, 500 const glw::GLchar *uniform_verification, const glw::GLchar *stage_specific_main_body, 501 std::string &out_source_code) const; 502 503 void prepareTestComputeShader(const glw::GLchar *uniform_definitions, const glw::GLchar *uniform_verification, 504 std::string &out_source_code) const; 505 506 void prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails &uniform_type, 507 std::string &out_source_code) const; 508 509 void prepareUniforms(shaderStage shader_stage, const uniformTypeDetails &uniform_type, 510 const Utils::programInfo &program_info) const; 511 512 void prepareUniformTypes(); 513 514 void prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails &uniform_type, 515 std::string &out_source_code) const; 516 517 bool test(shaderStage shader_stage, const uniformTypeDetails &uniform_type) const; 518 519 void testBegin(glw::GLuint program_id, shaderStage shader_stage) const; 520 521 void testEnd(shaderStage shader_stage) const; 522 void testInit(); 523 bool verifyResults(shaderStage shader_stage) const; 524 525 /* Private constants */ 526 static const glw::GLuint m_n_captured_results; 527 static const glw::GLint m_result_failure; 528 static const glw::GLint m_result_success; 529 static const glw::GLuint m_texture_width; 530 static const glw::GLuint m_texture_height; 531 static const glw::GLuint m_transform_feedback_buffer_size; 532 533 static const glw::GLchar *m_uniform_block_name; 534 535 static const glw::GLenum ARB_MAX_COMPUTE_UNIFORM_COMPONENTS; 536 537 /* Private fields */ 538 arbDispatchComputeFunc m_pDispatchCompute; 539 540 std::vector<shaderStage> m_shader_stages; 541 std::vector<uniformTypeDetails> m_uniform_types; 542 543 glw::GLuint m_framebuffer_id; 544 glw::GLuint m_texture_id; 545 glw::GLuint m_transform_feedback_buffer_id; 546 glw::GLuint m_uniform_buffer_id; 547 glw::GLuint m_vertex_array_object_id; 548 }; 549 550 /** Implements "Subtest 3" from CTS_ARB_gpu_shader_fp64, description follows: 551 * 552 * Make sure it is possible to use new types for member declaration 553 * in a named uniform block. 554 * The following members should be defined in the block: 555 * 556 * ivec3 unused1[3]; 557 * double double_value; 558 * bool unused2; 559 * dvec2 dvec2_value; 560 * bvec3 unused3; 561 * dvec3 dvec3_value; 562 * int unused4[3]; 563 * dvec4 dvec4_value; 564 * bool unused5; 565 * bool unused6[2]; 566 * dmat2 dmat2_value; 567 * dmat3 dmat3_value; 568 * bool unused7; 569 * dmat4 dmat4_value; 570 * dmat2x3 dmat2x3_value; 571 * uvec3 unused8; 572 * dmat2x4 dmat2x4_value; 573 * dmat3x2 dmat3x2_value; 574 * bool unused9; 575 * dmat3x4 dmat3x4_value; 576 * int unused10; 577 * dmat4x2 dmat4x2_value; 578 * dmat4x3 dmat4x3_value; 579 * 580 * std140, packed and shared layout qualifiers should be tested 581 * separately. 582 * 583 * For the purpose of the test, a buffer object, storage of which 584 * is to be used for the uniform buffer, should be filled with 585 * predefined values at member-specific offsets. These values 586 * should then be read in each shader stage covered by the test 587 * and verified. 588 * 589 * For std140 layout qualifier, the test should additionally verify 590 * the offsets assigned by GL implementation are as per specification. 591 * 592 * The following shader stages should be defined for a program object 593 * to be used by the test: 594 * 595 * 1) Vertex shader stage; 596 * 2) Geometry shader stage; 597 * 3) Tessellation control shader stage; 598 * 4) Tessellation evaluation shader stage; 599 * 5) Fragment shader stage; 600 * 601 * Vertex shader stage should set a stage-specific bool variable to 602 * true if all uniform buffer members are assigned valid values, 603 * false otherwise. 604 * 605 * Geometry shader stage should take points on input and emit a single 606 * point. Similarly to vertex shader stage, it should set a stage-specific 607 * bool variable to true, if all uniform buffer members are determined 608 * to expose valid values, false otherwise. 609 * Geometry shader stage should pass the result value from the vertex 610 * shader stage down the rendering pipeline using a new output variable, 611 * set to the value of the variable exposed by vertex shader stage. 612 * 613 * Tessellation control shader stage should set all inner/outer 614 * tessellation levels to 1 and output 1 vertex per patch. 615 * The verification should be carried out as in previous stages. 616 * TC shader stage should also define stage-specific output variables 617 * for vertex and geometry shader stages and set them to relevant 618 * values, similar to what's been described for geometry shader stage. 619 * 620 * Tessellation evaluation shader stage should take quads on 621 * input. It should be constructed in a way that will make it 622 * generate a quad that occupies whole screen-space. This is necessary 623 * to perform validation of the input variables in fragment shader 624 * stage. 625 * The verification should be carried out as in previous stages. 626 * TE stage should pass down validation results from previous stages 627 * in a similar manner as was described for TC shader stage. 628 * 629 * Fragment shader stage should verify all the uniform buffer members 630 * carry valid values. Upon success, it should output vec4(1) to the 631 * only output variable. Otherwise, it should set it to vec4(0). 632 * 633 * XFB should be used to read all the output variables defined in TE 634 * stage that carry result information from all the rendering stages 635 * until tessellation evaluation shader stage. The test passes, if 636 * all result values are set to true and the draw buffer is filled 637 * with vec4(1). 638 **/ 639 class GPUShaderFP64Test3 : public deqp::TestCase 640 { 641 public: 642 /* Public methods */ 643 GPUShaderFP64Test3(deqp::Context &); ~GPUShaderFP64Test3()644 virtual ~GPUShaderFP64Test3() 645 { 646 } 647 648 /* Public methods inherited from TestCase */ 649 virtual void deinit(void); 650 virtual tcu::TestNode::IterateResult iterate(void); 651 652 private: 653 /* Private types */ 654 655 /** Enumerate shader stages 656 * 657 **/ 658 enum shaderStage 659 { 660 FRAGMENT_SHADER, 661 GEOMETRY_SHADER, 662 TESS_CONTROL_SHADER, 663 TESS_EVAL_SHADER, 664 VERTEX_SHADER, 665 }; 666 667 /** Enumerate buffer data layouts 668 * 669 **/ 670 enum uniformDataLayout 671 { 672 PACKED, 673 SHARED, 674 STD140, 675 }; 676 677 /** Store details about "double precision" uniforms 678 * 679 **/ 680 struct uniformDetails 681 { uniformDetailsgl4cts::GPUShaderFP64Test3::uniformDetails682 uniformDetails(glw::GLint expected_std140_offset, const glw::GLchar *name, glw::GLuint n_columns, 683 glw::GLuint n_elements, const glw::GLchar *type_name) 684 : m_expected_std140_offset(expected_std140_offset) 685 , m_name(name) 686 , m_n_columns(n_columns) 687 , m_n_elements(n_elements) 688 , m_type_name(type_name) 689 { 690 /* Nothing to be done */ 691 } 692 693 glw::GLint m_expected_std140_offset; 694 const glw::GLchar *m_name; 695 glw::GLuint m_n_columns; 696 glw::GLuint m_n_elements; 697 const glw::GLchar *m_type_name; 698 }; 699 700 /** Store details about program object 701 * 702 **/ 703 struct programInfo 704 { 705 706 programInfo(); 707 708 void compile(deqp::Context &context, glw::GLuint shader_id, const glw::GLchar *shader_code) const; 709 710 void deinit(deqp::Context &context); 711 712 void init(deqp::Context &context, const std::vector<uniformDetails> m_uniform_details, 713 const glw::GLchar *fragment_shader_code, const glw::GLchar *geometry_shader_code, 714 const glw::GLchar *tesselation_control_shader_code, 715 const glw::GLchar *tesselation_evaluation_shader_code, const glw::GLchar *vertex_shader_code); 716 717 void link(deqp::Context &context) const; 718 719 static const glw::GLint m_invalid_uniform_offset; 720 static const glw::GLint m_invalid_uniform_matrix_stride; 721 static const glw::GLint m_non_matrix_uniform_matrix_stride; 722 723 glw::GLuint m_fragment_shader_id; 724 glw::GLuint m_geometry_shader_id; 725 glw::GLuint m_program_object_id; 726 glw::GLuint m_tesselation_control_shader_id; 727 glw::GLuint m_tesselation_evaluation_shader_id; 728 glw::GLuint m_vertex_shader_id; 729 730 glw::GLint m_buffer_size; 731 glw::GLuint m_uniform_block_index; 732 733 std::vector<glw::GLint> m_uniform_offsets; 734 std::vector<glw::GLint> m_uniform_matrix_strides; 735 }; 736 737 /* Private methods */ 738 glw::GLdouble getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const; 739 const programInfo &getProgramInfo(uniformDataLayout uniform_data_layout) const; 740 const glw::GLchar *getUniformLayoutName(uniformDataLayout uniform_data_layout) const; 741 742 void prepareProgram(programInfo &program_info, uniformDataLayout uniform_data_layout) const; 743 744 bool prepareUniformBuffer(const programInfo &program_info, bool verify_offsets) const; 745 746 void testInit(); 747 bool test(uniformDataLayout uniform_data_layout) const; 748 bool verifyResults() const; 749 750 void writeMainBody(std::ostream &stream, shaderStage shader_stage) const; 751 752 void writePreamble(std::ostream &stream, shaderStage shader_stage) const; 753 754 void writeUniformBlock(std::ostream &stream, uniformDataLayout uniform_data_layout) const; 755 756 void writeVaryingDeclarations(std::ostream &stream, shaderStage shader_stage) const; 757 758 void writeVaryingPassthrough(std::ostream &stream, shaderStage shader_stage) const; 759 760 /* Private fields */ 761 /* Constants */ 762 static const glw::GLuint m_result_failure; 763 static const glw::GLuint m_result_success; 764 765 static const glw::GLchar *m_uniform_block_name; 766 static const glw::GLchar *m_uniform_block_instance_name; 767 768 static const glw::GLchar *m_varying_name_fs_out_fs_result; 769 static const glw::GLchar *m_varying_name_gs_fs_gs_result; 770 static const glw::GLchar *m_varying_name_gs_fs_tcs_result; 771 static const glw::GLchar *m_varying_name_gs_fs_tes_result; 772 static const glw::GLchar *m_varying_name_gs_fs_vs_result; 773 static const glw::GLchar *m_varying_name_tcs_tes_tcs_result; 774 static const glw::GLchar *m_varying_name_tcs_tes_vs_result; 775 static const glw::GLchar *m_varying_name_tes_gs_tcs_result; 776 static const glw::GLchar *m_varying_name_tes_gs_tes_result; 777 static const glw::GLchar *m_varying_name_tes_gs_vs_result; 778 static const glw::GLchar *m_varying_name_vs_tcs_vs_result; 779 780 /* GL objects */ 781 glw::GLuint m_color_texture_id; 782 glw::GLuint m_framebuffer_id; 783 glw::GLuint m_transform_feedback_buffer_id; 784 glw::GLuint m_uniform_buffer_id; 785 glw::GLuint m_vertex_array_object_id; 786 787 /* Random values used by getExpectedValue */ 788 glw::GLdouble m_base_element; 789 glw::GLdouble m_base_type_ordinal; 790 791 /* Program details, one per data layout */ 792 programInfo m_packed_program; 793 programInfo m_shared_program; 794 programInfo m_std140_program; 795 796 /* Storage for uniforms' details */ 797 std::vector<uniformDetails> m_uniform_details; 798 }; 799 800 /** Make sure glGetUniformdv() reports correct values, as assigned 801 * by corresponding glUniform*() functions, for the following 802 * uniform types: 803 * 804 * a) double; 805 * b) dvec2; 806 * c) dvec3; 807 * d) dvec4; 808 * e) Arrays of a)-d); 809 * f) a)-d) defined in single-dimensional arrays built of the same 810 * structure. 811 * 812 * These uniforms should be defined in the default uniform block, 813 * separately in each stage defined for the following program 814 * objects: 815 * 816 * a) A program object consisting of a fragment, geometry, tessellation 817 * control, tessellation evaluation, vertex shader stages. 818 * b) A program object consisting of a compute shader stage. 819 * 820 * If GL_ARB_program_interface_query is supported, the test should 821 * also verify that the following API functions work correctly with 822 * the described uniforms: 823 * 824 * - glGetProgramResourceiv() (query GL_TYPE and GL_ARRAY_SIZE 825 * properties of GL_UNIFORM interface 826 * for all uniforms); 827 * - glGetProgramResourceIndex() (use GL_UNIFORM interface) 828 * - glGetProgramResourceName() (use GL_UNIFORM interface) 829 * 830 * To verify the values returned by these functions, values returned 831 * by relevant glGetUniform*() API functions should be used as 832 * reference. 833 */ 834 class GPUShaderFP64Test4 : public deqp::TestCase 835 { 836 public: 837 /* Public methods */ 838 GPUShaderFP64Test4(deqp::Context &context); 839 840 virtual void deinit(); 841 virtual tcu::TestNode::IterateResult iterate(); 842 843 private: 844 /* Private type definitions */ 845 /* Defines a type used as a data container for one of the test cases */ 846 typedef std::pair<glw::GLint /* uniform location */, double * /* value(s) assigned */> uniform_value_pair; 847 848 /* Holds uniform locations & associated values. used by one of the test cases */ 849 struct _data 850 { 851 _data(); 852 853 double uniform_double; 854 double uniform_double_arr[2]; 855 double uniform_dvec2[2]; 856 double uniform_dvec2_arr[4]; 857 double uniform_dvec3[3]; 858 double uniform_dvec3_arr[6]; 859 double uniform_dvec4[4]; 860 double uniform_dvec4_arr[8]; 861 862 glw::GLint uniform_location_double; 863 glw::GLint uniform_location_double_arr[2]; 864 glw::GLint uniform_location_dvec2; 865 glw::GLint uniform_location_dvec2_arr[2]; 866 glw::GLint uniform_location_dvec3; 867 glw::GLint uniform_location_dvec3_arr[2]; 868 glw::GLint uniform_location_dvec4; 869 glw::GLint uniform_location_dvec4_arr[2]; 870 }; 871 872 /** Holds uniform location & properties information. Used by one of the test cases. */ 873 struct _program_interface_query_test_item 874 { 875 glw::GLint expected_array_size; 876 std::string name; 877 glw::GLenum expected_type; 878 glw::GLint location; 879 }; 880 881 /** Holds information on all uniforms defined for a single shader stage. */ 882 struct _stage_data 883 { 884 _data uniform_structure_arrays[2]; 885 _data uniforms; 886 }; 887 888 /* Private methods */ 889 void generateUniformValues(); 890 void initProgramObjects(); 891 void initTest(); 892 void initUniformValues(); 893 bool verifyProgramInterfaceQuerySupport(); 894 bool verifyUniformValues(); 895 896 /* Private declarations */ 897 bool m_has_test_passed; 898 char *m_uniform_name_buffer; 899 900 glw::GLuint m_cs_id; 901 glw::GLuint m_fs_id; 902 glw::GLuint m_gs_id; 903 glw::GLuint m_po_cs_id; 904 glw::GLuint m_po_noncs_id; 905 glw::GLuint m_tc_id; 906 glw::GLuint m_te_id; 907 glw::GLuint m_vs_id; 908 909 _stage_data m_data_cs; 910 _stage_data m_data_fs; 911 _stage_data m_data_gs; 912 _stage_data m_data_tc; 913 _stage_data m_data_te; 914 _stage_data m_data_vs; 915 }; 916 917 /** Make sure the following implicit conversion work correctly: 918 * 919 * a) int -> double; 920 * b) ivec2 -> dvec2; 921 * c) ivec3 -> dvec3; 922 * d) ivec4 -> dvec4; 923 * e) uint -> double; 924 * f) uvec2 -> dvec2; 925 * g) uvec3 -> dvec3; 926 * h) uvec4 -> dvec4; 927 * i) float -> double; 928 * j) vec2 -> dvec2; 929 * k) vec3 -> dvec3; 930 * l) vec4 -> dvec4; 931 * m) mat2 -> dmat2; 932 * n) mat3 -> dmat3; 933 * o) mat4 -> dmat4; 934 * p) mat2x3 -> dmat2x3; 935 * q) mat2x4 -> dmat2x4; 936 * r) mat3x2 -> dmat3x2; 937 * s) mat3x4 -> dmat3x4; 938 * t) max4x2 -> dmat4x2; 939 * u) mat4x3 -> dmat4x3; 940 * 941 * The test should also verify the following explicit conversions 942 * are supported (that is: when the right-side value is used as 943 * an argument to a constructor of left-side type): 944 * 945 * a) int -> double; 946 * b) uint -> double; 947 * c) float -> double; 948 * d) double -> int; 949 * e) double -> uint; 950 * f) double -> float; 951 * g) double -> bool; 952 * h) bool -> double; 953 * 954 * For each conversion, the test should create a program object and 955 * attach a vertex shader to it. 956 * The shader should define an uniform named "base_value", with 957 * its type dependent on the type defined left-side for particular 958 * case, as defined below: 959 * 960 * [base_value type: bool] 961 * bool 962 * 963 * [base_value type: double] 964 * double 965 * 966 * [base_value type: int] 967 * int, ivec2, ivec3, ivec4 968 * 969 * [base_value type: uint] 970 * uint, uvec2, uvec3, uvec4 971 * 972 * [base_value type: float] 973 * float, vec2, vec3, vec4, 974 * mat2, mat3, mat4, mat2x3, 975 * mat2x4, mat3x2, mat3x4, mat4x2, 976 * mat4x3 977 * 978 * For each tested pair, it should build the "source" value/vector/matrix 979 * by taking the value specified in uniform of the same type as the one 980 * that is to be used as source, and use it for zeroth component. First 981 * component should be larger by one, second component should be bigger 982 * by two, and so on. 983 * Once the source value/vector/matrix is defined, the casting operation 984 * should be performed, giving a "destination" value/vector/matrix of 985 * type as defined for particular case. 986 * The resulting value should be XFBed out to the test implementation. 987 * The comparison should be performed on CPU to ensure validity of 988 * the resulting data. 989 * 990 * A swizzling operator should be used where possible when setting 991 * the output variables to additionally check that swizzling works 992 * correctly for multi-component double-precision types. 993 * 994 * The program object should be used for the following base values: 995 * 996 * a) -25.12065 997 * b) 0.0 998 * c) 0.001 999 * d) 1.0 1000 * e) 256.78901 1001 * 1002 * An epsilon of 1e-5 should be used for floating-point comparisons. 1003 **/ 1004 class GPUShaderFP64Test5 : public deqp::TestCase 1005 { 1006 public: 1007 /* Public methods */ 1008 GPUShaderFP64Test5(deqp::Context &context); 1009 1010 virtual void deinit(); 1011 virtual tcu::TestNode::IterateResult iterate(); 1012 1013 private: 1014 /* Private type definitions */ 1015 /* Defines swizzle operators used by shaders generated by the test */ 1016 enum _swizzle_type 1017 { 1018 SWIZZLE_TYPE_NONE, 1019 1020 SWIZZLE_TYPE_XWZY, 1021 SWIZZLE_TYPE_XZXY, 1022 SWIZZLE_TYPE_XZY, 1023 SWIZZLE_TYPE_XZYW, 1024 1025 SWIZZLE_TYPE_Y, 1026 SWIZZLE_TYPE_YX, 1027 SWIZZLE_TYPE_YXX, 1028 SWIZZLE_TYPE_YXXY, 1029 1030 SWIZZLE_TYPE_Z, 1031 SWIZZLE_TYPE_ZY, 1032 1033 SWIZZLE_TYPE_W, 1034 SWIZZLE_TYPE_WX, 1035 }; 1036 1037 /* Defines cast type to be used for specific test case */ 1038 enum _test_case_type 1039 { 1040 TEST_CASE_TYPE_EXPLICIT, 1041 TEST_CASE_TYPE_IMPLICIT, 1042 1043 /* Always last */ 1044 TEST_CASE_TYPE_UNKNOWN 1045 }; 1046 1047 /* Holds a complete description of a single test case */ 1048 struct _test_case 1049 { 1050 _test_case_type type; 1051 1052 Utils::_variable_type src_type; 1053 Utils::_variable_type dst_type; 1054 1055 std::string shader_body; 1056 }; 1057 1058 /* Private methods */ 1059 bool executeIteration(const _test_case &test_case); 1060 1061 void getSwizzleTypeProperties(_swizzle_type type, std::string *out_swizzle_string, unsigned int *out_n_components, 1062 unsigned int *out_component_order); 1063 1064 std::string getVertexShaderBody(const _test_case &test_case); 1065 void initIteration(_test_case &test_case); 1066 void initTest(); 1067 1068 bool verifyXFBData(const unsigned char *data_ptr, const _test_case &test_case); 1069 1070 void deinitInteration(); 1071 1072 /* Private declarations */ 1073 unsigned char *m_base_value_bo_data; 1074 glw::GLuint m_base_value_bo_id; 1075 bool m_has_test_passed; 1076 glw::GLint m_po_base_value_attribute_location; 1077 glw::GLint m_po_id; 1078 glw::GLuint m_vao_id; 1079 glw::GLint m_vs_id; 1080 glw::GLuint m_xfb_bo_id; 1081 unsigned int m_xfb_bo_size; 1082 1083 float m_base_values[5]; /* as per test spec */ 1084 _swizzle_type m_swizzle_matrix[4 /* max number of dst components */][4 /* max number of src components */]; 1085 }; 1086 1087 /** The test should verify it is a compilation error to perform the 1088 * following casts in the shader: 1089 * 1090 * a) int [2] -> double; 1091 * b) ivec2 [2] -> dvec2; 1092 * c) ivec3 [2] -> dvec3; 1093 * d) ivec4 [2] -> dvec4; 1094 * e) uint [2] -> double; 1095 * f) uvec2 [2] -> dvec2; 1096 * g) uvec3 [2] -> dvec3; 1097 * h) uvec4 [2] -> dvec4; 1098 * i) float [2] -> double; 1099 * j) vec2 [2] -> dvec2; 1100 * k) vec3 [2] -> dvec3; 1101 * l) vec4 [2] -> dvec4; 1102 * m) mat2 [2] -> dmat2; 1103 * n) mat3 [2] -> dmat3; 1104 * o) mat4 [2] -> dmat4; 1105 * p) mat2x3[2] -> dmat2x3; 1106 * q) mat2x4[2] -> dmat2x4; 1107 * r) mat3x2[2] -> dmat3x2; 1108 * s) mat3x4[2] -> dmat3x4; 1109 * t) mat4x2[2] -> dmat4x2; 1110 * u) mat4x3[2] -> dmat4x3; 1111 * 1112 * The test should also attempt to cast all types defined left-side 1113 * in a)-u) to structures, where the only variable embedded inside 1114 * the structure would be defined on the right-side of the test 1115 * case considered. 1116 * 1117 * The following shader stages should be considered for the purpose 1118 * of the test: 1119 * 1120 * 1) Fragment shader stage; 1121 * 2) Geometry shader stage; 1122 * 3) Tessellation control shader stage; 1123 * 4) Tessellation evaluation shader stage; 1124 * 5) Vertex shader stage; 1125 * 6) Compute shader stage; 1126 **/ 1127 class GPUShaderFP64Test6 : public deqp::TestCase 1128 { 1129 public: 1130 /* Public methods */ 1131 GPUShaderFP64Test6(deqp::Context &context); 1132 1133 virtual void deinit(); 1134 virtual tcu::TestNode::IterateResult iterate(); 1135 1136 private: 1137 /* Private type definitions */ 1138 1139 /* Holds a complete description of a single test case */ 1140 struct _test_case 1141 { 1142 unsigned int src_array_size; 1143 Utils::_variable_type src_type; 1144 Utils::_variable_type dst_type; 1145 1146 bool wrap_dst_type_in_structure; 1147 1148 std::string cs_shader_body; 1149 std::string fs_shader_body; 1150 std::string gs_shader_body; 1151 std::string tc_shader_body; 1152 std::string te_shader_body; 1153 std::string vs_shader_body; 1154 }; 1155 1156 /* Private methods */ 1157 bool executeIteration(const _test_case &test_case); 1158 std::string getComputeShaderBody(const _test_case &test_case); 1159 std::string getFragmentShaderBody(const _test_case &test_case); 1160 std::string getGeometryShaderBody(const _test_case &test_case); 1161 std::string getTessellationControlShaderBody(const _test_case &test_case); 1162 std::string getTessellationEvaluationShaderBody(const _test_case &test_case); 1163 std::string getVertexShaderBody(const _test_case &test_case); 1164 1165 void initTest(); 1166 void initIteration(_test_case &test_case); 1167 1168 /* Private declarations */ 1169 glw::GLuint m_cs_id; 1170 glw::GLuint m_fs_id; 1171 glw::GLuint m_gs_id; 1172 glw::GLuint m_tc_id; 1173 glw::GLuint m_te_id; 1174 glw::GLuint m_vs_id; 1175 1176 bool m_has_test_passed; 1177 }; 1178 1179 /** Make sure that double-precision types (double, dvec2, dvec3, 1180 * dvec4, dmat2, dmat3, dmat4, dmat2x3, dmat2x4, dmat3x2, dmat3x4, 1181 * dmat4x2, dmat4x2) and arrays of those: 1182 * 1183 * a) can be used as varyings (excl. vertex shader inputs *if* 1184 * GL_ARB_vertex_attrib_64bit support is *not* reported, and 1185 * fragment shader outputs; 'flat' layout qualifier should be 1186 * used for transferring data to fragment shader stage); 1187 * b) cannot be used as fragment shader output; (compilation error 1188 * expected). 1189 * c) cannot be used as fragment shader input if 'flat' layout 1190 * qualifier is missing) 1191 * 1192 * For case a), the following shader stages should be defined for 1193 * a single program object: 1194 * 1195 * 1) Vertex shader stage; 1196 * 2) Geometry shader stage; 1197 * 3) Tessellation control shader stage; 1198 * 4) Tessellation evaluation shader stage; 1199 * 5) Fragment shader stage; 1200 * 1201 * Vertex shader stage should define a single output variable for 1202 * each type considered. Each component of these output variables 1203 * should be set to predefined unique values. 1204 * Geometry shader stage should take points on input and emit a single 1205 * point. It should take all input variables from the previous stage, 1206 * add a predefined value to each component and pass it down the 1207 * rendering pipeline. 1208 * Tessellation control shader stage should set all inner/outer 1209 * tessellation levels to 1 and output 1 vertex per patch. 1210 * It should take all input variables from the previous stage, 1211 * add a predefined value to each component and pass it to 1212 * tessellation evaluation stage by using per-vertex outputs. 1213 * Tessellation evaluation shader stage should take quads on 1214 * input. It should also define all relevant input variables, as 1215 * defined by previous stage, add a predefined value to each 1216 * component and pass it to geometry shader stage. Finally, it 1217 * should be constructed in a way that will make it generate 1218 * a quad that occupies whole screen-space. This is necessary 1219 * to perform validation of the input variables in fragment shader 1220 * stage. 1221 * Fragment shader stage should take all inputs, as defined as 1222 * outputs in tessellation evaluation shader stage. It should 1223 * verify all the inputs carry valid values. Upon success, it 1224 * should output vec4(1) to the only output variable. Otherwise, 1225 * it should set it to vec4(0). 1226 **/ 1227 class GPUShaderFP64Test7 : public deqp::TestCase 1228 { 1229 public: 1230 /* Public methods */ 1231 GPUShaderFP64Test7(deqp::Context &context); 1232 1233 virtual void deinit(); 1234 virtual tcu::TestNode::IterateResult iterate(); 1235 1236 private: 1237 /* Private type definitions */ 1238 struct _variable 1239 { 1240 glw::GLint attribute_location; 1241 unsigned int array_size; 1242 Utils::_variable_type type; 1243 }; 1244 1245 typedef std::vector<_variable> _variables; 1246 typedef _variables::const_iterator _variables_const_iterator; 1247 1248 /* Private methods */ 1249 bool buildTestProgram(_variables &variables); 1250 bool compileShader(glw::GLint shader_id, const std::string &body); 1251 void configureXFBBuffer(const _variables &variables); 1252 bool executeFunctionalTest(_variables &variables); 1253 void generateXFBVaryingNames(const _variables &variables); 1254 1255 std::string getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(Utils::_variable_type input_variable_type, 1256 unsigned int array_size); 1257 1258 std::string getCodeOfFragmentShaderWithDoublePrecisionOutput(Utils::_variable_type output_variable_type, 1259 unsigned int array_size); 1260 1261 std::string getFragmentShaderBody(const _variables &variables); 1262 std::string getGeometryShaderBody(const _variables &variables); 1263 std::string getTessellationControlShaderBody(const _variables &variables); 1264 std::string getTessellationEvaluationShaderBody(const _variables &variables); 1265 1266 std::string getVariableDeclarations(const char *prefix, const _variables &variables, 1267 const char *layout_qualifier = ""); 1268 1269 std::string getVertexShaderBody(const _variables &variables); 1270 void initTest(); 1271 void logVariableContents(const _variables &variables); 1272 void releaseXFBVaryingNames(); 1273 void setInputAttributeValues(const _variables &variables); 1274 1275 /* Private declarations */ 1276 bool m_are_double_inputs_supported; 1277 std::string m_current_fs_body; 1278 std::string m_current_gs_body; 1279 std::string m_current_tc_body; 1280 std::string m_current_te_body; 1281 std::string m_current_vs_body; 1282 glw::GLuint m_fbo_id; 1283 glw::GLint m_fs_id; 1284 glw::GLint m_gs_id; 1285 bool m_has_test_passed; 1286 glw::GLint m_n_max_components_per_stage; 1287 unsigned int m_n_xfb_varyings; 1288 glw::GLint m_po_id; 1289 glw::GLint m_tc_id; 1290 glw::GLint m_te_id; 1291 glw::GLuint m_to_id; 1292 unsigned char *m_to_data; 1293 unsigned int m_to_height; 1294 unsigned int m_to_width; 1295 glw::GLuint m_xfb_bo_id; 1296 glw::GLchar **m_xfb_varyings; 1297 glw::GLuint m_vao_id; 1298 glw::GLint m_vs_id; 1299 }; 1300 1301 /** Make sure that all constructors valid for double-precision 1302 * vector/matrix types are accepted by the GLSL compiler for 1303 * all six shader stages. 1304 * 1305 * The test passes if all shaders compile successfully. 1306 **/ 1307 class GPUShaderFP64Test8 : public deqp::TestCase 1308 { 1309 public: 1310 /* Public methods */ 1311 GPUShaderFP64Test8(deqp::Context &context); 1312 1313 virtual void deinit(); 1314 virtual tcu::TestNode::IterateResult iterate(); 1315 1316 private: 1317 /* Private type definitions */ 1318 typedef std::vector<Utils::_variable_type> _argument_list; 1319 typedef _argument_list::const_iterator _argument_list_const_iterator; 1320 typedef std::vector<_argument_list> _argument_lists; 1321 typedef _argument_lists::const_iterator _argument_lists_const_iterator; 1322 1323 /* Holds a complete description of a single test case */ 1324 struct _argument_list_tree_node; 1325 1326 typedef std::vector<_argument_list_tree_node *> _argument_list_tree_nodes; 1327 typedef _argument_list_tree_nodes::const_iterator _argument_list_tree_nodes_const_iterator; 1328 typedef std::queue<_argument_list_tree_node *> _argument_list_tree_node_queue; 1329 1330 struct _argument_list_tree_node 1331 { 1332 _argument_list_tree_nodes children; 1333 int n_components_used; 1334 _argument_list_tree_node *parent; 1335 Utils::_variable_type type; 1336 ~_argument_list_tree_nodegl4cts::GPUShaderFP64Test8::_argument_list_tree_node1337 ~_argument_list_tree_node() 1338 { 1339 while (children.size() > 0) 1340 { 1341 _argument_list_tree_node *node_ptr = children.back(); 1342 1343 children.pop_back(); 1344 1345 delete node_ptr; 1346 node_ptr = NULL; 1347 } 1348 } 1349 }; 1350 1351 struct _test_case 1352 { 1353 _argument_list argument_list; 1354 Utils::_variable_type type; 1355 1356 std::string cs_shader_body; 1357 std::string fs_shader_body; 1358 std::string gs_shader_body; 1359 std::string tc_shader_body; 1360 std::string te_shader_body; 1361 std::string vs_shader_body; 1362 }; 1363 1364 /* Private methods */ 1365 bool executeIteration(const _test_case &test_case); 1366 _argument_lists getArgumentListsForVariableType(const Utils::_variable_type &variable_type); 1367 std::string getComputeShaderBody(const _test_case &test_case); 1368 std::string getFragmentShaderBody(const _test_case &test_case); 1369 std::string getGeneralBody(const _test_case &test_case); 1370 std::string getGeometryShaderBody(const _test_case &test_case); 1371 std::string getTessellationControlShaderBody(const _test_case &test_case); 1372 std::string getTessellationEvaluationShaderBody(const _test_case &test_case); 1373 std::string getVertexShaderBody(const _test_case &test_case); 1374 1375 void initTest(); 1376 void initIteration(_test_case &test_case); 1377 1378 /* Private declarations */ 1379 glw::GLuint m_cs_id; 1380 glw::GLuint m_fs_id; 1381 glw::GLuint m_gs_id; 1382 glw::GLuint m_tc_id; 1383 glw::GLuint m_te_id; 1384 glw::GLuint m_vs_id; 1385 1386 bool m_has_test_passed; 1387 }; 1388 1389 /** Make sure that the following operators work correctly for 1390 * double-precision floating-point scalars, vectors and matrices: 1391 * 1392 * a) + (addition) 1393 * b) - (subtraction) 1394 * c) * (multiplication) 1395 * d) / (division) 1396 * e) - (negation) 1397 * f) -- (pre-decrementation and post-decrementation) 1398 * g) ++ (pre-incrementation and post-incrementation) 1399 * 1400 * Furthermore, the following relational operators should also be 1401 * tested for double-precision floating-point expressions: 1402 * 1403 * a) < (less than) 1404 * b) <= (less than or equal) 1405 * c) > (greater than) 1406 * d) >= (greater than or equal) 1407 * 1408 * For each double-precision floating-point type, the test should 1409 * create a program object, to which it should then attach 1410 * a vertex shader, body of which was adjusted to handle case-specific 1411 * type. The shader should use all the operators and operations 1412 * described above. The result value should be XFBed out to the 1413 * test for verification. 1414 * 1415 * For relational operators, both cases described below should be 1416 * tested: 1417 * 1418 * a) fundamental type of the two operands should match without 1419 * any implicit type conversion involved in the process; 1420 * b) fundamental type of the two operands should match after an 1421 * implicit type conversion (use some of the casts enlisted for 1422 * test 6). 1423 * 1424 * The test passes if the returned set of values was correct for 1425 * all the types considered. Assume epsilon value of 1e-5. 1426 * 1427 **/ 1428 class GPUShaderFP64Test9 : public deqp::TestCase 1429 { 1430 public: 1431 /* Public methods */ 1432 GPUShaderFP64Test9(deqp::Context &context); 1433 1434 void deinit(); 1435 virtual tcu::TestNode::IterateResult iterate(); 1436 1437 private: 1438 /* Private type definitions */ 1439 typedef enum 1440 { 1441 OPERATION_TYPE_ADDITION, 1442 OPERATION_TYPE_DIVISION, 1443 OPERATION_TYPE_MULTIPLICATION, 1444 OPERATION_TYPE_SUBTRACTION, 1445 OPERATION_TYPE_PRE_DECREMENTATION, 1446 OPERATION_TYPE_PRE_INCREMENTATION, 1447 OPERATION_TYPE_POST_DECREMENTATION, 1448 OPERATION_TYPE_POST_INCREMENTATION, 1449 1450 /* Always last */ 1451 OPERATION_TYPE_COUNT 1452 } _operation_type; 1453 1454 struct _test_case 1455 { 1456 _operation_type operation_type; 1457 Utils::_variable_type result_variable_type; 1458 std::string vs_body; 1459 Utils::_variable_type variable_type; 1460 }; 1461 1462 /* Private methods */ 1463 bool executeTestIteration(const _test_case &test_case); 1464 1465 void getMatrixMultiplicationResult(const Utils::_variable_type &matrix_a_type, 1466 const std::vector<double> &matrix_a_data, 1467 const Utils::_variable_type &matrix_b_type, 1468 const std::vector<double> &matrix_b_data, double *out_result_ptr); 1469 1470 const char *getOperatorForOperationType(const _operation_type &operation_type); 1471 std::string getOperationTypeString(const _operation_type &operation_type); 1472 std::string getVertexShaderBody(_test_case &test_case); 1473 void initTest(); 1474 void initTestIteration(_test_case &test_case); 1475 1476 bool verifyXFBData(const _test_case &test_case, const unsigned char *xfb_data); 1477 1478 /* Private fields */ 1479 bool m_has_test_passed; 1480 glw::GLuint m_po_id; 1481 glw::GLuint m_xfb_bo_id; 1482 glw::GLuint m_vao_id; 1483 glw::GLuint m_vs_id; 1484 }; 1485 1486 /** Group class for GPU Shader FP64 conformance tests */ 1487 class GPUShaderFP64Tests : public deqp::TestCaseGroup 1488 { 1489 public: 1490 /* Public methods */ 1491 GPUShaderFP64Tests(deqp::Context &context); ~GPUShaderFP64Tests()1492 virtual ~GPUShaderFP64Tests() 1493 { 1494 } 1495 1496 virtual void init(void); 1497 1498 private: 1499 /* Private methods */ 1500 GPUShaderFP64Tests(const GPUShaderFP64Tests &); 1501 GPUShaderFP64Tests &operator=(const GPUShaderFP64Tests &); 1502 }; 1503 1504 } // namespace gl4cts 1505 1506 #endif // _GL4CGPUSHADERFP64TESTS_HPP 1507