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