| #ifndef _GL4CGPUSHADERFP64TESTS_HPP |
| #define _GL4CGPUSHADERFP64TESTS_HPP |
| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2014-2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ /*! |
| * \file |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| /** |
| * \file gl4cGPUShaderFP64Tests.hpp |
| * \brief Declares test classes for "GPU Shader FP64" functionality. |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "glcTestCase.hpp" |
| #include "glwDefs.hpp" |
| #include "glwEnums.hpp" |
| #include "tcuDefs.hpp" |
| #include "tcuVector.hpp" |
| #include <queue> |
| |
| namespace gl4cts |
| { |
| class Utils |
| { |
| public: |
| /* Public type definitions */ |
| |
| /** Store information about program object |
| * |
| **/ |
| struct programInfo |
| { |
| programInfo(deqp::Context& context); |
| ~programInfo(); |
| |
| void build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code, |
| const glw::GLchar* geometry_shader_code, const glw::GLchar* tesselation_control_shader_code, |
| const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code, |
| const glw::GLchar* const* varying_names, glw::GLuint n_varying_names); |
| |
| void compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const; |
| |
| void link() const; |
| |
| static const glw::GLenum ARB_COMPUTE_SHADER; |
| |
| deqp::Context& m_context; |
| |
| glw::GLuint m_compute_shader_id; |
| glw::GLuint m_fragment_shader_id; |
| glw::GLuint m_geometry_shader_id; |
| glw::GLuint m_program_object_id; |
| glw::GLuint m_tesselation_control_shader_id; |
| glw::GLuint m_tesselation_evaluation_shader_id; |
| glw::GLuint m_vertex_shader_id; |
| }; |
| |
| /* Defines GLSL variable type */ |
| enum _variable_type |
| { |
| VARIABLE_TYPE_BOOL, |
| VARIABLE_TYPE_BVEC2, |
| VARIABLE_TYPE_BVEC3, |
| VARIABLE_TYPE_BVEC4, |
| VARIABLE_TYPE_DOUBLE, |
| VARIABLE_TYPE_DMAT2, |
| VARIABLE_TYPE_DMAT2X3, |
| VARIABLE_TYPE_DMAT2X4, |
| VARIABLE_TYPE_DMAT3, |
| VARIABLE_TYPE_DMAT3X2, |
| VARIABLE_TYPE_DMAT3X4, |
| VARIABLE_TYPE_DMAT4, |
| VARIABLE_TYPE_DMAT4X2, |
| VARIABLE_TYPE_DMAT4X3, |
| VARIABLE_TYPE_DVEC2, |
| VARIABLE_TYPE_DVEC3, |
| VARIABLE_TYPE_DVEC4, |
| VARIABLE_TYPE_FLOAT, |
| VARIABLE_TYPE_INT, |
| VARIABLE_TYPE_IVEC2, |
| VARIABLE_TYPE_IVEC3, |
| VARIABLE_TYPE_IVEC4, |
| VARIABLE_TYPE_MAT2, |
| VARIABLE_TYPE_MAT2X3, |
| VARIABLE_TYPE_MAT2X4, |
| VARIABLE_TYPE_MAT3, |
| VARIABLE_TYPE_MAT3X2, |
| VARIABLE_TYPE_MAT3X4, |
| VARIABLE_TYPE_MAT4, |
| VARIABLE_TYPE_MAT4X2, |
| VARIABLE_TYPE_MAT4X3, |
| VARIABLE_TYPE_UINT, |
| VARIABLE_TYPE_UVEC2, |
| VARIABLE_TYPE_UVEC3, |
| VARIABLE_TYPE_UVEC4, |
| VARIABLE_TYPE_VEC2, |
| VARIABLE_TYPE_VEC3, |
| VARIABLE_TYPE_VEC4, |
| |
| /* Always last */ |
| VARIABLE_TYPE_UNKNOWN |
| }; |
| |
| /* Public static methods */ |
| static _variable_type getBaseVariableType(_variable_type type); |
| static unsigned int getBaseVariableTypeComponentSize(_variable_type type); |
| static unsigned char getComponentAtIndex(unsigned int index); |
| |
| static _variable_type getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows); |
| |
| static std::string getFPVariableTypeStringForVariableType(_variable_type type); |
| static glw::GLenum getGLDataTypeOfBaseVariableType(_variable_type type); |
| static glw::GLenum getGLDataTypeOfVariableType(_variable_type type); |
| |
| static _variable_type getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows); |
| |
| static unsigned int getNumberOfColumnsForVariableType(_variable_type type); |
| static unsigned int getNumberOfComponentsForVariableType(_variable_type type); |
| static unsigned int getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type); |
| static unsigned int getNumberOfRowsForVariableType(_variable_type type); |
| |
| static _variable_type getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a, |
| _variable_type type_matrix_b); |
| |
| static std::string getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr); |
| |
| static _variable_type getTransposedMatrixVariableType(_variable_type type); |
| |
| static _variable_type getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows); |
| |
| static std::string getVariableTypeString(_variable_type type); |
| |
| static bool isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor); |
| |
| static bool isMatrixVariableType(_variable_type type); |
| static bool isScalarVariableType(_variable_type type); |
| |
| static void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, |
| std::string& string); |
| }; |
| |
| /** Make sure errors as per spec are generated for new entry-points. |
| * |
| * a) Make sure GL_INVALID_OPERATION is generated by glUniform*() and |
| * glUniformMatrix*() functions if there is no current program object. |
| * b) Make sure GL_INVALID_OPERATION is generated by glUniform*() if |
| * the size of the uniform variable declared in the shader does not |
| * match the size indicated by the command. |
| * c) Make sure GL_INVALID_OPERATION is generated if glUniform*() and |
| * glUniformMatrix*() are used to load a uniform variable of type |
| * bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4, |
| * unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array |
| * of these. |
| * d) Make sure GL_INVALID_OPERATION is generated if glUniform*() and |
| * glUniformMatrix*() are used to load incompatible double-typed |
| * uniforms, as presented below: |
| * |
| * I. double-typed uniform configured by glUniform2d(); |
| * II. double-typed uniform configured by glUniform3d(); |
| * III. double-typed uniform configured by glUniform4d(); |
| * IV. double-typed uniform configured by glUniformMatrix*(); |
| * V. dvec2-typed uniform configured by glUniform1d(); |
| * VI. dvec2-typed uniform configured by glUniform3d(); |
| * VII. dvec2-typed uniform configured by glUniform4d(); |
| * VIII. dvec2-typed uniform configured by glUniformMatrix*(); |
| * |
| * (etc.) |
| * |
| * e) Make sure GL_INVALID_OPERATION is generated if <location> of |
| * glUniform*() and glUniformMatrix*() is an invalid uniform |
| * location for the current program object and location is not |
| * equal to -1. |
| * f) Make sure GL_INVALID_VALUE is generated if <count> of |
| * glUniform*() (*dv() functions only) and glUniformMatrix*() is |
| * negative. |
| * g) Make sure GL_INVALID_OPERATION is generated if <count> of |
| * glUniform*() (*dv() functions only) and glUniformMatrix*() is |
| * greater than 1 and the indicated uniform variable is not an |
| * array variable. |
| * h) Make sure GL_INVALID_OPERATION is generated if a sampler is |
| * loaded by glUniform*() and glUniformMatrix*(). |
| * i) Make sure GL_INVALID_OPERATION is generated if glUniform*() and |
| * glUniformMatrix*() is used to load values for uniforms of |
| * boolean types. |
| */ |
| class GPUShaderFP64Test1 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test1(deqp::Context& context); |
| |
| void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| /* Private type definitions */ |
| private: |
| typedef enum { |
| UNIFORM_FUNCTION_FIRST, |
| |
| UNIFORM_FUNCTION_1D = UNIFORM_FUNCTION_FIRST, |
| UNIFORM_FUNCTION_1DV, |
| UNIFORM_FUNCTION_2D, |
| UNIFORM_FUNCTION_2DV, |
| UNIFORM_FUNCTION_3D, |
| UNIFORM_FUNCTION_3DV, |
| UNIFORM_FUNCTION_4D, |
| UNIFORM_FUNCTION_4DV, |
| |
| UNIFORM_FUNCTION_MATRIX2DV, |
| UNIFORM_FUNCTION_MATRIX2X3DV, |
| UNIFORM_FUNCTION_MATRIX2X4DV, |
| UNIFORM_FUNCTION_MATRIX3DV, |
| UNIFORM_FUNCTION_MATRIX3X2DV, |
| UNIFORM_FUNCTION_MATRIX3X4DV, |
| UNIFORM_FUNCTION_MATRIX4DV, |
| UNIFORM_FUNCTION_MATRIX4X2DV, |
| UNIFORM_FUNCTION_MATRIX4X3DV, |
| |
| /* Always last */ |
| UNIFORM_FUNCTION_COUNT |
| } _uniform_function; |
| |
| /* Private methods */ |
| const char* getUniformFunctionString(_uniform_function func); |
| const char* getUniformNameForLocation(glw::GLint location); |
| void initTest(); |
| bool isMatrixUniform(glw::GLint uniform_location); |
| bool isMatrixUniformFunction(_uniform_function func); |
| bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans(); |
| bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers(); |
| bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount(); |
| bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation(); |
| bool verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount(); |
| bool verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions(); |
| bool verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions(); |
| bool verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions(); |
| bool verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO(); |
| |
| /* Private fields */ |
| bool m_has_test_passed; |
| glw::GLint m_po_bool_arr_uniform_location; |
| glw::GLint m_po_bool_uniform_location; |
| glw::GLint m_po_bvec2_arr_uniform_location; |
| glw::GLint m_po_bvec2_uniform_location; |
| glw::GLint m_po_bvec3_arr_uniform_location; |
| glw::GLint m_po_bvec3_uniform_location; |
| glw::GLint m_po_bvec4_arr_uniform_location; |
| glw::GLint m_po_bvec4_uniform_location; |
| glw::GLint m_po_dmat2_arr_uniform_location; |
| glw::GLint m_po_dmat2_uniform_location; |
| glw::GLint m_po_dmat2x3_arr_uniform_location; |
| glw::GLint m_po_dmat2x3_uniform_location; |
| glw::GLint m_po_dmat2x4_arr_uniform_location; |
| glw::GLint m_po_dmat2x4_uniform_location; |
| glw::GLint m_po_dmat3_arr_uniform_location; |
| glw::GLint m_po_dmat3_uniform_location; |
| glw::GLint m_po_dmat3x2_arr_uniform_location; |
| glw::GLint m_po_dmat3x2_uniform_location; |
| glw::GLint m_po_dmat3x4_arr_uniform_location; |
| glw::GLint m_po_dmat3x4_uniform_location; |
| glw::GLint m_po_dmat4_arr_uniform_location; |
| glw::GLint m_po_dmat4_uniform_location; |
| glw::GLint m_po_dmat4x2_arr_uniform_location; |
| glw::GLint m_po_dmat4x2_uniform_location; |
| glw::GLint m_po_dmat4x3_arr_uniform_location; |
| glw::GLint m_po_dmat4x3_uniform_location; |
| glw::GLint m_po_double_arr_uniform_location; |
| glw::GLint m_po_double_uniform_location; |
| glw::GLint m_po_dvec2_arr_uniform_location; |
| glw::GLint m_po_dvec2_uniform_location; |
| glw::GLint m_po_dvec3_arr_uniform_location; |
| glw::GLint m_po_dvec3_uniform_location; |
| glw::GLint m_po_dvec4_arr_uniform_location; |
| glw::GLint m_po_dvec4_uniform_location; |
| glw::GLint m_po_float_arr_uniform_location; |
| glw::GLint m_po_float_uniform_location; |
| glw::GLint m_po_int_arr_uniform_location; |
| glw::GLint m_po_int_uniform_location; |
| glw::GLint m_po_ivec2_arr_uniform_location; |
| glw::GLint m_po_ivec2_uniform_location; |
| glw::GLint m_po_ivec3_arr_uniform_location; |
| glw::GLint m_po_ivec3_uniform_location; |
| glw::GLint m_po_ivec4_arr_uniform_location; |
| glw::GLint m_po_ivec4_uniform_location; |
| glw::GLint m_po_sampler_uniform_location; |
| glw::GLint m_po_uint_arr_uniform_location; |
| glw::GLint m_po_uint_uniform_location; |
| glw::GLint m_po_uvec2_arr_uniform_location; |
| glw::GLint m_po_uvec2_uniform_location; |
| glw::GLint m_po_uvec3_arr_uniform_location; |
| glw::GLint m_po_uvec3_uniform_location; |
| glw::GLint m_po_uvec4_arr_uniform_location; |
| glw::GLint m_po_uvec4_uniform_location; |
| glw::GLint m_po_vec2_arr_uniform_location; |
| glw::GLint m_po_vec2_uniform_location; |
| glw::GLint m_po_vec3_arr_uniform_location; |
| glw::GLint m_po_vec3_uniform_location; |
| glw::GLint m_po_vec4_arr_uniform_location; |
| glw::GLint m_po_vec4_uniform_location; |
| glw::GLuint m_po_id; |
| glw::GLuint m_vs_id; |
| }; |
| |
| /** Implements "Subtest 2" from CTS_ARB_gpu_shader_fp64, description follows: |
| * Make sure that it is possible to use: |
| * |
| * a) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 2) double uniforms |
| * in a default uniform block of a vertex shader; |
| * b) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4) dvec2 uniforms |
| * in a default uniform block of a vertex shader; |
| * c) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 6) dvec3 uniforms |
| * in a default uniform block of a vertex shader; |
| * d) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 8) dvec4 uniforms |
| * in a default uniform block of a vertex shader; |
| * e) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 16) dmat2, dmat2x3, |
| * dmat2x4, dmat3x2, dmat4x2 uniforms in a default uniform block |
| * of a vertex shader; (each type tested in a separate shader) |
| * f) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 24) dmat3, dmat3x4, |
| * dmat4x3 uniforms in a default uniform block of a vertex shader; |
| * (each type tested in a separate shader) |
| * g) up to (GL_MAX_VERTEX_UNIFORM_COMPONENTS / 32) dmat4 uniforms |
| * in a default uniform block of a vertex shader; |
| * h) arrayed cases of a)-g), where the array size is 3 and the |
| * amount of uniforms that can be supported should be divided |
| * by three as well. |
| * i) cases a)-h), where "vertex shader" is replaced by "fragment |
| * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to |
| * GL_MAX_FRAGMENT_UNIFORM_COMPONENTS; |
| * j) cases a)-h) where "vertex shader" is replaced by "geometry |
| * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to |
| * GL_MAX_GEOMETRY_UNIFORM_COMPONENTS; |
| * k) cases a)-h) where "vertex shader" is replaced by "compute |
| * shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed to |
| * GL_MAX_COMPUTE_UNIFORM_COMPONENTS; |
| * l) cases a)-h) where "vertex shader" is replaced by "tessellation |
| * control shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is changed |
| * to GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS; |
| * m) cases a)-h) where "vertex shader" is replaced by "tessellation |
| * evaluation shader" and GL_MAX_VERTEX_UNIFORM_COMPONENTS is |
| * changed to GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS; |
| * |
| * For each case considered, the test should only define uniforms |
| * for the stage the test is dealing with. |
| * |
| * All uniform components considered as a whole should be assigned |
| * unique values, where the very first uniform component is set to |
| * a value of 1, the one following set to 2, the one afterward set |
| * to 3, and so on. |
| * |
| * For "vertex shader" cases, the test should work by creating |
| * a program object, to which a vertex shader (as per test case) |
| * would be attached. The shader would then read all the uniforms, |
| * verify their values are correct and then set an output bool |
| * variable to true if the validation passed, false otherwise. |
| * The test should draw 1024 points, XFB the contents of the output |
| * variable and verify the result. |
| * |
| * For "geometry shader" cases, the test should create a program object |
| * and attach vertex and geometry shaders to it. The vertex shader |
| * should set gl_Position to (1, 0, 0, 1). The geometry shader |
| * should accept points on input and emit 1 point, read all the |
| * uniforms, verify their values are correct and then set an output |
| * bool variable to true if the validation passed, false otherwise. |
| * The test should draw 1024 points, XFB the contents of the output |
| * variable and verify the result. |
| * |
| * For "tessellation control shader" cases, the test should create |
| * a program object and attach vertex and tessellation control shaders |
| * to the program object. The vertex shader should set gl_Position |
| * to (1, 0, 0, 1). The tessellation control shader should output |
| * a single vertex per patch and set all inner/outer tessellation. |
| * levels to 1. The shader should read all the uniforms, verify |
| * their values are correct and then set an output per-vertex bool |
| * variable to true if the validation passed, false otherwise. The |
| * test should draw 1024 patches, XFB the contents of the output |
| * variable and verify the result. |
| * |
| * For "tessellation evaluation shader" cases, the test should create |
| * a program object and attach vertex, tessellation control and |
| * tessellation evaluation shaders to the program object. The vertex |
| * shader should set gl_Position to (1, 0, 0, 1). The tessellation |
| * control shader should behave as in "tessellation control shader" |
| * case. The tessellation evaluation shader should accept isolines |
| * and work in point mode. The shader should read all the uniforms, |
| * verify their values are correct and then set an output |
| * bool variable to true if the validation passed, false otherwise. |
| * The test should draw 1024 patches, XFB the contents of the output |
| * variable and verify the result. |
| * |
| * For "fragment shader" cases, the test should create a program object |
| * and attach vertex and fragment shaders to the program object. The |
| * vertex shader should set gl_Position to 4 different values |
| * (depending on gl_VertexID value), defining screen-space corners |
| * for a GL_TRIANGLE_FAN-based draw call. The fragment shader should |
| * read all the uniforms, verify their values are correct and then |
| * set the output color to vec4(1) if the validation passed, vec4(0) |
| * otherwise. The test should draw 4 vertices making up a triangle fan, |
| * read the rasterized image and confirm the result. |
| * |
| * For all cases apart from "fragment shader", the test should also |
| * verify that glGetTransformFeedbackVarying() reports correct |
| * properties for the uniforms. |
| * |
| * The test should also verify that in all cases glGetActiveUniform() |
| * reports correct properties for all the defined uniforms. |
| **/ |
| class GPUShaderFP64Test2 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test2(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private types */ |
| typedef glw::GLint captured_varying_type; |
| typedef void(GLW_APIENTRY* arbDispatchComputeFunc)(glw::GLuint num_groups_x, glw::GLuint num_groups_y, |
| glw::GLuint num_groups_z); |
| |
| /** Shader stage enumeration |
| * |
| */ |
| enum shaderStage |
| { |
| COMPUTE_SHADER, |
| FRAGMENT_SHADER, |
| GEOMETRY_SHADER, |
| TESS_CTRL_SHADER, |
| TESS_EVAL_SHADER, |
| VERTEX_SHADER, |
| }; |
| |
| /** Store details about uniform type |
| * |
| **/ |
| struct uniformTypeDetails |
| { |
| uniformTypeDetails(glw::GLuint n_columns, glw::GLuint n_rows); |
| |
| glw::GLuint m_n_columns; |
| glw::GLuint m_n_rows; |
| glw::GLenum m_type; |
| std::string m_type_name; |
| }; |
| |
| /** Store details about uniform |
| * |
| **/ |
| struct uniformDetails |
| { |
| glw::GLuint m_array_stride; |
| glw::GLuint m_matrix_stride; |
| glw::GLuint m_offset; |
| }; |
| |
| /* Provate methods */ |
| glw::GLenum getCapturedPrimitiveType(shaderStage shader_stage) const; |
| glw::GLenum getDrawPrimitiveType(shaderStage shader_stage) const; |
| glw::GLuint getMaxUniformComponents(shaderStage shader_stage) const; |
| glw::GLuint getMaxUniformBlockSize() const; |
| glw::GLuint getRequiredComponentsNumber(const uniformTypeDetails& uniform_type) const; |
| glw::GLuint getUniformTypeMemberSize(const uniformTypeDetails& uniform_type) const; |
| glw::GLuint getAmountUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const; |
| const glw::GLchar* getShaderStageName(shaderStage shader_stage) const; |
| |
| void inspectProgram(glw::GLuint program_id, glw::GLint n_uniforms, const uniformTypeDetails& uniform_type, |
| glw::GLint& out_buffer_size, uniformDetails& out_offsets, |
| glw::GLuint& uniform_block_index) const; |
| |
| void prepareBoilerplateShader(const glw::GLchar* stage_specific_layout, const glw::GLchar* stage_specific_main_body, |
| std::string& out_source_code) const; |
| |
| void prepareProgram(shaderStage shader_stage, const uniformTypeDetails& uniform_type, |
| Utils::programInfo& out_program_info) const; |
| |
| void prepareShaderStages(); |
| |
| void prepareTestShader(const glw::GLchar* stage_specific_layout, const glw::GLchar* uniform_definitions, |
| const glw::GLchar* in_variable_definitions, const glw::GLchar* out_variable_definitions, |
| const glw::GLchar* uniform_verification, const glw::GLchar* stage_specific_main_body, |
| std::string& out_source_code) const; |
| |
| void prepareTestComputeShader(const glw::GLchar* uniform_definitions, const glw::GLchar* uniform_verification, |
| std::string& out_source_code) const; |
| |
| void prepareUniformDefinitions(shaderStage shader_stage, const uniformTypeDetails& uniform_type, |
| std::string& out_source_code) const; |
| |
| void prepareUniforms(shaderStage shader_stage, const uniformTypeDetails& uniform_type, |
| const Utils::programInfo& program_info) const; |
| |
| void prepareUniformTypes(); |
| |
| void prepareUniformVerification(shaderStage shader_stage, const uniformTypeDetails& uniform_type, |
| std::string& out_source_code) const; |
| |
| bool test(shaderStage shader_stage, const uniformTypeDetails& uniform_type) const; |
| |
| void testBegin(glw::GLuint program_id, shaderStage shader_stage) const; |
| |
| void testEnd(shaderStage shader_stage) const; |
| void testInit(); |
| bool verifyResults(shaderStage shader_stage) const; |
| |
| /* Private constants */ |
| static const glw::GLuint m_n_captured_results; |
| static const glw::GLint m_result_failure; |
| static const glw::GLint m_result_success; |
| static const glw::GLuint m_texture_width; |
| static const glw::GLuint m_texture_height; |
| static const glw::GLuint m_transform_feedback_buffer_size; |
| |
| static const glw::GLchar* m_uniform_block_name; |
| |
| static const glw::GLenum ARB_MAX_COMPUTE_UNIFORM_COMPONENTS; |
| |
| /* Private fields */ |
| arbDispatchComputeFunc m_pDispatchCompute; |
| |
| std::vector<shaderStage> m_shader_stages; |
| std::vector<uniformTypeDetails> m_uniform_types; |
| |
| glw::GLuint m_framebuffer_id; |
| glw::GLuint m_texture_id; |
| glw::GLuint m_transform_feedback_buffer_id; |
| glw::GLuint m_uniform_buffer_id; |
| glw::GLuint m_vertex_array_object_id; |
| }; |
| |
| /** Implements "Subtest 3" from CTS_ARB_gpu_shader_fp64, description follows: |
| * |
| * Make sure it is possible to use new types for member declaration |
| * in a named uniform block. |
| * The following members should be defined in the block: |
| * |
| * ivec3 dummy1[3]; |
| * double double_value; |
| * bool dummy2; |
| * dvec2 dvec2_value; |
| * bvec3 dummy3; |
| * dvec3 dvec3_value; |
| * int dummy4[3]; |
| * dvec4 dvec4_value; |
| * bool dummy5; |
| * bool dummy6[2]; |
| * dmat2 dmat2_value; |
| * dmat3 dmat3_value; |
| * bool dummy7; |
| * dmat4 dmat4_value; |
| * dmat2x3 dmat2x3_value; |
| * uvec3 dummy8; |
| * dmat2x4 dmat2x4_value; |
| * dmat3x2 dmat3x2_value; |
| * bool dummy9; |
| * dmat3x4 dmat3x4_value; |
| * int dummy10; |
| * dmat4x2 dmat4x2_value; |
| * dmat4x3 dmat4x3_value; |
| * |
| * std140, packed and shared layout qualifiers should be tested |
| * separately. |
| * |
| * For the purpose of the test, a buffer object, storage of which |
| * is to be used for the uniform buffer, should be filled with |
| * predefined values at member-specific offsets. These values |
| * should then be read in each shader stage covered by the test |
| * and verified. |
| * |
| * For std140 layout qualifier, the test should additionally verify |
| * the offsets assigned by GL implementation are as per specification. |
| * |
| * The following shader stages should be defined for a program object |
| * to be used by the test: |
| * |
| * 1) Vertex shader stage; |
| * 2) Geometry shader stage; |
| * 3) Tessellation control shader stage; |
| * 4) Tessellation evaluation shader stage; |
| * 5) Fragment shader stage; |
| * |
| * Vertex shader stage should set a stage-specific bool variable to |
| * true if all uniform buffer members are assigned valid values, |
| * false otherwise. |
| * |
| * Geometry shader stage should take points on input and emit a single |
| * point. Similarly to vertex shader stage, it should set a stage-specific |
| * bool variable to true, if all uniform buffer members are determined |
| * to expose valid values, false otherwise. |
| * Geometry shader stage should pass the result value from the vertex |
| * shader stage down the rendering pipeline using a new output variable, |
| * set to the value of the variable exposed by vertex shader stage. |
| * |
| * Tessellation control shader stage should set all inner/outer |
| * tessellation levels to 1 and output 1 vertex per patch. |
| * The verification should be carried out as in previous stages. |
| * TC shader stage should also define stage-specific output variables |
| * for vertex and geometry shader stages and set them to relevant |
| * values, similar to what's been described for geometry shader stage. |
| * |
| * Tessellation evaluation shader stage should take quads on |
| * input. It should be constructed in a way that will make it |
| * generate a quad that occupies whole screen-space. This is necessary |
| * to perform validation of the input variables in fragment shader |
| * stage. |
| * The verification should be carried out as in previous stages. |
| * TE stage should pass down validation results from previous stages |
| * in a similar manner as was described for TC shader stage. |
| * |
| * Fragment shader stage should verify all the uniform buffer members |
| * carry valid values. Upon success, it should output vec4(1) to the |
| * only output variable. Otherwise, it should set it to vec4(0). |
| * |
| * XFB should be used to read all the output variables defined in TE |
| * stage that carry result information from all the rendering stages |
| * until tessellation evaluation shader stage. The test passes, if |
| * all result values are set to true and the draw buffer is filled |
| * with vec4(1). |
| **/ |
| class GPUShaderFP64Test3 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test3(deqp::Context&); |
| virtual ~GPUShaderFP64Test3() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual void deinit(void); |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private types */ |
| |
| /** Enumerate shader stages |
| * |
| **/ |
| enum shaderStage |
| { |
| FRAGMENT_SHADER, |
| GEOMETRY_SHADER, |
| TESS_CONTROL_SHADER, |
| TESS_EVAL_SHADER, |
| VERTEX_SHADER, |
| }; |
| |
| /** Enumerate buffer data layouts |
| * |
| **/ |
| enum uniformDataLayout |
| { |
| PACKED, |
| SHARED, |
| STD140, |
| }; |
| |
| /** Store details about "double precision" uniforms |
| * |
| **/ |
| struct uniformDetails |
| { |
| uniformDetails(glw::GLint expected_std140_offset, const glw::GLchar* name, glw::GLuint n_columns, |
| glw::GLuint n_elements, const glw::GLchar* type_name) |
| : m_expected_std140_offset(expected_std140_offset) |
| , m_name(name) |
| , m_n_columns(n_columns) |
| , m_n_elements(n_elements) |
| , m_type_name(type_name) |
| { |
| /* Nothing to be done */ |
| } |
| |
| glw::GLint m_expected_std140_offset; |
| const glw::GLchar* m_name; |
| glw::GLuint m_n_columns; |
| glw::GLuint m_n_elements; |
| const glw::GLchar* m_type_name; |
| }; |
| |
| /** Store details about program object |
| * |
| **/ |
| struct programInfo |
| { |
| |
| programInfo(); |
| |
| void compile(deqp::Context& context, glw::GLuint shader_id, const glw::GLchar* shader_code) const; |
| |
| void deinit(deqp::Context& context); |
| |
| void init(deqp::Context& context, const std::vector<uniformDetails> m_uniform_details, |
| const glw::GLchar* fragment_shader_code, const glw::GLchar* geometry_shader_code, |
| const glw::GLchar* tesselation_control_shader_code, |
| const glw::GLchar* tesselation_evaluation_shader_code, const glw::GLchar* vertex_shader_code); |
| |
| void link(deqp::Context& context) const; |
| |
| static const glw::GLint m_invalid_uniform_offset; |
| static const glw::GLint m_invalid_uniform_matrix_stride; |
| static const glw::GLint m_non_matrix_uniform_matrix_stride; |
| |
| glw::GLuint m_fragment_shader_id; |
| glw::GLuint m_geometry_shader_id; |
| glw::GLuint m_program_object_id; |
| glw::GLuint m_tesselation_control_shader_id; |
| glw::GLuint m_tesselation_evaluation_shader_id; |
| glw::GLuint m_vertex_shader_id; |
| |
| glw::GLint m_buffer_size; |
| glw::GLuint m_uniform_block_index; |
| |
| std::vector<glw::GLint> m_uniform_offsets; |
| std::vector<glw::GLint> m_uniform_matrix_strides; |
| }; |
| |
| /* Private methods */ |
| glw::GLdouble getExpectedValue(glw::GLuint type_ordinal, glw::GLuint element) const; |
| const programInfo& getProgramInfo(uniformDataLayout uniform_data_layout) const; |
| const glw::GLchar* getUniformLayoutName(uniformDataLayout uniform_data_layout) const; |
| |
| void prepareProgram(programInfo& program_info, uniformDataLayout uniform_data_layout) const; |
| |
| bool prepareUniformBuffer(const programInfo& program_info, bool verify_offsets) const; |
| |
| void testInit(); |
| bool test(uniformDataLayout uniform_data_layout) const; |
| bool verifyResults() const; |
| |
| void writeMainBody(std::ostream& stream, shaderStage shader_stage) const; |
| |
| void writePreamble(std::ostream& stream, shaderStage shader_stage) const; |
| |
| void writeUniformBlock(std::ostream& stream, uniformDataLayout uniform_data_layout) const; |
| |
| void writeVaryingDeclarations(std::ostream& stream, shaderStage shader_stage) const; |
| |
| void writeVaryingPassthrough(std::ostream& stream, shaderStage shader_stage) const; |
| |
| /* Private fields */ |
| /* Constants */ |
| static const glw::GLuint m_result_failure; |
| static const glw::GLuint m_result_success; |
| |
| static const glw::GLchar* m_uniform_block_name; |
| static const glw::GLchar* m_uniform_block_instance_name; |
| |
| static const glw::GLchar* m_varying_name_fs_out_fs_result; |
| static const glw::GLchar* m_varying_name_gs_fs_gs_result; |
| static const glw::GLchar* m_varying_name_gs_fs_tcs_result; |
| static const glw::GLchar* m_varying_name_gs_fs_tes_result; |
| static const glw::GLchar* m_varying_name_gs_fs_vs_result; |
| static const glw::GLchar* m_varying_name_tcs_tes_tcs_result; |
| static const glw::GLchar* m_varying_name_tcs_tes_vs_result; |
| static const glw::GLchar* m_varying_name_tes_gs_tcs_result; |
| static const glw::GLchar* m_varying_name_tes_gs_tes_result; |
| static const glw::GLchar* m_varying_name_tes_gs_vs_result; |
| static const glw::GLchar* m_varying_name_vs_tcs_vs_result; |
| |
| /* GL objects */ |
| glw::GLuint m_color_texture_id; |
| glw::GLuint m_framebuffer_id; |
| glw::GLuint m_transform_feedback_buffer_id; |
| glw::GLuint m_uniform_buffer_id; |
| glw::GLuint m_vertex_array_object_id; |
| |
| /* Random values used by getExpectedValue */ |
| glw::GLdouble m_base_element; |
| glw::GLdouble m_base_type_ordinal; |
| |
| /* Program details, one per data layout */ |
| programInfo m_packed_program; |
| programInfo m_shared_program; |
| programInfo m_std140_program; |
| |
| /* Storage for uniforms' details */ |
| std::vector<uniformDetails> m_uniform_details; |
| }; |
| |
| /** Make sure glGetUniformdv() reports correct values, as assigned |
| * by corresponding glUniform*() functions, for the following |
| * uniform types: |
| * |
| * a) double; |
| * b) dvec2; |
| * c) dvec3; |
| * d) dvec4; |
| * e) Arrays of a)-d); |
| * f) a)-d) defined in single-dimensional arrays built of the same |
| * structure. |
| * |
| * These uniforms should be defined in the default uniform block, |
| * separately in each stage defined for the following program |
| * objects: |
| * |
| * a) A program object consisting of a fragment, geometry, tessellation |
| * control, tessellation evaluation, vertex shader stages. |
| * b) A program object consisting of a compute shader stage. |
| * |
| * If GL_ARB_program_interface_query is supported, the test should |
| * also verify that the following API functions work correctly with |
| * the described uniforms: |
| * |
| * - glGetProgramResourceiv() (query GL_TYPE and GL_ARRAY_SIZE |
| * properties of GL_UNIFORM interface |
| * for all uniforms); |
| * - glGetProgramResourceIndex() (use GL_UNIFORM interface) |
| * - glGetProgramResourceName() (use GL_UNIFORM interface) |
| * |
| * To verify the values returned by these functions, values returned |
| * by relevant glGetUniform*() API functions should be used as |
| * reference. |
| */ |
| class GPUShaderFP64Test4 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test4(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| /* Defines a type used as a data container for one of the test cases */ |
| typedef std::pair<glw::GLint /* uniform location */, double* /* value(s) assigned */> uniform_value_pair; |
| |
| /* Holds uniform locations & associated values. used by one of the test cases */ |
| struct _data |
| { |
| _data(); |
| |
| double uniform_double; |
| double uniform_double_arr[2]; |
| double uniform_dvec2[2]; |
| double uniform_dvec2_arr[4]; |
| double uniform_dvec3[3]; |
| double uniform_dvec3_arr[6]; |
| double uniform_dvec4[4]; |
| double uniform_dvec4_arr[8]; |
| |
| glw::GLint uniform_location_double; |
| glw::GLint uniform_location_double_arr[2]; |
| glw::GLint uniform_location_dvec2; |
| glw::GLint uniform_location_dvec2_arr[2]; |
| glw::GLint uniform_location_dvec3; |
| glw::GLint uniform_location_dvec3_arr[2]; |
| glw::GLint uniform_location_dvec4; |
| glw::GLint uniform_location_dvec4_arr[2]; |
| }; |
| |
| /** Holds uniform location & properties information. Used by one of the test cases. */ |
| struct _program_interface_query_test_item |
| { |
| glw::GLint expected_array_size; |
| std::string name; |
| glw::GLenum expected_type; |
| glw::GLint location; |
| }; |
| |
| /** Holds information on all uniforms defined for a single shader stage. */ |
| struct _stage_data |
| { |
| _data uniform_structure_arrays[2]; |
| _data uniforms; |
| }; |
| |
| /* Private methods */ |
| void generateUniformValues(); |
| void initProgramObjects(); |
| void initTest(); |
| void initUniformValues(); |
| bool verifyProgramInterfaceQuerySupport(); |
| bool verifyUniformValues(); |
| |
| /* Private declarations */ |
| bool m_has_test_passed; |
| char* m_uniform_name_buffer; |
| |
| glw::GLuint m_cs_id; |
| glw::GLuint m_fs_id; |
| glw::GLuint m_gs_id; |
| glw::GLuint m_po_cs_id; |
| glw::GLuint m_po_noncs_id; |
| glw::GLuint m_tc_id; |
| glw::GLuint m_te_id; |
| glw::GLuint m_vs_id; |
| |
| _stage_data m_data_cs; |
| _stage_data m_data_fs; |
| _stage_data m_data_gs; |
| _stage_data m_data_tc; |
| _stage_data m_data_te; |
| _stage_data m_data_vs; |
| }; |
| |
| /** Make sure the following implicit conversion work correctly: |
| * |
| * a) int -> double; |
| * b) ivec2 -> dvec2; |
| * c) ivec3 -> dvec3; |
| * d) ivec4 -> dvec4; |
| * e) uint -> double; |
| * f) uvec2 -> dvec2; |
| * g) uvec3 -> dvec3; |
| * h) uvec4 -> dvec4; |
| * i) float -> double; |
| * j) vec2 -> dvec2; |
| * k) vec3 -> dvec3; |
| * l) vec4 -> dvec4; |
| * m) mat2 -> dmat2; |
| * n) mat3 -> dmat3; |
| * o) mat4 -> dmat4; |
| * p) mat2x3 -> dmat2x3; |
| * q) mat2x4 -> dmat2x4; |
| * r) mat3x2 -> dmat3x2; |
| * s) mat3x4 -> dmat3x4; |
| * t) max4x2 -> dmat4x2; |
| * u) mat4x3 -> dmat4x3; |
| * |
| * The test should also verify the following explicit conversions |
| * are supported (that is: when the right-side value is used as |
| * an argument to a constructor of left-side type): |
| * |
| * a) int -> double; |
| * b) uint -> double; |
| * c) float -> double; |
| * d) double -> int; |
| * e) double -> uint; |
| * f) double -> float; |
| * g) double -> bool; |
| * h) bool -> double; |
| * |
| * For each conversion, the test should create a program object and |
| * attach a vertex shader to it. |
| * The shader should define an uniform named "base_value", with |
| * its type dependent on the type defined left-side for particular |
| * case, as defined below: |
| * |
| * [base_value type: bool] |
| * bool |
| * |
| * [base_value type: double] |
| * double |
| * |
| * [base_value type: int] |
| * int, ivec2, ivec3, ivec4 |
| * |
| * [base_value type: uint] |
| * uint, uvec2, uvec3, uvec4 |
| * |
| * [base_value type: float] |
| * float, vec2, vec3, vec4, |
| * mat2, mat3, mat4, mat2x3, |
| * mat2x4, mat3x2, mat3x4, mat4x2, |
| * mat4x3 |
| * |
| * For each tested pair, it should build the "source" value/vector/matrix |
| * by taking the value specified in uniform of the same type as the one |
| * that is to be used as source, and use it for zeroth component. First |
| * component should be larger by one, second component should be bigger |
| * by two, and so on. |
| * Once the source value/vector/matrix is defined, the casting operation |
| * should be performed, giving a "destination" value/vector/matrix of |
| * type as defined for particular case. |
| * The resulting value should be XFBed out to the test implementation. |
| * The comparison should be performed on CPU to ensure validity of |
| * the resulting data. |
| * |
| * A swizzling operator should be used where possible when setting |
| * the output variables to additionally check that swizzling works |
| * correctly for multi-component double-precision types. |
| * |
| * The program object should be used for the following base values: |
| * |
| * a) -25.12065 |
| * b) 0.0 |
| * c) 0.001 |
| * d) 1.0 |
| * e) 256.78901 |
| * |
| * An epsilon of 1e-5 should be used for floating-point comparisons. |
| **/ |
| class GPUShaderFP64Test5 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test5(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| /* Defines swizzle operators used by shaders generated by the test */ |
| enum _swizzle_type |
| { |
| SWIZZLE_TYPE_NONE, |
| |
| SWIZZLE_TYPE_XWZY, |
| SWIZZLE_TYPE_XZXY, |
| SWIZZLE_TYPE_XZY, |
| SWIZZLE_TYPE_XZYW, |
| |
| SWIZZLE_TYPE_Y, |
| SWIZZLE_TYPE_YX, |
| SWIZZLE_TYPE_YXX, |
| SWIZZLE_TYPE_YXXY, |
| |
| SWIZZLE_TYPE_Z, |
| SWIZZLE_TYPE_ZY, |
| |
| SWIZZLE_TYPE_W, |
| SWIZZLE_TYPE_WX, |
| }; |
| |
| /* Defines cast type to be used for specific test case */ |
| enum _test_case_type |
| { |
| TEST_CASE_TYPE_EXPLICIT, |
| TEST_CASE_TYPE_IMPLICIT, |
| |
| /* Always last */ |
| TEST_CASE_TYPE_UNKNOWN |
| }; |
| |
| /* Holds a complete description of a single test case */ |
| struct _test_case |
| { |
| _test_case_type type; |
| |
| Utils::_variable_type src_type; |
| Utils::_variable_type dst_type; |
| |
| std::string shader_body; |
| }; |
| |
| /* Private methods */ |
| bool executeIteration(const _test_case& test_case); |
| |
| void getSwizzleTypeProperties(_swizzle_type type, std::string* out_swizzle_string, unsigned int* out_n_components, |
| unsigned int* out_component_order); |
| |
| std::string getVertexShaderBody(const _test_case& test_case); |
| void initIteration(_test_case& test_case); |
| void initTest(); |
| |
| bool verifyXFBData(const unsigned char* data_ptr, const _test_case& test_case); |
| |
| void deinitInteration(); |
| |
| /* Private declarations */ |
| unsigned char* m_base_value_bo_data; |
| glw::GLuint m_base_value_bo_id; |
| bool m_has_test_passed; |
| glw::GLint m_po_base_value_attribute_location; |
| glw::GLint m_po_id; |
| glw::GLuint m_vao_id; |
| glw::GLint m_vs_id; |
| glw::GLuint m_xfb_bo_id; |
| unsigned int m_xfb_bo_size; |
| |
| float m_base_values[5]; /* as per test spec */ |
| _swizzle_type m_swizzle_matrix[4 /* max number of dst components */][4 /* max number of src components */]; |
| }; |
| |
| /** The test should verify it is a compilation error to perform the |
| * following casts in the shader: |
| * |
| * a) int [2] -> double; |
| * b) ivec2 [2] -> dvec2; |
| * c) ivec3 [2] -> dvec3; |
| * d) ivec4 [2] -> dvec4; |
| * e) uint [2] -> double; |
| * f) uvec2 [2] -> dvec2; |
| * g) uvec3 [2] -> dvec3; |
| * h) uvec4 [2] -> dvec4; |
| * i) float [2] -> double; |
| * j) vec2 [2] -> dvec2; |
| * k) vec3 [2] -> dvec3; |
| * l) vec4 [2] -> dvec4; |
| * m) mat2 [2] -> dmat2; |
| * n) mat3 [2] -> dmat3; |
| * o) mat4 [2] -> dmat4; |
| * p) mat2x3[2] -> dmat2x3; |
| * q) mat2x4[2] -> dmat2x4; |
| * r) mat3x2[2] -> dmat3x2; |
| * s) mat3x4[2] -> dmat3x4; |
| * t) mat4x2[2] -> dmat4x2; |
| * u) mat4x3[2] -> dmat4x3; |
| * |
| * The test should also attempt to cast all types defined left-side |
| * in a)-u) to structures, where the only variable embedded inside |
| * the structure would be defined on the right-side of the test |
| * case considered. |
| * |
| * The following shader stages should be considered for the purpose |
| * of the test: |
| * |
| * 1) Fragment shader stage; |
| * 2) Geometry shader stage; |
| * 3) Tessellation control shader stage; |
| * 4) Tessellation evaluation shader stage; |
| * 5) Vertex shader stage; |
| * 6) Compute shader stage; |
| **/ |
| class GPUShaderFP64Test6 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test6(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| |
| /* Holds a complete description of a single test case */ |
| struct _test_case |
| { |
| unsigned int src_array_size; |
| Utils::_variable_type src_type; |
| Utils::_variable_type dst_type; |
| |
| bool wrap_dst_type_in_structure; |
| |
| std::string cs_shader_body; |
| std::string fs_shader_body; |
| std::string gs_shader_body; |
| std::string tc_shader_body; |
| std::string te_shader_body; |
| std::string vs_shader_body; |
| }; |
| |
| /* Private methods */ |
| bool executeIteration(const _test_case& test_case); |
| std::string getComputeShaderBody(const _test_case& test_case); |
| std::string getFragmentShaderBody(const _test_case& test_case); |
| std::string getGeometryShaderBody(const _test_case& test_case); |
| std::string getTessellationControlShaderBody(const _test_case& test_case); |
| std::string getTessellationEvaluationShaderBody(const _test_case& test_case); |
| std::string getVertexShaderBody(const _test_case& test_case); |
| |
| void initTest(); |
| void initIteration(_test_case& test_case); |
| |
| /* Private declarations */ |
| glw::GLuint m_cs_id; |
| glw::GLuint m_fs_id; |
| glw::GLuint m_gs_id; |
| glw::GLuint m_tc_id; |
| glw::GLuint m_te_id; |
| glw::GLuint m_vs_id; |
| |
| bool m_has_test_passed; |
| }; |
| |
| /** Make sure that double-precision types (double, dvec2, dvec3, |
| * dvec4, dmat2, dmat3, dmat4, dmat2x3, dmat2x4, dmat3x2, dmat3x4, |
| * dmat4x2, dmat4x2) and arrays of those: |
| * |
| * a) can be used as varyings (excl. vertex shader inputs *if* |
| * GL_ARB_vertex_attrib_64bit support is *not* reported, and |
| * fragment shader outputs; 'flat' layout qualifier should be |
| * used for transferring data to fragment shader stage); |
| * b) cannot be used as fragment shader output; (compilation error |
| * expected). |
| * c) cannot be used as fragment shader input if 'flat' layout |
| * qualifier is missing) |
| * |
| * For case a), the following shader stages should be defined for |
| * a single program object: |
| * |
| * 1) Vertex shader stage; |
| * 2) Geometry shader stage; |
| * 3) Tessellation control shader stage; |
| * 4) Tessellation evaluation shader stage; |
| * 5) Fragment shader stage; |
| * |
| * Vertex shader stage should define a single output variable for |
| * each type considered. Each component of these output variables |
| * should be set to predefined unique values. |
| * Geometry shader stage should take points on input and emit a single |
| * point. It should take all input variables from the previous stage, |
| * add a predefined value to each component and pass it down the |
| * rendering pipeline. |
| * Tessellation control shader stage should set all inner/outer |
| * tessellation levels to 1 and output 1 vertex per patch. |
| * It should take all input variables from the previous stage, |
| * add a predefined value to each component and pass it to |
| * tessellation evaluation stage by using per-vertex outputs. |
| * Tessellation evaluation shader stage should take quads on |
| * input. It should also define all relevant input variables, as |
| * defined by previous stage, add a predefined value to each |
| * component and pass it to geometry shader stage. Finally, it |
| * should be constructed in a way that will make it generate |
| * a quad that occupies whole screen-space. This is necessary |
| * to perform validation of the input variables in fragment shader |
| * stage. |
| * Fragment shader stage should take all inputs, as defined as |
| * outputs in tessellation evaluation shader stage. It should |
| * verify all the inputs carry valid values. Upon success, it |
| * should output vec4(1) to the only output variable. Otherwise, |
| * it should set it to vec4(0). |
| **/ |
| class GPUShaderFP64Test7 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test7(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| struct _variable |
| { |
| glw::GLint attribute_location; |
| unsigned int array_size; |
| Utils::_variable_type type; |
| }; |
| |
| typedef std::vector<_variable> _variables; |
| typedef _variables::const_iterator _variables_const_iterator; |
| |
| /* Private methods */ |
| bool buildTestProgram(_variables& variables); |
| bool compileShader(glw::GLint shader_id, const std::string& body); |
| void configureXFBBuffer(const _variables& variables); |
| bool executeFunctionalTest(_variables& variables); |
| void generateXFBVaryingNames(const _variables& variables); |
| |
| std::string getCodeOfFragmentShaderWithNonFlatDoublePrecisionInput(Utils::_variable_type input_variable_type, |
| unsigned int array_size); |
| |
| std::string getCodeOfFragmentShaderWithDoublePrecisionOutput(Utils::_variable_type output_variable_type, |
| unsigned int array_size); |
| |
| std::string getFragmentShaderBody(const _variables& variables); |
| std::string getGeometryShaderBody(const _variables& variables); |
| std::string getTessellationControlShaderBody(const _variables& variables); |
| std::string getTessellationEvaluationShaderBody(const _variables& variables); |
| |
| std::string getVariableDeclarations(const char* prefix, const _variables& variables, |
| const char* layout_qualifier = ""); |
| |
| std::string getVertexShaderBody(const _variables& variables); |
| void initTest(); |
| void logVariableContents(const _variables& variables); |
| void releaseXFBVaryingNames(); |
| void setInputAttributeValues(const _variables& variables); |
| |
| /* Private declarations */ |
| bool m_are_double_inputs_supported; |
| std::string m_current_fs_body; |
| std::string m_current_gs_body; |
| std::string m_current_tc_body; |
| std::string m_current_te_body; |
| std::string m_current_vs_body; |
| glw::GLuint m_fbo_id; |
| glw::GLint m_fs_id; |
| glw::GLint m_gs_id; |
| bool m_has_test_passed; |
| glw::GLint m_n_max_components_per_stage; |
| unsigned int m_n_xfb_varyings; |
| glw::GLint m_po_id; |
| glw::GLint m_tc_id; |
| glw::GLint m_te_id; |
| glw::GLuint m_to_id; |
| unsigned char* m_to_data; |
| unsigned int m_to_height; |
| unsigned int m_to_width; |
| glw::GLuint m_xfb_bo_id; |
| glw::GLchar** m_xfb_varyings; |
| glw::GLuint m_vao_id; |
| glw::GLint m_vs_id; |
| }; |
| |
| /** Make sure that all constructors valid for double-precision |
| * vector/matrix types are accepted by the GLSL compiler for |
| * all six shader stages. |
| * |
| * The test passes if all shaders compile successfully. |
| **/ |
| class GPUShaderFP64Test8 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test8(deqp::Context& context); |
| |
| virtual void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| typedef std::vector<Utils::_variable_type> _argument_list; |
| typedef _argument_list::const_iterator _argument_list_const_iterator; |
| typedef std::vector<_argument_list> _argument_lists; |
| typedef _argument_lists::const_iterator _argument_lists_const_iterator; |
| |
| /* Holds a complete description of a single test case */ |
| struct _argument_list_tree_node; |
| |
| typedef std::vector<_argument_list_tree_node*> _argument_list_tree_nodes; |
| typedef _argument_list_tree_nodes::const_iterator _argument_list_tree_nodes_const_iterator; |
| typedef std::queue<_argument_list_tree_node*> _argument_list_tree_node_queue; |
| |
| struct _argument_list_tree_node |
| { |
| _argument_list_tree_nodes children; |
| int n_components_used; |
| _argument_list_tree_node* parent; |
| Utils::_variable_type type; |
| |
| ~_argument_list_tree_node() |
| { |
| while (children.size() > 0) |
| { |
| _argument_list_tree_node* node_ptr = children.back(); |
| |
| children.pop_back(); |
| |
| delete node_ptr; |
| node_ptr = NULL; |
| } |
| } |
| }; |
| |
| struct _test_case |
| { |
| _argument_list argument_list; |
| Utils::_variable_type type; |
| |
| std::string cs_shader_body; |
| std::string fs_shader_body; |
| std::string gs_shader_body; |
| std::string tc_shader_body; |
| std::string te_shader_body; |
| std::string vs_shader_body; |
| }; |
| |
| /* Private methods */ |
| bool executeIteration(const _test_case& test_case); |
| _argument_lists getArgumentListsForVariableType(const Utils::_variable_type& variable_type); |
| std::string getComputeShaderBody(const _test_case& test_case); |
| std::string getFragmentShaderBody(const _test_case& test_case); |
| std::string getGeneralBody(const _test_case& test_case); |
| std::string getGeometryShaderBody(const _test_case& test_case); |
| std::string getTessellationControlShaderBody(const _test_case& test_case); |
| std::string getTessellationEvaluationShaderBody(const _test_case& test_case); |
| std::string getVertexShaderBody(const _test_case& test_case); |
| |
| void initTest(); |
| void initIteration(_test_case& test_case); |
| |
| /* Private declarations */ |
| glw::GLuint m_cs_id; |
| glw::GLuint m_fs_id; |
| glw::GLuint m_gs_id; |
| glw::GLuint m_tc_id; |
| glw::GLuint m_te_id; |
| glw::GLuint m_vs_id; |
| |
| bool m_has_test_passed; |
| }; |
| |
| /** Make sure that the following operators work correctly for |
| * double-precision floating-point scalars, vectors and matrices: |
| * |
| * a) + (addition) |
| * b) - (subtraction) |
| * c) * (multiplication) |
| * d) / (division) |
| * e) - (negation) |
| * f) -- (pre-decrementation and post-decrementation) |
| * g) ++ (pre-incrementation and post-incrementation) |
| * |
| * Furthermore, the following relational operators should also be |
| * tested for double-precision floating-point expressions: |
| * |
| * a) < (less than) |
| * b) <= (less than or equal) |
| * c) > (greater than) |
| * d) >= (greater than or equal) |
| * |
| * For each double-precision floating-point type, the test should |
| * create a program object, to which it should then attach |
| * a vertex shader, body of which was adjusted to handle case-specific |
| * type. The shader should use all the operators and operations |
| * described above. The result value should be XFBed out to the |
| * test for verification. |
| * |
| * For relational operators, both cases described below should be |
| * tested: |
| * |
| * a) fundamental type of the two operands should match without |
| * any implicit type conversion involved in the process; |
| * b) fundamental type of the two operands should match after an |
| * implicit type conversion (use some of the casts enlisted for |
| * test 6). |
| * |
| * The test passes if the returned set of values was correct for |
| * all the types considered. Assume epsilon value of 1e-5. |
| * |
| **/ |
| class GPUShaderFP64Test9 : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Test9(deqp::Context& context); |
| |
| void deinit(); |
| virtual tcu::TestNode::IterateResult iterate(); |
| |
| private: |
| /* Private type definitions */ |
| typedef enum { |
| OPERATION_TYPE_ADDITION, |
| OPERATION_TYPE_DIVISION, |
| OPERATION_TYPE_MULTIPLICATION, |
| OPERATION_TYPE_SUBTRACTION, |
| OPERATION_TYPE_PRE_DECREMENTATION, |
| OPERATION_TYPE_PRE_INCREMENTATION, |
| OPERATION_TYPE_POST_DECREMENTATION, |
| OPERATION_TYPE_POST_INCREMENTATION, |
| |
| /* Always last */ |
| OPERATION_TYPE_COUNT |
| } _operation_type; |
| |
| struct _test_case |
| { |
| _operation_type operation_type; |
| Utils::_variable_type result_variable_type; |
| std::string vs_body; |
| Utils::_variable_type variable_type; |
| }; |
| |
| /* Private methods */ |
| bool executeTestIteration(const _test_case& test_case); |
| |
| void getMatrixMultiplicationResult(const Utils::_variable_type& matrix_a_type, |
| const std::vector<double>& matrix_a_data, |
| const Utils::_variable_type& matrix_b_type, |
| const std::vector<double>& matrix_b_data, double* out_result_ptr); |
| |
| const char* getOperatorForOperationType(const _operation_type& operation_type); |
| std::string getOperationTypeString(const _operation_type& operation_type); |
| std::string getVertexShaderBody(_test_case& test_case); |
| void initTest(); |
| void initTestIteration(_test_case& test_case); |
| |
| bool verifyXFBData(const _test_case& test_case, const unsigned char* xfb_data); |
| |
| /* Private fields */ |
| bool m_has_test_passed; |
| glw::GLuint m_po_id; |
| glw::GLuint m_xfb_bo_id; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_vs_id; |
| }; |
| |
| /** Group class for GPU Shader FP64 conformance tests */ |
| class GPUShaderFP64Tests : public deqp::TestCaseGroup |
| { |
| public: |
| /* Public methods */ |
| GPUShaderFP64Tests(deqp::Context& context); |
| virtual ~GPUShaderFP64Tests() |
| { |
| } |
| |
| virtual void init(void); |
| |
| private: |
| /* Private methods */ |
| GPUShaderFP64Tests(const GPUShaderFP64Tests&); |
| GPUShaderFP64Tests& operator=(const GPUShaderFP64Tests&); |
| }; |
| |
| } /* gl4cts namespace */ |
| |
| #endif // _GL4CGPUSHADERFP64TESTS_HPP |