| /*------------------------------------------------------------------------- |
| * 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 |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "es31cArrayOfArraysTests.hpp" |
| #include "gluContextInfo.hpp" |
| #include "gluDefs.hpp" |
| #include "gluRenderContext.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuTestLog.hpp" |
| |
| #include <algorithm> |
| #include <cassert> |
| #include <cstdio> |
| #include <string> |
| using std::string; |
| |
| /* Selects if debug output is enabled */ |
| #define IS_DEBUG 0 |
| #define IS_DEBUG_DUMP_ALL_SHADERS 0 |
| |
| /* Selects if workaround in ExpressionsInvalid2 test is enabled */ |
| #define WRKARD_EXPRESSIONSINVALID2 0 |
| |
| #if IS_DEBUG |
| #include "tcuTestLog.hpp" |
| #endif |
| |
| namespace glcts |
| { |
| namespace ArraysOfArrays |
| { |
| namespace Interface |
| { |
| /* Sets limits on number of dimensions. Value 8 comes from ogirinal "ES" implementation. |
| * Explanation was as follows: |
| * |
| * "The current specifations allow up to 8 array dimensions." |
| */ |
| const size_t ES::MAX_ARRAY_DIMENSIONS = 8; |
| const size_t GL::MAX_ARRAY_DIMENSIONS = 8; |
| |
| /* API specific shader parts */ |
| const char* ES::shader_version_gpu5 = |
| "#version 310 es\n#extension GL_EXT_gpu_shader5 : require\nprecision mediump float;\n\n"; |
| const char* ES::shader_version = "#version 310 es\nprecision mediump float;\n\n"; |
| |
| const char* GL::shader_version_gpu5 = "#version 430 core\n\n"; |
| const char* GL::shader_version = "#version 430 core\n\n"; |
| } /* namespace Interface */ |
| |
| /* Dummy fragment shader source code. |
| * Used when testing the vertex shader. */ |
| const std::string default_fragment_shader_source = "//default fragment shader\n" |
| "out vec4 color;\n" |
| "void main()\n" |
| "{\n" |
| " color = vec4(1.0);\n" |
| "}\n"; |
| |
| /* Dummy vertex shader source code. |
| * Used when testing the fragment shader. */ |
| const std::string default_vertex_shader_source = "//default vertex shader\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(0.0,0.0,0.0,1.0);\n" |
| "}\n"; |
| |
| /* Dummy geometry shader source code. |
| * Used when testing the other shaders. */ |
| const std::string default_geometry_shader_source = "//default geometry\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| "}\n"; |
| |
| /* Dummy tesselation control shader source code. |
| * Used when testing the other shaders. */ |
| const std::string default_tc_shader_source = "//default tcs\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n" |
| "}\n"; |
| |
| /* Dummy tesselation evaluation shader source code. |
| * Used when testing the other shaders. */ |
| const std::string default_te_shader_source = "//default tes\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "}\n"; |
| |
| /* Pass-through shaders source code. Used when testing other stage. */ |
| const std::string pass_fragment_shader_source = "//pass fragment shader\n" |
| "in float fs_result;\n" |
| "out vec4 color;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " color = vec4(fs_result);\n" |
| "}\n"; |
| |
| const std::string pass_geometry_shader_source = "//pass geometry\n" |
| "in float gs_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = gs_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = gs_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = gs_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = gs_result[0];\n" |
| " EmitVertex();\n" |
| "}\n"; |
| |
| const std::string pass_te_shader_source = "//pass tes\n" |
| "in float tcs_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " fs_result = tcs_result[0];\n" |
| "}\n"; |
| |
| /* Empty string */ |
| static const std::string empty_string = ""; |
| |
| /* Beginning of a shader source code. */ |
| const std::string shader_start = "void main()\n" |
| "{\n"; |
| |
| /* End of a shader source code. */ |
| const std::string shader_end = "}\n"; |
| |
| /* Emit full screen quad from GS */ |
| const std::string emit_quad = " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " EmitVertex();\n"; |
| |
| /* Set tesselation levels */ |
| const std::string set_tesseation = " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n"; |
| |
| /* Input and output data type modifiers. */ |
| const std::string in_out_type_modifiers[] = { "in", "out", "uniform" }; |
| |
| /* Types and appropriate initialisers, used throughout these tests */ |
| const var_descriptor var_descriptors[] = { |
| { "bool", "", "true", "false", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "int", "", "1", "0", "0", "int", "", "iterator", "1", "N/A", "N/A" }, |
| { "uint", "", "1u", "0u", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "float", "", "1.0", "0.0", "0.0", "float", "", "iterator", "1.0", "N/A", "N/A" }, |
| { "vec2", "", "vec2(1.0)", "vec2(0.0)", "0.0", "float", "[0]", "vec2(iterator)", "vec2(1.0)", "N/A", "N/A" }, |
| { "vec3", "", "vec3(1.0)", "vec3(0.0)", "0.0", "float", "[0]", "vec3(iterator)", "vec3(1.0)", "N/A", "N/A" }, |
| { "vec4", "", "vec4(1.0)", "vec4(0.0)", "0.0", "float", "[0]", "vec4(iterator)", "vec4(1.0)", "N/A", "N/A" }, |
| { "bvec2", "", "bvec2(1)", "bvec2(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "bvec3", "", "bvec3(1)", "bvec3(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "bvec4", "", "bvec4(1)", "bvec4(0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "ivec2", "", "ivec2(1)", "ivec2(0)", "0", "int", "[0]", "ivec2(iterator)", "ivec2(1)", "N/A", "N/A" }, |
| { "ivec3", "", "ivec3(1)", "ivec3(0)", "0", "int", "[0]", "ivec3(iterator)", "ivec3(1)", "N/A", "N/A" }, |
| { "ivec4", "", "ivec4(1)", "ivec4(0)", "0", "int", "[0]", "ivec4(iterator)", "ivec4(1)", "N/A", "N/A" }, |
| { "uvec2", "", "uvec2(1u)", "uvec2(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "uvec3", "", "uvec3(1u)", "uvec3(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "uvec4", "", "uvec4(1u)", "uvec4(0u)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat2", "", "mat2(1.0)", "mat2(0.0)", "0.0", "float", "[0][0]", "mat2(iterator)", "mat2(1.0)", "N/A", "N/A" }, |
| { "mat3", "", "mat3(1.0)", "mat3(0.0)", "0.0", "float", "[0][0]", "mat3(iterator)", "mat3(1.0)", "N/A", "N/A" }, |
| { "mat4", "", "mat4(1.0)", "mat4(0.0)", "0.0", "float", "[0][0]", "mat4(iterator)", "mat4(1.0)", "N/A", "N/A" }, |
| { "mat2x2", "", "mat2x2(1.0)", "mat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat2x3", "", "mat2x3(1.0)", "mat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat2x4", "", "mat2x4(1.0)", "mat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat3x2", "", "mat3x2(1.0)", "mat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat3x3", "", "mat3x3(1.0)", "mat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat3x4", "", "mat3x4(1.0)", "mat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat4x2", "", "mat4x2(1.0)", "mat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat4x3", "", "mat4x3(1.0)", "mat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "mat4x4", "", "mat4x4(1.0)", "mat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "imageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "iimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "uimageBuffer", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "samplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "isamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "usamplerBuffer", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "sampler2D", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "vec4" }, |
| { "sampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" }, |
| { "samplerCube", "", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" }, |
| { |
| "samplerCubeShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float", |
| }, |
| { "sampler2DShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "float" }, |
| { "sampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "vec4" }, |
| { "sampler2DArrayShadow", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec4(0.0)", "float" }, |
| { "isampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "ivec4" }, |
| { "isampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" }, |
| { "isamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" }, |
| { "isampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "ivec4" }, |
| { "usampler2D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec2(0.0)", "uvec4" }, |
| { "usampler3D", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" }, |
| { "usamplerCube", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" }, |
| { "usampler2DArray", "lowp", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "vec3(0.0)", "uvec4" }, |
| }; |
| |
| const var_descriptor var_double_descriptors[] = { |
| { "double", "", "1.0", "0.0", "0.0", "double", "", "iterator", "1.0", "N/A", "N/A" }, |
| { "dmat2", "", "dmat2(1.0)", "dmat2(0.0)", "0.0", "double", "[0][0]", "dmat2(iterator)", "dmat2(1.0)", "N/A", |
| "N/A" }, |
| { "dmat3", "", "dmat3(1.0)", "dmat3(0.0)", "0.0", "double", "[0][0]", "dmat3(iterator)", "dmat3(1.0)", "N/A", |
| "N/A" }, |
| { "dmat4", "", "dmat4(1.0)", "dmat4(0.0)", "0.0", "double", "[0][0]", "dmat4(iterator)", "dmat4(1.0)", "N/A", |
| "N/A" }, |
| { "dmat2x2", "", "dmat2x2(1.0)", "dmat2x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat2x3", "", "dmat2x3(1.0)", "dmat2x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat2x4", "", "dmat2x4(1.0)", "dmat2x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat3x2", "", "dmat3x2(1.0)", "dmat3x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat3x3", "", "dmat3x3(1.0)", "dmat3x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat3x4", "", "dmat3x4(1.0)", "dmat3x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat4x2", "", "dmat4x2(1.0)", "dmat4x2(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat4x3", "", "dmat4x3(1.0)", "dmat4x3(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| { "dmat4x4", "", "dmat4x4(1.0)", "dmat4x4(0.0)", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A", "N/A" }, |
| }; |
| |
| _supported_variable_types_map supported_variable_types_map; |
| |
| /** List of all supported variable types for es. */ |
| const test_var_type var_types_es[] = { |
| VAR_TYPE_BOOL, VAR_TYPE_INT, VAR_TYPE_UINT, VAR_TYPE_FLOAT, VAR_TYPE_VEC2, VAR_TYPE_VEC3, |
| VAR_TYPE_VEC4, VAR_TYPE_BVEC2, VAR_TYPE_BVEC3, VAR_TYPE_BVEC4, VAR_TYPE_IVEC2, VAR_TYPE_IVEC3, |
| VAR_TYPE_IVEC4, VAR_TYPE_UVEC2, VAR_TYPE_UVEC3, VAR_TYPE_UVEC4, VAR_TYPE_MAT2, VAR_TYPE_MAT3, |
| VAR_TYPE_MAT4, VAR_TYPE_MAT2X2, VAR_TYPE_MAT2X3, VAR_TYPE_MAT2X4, VAR_TYPE_MAT3X2, VAR_TYPE_MAT3X3, |
| VAR_TYPE_MAT3X4, VAR_TYPE_MAT4X2, VAR_TYPE_MAT4X3, VAR_TYPE_MAT4X4, |
| }; |
| |
| const test_var_type* Interface::ES::var_types = var_types_es; |
| const size_t Interface::ES::n_var_types = sizeof(var_types_es) / sizeof(var_types_es[0]); |
| |
| /** List of all supported variable types for gl. */ |
| static const glcts::test_var_type var_types_gl[] = { |
| VAR_TYPE_BOOL, VAR_TYPE_INT, VAR_TYPE_UINT, VAR_TYPE_FLOAT, VAR_TYPE_VEC2, VAR_TYPE_VEC3, |
| VAR_TYPE_VEC4, VAR_TYPE_BVEC2, VAR_TYPE_BVEC3, VAR_TYPE_BVEC4, VAR_TYPE_IVEC2, VAR_TYPE_IVEC3, |
| VAR_TYPE_IVEC4, VAR_TYPE_UVEC2, VAR_TYPE_UVEC3, VAR_TYPE_UVEC4, VAR_TYPE_MAT2, VAR_TYPE_MAT3, |
| VAR_TYPE_MAT4, VAR_TYPE_MAT2X2, VAR_TYPE_MAT2X3, VAR_TYPE_MAT2X4, VAR_TYPE_MAT3X2, VAR_TYPE_MAT3X3, |
| VAR_TYPE_MAT3X4, VAR_TYPE_MAT4X2, VAR_TYPE_MAT4X3, VAR_TYPE_MAT4X4, VAR_TYPE_DOUBLE, VAR_TYPE_DMAT2, |
| VAR_TYPE_DMAT3, VAR_TYPE_DMAT4, VAR_TYPE_DMAT2X2, VAR_TYPE_DMAT2X3, VAR_TYPE_DMAT2X4, VAR_TYPE_DMAT3X2, |
| VAR_TYPE_DMAT3X3, VAR_TYPE_DMAT3X4, VAR_TYPE_DMAT4X2, VAR_TYPE_DMAT4X3, VAR_TYPE_DMAT4X4, |
| }; |
| |
| const test_var_type* Interface::GL::var_types = var_types_gl; |
| const size_t Interface::GL::n_var_types = sizeof(var_types_gl) / sizeof(var_types_gl[0]); |
| |
| /** List of all supported opaque types. */ |
| const glcts::test_var_type opaque_var_types[] = { |
| //Floating Point Sampler Types (opaque) |
| VAR_TYPE_SAMPLER2D, VAR_TYPE_SAMPLER3D, VAR_TYPE_SAMPLERCUBE, VAR_TYPE_SAMPLERCUBESHADOW, VAR_TYPE_SAMPLER2DSHADOW, |
| VAR_TYPE_SAMPLER2DARRAY, VAR_TYPE_SAMPLER2DARRAYSHADOW, |
| //Signed Integer Sampler Types (opaque) |
| VAR_TYPE_ISAMPLER2D, VAR_TYPE_ISAMPLER3D, VAR_TYPE_ISAMPLERCUBE, VAR_TYPE_ISAMPLER2DARRAY, |
| //Unsigned Integer Sampler Types (opaque) |
| VAR_TYPE_USAMPLER2D, VAR_TYPE_USAMPLER3D, VAR_TYPE_USAMPLERCUBE, VAR_TYPE_USAMPLER2DARRAY, |
| }; |
| |
| /** Sets up the type map that will be used to look up the type names, initialisation |
| * values, etc., associated with each of the types used within the array tests |
| * |
| **/ |
| template <class API> |
| void initializeMap() |
| { |
| int temp_index = 0; |
| |
| // Set up the map |
| supported_variable_types_map[VAR_TYPE_BOOL] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_INT] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_UINT] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_FLOAT] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_VEC2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_VEC3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_VEC4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_BVEC2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_BVEC3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_BVEC4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_IVEC2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_IVEC3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_IVEC4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_UVEC2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_UVEC3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_UVEC4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT2X2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT2X3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT2X4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT3X2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT3X3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT3X4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT4X2] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT4X3] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_MAT4X4] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_IMAGEBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_IIMAGEBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_UIMAGEBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLERBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_ISAMPLERBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_USAMPLERBUFFER] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLER2D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLER3D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLERCUBE] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLERCUBESHADOW] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLER2DSHADOW] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAY] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_SAMPLER2DARRAYSHADOW] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_ISAMPLER2D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_ISAMPLER3D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_ISAMPLERCUBE] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_ISAMPLER2DARRAY] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_USAMPLER2D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_USAMPLER3D] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_USAMPLERCUBE] = var_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_USAMPLER2DARRAY] = var_descriptors[temp_index++]; |
| |
| if (API::USE_DOUBLE) |
| { |
| temp_index = 0; |
| |
| supported_variable_types_map[VAR_TYPE_DOUBLE] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT2] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT3] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT4] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT2X2] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT2X3] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT2X4] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT3X2] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT3X3] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT3X4] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT4X2] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT4X3] = var_double_descriptors[temp_index++]; |
| supported_variable_types_map[VAR_TYPE_DMAT4X4] = var_double_descriptors[temp_index++]; |
| } |
| } |
| |
| /** Macro appends default ending of main function to source string |
| * |
| * @param SOURCE Tested shader source |
| **/ |
| #define DEFAULT_MAIN_ENDING(TYPE, SOURCE) \ |
| { \ |
| /* Apply stage specific stuff */ \ |
| switch (TYPE) \ |
| { \ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: \ |
| SOURCE += "\n gl_Position = vec4(0.0);\n"; \ |
| break; \ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: \ |
| break; \ |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: \ |
| break; \ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: \ |
| SOURCE += emit_quad; \ |
| break; \ |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: \ |
| SOURCE += set_tesseation; \ |
| break; \ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: \ |
| break; \ |
| default: \ |
| TCU_FAIL("Unrecognized shader type."); \ |
| break; \ |
| } \ |
| \ |
| /* End main function */ \ |
| SOURCE += shader_end; \ |
| } |
| |
| /** Macro executes positive test selected on USE_ALL_SHADER_STAGES |
| * |
| * @param TYPE Tested shader stage |
| * @param SOURCE Tested shader source |
| * @param DELETE Selects if program should be deleted afterwards |
| **/ |
| #define EXECUTE_POSITIVE_TEST(TYPE, SOURCE, DELETE, GPU5) \ |
| { \ |
| const std::string* cs = &empty_string; \ |
| const std::string* vs = &default_vertex_shader_source; \ |
| const std::string* tcs = &default_tc_shader_source; \ |
| const std::string* tes = &default_te_shader_source; \ |
| const std::string* gs = &default_geometry_shader_source; \ |
| const std::string* fs = &default_fragment_shader_source; \ |
| \ |
| switch (TYPE) \ |
| { \ |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: \ |
| cs = &SOURCE; \ |
| vs = &empty_string; \ |
| tcs = &empty_string; \ |
| tes = &empty_string; \ |
| gs = &empty_string; \ |
| fs = &empty_string; \ |
| break; \ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: \ |
| fs = &SOURCE; \ |
| break; \ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: \ |
| gs = &SOURCE; \ |
| break; \ |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: \ |
| tcs = &SOURCE; \ |
| break; \ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: \ |
| tes = &SOURCE; \ |
| break; \ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: \ |
| vs = &SOURCE; \ |
| break; \ |
| default: \ |
| TCU_FAIL("Invalid enum"); \ |
| break; \ |
| }; \ |
| \ |
| if (API::USE_ALL_SHADER_STAGES) \ |
| { \ |
| this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, DELETE, GPU5); \ |
| } \ |
| else \ |
| { \ |
| this->execute_positive_test(*vs, *fs, DELETE, GPU5); \ |
| } \ |
| } |
| |
| /** Macro executes either positive or negative test |
| * |
| * @param S Selects negative test when 0, positive test otherwise |
| * @param TYPE Tested shader stage |
| * @param SOURCE Tested shader source |
| **/ |
| #define EXECUTE_SHADER_TEST(S, TYPE, SOURCE) \ |
| if (S) \ |
| { \ |
| EXECUTE_POSITIVE_TEST(TYPE, SOURCE, true, false); \ |
| } \ |
| else \ |
| { \ |
| this->execute_negative_test(TYPE, SOURCE); \ |
| } |
| |
| /** Test case constructor. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param context EGL context ID. |
| * @param name Name of a test case. |
| * @param description Test case description. |
| **/ |
| template <class API> |
| TestCaseBase<API>::TestCaseBase(Context& context, const char* name, const char* description) |
| : tcu::TestCase(context.getTestContext(), name, description) |
| , context_id(context) |
| , program_object_id(0) |
| , compute_shader_object_id(0) |
| , fragment_shader_object_id(0) |
| , geometry_shader_object_id(0) |
| , tess_ctrl_shader_object_id(0) |
| , tess_eval_shader_object_id(0) |
| , vertex_shader_object_id(0) |
| { |
| /* Left blank on purpose */ |
| } |
| |
| /** Clears up the shaders and program that were created during the tests |
| * |
| * @tparam API Tested API descriptor |
| */ |
| template <class API> |
| void TestCaseBase<API>::delete_objects(void) |
| { |
| const glw::Functions& gl = context_id.getRenderContext().getFunctions(); |
| |
| /* Release all ES objects that may have been created by iterate() */ |
| if (program_object_id != 0) |
| { |
| gl.deleteProgram(program_object_id); |
| program_object_id = 0; |
| } |
| |
| /* Use default program object to be sure the objects were released. */ |
| gl.useProgram(0); |
| } |
| |
| /** Releases all OpenGL ES objects that were created for test case purposes. |
| * |
| * @tparam API Tested API descriptor |
| */ |
| template <class API> |
| void TestCaseBase<API>::deinit(void) |
| { |
| this->delete_objects(); |
| } |
| |
| /** Runs the actual test for each shader type. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @return QP_TEST_RESULT_FAIL - test has failed; |
| * QP_TEST_RESULT_PASS - test has succeeded; |
| **/ |
| template <class API> |
| tcu::TestNode::IterateResult TestCaseBase<API>::iterate(void) |
| { |
| test_shader_compilation(TestCaseBase<API>::VERTEX_SHADER_TYPE); |
| test_shader_compilation(TestCaseBase<API>::FRAGMENT_SHADER_TYPE); |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| test_shader_compilation(TestCaseBase<API>::COMPUTE_SHADER_TYPE); |
| test_shader_compilation(TestCaseBase<API>::GEOMETRY_SHADER_TYPE); |
| test_shader_compilation(TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE); |
| test_shader_compilation(TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE); |
| } |
| |
| return STOP; |
| } |
| |
| /** Generates a shader object of the specified type, |
| * attaches the specified shader source, |
| * compiles it, and returns the compilation result. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param shader_source The source for the shader object. |
| * @param tested_shader_type The type of shader being compiled (vertex or fragment). |
| * |
| * @return Compilation result (GL_TRUE if the shader compilation succeeded, GL_FALSE otherwise). |
| **/ |
| template <class API> |
| glw::GLint TestCaseBase<API>::compile_shader_and_get_compilation_result(const std::string& tested_snippet, |
| TestShaderType tested_shader_type, |
| bool require_gpu_shader5) |
| { |
| static const char* preamble_cs = "\n" |
| "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" |
| "\n"; |
| |
| static const char* preamble_gs = "\n" |
| "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n"; |
| |
| static const char* preamble_tcs = "\n" |
| "layout(vertices = 1) out;\n" |
| "\n"; |
| |
| static const char* preamble_tes = "\n" |
| "layout(isolines, point_mode) in;\n" |
| "\n"; |
| |
| glw::GLint compile_status = GL_TRUE; |
| const glw::Functions& gl = context_id.getRenderContext().getFunctions(); |
| glw::GLint shader_object_id = 0; |
| |
| std::string shader_source; |
| |
| if (true == tested_snippet.empty()) |
| { |
| return compile_status; |
| } |
| |
| if (require_gpu_shader5) |
| { |
| // Add the version number here, rather than in each individual test |
| shader_source = API::shader_version_gpu5; |
| } |
| else |
| { |
| // Add the version number here, rather than in each individual test |
| shader_source = API::shader_version; |
| } |
| |
| /* Apply stage specific stuff */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| break; |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| shader_source += preamble_cs; |
| break; |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| shader_source += preamble_gs; |
| break; |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| shader_source += preamble_tcs; |
| break; |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| shader_source += preamble_tes; |
| break; |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| shader_source += tested_snippet; |
| |
| /* Prepare shader object */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_VERTEX_SHADER); |
| assert(0 == vertex_shader_object_id); |
| vertex_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a vertex shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::VERTEX_SHADER_TYPE: */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_FRAGMENT_SHADER); |
| assert(0 == fragment_shader_object_id); |
| fragment_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a fragment shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: */ |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_COMPUTE_SHADER); |
| assert(0 == compute_shader_object_id); |
| compute_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a compute shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::COMPUTE_SHADER_TYPE: */ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_GEOMETRY_SHADER); |
| assert(0 == geometry_shader_object_id); |
| geometry_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a geometry shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: */ |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_TESS_CONTROL_SHADER); |
| assert(0 == tess_ctrl_shader_object_id); |
| tess_ctrl_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation control shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| { |
| shader_object_id = gl.createShader(GL_TESS_EVALUATION_SHADER); |
| assert(0 == tess_eval_shader_object_id); |
| tess_eval_shader_object_id = shader_object_id; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a tesselation evaluation shader."); |
| |
| break; |
| } /* case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: */ |
| default: |
| { |
| TCU_FAIL("Unrecognized shader type."); |
| |
| break; |
| } /* default: */ |
| } /* switch (tested_shader_type) */ |
| |
| /* Assign source code to the objects */ |
| const char* code_ptr = shader_source.c_str(); |
| |
| #if IS_DEBUG_DUMP_ALL_SHADERS |
| context_id.getTestContext().getLog() << tcu::TestLog::Message << "Compiling: " << tcu::TestLog::EndMessage; |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr); |
| #endif /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| |
| gl.shaderSource(shader_object_id, 1 /* count */, &code_ptr, NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() failed"); |
| |
| /* Compile the shader */ |
| gl.compileShader(shader_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() failed"); |
| |
| /* Get the compilation result. */ |
| gl.getShaderiv(shader_object_id, GL_COMPILE_STATUS, &compile_status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() failed"); |
| |
| #if IS_DEBUG |
| if (GL_TRUE != compile_status) |
| { |
| glw::GLint length = 0; |
| std::string message; |
| |
| /* Error log length */ |
| gl.getShaderiv(shader_object_id, GL_INFO_LOG_LENGTH, &length); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv"); |
| |
| /* Prepare storage */ |
| message.resize(length, 0); |
| |
| /* Get error log */ |
| gl.getShaderInfoLog(shader_object_id, length, 0, &message[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog"); |
| |
| context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0] |
| << tcu::TestLog::EndMessage; |
| |
| #if IS_DEBUG_DUMP_ALL_SHADERS |
| #else /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(code_ptr); |
| #endif /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| } |
| #endif /* IS_DEBUG */ |
| |
| return compile_status; |
| } |
| |
| /** Runs the negative test. |
| * The shader sources are considered as invalid, |
| * and the compilation of a shader object with the specified |
| * shader source is expected to fail. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader object (can be fragment or vertex). |
| * @param shader_source The source for the shader object to be used for this test. |
| * |
| * @return QP_TEST_RESULT_FAIL - test has failed; |
| * QP_TEST_RESULT_PASS - test has succeeded; |
| **/ |
| template <class API> |
| tcu::TestNode::IterateResult TestCaseBase<API>::execute_negative_test( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& shader_source) |
| { |
| glw::GLint compile_status = GL_FALSE; |
| const char* error_message = 0; |
| const glw::Functions& gl = context_id.getRenderContext().getFunctions(); |
| bool test_result = true; |
| |
| /* Try to generate and compile the shader object. */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| error_message = |
| "The fragment shader was expected to fail to compile, but the compilation process was successful."; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| error_message = |
| "The vertex shader was expected to fail to compile, but the compilation process was successful."; |
| |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| error_message = |
| "The compute shader was expected to fail to compile, but the compilation process was successful."; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| error_message = |
| "The geometry shader was expected to fail to compile, but the compilation process was successful."; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| error_message = "The tesselation control shader was expected to fail to compile, but the compilation process " |
| "was successful."; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| error_message = "The tesselation evaluation shader was expected to fail to compile, but the compilation " |
| "process was successful."; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| test_result = false; |
| |
| break; |
| } /* switch (shader_type) */ |
| |
| compile_status = compile_shader_and_get_compilation_result(shader_source, tested_shader_type); |
| |
| if (compile_status == GL_TRUE) |
| { |
| TCU_FAIL(error_message); |
| |
| test_result = false; |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| if (0 != compute_shader_object_id) |
| { |
| gl.deleteShader(compute_shader_object_id); |
| compute_shader_object_id = 0; |
| } |
| if (0 != fragment_shader_object_id) |
| { |
| gl.deleteShader(fragment_shader_object_id); |
| fragment_shader_object_id = 0; |
| } |
| if (0 != geometry_shader_object_id) |
| { |
| gl.deleteShader(geometry_shader_object_id); |
| geometry_shader_object_id = 0; |
| } |
| if (0 != tess_ctrl_shader_object_id) |
| { |
| gl.deleteShader(tess_ctrl_shader_object_id); |
| tess_ctrl_shader_object_id = 0; |
| } |
| if (0 != tess_eval_shader_object_id) |
| { |
| gl.deleteShader(tess_eval_shader_object_id); |
| tess_eval_shader_object_id = 0; |
| } |
| if (0 != vertex_shader_object_id) |
| { |
| gl.deleteShader(vertex_shader_object_id); |
| vertex_shader_object_id = 0; |
| } |
| |
| /* Return test pass if true. */ |
| if (true == test_result) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| |
| return CONTINUE; |
| } |
| |
| /** Runs the positive test. |
| * The shader sources are considered as valid, |
| * and the compilation and program linking are expected to succeed. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param vertex_shader_source The source for the vertex shader to be used for this test. |
| * @param fragment_shader_source The source for the fragment shader to be used for this test. |
| * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning. |
| * |
| * @return QP_TEST_RESULT_FAIL - test has failed; |
| * QP_TEST_RESULT_PASS - test has succeeded; |
| **/ |
| template <class API> |
| tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test(const std::string& vertex_shader_source, |
| const std::string& fragment_shader_source, |
| bool delete_generated_objects, |
| bool require_gpu_shader5) |
| { |
| glw::GLint compile_status = GL_TRUE; |
| const glw::Functions& gl = context_id.getRenderContext().getFunctions(); |
| glw::GLint link_status = GL_TRUE; |
| bool test_result = true; |
| |
| /* Compile, and check the compilation result for the fragment shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| /* Compile, and check the compilation result for the vertex shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| if (true == test_result) |
| { |
| /* Create program object. */ |
| assert(0 == program_object_id); |
| program_object_id = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object."); |
| |
| /* Configure the program object */ |
| gl.attachShader(program_object_id, fragment_shader_object_id); |
| gl.attachShader(program_object_id, vertex_shader_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed."); |
| |
| gl.deleteShader(fragment_shader_object_id); |
| gl.deleteShader(vertex_shader_object_id); |
| fragment_shader_object_id = 0; |
| vertex_shader_object_id = 0; |
| |
| /* Link the program object */ |
| gl.linkProgram(program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed."); |
| |
| /* Make sure the linking operation succeeded. */ |
| gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed."); |
| |
| if (link_status != GL_TRUE) |
| { |
| #if IS_DEBUG |
| glw::GLint length = 0; |
| std::string message; |
| |
| /* Get error log length */ |
| gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); |
| |
| message.resize(length, 0); |
| |
| /* Get error log */ |
| gl.getProgramInfoLog(program_object_id, length, 0, &message[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); |
| |
| context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0] |
| << tcu::TestLog::EndMessage; |
| |
| #if IS_DEBUG_DUMP_ALL_SHADERS |
| #else /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source); |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source); |
| #endif /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| #endif /* IS_DEBUG */ |
| |
| TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful."); |
| |
| test_result = false; |
| } |
| } |
| |
| if (delete_generated_objects) |
| { |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } |
| |
| /* Return test pass if true. */ |
| if (true == test_result) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| |
| return CONTINUE; |
| } |
| |
| /** Runs the positive test. |
| * The shader sources are considered as valid, |
| * and the compilation and program linking are expected to succeed. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param vertex_shader_source The source for the vertex shader to be used for this test. |
| * @param tess_ctrl_shader_source The source for the vertex shader to be used for this test. |
| * @param tess_eval_shader_source The source for the vertex shader to be used for this test. |
| * @param geometry_shader_source The source for the vertex shader to be used for this test. |
| * @param fragment_shader_source The source for the vertex shader to be used for this test. |
| * @param compute_shader_source The source for the fragment shader to be used for this test. |
| * @param delete_generated_objects If true, the compiled shader objects will be deleted before returning. |
| * |
| * @return QP_TEST_RESULT_FAIL - test has failed; |
| * QP_TEST_RESULT_PASS - test has succeeded; |
| **/ |
| template <class API> |
| tcu::TestNode::IterateResult TestCaseBase<API>::execute_positive_test( |
| const std::string& vertex_shader_source, const std::string& tess_ctrl_shader_source, |
| const std::string& tess_eval_shader_source, const std::string& geometry_shader_source, |
| const std::string& fragment_shader_source, const std::string& compute_shader_source, bool delete_generated_objects, |
| bool require_gpu_shader5) |
| { |
| glw::GLint compile_status = GL_TRUE; |
| const glw::Functions& gl = context_id.getRenderContext().getFunctions(); |
| glw::GLint link_status = GL_TRUE; |
| bool test_compute = !compute_shader_source.empty(); |
| bool test_result = true; |
| |
| if (false == test_compute) |
| { |
| /* Compile, and check the compilation result for the fragment shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| fragment_shader_source, TestCaseBase<API>::FRAGMENT_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The fragment shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| /* Compile, and check the compilation result for the geometry shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| geometry_shader_source, TestCaseBase<API>::GEOMETRY_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The geometry shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| /* Compile, and check the compilation result for the te shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| tess_eval_shader_source, TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The tesselation evaluation shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| /* Compile, and check the compilation result for the tc shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| tess_ctrl_shader_source, TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The tesselation control shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| |
| /* Compile, and check the compilation result for the vertex shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| vertex_shader_source, TestCaseBase<API>::VERTEX_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The vertex shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| } |
| else |
| { |
| /* Compile, and check the compilation result for the compute shader object. */ |
| compile_status = compile_shader_and_get_compilation_result( |
| compute_shader_source, TestCaseBase<API>::COMPUTE_SHADER_TYPE, require_gpu_shader5); |
| |
| if (compile_status == GL_FALSE) |
| { |
| TCU_FAIL("The compute shader was expected to compile successfully, but failed to compile."); |
| |
| test_result = false; |
| } |
| } |
| |
| if (true == test_result) |
| { |
| /* Create program object. */ |
| program_object_id = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a program object."); |
| |
| /* Configure the program object */ |
| if (false == test_compute) |
| { |
| gl.attachShader(program_object_id, fragment_shader_object_id); |
| |
| if (geometry_shader_object_id) |
| { |
| gl.attachShader(program_object_id, geometry_shader_object_id); |
| } |
| |
| if (tess_ctrl_shader_object_id) |
| { |
| gl.attachShader(program_object_id, tess_ctrl_shader_object_id); |
| } |
| |
| if (tess_eval_shader_object_id) |
| { |
| gl.attachShader(program_object_id, tess_eval_shader_object_id); |
| } |
| |
| gl.attachShader(program_object_id, vertex_shader_object_id); |
| } |
| else |
| { |
| gl.attachShader(program_object_id, compute_shader_object_id); |
| } |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() failed."); |
| |
| if (false == test_compute) |
| { |
| gl.deleteShader(fragment_shader_object_id); |
| |
| if (geometry_shader_object_id) |
| { |
| gl.deleteShader(geometry_shader_object_id); |
| } |
| |
| if (tess_ctrl_shader_object_id) |
| { |
| gl.deleteShader(tess_ctrl_shader_object_id); |
| } |
| |
| if (tess_eval_shader_object_id) |
| { |
| gl.deleteShader(tess_eval_shader_object_id); |
| } |
| |
| gl.deleteShader(vertex_shader_object_id); |
| } |
| else |
| { |
| gl.deleteShader(compute_shader_object_id); |
| } |
| |
| fragment_shader_object_id = 0; |
| vertex_shader_object_id = 0; |
| geometry_shader_object_id = 0; |
| tess_ctrl_shader_object_id = 0; |
| tess_eval_shader_object_id = 0; |
| compute_shader_object_id = 0; |
| |
| /* Link the program object */ |
| gl.linkProgram(program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() failed."); |
| |
| /* Make sure the linking operation succeeded. */ |
| gl.getProgramiv(program_object_id, GL_LINK_STATUS, &link_status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() failed."); |
| |
| if (link_status != GL_TRUE) |
| { |
| #if IS_DEBUG |
| glw::GLint length = 0; |
| std::string message; |
| |
| /* Get error log length */ |
| gl.getProgramiv(program_object_id, GL_INFO_LOG_LENGTH, &length); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv"); |
| |
| message.resize(length, 0); |
| |
| /* Get error log */ |
| gl.getProgramInfoLog(program_object_id, length, 0, &message[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog"); |
| |
| context_id.getTestContext().getLog() << tcu::TestLog::Message << "Error message: " << &message[0] |
| << tcu::TestLog::EndMessage; |
| |
| #if IS_DEBUG_DUMP_ALL_SHADERS |
| if (false == test_compute) |
| { |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(vertex_shader_source); |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_ctrl_shader_source); |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(tess_eval_shader_source); |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(geometry_shader_source); |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(fragment_shader_source); |
| } |
| else |
| { |
| context_id.getTestContext().getLog() << tcu::TestLog::KernelSource(compute_shader_source); |
| } |
| #endif /* IS_DEBUG_DUMP_ALL_SHADERS */ |
| #endif /* IS_DEBUG */ |
| |
| TCU_FAIL("Linking was expected to succeed, but the process was unsuccessful."); |
| |
| test_result = false; |
| } |
| } |
| |
| if (delete_generated_objects) |
| { |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } |
| |
| /* Return test pass if true. */ |
| if (true == test_result) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| |
| return CONTINUE; |
| } |
| |
| /** Adds the specified @param sub_script onto the base_string @param number_of_elements times. |
| * E.g. extend_string("a", [2], 3) would give a[2][2][2]. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param base_string The base string that is to be added to. |
| * @param sub_string The string to be repeatedly added |
| * @param number_of_elements The number of repetitions. |
| * |
| * @return The extended string. |
| **/ |
| template <class API> |
| std::string TestCaseBase<API>::extend_string(std::string base_string, std::string sub_string, size_t number_of_elements) |
| { |
| std::string temp_string = base_string; |
| |
| for (size_t sub_script_index = 0; sub_script_index < number_of_elements; sub_script_index++) |
| { |
| temp_string += sub_string; |
| } |
| |
| return temp_string; |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsPrimitive |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| * |
| **/ |
| template <class API> |
| void SizedDeclarationsPrimitive<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| /* Loop round for each var_types ("int", "uint", "float", etc.) |
| * We are testing a[][] to a [][][][][][][][], so start counter at 2. */ |
| for (size_t max_dimension_limit = 2; max_dimension_limit <= API::MAX_ARRAY_DIMENSIONS; |
| max_dimension_limit++) |
| { |
| // Record the base varTypeModifier + varType |
| std::string base_var_type = var_iterator->second.type; |
| std::string base_variable_string = base_var_type; |
| |
| for (size_t base_sub_script_index = 0; base_sub_script_index <= max_dimension_limit; |
| base_sub_script_index++) |
| { |
| std::string shader_source = ""; |
| |
| // Add the shader body start, and the base varTypeModifier + varType + variable name. |
| shader_source += shader_start + " " + base_variable_string + " a"; |
| |
| for (size_t remaining_sub_script_index = base_sub_script_index; |
| remaining_sub_script_index < max_dimension_limit; remaining_sub_script_index++) |
| { |
| /* Add as many array sub_scripts as we can, up to the current dimension limit. */ |
| shader_source += "[2]"; |
| } |
| |
| /* End line */ |
| shader_source += ";\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| |
| /* From now on, we'll have an extra sub_script each time. */ |
| base_variable_string += "[2]"; |
| } /* for (int base_sub_script_index = 0; ...) */ |
| } /* for (int max_dimension_limit = 2; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsStructTypes1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsStructTypes1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct("struct light {\n" |
| " float intensity;\n" |
| " int position;\n" |
| "};\n\n"); |
| std::string shader_source; |
| |
| for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| shader_source = example_struct; |
| shader_source += shader_start; |
| shader_source += " light[2]"; |
| |
| for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++) |
| { |
| shader_source += "[2]"; |
| } |
| |
| shader_source += " x;\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| |
| } /* for (int max_dimension_index = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsStructTypes2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsStructTypes2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string structure_declaration = "struct MyStructure {\n" |
| " float a[2], " |
| "b[2][2], " |
| "c[2][2][2], " |
| "d[2][2][2][2], " |
| "e[2][2][2][2][2], " |
| "f[2][2][2][2][2][2], " |
| "g[2][2][2][2][2][2][2], " |
| "h[2][2][2][2][2][2][2][2];\n" |
| "} myStructureObject;\n\n"; |
| std::string shader_source = structure_declaration; |
| |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsStructTypes3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsStructTypes3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct("struct light {\n" |
| " float[2] intensity;\n" |
| " int[2] position;\n" |
| "};\n"); |
| std::string shader_source; |
| |
| for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| shader_source = example_struct; |
| shader_source += shader_start; |
| shader_source += this->extend_string(" light my_light_object", "[2]", max_dimension_index); |
| shader_source += ";\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsStructTypes4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsStructTypes4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct("struct light {\n" |
| " float[2] intensity;\n" |
| " int[2] position;\n" |
| "} lightVar[2]"); |
| std::string shader_source; |
| |
| for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| shader_source = example_struct; |
| |
| for (size_t temp_dimension_index = 0; temp_dimension_index < max_dimension_index; temp_dimension_index++) |
| { |
| shader_source += "[2]"; |
| } |
| shader_source += ";\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsTypenameStyle1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsTypenameStyle1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string shader_source = shader_start; |
| |
| shader_source += this->extend_string(" float", "[2]", max_dimension_index); |
| shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index); |
| shader_source += ";\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsTypenameStyle2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsTypenameStyle2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_source = shader_start; |
| |
| shader_source += this->extend_string(" float", "[2]", 2); |
| shader_source += this->extend_string(" a", "[2]", 0); |
| shader_source += ", "; |
| shader_source += this->extend_string("b", "[2]", 1); |
| shader_source += ", "; |
| shader_source += this->extend_string("c", "[2]", 2); |
| shader_source += ", "; |
| shader_source += this->extend_string("d", "[2]", 3); |
| shader_source += ", "; |
| shader_source += this->extend_string("e", "[2]", 4); |
| shader_source += ", "; |
| shader_source += this->extend_string("f", "[2]", 5); |
| shader_source += ", "; |
| shader_source += this->extend_string("g", "[2]", 6); |
| shader_source += ";\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsTypenameStyle3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsTypenameStyle3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_source = "struct{\n" + this->extend_string(" float", "[2]", 2); |
| |
| shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS); |
| shader_source += ","; |
| shader_source += this->extend_string(" b", "[2]", 1); |
| shader_source += ","; |
| shader_source += this->extend_string(" c", "[2]", 2); |
| shader_source += ","; |
| shader_source += this->extend_string(" d", "[2]", 3); |
| shader_source += ","; |
| shader_source += this->extend_string(" e", "[2]", 4); |
| shader_source += ","; |
| shader_source += this->extend_string(" f", "[2]", 5); |
| shader_source += ","; |
| shader_source += this->extend_string(" g", "[2]", 6); |
| shader_source += ";\n} x;\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsTypenameStyle4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsTypenameStyle4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct_begin("struct light {\n"); |
| std::string example_struct_end("};\n\n"); |
| |
| for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string shader_source = example_struct_begin; |
| |
| shader_source += this->extend_string(" float", "[2]", max_dimension_index); |
| shader_source += this->extend_string(" x", "[2]", API::MAX_ARRAY_DIMENSIONS - max_dimension_index); |
| shader_source += ";\n"; |
| shader_source += example_struct_end; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsTypenameStyle5 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsTypenameStyle5<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct_begin("struct light {\n"); |
| std::string example_struct_end("};\n\n"); |
| |
| std::string shader_source = example_struct_begin; |
| |
| shader_source += this->extend_string(" float", "[2]", 2); |
| shader_source += this->extend_string(" a", "[2]", API::MAX_ARRAY_DIMENSIONS - API::MAX_ARRAY_DIMENSIONS); |
| shader_source += ", "; |
| shader_source += this->extend_string("b", "[2]", 2); |
| shader_source += ", "; |
| shader_source += this->extend_string("c", "[2]", 3); |
| shader_source += ", "; |
| shader_source += this->extend_string("d", "[2]", 4); |
| shader_source += ", "; |
| shader_source += this->extend_string("e", "[2]", 5); |
| shader_source += ", "; |
| shader_source += this->extend_string("f", "[2]", 6); |
| shader_source += ";\n"; |
| shader_source += example_struct_end; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Generates the shader source code for the SizedDeclarationsFunctionParams |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void SizedDeclarationsFunctionParams<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| size_t dimension_index = 0; |
| std::string example_struct1("\nvoid my_function("); |
| std::string example_struct2(")\n" |
| "{\n" |
| "}\n\n"); |
| std::string base_variable_string; |
| std::string variable_basenames[API::MAX_ARRAY_DIMENSIONS] = { "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8" }; |
| std::string full_variable_names[API::MAX_ARRAY_DIMENSIONS]; |
| |
| for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| full_variable_names[max_dimension_index] = |
| this->extend_string(variable_basenames[max_dimension_index], "[2]", max_dimension_index + 1); |
| } |
| |
| for (size_t max_dimension_index = 0; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| base_variable_string += "float "; |
| base_variable_string += full_variable_names[max_dimension_index]; |
| base_variable_string += ";\n"; |
| } |
| |
| base_variable_string += example_struct1; |
| base_variable_string += this->extend_string("float a", "[2]", 1); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float b", "[2]", 2); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float c", "[2]", 3); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float d", "[2]", 4); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float e", "[2]", 5); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float f", "[2]", 6); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float g", "[2]", 7); |
| base_variable_string += ", "; |
| base_variable_string += this->extend_string("float h", "[2]", 8); |
| base_variable_string += example_struct2; |
| |
| std::string shader_source = base_variable_string; |
| |
| shader_source += shader_start; |
| shader_source += " my_function("; |
| |
| for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++) |
| { |
| shader_source += variable_basenames[dimension_index]; |
| shader_source += ", "; |
| } |
| |
| shader_source += variable_basenames[dimension_index]; |
| shader_source += ");\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| |
| /* Only the previous case should succeed, so start from index 1 rather than 0. |
| * The other cases should fail, so only compile them, rather than trying to also link them. |
| * We'll swap items 2/3, then 2/4, then 2/5, then 2/6, ... |
| * Then we'll swap items 3/4, then 3/5, ... |
| * Repeat, starting for 4/5-8, 5/6-8, 6/7-8... |
| * Finally, we'll swap items 7/8 |
| */ |
| for (size_t swap_item = 1; swap_item < API::MAX_ARRAY_DIMENSIONS; swap_item++) |
| { |
| for (size_t max_dimension_index = swap_item + 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; |
| max_dimension_index++) |
| { |
| std::string temp = variable_basenames[swap_item]; |
| |
| shader_source = base_variable_string; |
| variable_basenames[swap_item] = variable_basenames[max_dimension_index]; |
| variable_basenames[max_dimension_index] = temp; |
| |
| shader_source += shader_start; |
| shader_source += " my_function("; |
| |
| for (dimension_index = 0; dimension_index < API::MAX_ARRAY_DIMENSIONS - 1; dimension_index++) |
| { |
| shader_source += variable_basenames[dimension_index]; |
| shader_source += ", "; |
| } |
| |
| shader_source += variable_basenames[dimension_index]; |
| shader_source += ");\n"; |
| |
| temp = variable_basenames[swap_item]; |
| variable_basenames[swap_item] = variable_basenames[max_dimension_index]; |
| variable_basenames[max_dimension_index] = temp; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int max_dimension_index = swap_item + 1; ...) */ |
| } /* for (int swap_item = 1; ...) */ |
| } |
| |
| /* Generates the shader source code for the sized_declarations_invalid_sizes1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void sized_declarations_invalid_sizes1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_declarations[] = { |
| "float x[2][2][2][0];\n", "float x[2][2][0][2];\n", "float x[2][0][2][2];\n", "float x[0][2][2][2];\n", |
| "float x[2][2][0][0];\n", "float x[2][0][2][0];\n", "float x[0][2][2][0];\n", "float x[2][0][0][2];\n", |
| "float x[0][2][0][2];\n", "float x[0][0][2][2];\n", "float x[2][0][0][0];\n", "float x[0][2][0][0];\n", |
| "float x[0][0][2][0];\n", "float x[0][0][0][2];\n", "float x[0][0][0][0];\n" |
| }; |
| |
| for (size_t invalid_declarations_index = 0; |
| invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations); |
| invalid_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += invalid_declarations[invalid_declarations_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_declarations_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the sized_declarations_invalid_sizes2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void sized_declarations_invalid_sizes2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_declarations[] = { |
| " float x[2][2][2][-1];\n", " float x[2][2][-1][2];\n", " float x[2][-1][2][2];\n", |
| " float x[-1][2][2][2];\n", " float x[2][2][-1][-1];\n", " float x[2][-1][2][-1];\n", |
| " float x[-1][2][2][-1];\n", " float x[2][-1][-1][2];\n", " float x[-1][2][-1][2];\n", |
| " float x[-1][-1][2][2];\n", " float x[2][-1][-1][-1];\n", " float x[-1][2][-1][-1];\n", |
| " float x[-1][-1][2][-1];\n", " float x[-1][-1][-1][2];\n", " float x[-1][-1][-1][-1];\n" |
| }; |
| |
| for (size_t invalid_declarations_index = 0; |
| invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations); |
| invalid_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += invalid_declarations[invalid_declarations_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_declarations_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the sized_declarations_invalid_sizes3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void sized_declarations_invalid_sizes3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_declarations[] = { |
| " float x[2][2][2][a];\n", " float x[2][2][a][2];\n", " float x[2][a][2][2];\n", |
| " float x[a][2][2][2];\n", " float x[2][2][a][a];\n", " float x[2][a][2][a];\n", |
| " float x[a][2][2][a];\n", " float x[2][a][a][2];\n", " float x[a][2][a][2];\n", |
| " float x[a][a][2][2];\n", " float x[2][a][a][a];\n", " float x[a][2][a][a];\n", |
| " float x[a][a][2][a];\n", " float x[a][a][a][2];\n", " float x[a][a][a][a];\n" |
| }; |
| std::string non_constant_variable_declaration = " uint a = 2u;\n"; |
| |
| for (size_t invalid_declarations_index = 0; |
| invalid_declarations_index < DE_LENGTH_OF_ARRAY(invalid_declarations); |
| invalid_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += non_constant_variable_declaration; |
| shader_source += invalid_declarations[invalid_declarations_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_declarations_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the sized_declarations_invalid_sizes4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void sized_declarations_invalid_sizes4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string input[] = { " float x[2,2][2][2];\n", " float x[2][2,2][2];\n", " float x[2][2][2,2];\n", |
| " float x[2,2,2][2];\n", " float x[2][2,2,2];\n", " float x[2,2,2,2];\n" }; |
| |
| for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++) |
| { |
| std::string shader_source; |
| |
| shader_source += shader_start; |
| shader_source += input[string_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Constructs a suitable constructor for the specified number of dimensions. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param var_type The type of the variable |
| * @param dimension_index The current recursion level (counts down) |
| * @param init_string The initialisation string |
| */ |
| template <class API> |
| std::string ConstructorsAndUnsizedDeclConstructors1<API>::recursively_initialise(std::string var_type, |
| size_t dimension_index, |
| std::string init_string) |
| { |
| std::string temp_string; |
| |
| if (dimension_index == 0) |
| { |
| temp_string = init_string; |
| } |
| else |
| { |
| std::string prefix = "\n"; |
| |
| for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++) |
| { |
| prefix += " "; |
| } |
| |
| prefix += this->extend_string(var_type, "[]", dimension_index); |
| prefix += "("; |
| for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++) |
| { |
| temp_string += prefix; |
| temp_string += recursively_initialise(var_type, dimension_index - 1, init_string); |
| prefix = ", "; |
| if (sub_script_index == 1) |
| { |
| break; |
| } |
| } |
| temp_string += ")"; |
| } |
| |
| return temp_string; |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclConstructors1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| //vec4 color = vec4(0.0, 1.0, 0.0, 1.0); |
| int num_var_types = API::n_var_types; |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t max_dimension_index = 2; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string base_variable_string = |
| this->extend_string(" " + var_iterator->second.type + " a", "[]", max_dimension_index); |
| |
| base_variable_string += " = "; |
| base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index, |
| var_iterator->second.initializer_with_ones); |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string base_structure = "struct my_structure\n"; |
| |
| base_structure += "{\n"; |
| base_structure += " " + var_iterator->second.type + " b;\n"; |
| base_structure += " " + var_iterator->second.type + " c;\n"; |
| base_structure += "};\n\n"; |
| |
| for (size_t max_dimension_index = 1; max_dimension_index < API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string outer_separator = "("; |
| std::string base_variable_string; |
| |
| base_variable_string += |
| this->extend_string(" " + var_iterator->second.type + " a", "[2]", max_dimension_index); |
| base_variable_string += " = "; |
| base_variable_string += recursively_initialise(var_iterator->second.type, max_dimension_index, |
| var_iterator->second.initializer_with_ones); |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = base_structure + shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 1; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructors2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclConstructors2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_variable_string = " float[2][2] x = float[2][2](float[4](1.0, 2.0, 3.0, 4.0));\n"; |
| std::string shader_source = shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| |
| base_variable_string = "float[2][2] x = float[2][2](float[1][4](float[4](1.0, 2.0, 3.0, 4.0)));\n\n"; |
| shader_source = base_variable_string + shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedConstructors |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclUnsizedConstructors<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_variable_declarations = "= float[2][1][2][1](\n" |
| " float[1][2][1](\n" |
| " float[2][1]( \n" |
| " float[1](12.3), float[1](54.2) \n" |
| " )\n" |
| " ),\n" |
| " float[1][2][1](\n" |
| " float[2][1]( \n" |
| " float[1]( 3.2), float[1]( 7.4) \n" |
| " )\n" |
| " )\n" |
| " );\n\n"; |
| |
| std::string input[] = { "float a[2][1][2][]", "float a[2][1][][1]", "float a[2][1][][]", "float a[2][][2][1]", |
| "float a[2][][2][]", "float a[2][][][1]", "float a[2][][][]", "float a[][1][2][1]", |
| "float a[][1][2][]", "float a[][1][][1]", "float a[][1][][]", "float a[][][2][1]", |
| "float a[][][2][]", "float a[][][][1]", "float a[][][][]" }; |
| |
| for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++) |
| { |
| std::string shader_source = shader_start + " " + input[string_index] + shader_variable_declarations; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclConst |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclConst<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_source = "const float[2][2] x = float[2][2](float[2](1.0, 2.0), float[2](3.0, 4.0));\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclInvalidConstructors1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]); |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(opaque_var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string base_variable_string = |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler1;\n" + |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler2;\n" + |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler3;\n" + |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " my_sampler4;\n\n"; |
| |
| std::string shader_source = base_variable_string + shader_start; |
| shader_source += " const " + var_iterator->second.type + "[2][2] x = " + var_iterator->second.type + |
| "[2][2](" + var_iterator->second.type + "[2](my_sampler1, my_sampler2), " + |
| var_iterator->second.type + "[2](my_sampler3, my_sampler4));\n\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclInvalidConstructors2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_initializers[] = { " int x[2][2][0]; \n", " int x[2][0][2]; \n", " int x[0][2][2]; \n", |
| " int x[2][0][0]; \n", " int x[0][2][0]; \n", " int x[0][0][2]; \n", |
| " int x[0][0][0]; \n" }; |
| |
| for (size_t invalid_initializers_index = 0; |
| invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]); |
| invalid_initializers_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += invalid_initializers[invalid_initializers_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_initializers_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclInvalidConstructors3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_initializers[] = { " int x[2][2][-1]; \n", " int x[2][-1][2]; \n", |
| " int x[-1][2][2]; \n", " int x[2][-1][-1]; \n", |
| " int x[-1][2][-1]; \n", " int x[-1][-1][2]; \n", |
| " int x[-1][-1][-1]; \n" }; |
| |
| for (size_t invalid_initializers_index = 0; |
| invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]); |
| invalid_initializers_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += invalid_initializers[invalid_initializers_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_initializers_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclInvalidConstructors4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclInvalidConstructors4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string invalid_initializers[] = { " int x[2][2][a]; \n", " int x[2][a][2]; \n", " int x[a][2][2]; \n", |
| " int x[2][a][a]; \n", " int x[a][2][a]; \n", " int x[a][a][2]; \n", |
| " int x[a][a][a]; \n" }; |
| std::string non_constant_variable_init = " uint a = 2u;\n"; |
| |
| for (size_t invalid_initializers_index = 0; |
| invalid_initializers_index < sizeof(invalid_initializers) / sizeof(invalid_initializers[0]); |
| invalid_initializers_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = shader_start; |
| shader_source += non_constant_variable_init; |
| shader_source += invalid_initializers[invalid_initializers_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_initializers_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclConstructorSizing1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string valid_size_initializers[] = { "[1][1][1][]", "[1][1][][1]", "[1][][1][1]", "[][1][1][1]", "[1][1][][]", |
| "[1][][1][]", "[][1][1][]", "[1][][][1]", "[][1][][1]", "[][][1][1]", |
| "[1][][][]", "[][1][][]", "[][][1][]", "[][][][1]", "[][][][]" }; |
| |
| for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t valid_size_initializers_index = 0; |
| valid_size_initializers_index < sizeof(valid_size_initializers) / sizeof(valid_size_initializers[0]); |
| valid_size_initializers_index++) |
| { |
| std::string shader_source; |
| std::string variable_constructor = |
| " " + var_iterator->second.type + " x" + valid_size_initializers[valid_size_initializers_index] + |
| " = " + var_iterator->second.type + "[1][1][1][1](" + var_iterator->second.type + "[1][1][1](" + |
| var_iterator->second.type + "[1][1](" + var_iterator->second.type + "[1](" + |
| var_iterator->second.initializer_with_zeroes + "))));\n"; |
| |
| shader_source = shader_start; |
| shader_source += variable_constructor; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int valid_size_initializers_index = 0; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclConstructorSizing2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclConstructorSizing2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_source = shader_start; |
| |
| shader_source += " float[] a =" |
| " float[](1.0, 2.0)," |
| " b[] =" |
| " float[][](" |
| " float[](1.0, 2.0)," |
| " float[](3.0, 4.0)" |
| " )," |
| " c[][] =" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )" |
| " )," |
| " d[][][] =" |
| " float[][][][](" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0, 2.0)," |
| " float[](3.0, 4.0)," |
| " float[](5.0, 6.0)" |
| " )" |
| " )," |
| " float[][][](" |
| " float[][](" |
| " float[](1.0, 2.0)," |
| " float[](3.0, 4.0)," |
| " float[](5.0, 6.0)" |
| " )" |
| " )" |
| " )," |
| " e[][][][]=" |
| " float[][][][][](" |
| " float[][][][](" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )," |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )," |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )" |
| " )," |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )," |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )," |
| " float[][](" |
| " float[](1.0)," |
| " float[](2.0)" |
| " )" |
| " )" |
| " )" |
| " )," |
| " f[][][][][]=" |
| " float[][][][][][](" |
| " float[][][][][](" |
| " float[][][][](" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)" |
| " )" |
| " )" |
| " )" |
| " )" |
| " )," |
| " g[][][][][][]=" |
| " float[][][][][][][](" |
| " float[][][][][][](" |
| " float[][][][][](" |
| " float[][][][](" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)" |
| " )" |
| " )" |
| " )" |
| " )" |
| " )" |
| " )," |
| " h[][][][][][][]=" |
| " float[][][][][][][][](" |
| " float[][][][][][][](" |
| " float[][][][][][](" |
| " float[][][][][](" |
| " float[][][][](" |
| " float[][][](" |
| " float[][](" |
| " float[](1.0)" |
| " )" |
| " )" |
| " )" |
| " )" |
| " )" |
| " )" |
| " );\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Constructs a suitable constructor for the specified number of dimensions. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param var_type The type of the variable |
| * @param dimension_index The current recursion level (counts down) |
| * @param init_string The initialisation string |
| */ |
| template <class API> |
| std::string ConstructorsAndUnsizedDeclStructConstructors<API>::recursively_initialise(std::string var_type, |
| size_t dimension_index, |
| std::string init_string) |
| { |
| std::string temp_string; |
| |
| if (dimension_index == 0) |
| { |
| temp_string = var_type + "(" + init_string + ")"; |
| } |
| else |
| { |
| std::string prefix = "\n"; |
| |
| for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++) |
| { |
| prefix += " "; |
| } |
| |
| prefix += this->extend_string(var_type, "[]", dimension_index); |
| prefix += "("; |
| |
| for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++) |
| { |
| temp_string += prefix; |
| temp_string += recursively_initialise(var_type, dimension_index - 1, init_string); |
| prefix = ", "; |
| |
| if (dimension_index == 1) |
| { |
| break; |
| } |
| } |
| temp_string += ")"; |
| } |
| |
| return temp_string; |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclStructConstructors |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclStructConstructors<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_structure_definition("struct light {\n" |
| " float intensity;\n" |
| " int position;\n" |
| "};\n"); |
| std::string example_structure_object(" light my_light_variable"); |
| |
| for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string base_variable_string = this->extend_string(example_structure_object, "[]", max_dimension_index); |
| base_variable_string += " = "; |
| base_variable_string += recursively_initialise("light", max_dimension_index, "1.0, 2"); |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = example_structure_definition + shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 2; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclUnsizedArrays1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_variable_string; |
| |
| for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| base_variable_string = this->extend_string(" int x", "[]", max_dimension_index); |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int max_dimension_index = 2; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclUnsizedArrays2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string input[] = { " float [] x = float[](1), y;\n\n" }; |
| |
| for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++) |
| { |
| std::string shader_source; |
| |
| shader_source += shader_start; |
| shader_source += input[string_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION, tested_shader_type, shader_source); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclUnsizedArrays3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_variable_string(" float[][] x = mat4(0);\n\n"); |
| |
| std::string shader_source = shader_start + base_variable_string; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } |
| |
| /* Generates the shader source code for the ConstructorsAndUnsizedDeclUnsizedArrays4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ConstructorsAndUnsizedDeclUnsizedArrays4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string example_struct("struct light {\n" |
| " float[][] intensity;\n" |
| " int position;\n" |
| "} myLight;\n\n"); |
| |
| std::string shader_source = example_struct + shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } |
| |
| /* Constructs a suitable constructor for the specified number of dimensions. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param dimension_index The current recursion level (counts down) |
| * @param init_string The initialisation string |
| */ |
| template <class API> |
| std::string ExpressionsAssignment1<API>::recursively_initialise(std::string var_type, size_t dimension_index, |
| std::string init_string) |
| { |
| std::string temp_string; |
| |
| if (dimension_index == 0) |
| { |
| temp_string = init_string; |
| } |
| else |
| { |
| std::string prefix = "\n"; |
| |
| for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++) |
| { |
| prefix += " "; |
| } |
| |
| prefix += this->extend_string(var_type, "[]", dimension_index); |
| prefix += "("; |
| for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++) |
| { |
| temp_string += prefix; |
| temp_string += recursively_initialise(var_type, dimension_index - 1, init_string); |
| prefix = ", "; |
| if (dimension_index == 1) |
| { |
| break; |
| } |
| } |
| temp_string += ")"; |
| } |
| |
| return temp_string; |
| } |
| |
| /* Generates the shader source code for the ExpressionsAssignment1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsAssignment1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| for (size_t max_dimension_index = 2; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string prefix = "("; |
| std::string base_variable_string; |
| |
| base_variable_string += this->extend_string(" float x", "[2]", max_dimension_index); |
| base_variable_string += " = "; |
| base_variable_string += recursively_initialise("float", max_dimension_index, "4.0, 6.0"); |
| base_variable_string += ";\n"; |
| base_variable_string += this->extend_string(" float y", "[2]", max_dimension_index); |
| base_variable_string += " = "; |
| base_variable_string += recursively_initialise("float", max_dimension_index, "1.0, 2.0"); |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = shader_start + base_variable_string; |
| |
| shader_source += " x = y;\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int max_dimension_index = 2; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsAssignment2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsAssignment2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_body(" float a[2] = float[](1.0, 2.0);\n" |
| " float b[2][2] = float[][](float[](1.0, 2.0), float[](1.0, 2.0));\n" |
| " float c[2][2][2] = float[][][](" |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0))," |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0)));\n" |
| " float d[2][2][2][2] = float[][][][](" |
| "float[][][](" |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0)), " |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0)))," |
| "float[][][](" |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0)), " |
| "float[][](float[](1.0, 2.0), float[](1.0, 2.0))));\n\n"); |
| |
| std::string variable_basenames[] = { "a", "b", "c", "d" }; |
| int number_of_elements = sizeof(variable_basenames) / sizeof(variable_basenames[0]); |
| |
| for (int variable_index = 0; variable_index < number_of_elements; variable_index++) |
| { |
| for (int value_index = variable_index; value_index < number_of_elements; value_index++) |
| { |
| std::string shader_source = shader_start + shader_body; |
| |
| /* Avoid the situation when a variable is assign to itself. */ |
| if (variable_index != value_index) |
| { |
| shader_source += " " + variable_basenames[variable_index] + " = " + variable_basenames[value_index]; |
| shader_source += ";\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if(variable_index != value_index) */ |
| } /* for (int value_index = variable_index; ...) */ |
| } /* for (int variable_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsAssignment3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsAssignment3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string prefix, base_variable_string; |
| |
| const int test_array_dimensions = 4; |
| |
| prefix = this->extend_string(" float a", "[1]", 4); |
| prefix += " = float[][][][](\n" |
| " float[][][](\n" |
| " float[][](\n" |
| " float[](1.0))));\n"; |
| |
| prefix += " float b"; |
| |
| for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++) |
| { |
| base_variable_string = prefix; |
| |
| for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--) |
| { |
| if (permutation & (1 << sub_script_index)) |
| { |
| base_variable_string += "[1]"; |
| } |
| else |
| { |
| base_variable_string += "[2]"; |
| } |
| } |
| |
| base_variable_string += ";\n\n"; |
| |
| if (permutation != (1 << test_array_dimensions) - 1) |
| { |
| std::string shader_source = shader_start + base_variable_string; |
| |
| shader_source += " b = a;\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if (permutation != (1 << test_array_dimensions) - 1) */ |
| } /* for (int permutation = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsTypeRestrictions1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsTypeRestrictions1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]); |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(opaque_var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source = |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " var1[2][2];\n" |
| "uniform " + |
| var_iterator->second.precision + " " + var_iterator->second.type + " var2[2][2];\n\n"; |
| shader_source += shader_start; |
| |
| shader_source += " var1 = var2;\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsTypeRestrictions2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsTypeRestrictions2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]); |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(opaque_var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source = |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " sampler1;\n" |
| "uniform " + |
| var_iterator->second.precision + " " + var_iterator->second.type + " sampler2;\n" |
| "uniform " + |
| var_iterator->second.precision + " " + var_iterator->second.type + " sampler3;\n" |
| "uniform " + |
| var_iterator->second.precision + " " + var_iterator->second.type + " sampler4;\n" |
| "struct light1 {\n" |
| " " + |
| var_iterator->second.type + " var1[2][2];\n" |
| "};\n\n"; |
| shader_source += shader_start; |
| |
| shader_source += |
| (" light1 x = light1(" + var_iterator->second.type + "[][](" + var_iterator->second.type + |
| "[](sampler1, sampler2), " + var_iterator->second.type + "[](sampler3, sampler4)));\n"); |
| shader_source += " light1 y = x;\n\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingScalar1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingScalar1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source = shader_start + " " + var_iterator->second.type + " x[1][2][3][4];\n\n"; |
| |
| shader_source += " for (uint i = 0u; i < 2u; i++) {\n"; |
| shader_source += " for (uint j = 0u; j < 3u; j++) {\n"; |
| shader_source += " for (uint k = 0u; k < 4u; k++) {\n"; |
| shader_source += " x[0][i][j][k] = " + var_iterator->second.initializer_with_ones + ";\n"; |
| shader_source += " }\n"; |
| shader_source += " }\n"; |
| shader_source += " }\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingScalar2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingScalar2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_shader_string, shader_source; |
| |
| // This test tests arrays with 4 dimensions, e.g. x[1][1][1][1] |
| const int test_array_dimensions = 4; |
| |
| base_shader_string = "float a[1][2][3][4];\n"; |
| base_shader_string += "float b = 2.0;\n\n"; |
| base_shader_string += shader_start; |
| |
| // There are 16 permutations, so loop 4x4 times. |
| for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++) |
| { |
| shader_source = base_shader_string + " a"; // a var called 'a' |
| |
| for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--) |
| { |
| /* If any bit is set for a particular number then add |
| * a valid array sub_script at that place, otherwise |
| * add an invalid array sub_script. */ |
| if (permutation & (1 << sub_script_index)) |
| { |
| shader_source += "[0]"; |
| } |
| else |
| { |
| shader_source += "[-1]"; |
| } |
| } |
| |
| shader_source += " = b;\n"; |
| |
| if (permutation != (1 << test_array_dimensions) - 1) |
| { |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if (permutation != (1 << test_array_dimensions) - 1) */ |
| } /* for (int permutation = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingScalar3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingScalar3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_shader_string; |
| std::string shader_source; |
| const int test_array_dimensions = 4; |
| |
| base_shader_string = "float a[1][2][3][4];\n"; |
| base_shader_string += "float b = 2.0;\n\n"; |
| base_shader_string += shader_start; |
| |
| for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++) |
| { |
| shader_source = base_shader_string + " a"; |
| |
| for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--) |
| { |
| if (permutation & (1 << sub_script_index)) |
| { |
| shader_source += "[0]"; |
| } |
| else |
| { |
| shader_source += "[4]"; |
| } |
| } |
| |
| shader_source += " = b;\n"; |
| |
| if (permutation != (1 << test_array_dimensions) - 1) |
| { |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if (permutation != (1 << test_array_dimensions) - 1) */ |
| } /* for (int permutation = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingScalar4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingScalar4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string base_shader_string; |
| std::string shader_source; |
| |
| const int test_array_dimensions = 4; |
| |
| base_shader_string = "float a[1][2][3][4];\n"; |
| base_shader_string += "float b = 2.0;\n\n"; |
| base_shader_string += shader_start; |
| |
| for (int permutation = 0; permutation < (1 << test_array_dimensions); permutation++) |
| { |
| shader_source = base_shader_string + " a"; |
| |
| for (int sub_script_index = test_array_dimensions - 1; sub_script_index >= 0; sub_script_index--) |
| { |
| if (permutation & (1 << sub_script_index)) |
| { |
| shader_source += "[0]"; |
| } |
| else |
| { |
| shader_source += "[]"; |
| } |
| } |
| |
| shader_source += " = b;\n"; |
| |
| if (permutation != (1 << test_array_dimensions) - 1) |
| { |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* if (permutation != (1 << test_array_dimensions) - 1) */ |
| } /* for (int permutation = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingArray1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingArray1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_source; |
| std::string variable_declaration = "float x[1][1][1][1][1][1][1][1];\n\n"; |
| |
| std::string variable_initializations[] = { |
| "x[0] = float[1][1][1][1][1][1][1](" |
| "float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))))));" |
| "\n", |
| "x[0][0] = " |
| "float[1][1][1][1][1][1](float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))))));" |
| "\n", |
| "x[0][0][0] = " |
| "float[1][1][1][1][1](float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0)))));\n", |
| "x[0][0][0][0] = float[1][1][1][1](float[1][1][1](float[1][1](float[1](1.0))));\n", |
| "x[0][0][0][0][0] = float[1][1][1](float[1][1](float[1](1.0)));\n", |
| "x[0][0][0][0][0][0] = float[1][1](float[1](1.0));\n", "x[0][0][0][0][0][0][0] = float[1](1.0);\n", |
| "x[0][0][0][0][0][0][0][0] = 1.0;\n" |
| }; |
| |
| for (size_t string_index = 0; string_index < sizeof(variable_initializations) / sizeof(variable_initializations[0]); |
| string_index++) |
| { |
| shader_source = variable_declaration + shader_start; |
| shader_source += " " + variable_initializations[string_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Constructs a suitable constructor for the specified number of dimensions. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param dimension_index The current recursion level (counts down) |
| * @param init_string The initialisation string |
| */ |
| template <class API> |
| std::string ExpressionsIndexingArray2<API>::recursively_initialise(std::string var_type, size_t dimension_index, |
| std::string init_string) |
| { |
| std::string temp_string; |
| |
| if (dimension_index == 0) |
| { |
| temp_string = init_string; |
| } |
| else |
| { |
| std::string prefix = "\n"; |
| |
| for (size_t indent_index = dimension_index; indent_index < (API::MAX_ARRAY_DIMENSIONS + 1); indent_index++) |
| { |
| prefix += " "; |
| } |
| |
| prefix += this->extend_string(var_type, "[]", dimension_index); |
| prefix += "("; |
| for (int sub_script_index = 0; sub_script_index < 2; sub_script_index++) |
| { |
| temp_string += prefix; |
| temp_string += recursively_initialise(var_type, dimension_index - 1, init_string); |
| prefix = ", "; |
| if (dimension_index == 1) |
| { |
| break; |
| } |
| } |
| temp_string += ")"; |
| } |
| |
| return temp_string; |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingArray2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingArray2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string variable_initialiser = " float[](float[](float(float(float(float(float(float(1.0))))))));\n"; |
| |
| std::string x_variable_initializaton = |
| " float x[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") + |
| ";\n"; |
| std::string y_variable_initializaton = |
| " float y[2][2][2][2][2][2][2][1] = " + recursively_initialise("float", API::MAX_ARRAY_DIMENSIONS, "1.0") + |
| ";\n"; |
| |
| std::string shader_code_common_part = shader_start + x_variable_initializaton + y_variable_initializaton; |
| |
| for (size_t max_dimension_index = 1; max_dimension_index <= API::MAX_ARRAY_DIMENSIONS; max_dimension_index++) |
| { |
| std::string iteration_specific_shader_code_part; |
| |
| iteration_specific_shader_code_part += this->extend_string(" x", "[0]", max_dimension_index); |
| iteration_specific_shader_code_part += " = "; |
| iteration_specific_shader_code_part += this->extend_string("y", "[0]", max_dimension_index); |
| iteration_specific_shader_code_part += ";\n"; |
| |
| std::string shader_source = shader_code_common_part + iteration_specific_shader_code_part; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| } |
| |
| /* Generates the shader source code for the ExpressionsIndexingArray3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsIndexingArray3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string input[] = { " x[ivec2(0)] = 1.0;\n\n", " x[ivec3(0)] = 1.0;\n\n", " x[ivec4(0)] = 1.0;\n\n" }; |
| |
| for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++) |
| { |
| std::string shader_source = shader_start + this->extend_string(" float x", "[2]", (int)string_index + 2) + |
| ";\n\n" + input[string_index]; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsDynamicIndexing1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsDynamicIndexing1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string expression_type_declarations = "uniform int a;\n" |
| "const int b = 0;\n" |
| "int c = 0;\n" |
| "float x[2][2];\n"; |
| |
| std::string expressions[] = { "a", "b", "c", "0 + 1" }; |
| std::string shader_source; |
| |
| for (size_t write_index = 0; write_index < sizeof(expressions) / sizeof(expressions[0]); write_index++) |
| { |
| for (size_t read_index = 0; read_index < sizeof(expressions) / sizeof(expressions[0]); read_index++) |
| { |
| shader_source = expression_type_declarations; |
| shader_source += shader_start; |
| shader_source += " x["; |
| shader_source += expressions[write_index]; |
| shader_source += "]["; |
| shader_source += expressions[read_index]; |
| shader_source += "] = 1.0;\n\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* for (int read_index = 0; ...) */ |
| } /* for (int write_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsDynamicIndexing2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsDynamicIndexing2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = sizeof(opaque_var_types) / sizeof(opaque_var_types[0]); |
| const std::string invalid_size_declarations[] = { "[0][0][0][y]", "[0][0][y][0]", "[0][y][0][0]", "[y][0][0][0]", |
| "[0][0][y][y]", "[0][y][0][y]", "[y][0][0][y]", "[0][y][y][0]", |
| "[y][0][y][0]", "[y][y][0][0]", "[0][y][y][y]", "[y][0][y][y]", |
| "[y][y][0][y]", "[y][y][y][0]", "[y][y][y][y]" }; |
| |
| bool dynamic_indexing_supported = false; |
| if (glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::es(3, 2)) || |
| glu::contextSupports(this->context_id.getRenderContext().getType(), glu::ApiType::core(4, 0)) || |
| this->context_id.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5")) |
| { |
| dynamic_indexing_supported = true; |
| } |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(opaque_var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| int num_invalid_size_declarations = |
| sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]); |
| |
| for (int invalid_size_index = 0; invalid_size_index < num_invalid_size_declarations; invalid_size_index++) |
| { |
| std::string shader_source = "int y = 1;\n"; |
| |
| shader_source += "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + |
| " x[2][2][2][2];\n\n"; |
| shader_source += "void main()\n"; |
| shader_source += "{\n"; |
| shader_source += (" " + var_iterator->second.type_of_result_of_texture_function + |
| " color = texture(x" + invalid_size_declarations[invalid_size_index] + ", " + |
| var_iterator->second.coord_param_for_texture_function + ");\n"); |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| if (dynamic_indexing_supported) |
| { |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, true); |
| } |
| else |
| { |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } |
| } /* for (int invalid_size_index = 0; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsEquality1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsEquality1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = API::n_var_types; |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source = shader_start; |
| |
| shader_source += " "; |
| shader_source += var_iterator->second.type; |
| shader_source += "[][] x = "; |
| shader_source += var_iterator->second.type; |
| shader_source += "[][]("; |
| shader_source += var_iterator->second.type; |
| shader_source += "[]("; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += ","; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += "),"; |
| shader_source += var_iterator->second.type; |
| shader_source += "[]("; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += ","; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += "));\n"; |
| shader_source += " "; |
| shader_source += var_iterator->second.type; |
| shader_source += "[][] y = "; |
| shader_source += var_iterator->second.type; |
| shader_source += "[][]("; |
| shader_source += var_iterator->second.type; |
| shader_source += "[]("; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += ","; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += "),"; |
| shader_source += var_iterator->second.type; |
| shader_source += "[]("; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += ","; |
| shader_source += var_iterator->second.initializer_with_zeroes; |
| shader_source += "));\n\n"; |
| shader_source += " float result = 0.0;\n\n"; |
| shader_source += " if (x == y)\n"; |
| shader_source += " {\n"; |
| shader_source += " result = 1.0;\n"; |
| shader_source += " }\n"; |
| shader_source += " if (y != x)\n"; |
| shader_source += " {\n"; |
| shader_source += " result = 2.0;\n"; |
| shader_source += " }\n"; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the ExpressionsEquality2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsEquality2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| int num_var_types = API::n_var_types; |
| |
| for (int var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source = "struct light {\n float intensity;\n int position;\n};\n\n"; |
| |
| shader_source += shader_start; |
| shader_source += " light[][] x ="; |
| shader_source += "light"; |
| shader_source += "[][]("; |
| shader_source += "light"; |
| shader_source += "[](light(1.0, 1)),"; |
| shader_source += "light"; |
| shader_source += "[](light(2.0, 2)));\n\n"; |
| shader_source += " light[][] y ="; |
| shader_source += "light"; |
| shader_source += "[][]("; |
| shader_source += "light"; |
| shader_source += "[](light(3.0, 3)),"; |
| shader_source += "light"; |
| shader_source += "[](light(4.0, 4)));\n\n"; |
| shader_source += " float result = 0.0;\n\n"; |
| shader_source += " if (x == y)\n"; |
| shader_source += " {\n"; |
| shader_source += " result = 1.0;\n"; |
| shader_source += " }\n"; |
| shader_source += " if (y != x)\n"; |
| shader_source += " {\n"; |
| shader_source += " result = 2.0;\n"; |
| shader_source += " }\n"; |
| |
| /* Apply stage specific stuff */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| shader_source += "\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n"; |
| break; |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| shader_source += "\n gl_FragDepth = result;\n"; |
| break; |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| shader_source += emit_quad; |
| break; |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| shader_source += set_tesseation; |
| break; |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| break; |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| /* End main function */ |
| shader_source += shader_end; |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the ExpressionsLength1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsLength1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string array_declaration = " int x[4][3][2][1];\n\n"; |
| std::string case_specific_string[] = { " if (x.length() != 4) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0].length() != 3) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0][0].length() != 2) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0][0][0].length() != 1) {\n" |
| " result = 0.0f;\n }\n" }; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| for (size_t case_specific_string_index = 0; |
| case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]); |
| case_specific_string_index++) |
| { |
| const std::string& test_snippet = case_specific_string[case_specific_string_index]; |
| |
| if (false == test_compute) |
| { |
| execute_draw_test(tested_shader_type, array_declaration, test_snippet); |
| } |
| else |
| { |
| execute_dispatch_test(tested_shader_type, array_declaration, test_snippet); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* for (int case_specific_string_index = 0; ...) */ |
| } |
| |
| /** Executes test for compute program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| void ExpressionsLength1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type, |
| const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| const std::string& compute_shader_source = |
| prepare_compute_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string, |
| compute_shader_source, false, false); |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLint location = -1; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */, |
| GL_WRITE_ONLY, GL_RGBA8); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed."); |
| |
| location = gl.getUniformLocation(this->program_object_id, "uni_image"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed."); |
| |
| if (-1 == location) |
| { |
| TCU_FAIL("Uniform is inactive"); |
| } |
| |
| gl.uniform1i(location, 0 /* image unit */); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed."); |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| if (buffer[0] != 255) |
| { |
| TCU_FAIL("Invalid array size was returned."); |
| } |
| |
| /* Delete generated objects. */ |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| |
| /** Executes test for draw program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| void ExpressionsLength1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type, |
| const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = empty_string; |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, false, |
| false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, tested_declaration, tested_snippet); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, tested_declaration, tested_snippet); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| gl.drawArrays(GL_TRIANGLE_FAN, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| if (buffer[0] != 255) |
| { |
| TCU_FAIL("Invalid array size was returned."); |
| } |
| |
| /* Delete generated objects. */ |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_compute_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string compute_shader_source; |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type) |
| { |
| compute_shader_source = "writeonly uniform image2D uni_image;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " float result = 1u;\n" |
| "\n"; |
| compute_shader_source += tested_declaration; |
| compute_shader_source += tested_snippet; |
| compute_shader_source += "\n" |
| " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n" |
| "}\n" |
| "\n"; |
| } |
| |
| return compute_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_fragment_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string fragment_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| fragment_shader_source = "out vec4 colour;\n" |
| "\n" |
| "void main()\n" |
| "{\n"; |
| fragment_shader_source += tested_declaration; |
| fragment_shader_source += " float result = 1.0f;\n"; |
| fragment_shader_source += tested_snippet; |
| fragment_shader_source += " colour = vec4(result);\n" |
| "}\n\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| fragment_shader_source = "in float fs_result;\n\n" |
| "out vec4 colour;\n\n" |
| "void main()\n" |
| "{\n" |
| " colour = vec4(fs_result);\n" |
| "}\n" |
| "\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return fragment_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_geometry_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string geometry_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "in float tes_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n"; |
| geometry_shader_source += tested_declaration; |
| geometry_shader_source += " float result = 1.0;\n\n"; |
| geometry_shader_source += tested_snippet; |
| geometry_shader_source += "\n gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return geometry_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_tess_ctrl_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string tess_ctrl_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_ctrl_shader_source = "layout(vertices = 1) out;\n" |
| "\n" |
| "out float tcs_result[];\n" |
| "\n" |
| "void main()\n" |
| "{\n"; |
| tess_ctrl_shader_source += tested_declaration; |
| tess_ctrl_shader_source += " float result = 1.0;\n\n"; |
| tess_ctrl_shader_source += tested_snippet; |
| tess_ctrl_shader_source += " tcs_result[gl_InvocationID] = result;\n" |
| "\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_ctrl_shader_source = default_tc_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_ctrl_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_tess_eval_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string tess_eval_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "in float tcs_result[];\n" |
| "out float tes_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " tes_result = tcs_result[0];\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "out float tes_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n"; |
| tess_eval_shader_source += tested_declaration; |
| tess_eval_shader_source += " float result = 1.0;\n\n"; |
| tess_eval_shader_source += tested_snippet; |
| tess_eval_shader_source += " tes_result = result;\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_eval_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param tested_declaration Declaration used to prepare shader |
| * @param tested_snippet Snippet used to prepare shader |
| **/ |
| template <class API> |
| std::string ExpressionsLength1<API>::prepare_vertex_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& tested_declaration, |
| const std::string& tested_snippet) |
| { |
| std::string vertex_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vertex_positions[gl_VertexID];" |
| "}\n\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| vertex_shader_source = default_vertex_shader_source; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| vertex_shader_source = "out float fs_result;\n" |
| "\n" |
| "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n" |
| "\n" |
| "void main()\n" |
| "{\n"; |
| vertex_shader_source += tested_declaration; |
| vertex_shader_source += " float result = 1.0;\n\n"; |
| vertex_shader_source += tested_snippet; |
| vertex_shader_source += " gl_Position = vertex_positions[gl_VertexID];\n" |
| " fs_result = result;\n"; |
| vertex_shader_source += shader_end; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return vertex_shader_source; |
| } |
| |
| /* Generates the shader source code for the ExpressionsLength2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsLength2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string array_declaration = " int x[1][2][3][4];\n\n"; |
| std::string case_specific_string[] = { " if (x.length() != 1) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0].length() != 2) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0][0].length() != 3) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[0][0][0].length() != 4) {\n" |
| " result = 0.0f;\n }\n" }; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| for (size_t case_specific_string_index = 0; |
| case_specific_string_index < sizeof(case_specific_string) / sizeof(case_specific_string[0]); |
| case_specific_string_index++) |
| { |
| const std::string& test_snippet = case_specific_string[case_specific_string_index]; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, array_declaration, test_snippet); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, array_declaration, test_snippet); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* for (int case_specific_string_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsLength3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsLength3<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string array_declaration = " int x[1][1][1][1];\n\n"; |
| std::string input[] = { " if (x[].length() != 2) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[][].length() != 2) {\n" |
| " result = 0.0f;\n }\n", |
| " if (x[][][].length() != 2) {\n" |
| " result = 0.0f;\n }\n" }; |
| |
| for (size_t string_index = 0; string_index < sizeof(input) / sizeof(input[0]); string_index++) |
| { |
| std::string shader_source; |
| const std::string& test_snippet = input[string_index]; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| shader_source = this->prepare_vertex_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| shader_source = this->prepare_fragment_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| shader_source = this->prepare_compute_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| shader_source = this->prepare_geometry_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| shader_source = this->prepare_tess_ctrl_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| shader_source = this->prepare_tess_eval_shader(tested_shader_type, array_declaration, test_snippet); |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } /* switch (tested_shader_type) */ |
| |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int string_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the ExpressionsInvalid1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsInvalid1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| std::string shader_variable_declarations = |
| " mat2 y = mat2(0.0);\n" |
| " float x[2][2] = float[2][2](float[2](4.0, 5.0), float[2](6.0, 7.0));\n\n"; |
| |
| std::string shader_source = shader_start + shader_variable_declarations; |
| |
| shader_source += " y = x;\n"; |
| |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } |
| |
| /* Generates the shader source code for the ExpressionsInvalid2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void ExpressionsInvalid2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| |
| std::string shader_variable_declarations[] = { " x", " y" }; |
| std::string variable_relation_opeartors[] = { |
| " float result = 0.0;\n\n if(x < y)\n {\n result = 1.0;\n }\n\n\n", |
| " float result = 0.0;\n\n if(x <= y)\n {\n result = 1.0;\n }\n\n\n", |
| " float result = 0.0;\n\n if(x > y)\n {\n result = 1.0;\n }\n\n\n", |
| " float result = 0.0;\n\n if(x >= y)\n {\n result = 1.0;\n }\n\n\n" |
| }; |
| std::string valid_relation_opeartors = |
| " float result = 0.0;\n\n if(x == y)\n {\n result = 1.0;\n }\n\n\n"; |
| |
| for (size_t var_type_index = 0; var_type_index < API::n_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(API::var_types[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string base_variable_string; |
| |
| for (size_t variable_declaration_index = 0; |
| variable_declaration_index < |
| sizeof(shader_variable_declarations) / sizeof(shader_variable_declarations[0]); |
| variable_declaration_index++) |
| { |
| base_variable_string += var_iterator->second.type; |
| base_variable_string += shader_variable_declarations[variable_declaration_index]; |
| |
| base_variable_string += "[1][1][1][1][1][1][1][1] = "; |
| |
| for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++) |
| { |
| base_variable_string += this->extend_string(var_iterator->second.type, "[1]", |
| API::MAX_ARRAY_DIMENSIONS - sub_script_index); |
| base_variable_string += "("; |
| } |
| |
| base_variable_string += var_iterator->second.initializer_with_ones; |
| |
| for (size_t sub_script_index = 0; sub_script_index < API::MAX_ARRAY_DIMENSIONS; sub_script_index++) |
| { |
| base_variable_string += ")"; |
| } |
| |
| base_variable_string += ";\n"; |
| } /* for (int variable_declaration_index = 0; ...) */ |
| |
| /* Run positive case */ |
| { |
| std::string shader_source; |
| |
| shader_source = base_variable_string + "\n"; |
| shader_source += shader_start + valid_relation_opeartors; |
| |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } |
| |
| /* Run negative cases */ |
| for (size_t string_index = 0; |
| string_index < sizeof(variable_relation_opeartors) / sizeof(variable_relation_opeartors[0]); |
| string_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = base_variable_string + "\n"; |
| shader_source += shader_start + variable_relation_opeartors[string_index]; |
| |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int string_index = 0; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the InteractionFunctionCalls1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionFunctionCalls1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string iterator_declaration = " " + var_iterator->second.iterator_type + |
| " iterator = " + var_iterator->second.iterator_initialization + ";\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition = "void my_function(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " output_array[2][2][2][2]) {\n"; |
| function_definition += iterator_declaration; |
| function_definition += iteration_loop_start; |
| function_definition += " output_array[a][b][c][d] = " + |
| var_iterator->second.variable_type_initializer1 + ";\n"; |
| function_definition += |
| " iterator += " + var_iterator->second.iterator_type + "(1);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}"; |
| |
| function_use = " " + var_iterator->second.type + " my_array[2][2][2][2];\n"; |
| function_use += " my_function(my_array);"; |
| |
| verification = iterator_declaration; |
| verification += " float result = 1.0;\n"; |
| verification += iteration_loop_start; |
| verification += " if (my_array[a][b][c][d] " + |
| var_iterator->second.specific_element + |
| " != iterator)\n" |
| " {\n" |
| " result = 0.0;\n" |
| " }\n" |
| " iterator += " + |
| var_iterator->second.iterator_type + "(1);\n"; |
| verification += iteration_loop_end; |
| |
| if (false == test_compute) |
| { |
| execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Executes test for compute program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| void InteractionFunctionCalls1<API>::execute_dispatch_test( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| const std::string& compute_shader_source = |
| prepare_compute_shader(tested_shader_type, function_definition, function_use, verification); |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string, |
| compute_shader_source, false, false); |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLint location = -1; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */, |
| GL_WRITE_ONLY, GL_RGBA8); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed."); |
| |
| location = gl.getUniformLocation(this->program_object_id, "uni_image"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed."); |
| |
| if (-1 == location) |
| { |
| TCU_FAIL("Uniform is inactive"); |
| } |
| |
| gl.uniform1i(location, 0 /* image unit */); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed."); |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| if (buffer[0] != 255) |
| { |
| TCU_FAIL("Invalid array size was returned."); |
| } |
| |
| /* Delete generated objects. */ |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| |
| /** Executes test for draw program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| void InteractionFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type, |
| const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = empty_string; |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, false, |
| false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| gl.drawArrays(GL_TRIANGLE_FAN, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| if (buffer[0] != 255) |
| { |
| TCU_FAIL("Invalid array size was returned."); |
| } |
| |
| /* Delete generated objects. */ |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| gl.bindVertexArray(0); |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_compute_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string compute_shader_source; |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type) |
| { |
| compute_shader_source = "writeonly uniform image2D uni_image;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| compute_shader_source += function_definition; |
| compute_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| compute_shader_source += shader_start; |
| compute_shader_source += function_use; |
| compute_shader_source += "\n\n"; |
| compute_shader_source += verification; |
| compute_shader_source += "\n\n"; |
| compute_shader_source += "\n" |
| " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n" |
| "}\n" |
| "\n"; |
| } |
| |
| return compute_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_fragment_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string fragment_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| fragment_shader_source = "out vec4 colour;\n\n"; |
| |
| /* User-defined function definition. */ |
| fragment_shader_source += function_definition; |
| fragment_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| fragment_shader_source += shader_start; |
| fragment_shader_source += function_use; |
| fragment_shader_source += "\n\n"; |
| fragment_shader_source += verification; |
| fragment_shader_source += "\n\n"; |
| fragment_shader_source += " colour = vec4(result);\n"; |
| fragment_shader_source += shader_end; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| fragment_shader_source = "in float fs_result;\n\n" |
| "out vec4 colour;\n\n" |
| "void main()\n" |
| "{\n" |
| " colour = vec4(fs_result);\n" |
| "}\n" |
| "\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return fragment_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_geometry_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string geometry_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "in float tes_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "out float fs_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| geometry_shader_source += function_definition; |
| geometry_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| geometry_shader_source += shader_start; |
| geometry_shader_source += function_use; |
| geometry_shader_source += "\n\n"; |
| geometry_shader_source += verification; |
| geometry_shader_source += "\n\n"; |
| geometry_shader_source += "\n gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return geometry_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_tess_ctrl_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string tess_ctrl_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_ctrl_shader_source = "layout(vertices = 1) out;\n" |
| "\n" |
| "out float tcs_result[];\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_ctrl_shader_source += function_definition; |
| tess_ctrl_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_ctrl_shader_source += shader_start; |
| tess_ctrl_shader_source += function_use; |
| tess_ctrl_shader_source += "\n\n"; |
| tess_ctrl_shader_source += verification; |
| tess_ctrl_shader_source += "\n\n"; |
| tess_ctrl_shader_source += " tcs_result[gl_InvocationID] = result;\n" |
| "\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_ctrl_shader_source = default_tc_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_ctrl_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_tess_eval_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string tess_eval_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "in float tcs_result[];\n" |
| "out float tes_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " tes_result = tcs_result[0];\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "out float tes_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_eval_shader_source += function_definition; |
| tess_eval_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_eval_shader_source += shader_start; |
| tess_eval_shader_source += function_use; |
| tess_eval_shader_source += "\n\n"; |
| tess_eval_shader_source += verification; |
| tess_eval_shader_source += "\n\n"; |
| tess_eval_shader_source += " tes_result = result;\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_eval_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Snippet that makes use of defined function |
| * @param verification Snippet that verifies results |
| **/ |
| template <class API> |
| std::string InteractionFunctionCalls1<API>::prepare_vertex_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string vertex_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vertex_positions[gl_VertexID];" |
| "}\n\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| vertex_shader_source = default_vertex_shader_source; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| /* Vertex shader source. */ |
| vertex_shader_source = "out float fs_result;\n\n"; |
| vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n\n"; |
| |
| /* User-defined function definition. */ |
| vertex_shader_source += function_definition; |
| vertex_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| vertex_shader_source += shader_start; |
| vertex_shader_source += function_use; |
| vertex_shader_source += "\n\n"; |
| vertex_shader_source += verification; |
| vertex_shader_source += "\n\n"; |
| vertex_shader_source += " fs_result = result;\n" |
| " gl_Position = vertex_positions[gl_VertexID];\n"; |
| vertex_shader_source += shader_end; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return vertex_shader_source; |
| } |
| |
| /* Generates the shader source code for the InteractionFunctionCalls2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionFunctionCalls2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const std::string multiplier_array = "const int[] multiplier_array = int[]( 1, 2, 3, 4, 5, 6, 7, 8,\n" |
| " 11, 12, 13, 14, 15, 16, 17, 18,\n" |
| " 21, 22, 23, 24, 25, 26, 27, 28,\n" |
| " 31, 32, 33, 34, 35, 36, 37, 38,\n" |
| " 41, 42, 43, 44, 45, 46, 47, 48,\n" |
| " 51, 52, 53, 54, 55, 56, 57, 58,\n" |
| " 61, 62, 63, 64, 65, 66, 67, 68,\n" |
| " 71, 72, 73, 74, 75, 76, 77, 78,\n" |
| " 81, 82, 83, 84, 85, 86, 87, 88);\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += multiplier_array; |
| function_definition += "void my_function(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " inout_array[2][2][2][2]) {\n" |
| " uint i = 0u;\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " inout_array[a][b][c][d] *= " + |
| var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n"; |
| function_definition += " i+= 1u;\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}"; |
| |
| function_use += " float result = 1.0;\n"; |
| function_use += " uint iterator = 0u;\n"; |
| function_use += " " + var_iterator->second.type + " my_array[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " my_array[a][b][c][d] = " + |
| var_iterator->second.variable_type_initializer2 + ";\n"; |
| function_use += iteration_loop_end; |
| function_use += " my_function(my_array);"; |
| |
| verification += iteration_loop_start; |
| verification += " if (my_array[a][b][c][d] " + |
| var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type + |
| "(multiplier_array[iterator % 64u]))\n" |
| " {\n" |
| " result = 0.0;\n" |
| " }\n" |
| " iterator += 1u;\n"; |
| verification += iteration_loop_end; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + |
| "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + " z[2][2][2][2];\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(out " + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + |
| "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}\n\n"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += "out " + var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + |
| "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}\n\n"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing5<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(inout " + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + |
| "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}\n\n"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionArgumentAliasing4 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionArgumentAliasing6<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string array_declaration = var_iterator->second.type + "[2][2][2][2] z;\n\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "bool gfunc(" + var_iterator->second.type + " x[2][2][2][2], "; |
| function_definition += "inout " + var_iterator->second.type + " y[2][2][2][2])\n"; |
| function_definition += "{\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + |
| "(123);\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += " " + iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += " " + iteration_loop_end; |
| function_definition += " return true;\n"; |
| function_definition += "}\n\n"; |
| |
| function_use += " " + array_declaration; |
| function_use += " " + iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += " " + iteration_loop_end; |
| |
| verification += " float result = 0.0;\n"; |
| verification += " if(gfunc(z, z) == true)\n"; |
| verification += " {\n"; |
| verification += " result = 1.0;\n\n"; |
| verification += " }\n"; |
| verification += " else\n"; |
| verification += " {\n"; |
| verification += " result = 0.0;\n\n"; |
| verification += " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionUniforms1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionUniforms1<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string uniform_definition; |
| std::string uniform_use; |
| |
| uniform_definition += "uniform "; |
| uniform_definition += var_iterator->second.precision; |
| uniform_definition += " "; |
| uniform_definition += var_iterator->second.type; |
| uniform_definition += " my_uniform_1[1][1][1][1];\n\n"; |
| |
| uniform_use = " float result = float(my_uniform_1[0][0][0][0]);\n"; |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = |
| this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, |
| false, false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| glw::GLint uniform_location = -1; |
| |
| /* Make program object active. */ |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| /* Get uniform location. */ |
| uniform_location = gl.getUniformLocation(this->program_object_id, "my_uniform_1[0][0][0][0]"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed."); |
| |
| if (uniform_location == -1) |
| { |
| TCU_FAIL("Uniform is not found or is considered as not active."); |
| } |
| |
| switch (var_type_index) |
| { |
| case 0: //float type of uniform is considered |
| { |
| glw::GLfloat uniform_value = 1.0f; |
| |
| gl.uniform1f(uniform_location, uniform_value); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f() failed."); |
| |
| break; |
| } |
| case 1: //int type of uniform is considered |
| { |
| glw::GLint uniform_value = 1; |
| |
| gl.uniform1i(uniform_location, uniform_value); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed."); |
| |
| break; |
| } |
| case 2: //uint type of uniform is considered |
| { |
| glw::GLuint uniform_value = 1; |
| |
| gl.uniform1ui(uniform_location, uniform_value); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1ui() failed."); |
| |
| break; |
| } |
| case 3: //double type of uniform is considered |
| { |
| glw::GLdouble uniform_value = 1.0; |
| |
| gl.uniform1d(uniform_location, uniform_value); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1d() failed."); |
| |
| break; |
| } |
| default: |
| { |
| TCU_FAIL("Invalid variable-type index."); |
| |
| break; |
| } |
| } /* switch (var_type_index) */ |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_compute_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string compute_shader_source; |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type) |
| { |
| compute_shader_source = "writeonly uniform image2D uni_image;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| compute_shader_source += uniform_definition; |
| compute_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| compute_shader_source += shader_start; |
| compute_shader_source += uniform_use; |
| compute_shader_source += "\n\n"; |
| compute_shader_source += "\n" |
| " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n" |
| "}\n" |
| "\n"; |
| } |
| |
| return compute_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_fragment_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string fragment_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| fragment_shader_source = "out vec4 colour;\n\n"; |
| |
| /* User-defined function definition. */ |
| fragment_shader_source += uniform_definition; |
| fragment_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| fragment_shader_source += shader_start; |
| fragment_shader_source += uniform_use; |
| fragment_shader_source += "\n\n"; |
| fragment_shader_source += " colour = vec4(result);\n"; |
| fragment_shader_source += shader_end; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| fragment_shader_source = "in float fs_result;\n\n" |
| "out vec4 colour;\n\n" |
| "void main()\n" |
| "{\n" |
| " colour = vec4(fs_result);\n" |
| "}\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| fragment_shader_source = default_fragment_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return fragment_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_geometry_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string geometry_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "in float tes_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "out float fs_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| geometry_shader_source += uniform_definition; |
| geometry_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| geometry_shader_source += shader_start; |
| geometry_shader_source += uniform_use; |
| geometry_shader_source += "\n\n"; |
| geometry_shader_source += "\n gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return geometry_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_tess_ctrl_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string tess_ctrl_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_ctrl_shader_source = "layout(vertices = 1) out;\n" |
| "\n" |
| "out float tcs_result[];\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_ctrl_shader_source += uniform_definition; |
| tess_ctrl_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_ctrl_shader_source += shader_start; |
| tess_ctrl_shader_source += uniform_use; |
| tess_ctrl_shader_source += "\n\n"; |
| tess_ctrl_shader_source += " tcs_result[gl_InvocationID] = result;\n" |
| "\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_ctrl_shader_source = default_tc_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_ctrl_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_tess_eval_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string tess_eval_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "in float tcs_result[];\n" |
| "out float tes_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " tes_result = tcs_result[0];\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "out float tes_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_eval_shader_source += uniform_definition; |
| tess_eval_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_eval_shader_source += shader_start; |
| tess_eval_shader_source += uniform_use; |
| tess_eval_shader_source += "\n\n"; |
| tess_eval_shader_source += " tes_result = result;\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_eval_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param uniform_definition Definition used to prepare shader |
| * @param uniform_use Snippet that use defined uniform |
| **/ |
| template <class API> |
| std::string InteractionUniforms1<API>::prepare_vertex_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& uniform_definition, |
| const std::string& uniform_use) |
| { |
| std::string vertex_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| vertex_shader_source = default_vertex_shader_source; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| /* User-defined function definition. */ |
| vertex_shader_source += uniform_definition; |
| |
| /* Main function definition. */ |
| vertex_shader_source += shader_start; |
| vertex_shader_source += uniform_use; |
| vertex_shader_source += " gl_Position = vec4(result);\n"; |
| vertex_shader_source += shader_end; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return vertex_shader_source; |
| } |
| |
| /* Generates the shader source code for the InteractionUniforms2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionUniforms2<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_MAT4, |
| VAR_TYPE_DOUBLE, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string array_initializers[] = { "int[2][2][2][2](\n" |
| " int[2][2][2](\n" |
| " int[2][2](\n" |
| " int[2]( 1, 2),\n" |
| " int[2]( 3, 4)\n" |
| " ),\n" |
| " int[2][2](\n" |
| " int[2]( 5, 6),\n" |
| " int[2]( 7, 8)\n" |
| " )\n" |
| " ),\n" |
| " int[2][2][2](\n" |
| " int[2][2](\n" |
| " int[2](11, 12),\n" |
| " int[2](13, 14)\n" |
| " ),\n" |
| " int[2][2](\n" |
| " int[2](15, 16),\n" |
| " int[2](17, 18)\n" |
| " )\n" |
| " )\n" |
| ")", |
| |
| "float[2][2][2][2](\n" |
| " float[2][2][2](\n" |
| " float[2][2](\n" |
| " float[2](1.0, 2.0),\n" |
| " float[2](3.0, 4.0)),\n" |
| " float[2][2](\n" |
| " float[2](5.0, 6.0),\n" |
| " float[2](7.0, 8.0))),\n" |
| " float[2][2][2](\n" |
| " float[2][2](\n" |
| " float[2](1.1, 2.1),\n" |
| " float[2](3.1, 4.1)\n" |
| " ),\n" |
| " float[2][2](\n" |
| " float[2](5.1, 6.1),\n" |
| " float[2](7.1, 8.1)\n" |
| " )\n" |
| " )\n" |
| ")", |
| |
| "mat4[2][2][2][2](\n" |
| " mat4[2][2][2](\n" |
| " mat4[2][2](\n" |
| " mat4[2]( mat4(1), mat4(2)),\n" |
| " mat4[2]( mat4(3), mat4(4))\n" |
| " ),\n" |
| " mat4[2][2](\n" |
| " mat4[2](mat4(5), mat4(6)),\n" |
| " mat4[2](mat4(7), mat4(8))\n" |
| " )\n" |
| " ),\n" |
| " mat4[2][2][2](\n" |
| " mat4[2][2](\n" |
| " mat4[2](mat4(9), mat4(10)),\n" |
| " mat4[2](mat4(11), mat4(12))\n" |
| " ),\n" |
| " mat4[2][2](\n" |
| " mat4[2](mat4(13), mat4(14)),\n" |
| " mat4[2](mat4(15), mat4(16))\n" |
| " )\n" |
| " )\n" |
| ")", |
| |
| "double[2][2][2][2](\n" |
| " double[2][2][2](\n" |
| " double[2][2](\n" |
| " double[2](1.0, 2.0),\n" |
| " double[2](3.0, 4.0)),\n" |
| " double[2][2](\n" |
| " double[2](5.0, 6.0),\n" |
| " double[2](7.0, 8.0))),\n" |
| " double[2][2][2](\n" |
| " double[2][2](\n" |
| " double[2](1.1, 2.1),\n" |
| " double[2](3.1, 4.1)\n" |
| " ),\n" |
| " double[2][2](\n" |
| " double[2](5.1, 6.1),\n" |
| " double[2](7.1, 8.1)\n" |
| " )\n" |
| " )\n" |
| ")", |
| |
| "dmat4[2][2][2][2](\n" |
| " dmat4[2][2][2](\n" |
| " dmat4[2][2](\n" |
| " dmat4[2]( dmat4(1), dmat4(2)),\n" |
| " dmat4[2]( dmat4(3), dmat4(4))\n" |
| " ),\n" |
| " dmat4[2][2](\n" |
| " dmat4[2](dmat4(5), dmat4(6)),\n" |
| " dmat4[2](dmat4(7), dmat4(8))\n" |
| " )\n" |
| " ),\n" |
| " dmat4[2][2][2](\n" |
| " dmat4[2][2](\n" |
| " dmat4[2](dmat4(9), dmat4(10)),\n" |
| " dmat4[2](dmat4(11), dmat4(12))\n" |
| " ),\n" |
| " dmat4[2][2](\n" |
| " dmat4[2](dmat4(13), dmat4(14)),\n" |
| " dmat4[2](dmat4(15), dmat4(16))\n" |
| " )\n" |
| " )\n" |
| ")" }; |
| |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string base_variable_string; |
| |
| for (int initialiser_selector = 1; initialiser_selector >= 0; initialiser_selector--) |
| { |
| // We normally do all 16 possible permutations of [4][4][4][4] items (15..0). |
| // However, in this case we will skip the case that will work, |
| // so we'll merely process permutations 14..0 |
| for (int permutation_index = 14; permutation_index >= 0; permutation_index--) |
| { |
| base_variable_string = |
| "uniform " + var_iterator->second.precision + " " + var_iterator->second.type + " x"; |
| |
| // for all 4 possible sub_script entries |
| for (int sub_script_entry_index = 3; sub_script_entry_index >= 0; sub_script_entry_index--) |
| { |
| if (permutation_index & (1 << sub_script_entry_index)) |
| { |
| // In this case, we'll use a valid sub_script |
| base_variable_string += "[2]"; |
| } |
| else |
| { |
| // In this case, we'll use an invalid sub_script |
| base_variable_string += "[]"; |
| } |
| } |
| |
| if (initialiser_selector == 0) |
| { |
| // We'll use an initialiser |
| base_variable_string += " = " + array_initializers[var_type_index]; |
| } |
| |
| base_variable_string += ";\n\n"; |
| |
| std::string shader_source = base_variable_string + shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test: |
| * |
| * This will succeed in case of allowed unsized |
| * declarations and when at least one of these is |
| * true: |
| * 1. There is an initialiser. |
| * 2. Only the outermost dimension is unsized, |
| * as in [][2][2][2]. |
| */ |
| EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && |
| (initialiser_selector == 0 || permutation_index == 7), |
| tested_shader_type, shader_source); |
| } /* for (int permutation_index = 14; ...) */ |
| } /* for (int initialiser_selector = 1; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the InteractionUniformBuffers1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionUniformBuffers1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source; |
| |
| shader_source += "uniform uBlocka {\n"; |
| shader_source += " " + var_iterator->second.type + " x[1][1][1][1][1][1];\n"; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionUniformBuffers2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionUniformBuffers2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| /* Iterate through float / int / uint values. */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string uniform_definition; |
| std::string uniform_use; |
| |
| uniform_definition += "layout (std140) uniform uniform_block_name\n" |
| "{\n"; |
| uniform_definition += " "; |
| uniform_definition += var_iterator->second.type; |
| uniform_definition += " my_uniform_1[1][1][1][1];\n" |
| "};\n"; |
| |
| uniform_use = " float result = float(my_uniform_1[0][0][0][0]);\n"; |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = |
| this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, |
| false, false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| glw::GLuint buffer_object_id = 0; |
| glw::GLint my_uniform_block_index = GL_INVALID_INDEX; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| my_uniform_block_index = gl.getUniformBlockIndex(this->program_object_id, "uniform_block_name"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformBlockIndex() failed."); |
| |
| if ((unsigned)my_uniform_block_index == GL_INVALID_INDEX) |
| { |
| TCU_FAIL("Uniform block not found or is considered as not active."); |
| } |
| |
| gl.genBuffers(1, &buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed."); |
| |
| gl.bindBuffer(GL_UNIFORM_BUFFER, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed."); |
| |
| switch (var_type_index) |
| { |
| case 0: //float type of uniform is considered |
| { |
| glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, |
| 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f }; |
| |
| gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* float case */ |
| case 1: //int type of uniform is considered |
| { |
| |
| glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| |
| gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* int case */ |
| case 2: //uint type of uniform is considered |
| { |
| glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| |
| gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* uint case */ |
| case 3: //double type of uniform is considered |
| { |
| glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, |
| 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 }; |
| |
| gl.bufferData(GL_UNIFORM_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* double case */ |
| default: |
| { |
| TCU_FAIL("Invalid variable-type index."); |
| |
| break; |
| } |
| } /* switch (var_type_index) */ |
| |
| gl.uniformBlockBinding(this->program_object_id, my_uniform_block_index, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed."); |
| |
| gl.bindBufferBase(GL_UNIFORM_BUFFER, 0, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed."); |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type) |
| { |
| execute_draw_test(tested_shader_type); |
| } |
| else |
| { |
| execute_dispatch_test(); |
| } |
| |
| /* Deallocate any resources used. */ |
| gl.deleteBuffers(1, &buffer_object_id); |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Executes test for compute program |
| * |
| * @tparam API Tested API descriptor |
| **/ |
| template <class API> |
| void InteractionUniformBuffers2<API>::execute_dispatch_test() |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| } |
| |
| /** Executes test for draw program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| **/ |
| template <class API> |
| void InteractionUniformBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| glw::GLuint vao_id = 0; |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed."); |
| } |
| |
| /* Generates the shader source code for the InteractionUniformBuffers3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionUniformBuffers3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]", |
| "[2][2][][]", "[2][][2][]", "[][2][2][]", "[2][][][2]", |
| "[][2][][2]", "[][][2][2]", "[2][][][]", "[][2][][]", |
| "[][][2][]", "[][][][2]", "[][][][]" }; |
| |
| const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0)," |
| "float[2](3.0, 4.0))," |
| "float[2][2](float[2](5.0, 6.0)," |
| "float[2](7.0, 8.0)))," |
| "float[2][2][2](float[2][2](float[2](1.1, 2.1)," |
| "float[2](3.1, 4.1))," |
| "float[2][2](float[2](5.1, 6.1)," |
| "float[2](7.1, 8.1))));\n", |
| |
| "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1, 2)," |
| "int[2]( 3, 4))," |
| "int[2][2](int[2]( 5, 6)," |
| "int[2]( 7, 8)))," |
| "int[2][2][2](int[2][2](int[2](11, 12)," |
| "int[2](13, 14))," |
| "int[2][2](int[2](15, 16)," |
| "int[2](17, 18))));\n", |
| |
| "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u, 2u)," |
| "uint[2]( 3u, 4u))," |
| "uint[2][2](uint[2]( 5u, 6u)," |
| "uint[2]( 7u, 8u)))," |
| "uint[2][2][2](uint[2][2](uint[2](11u, 12u)," |
| "uint[2](13u, 14u))," |
| "uint[2][2](uint[2](15u, 16u)," |
| "uint[2](17u, 18u))));\n", |
| |
| "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0)," |
| "double[2](3.0, 4.0))," |
| "double[2][2](double[2](5.0, 6.0)," |
| "double[2](7.0, 8.0)))," |
| "double[2][2][2](double[2][2](double[2](1.1, 2.1)," |
| "double[2](3.1, 4.1))," |
| "double[2][2](double[2](5.1, 6.1)," |
| "double[2](7.1, 8.1))));\n" }; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| /* Iterate through float/ int/ uint types. |
| * Case: without initializer. |
| */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t invalid_size_declarations_index = 0; |
| invalid_size_declarations_index < |
| sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]); |
| invalid_size_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = "layout (std140) uniform MyUniform {\n"; |
| shader_source += " " + var_iterator->second.type + |
| invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n"; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3, |
| tested_shader_type, shader_source); |
| } /* for (int invalid_size_declarations_index = 0; ...) */ |
| } |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| |
| /* Iterate through float/ int/ uint types. |
| * Case: with initializer. |
| */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t invalid_size_declarations_index = 0; |
| invalid_size_declarations_index < |
| sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]); |
| invalid_size_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = "layout (std140) uniform MyUniform {\n"; |
| shader_source += " " + var_iterator->second.type + |
| invalid_size_declarations[invalid_size_declarations_index] + |
| " my_variable = " + array_initializers[var_type_index]; |
| |
| var_iterator->second.type + invalid_size_declarations[invalid_size_declarations_index] + |
| " my_variable = " + array_initializers[var_type_index]; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_size_declarations_index = 0; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the InteractionStorageBuffers1 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionStorageBuffers1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string shader_source; |
| |
| shader_source += "buffer uBlocka {\n"; |
| shader_source += " " + var_iterator->second.type + " x[1][1][1][1][1][1];\n"; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, shader_source, true, false); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionUniformBuffers2 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionStorageBuffers2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| /* Iterate through float / int / uint values. */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string uniform_definition; |
| std::string uniform_use; |
| |
| uniform_definition += "layout (std140) buffer storage_block_name\n" |
| "{\n"; |
| uniform_definition += " "; |
| uniform_definition += var_iterator->second.type; |
| uniform_definition += " my_storage_1[1][1][1][1];\n" |
| "};\n"; |
| |
| uniform_use = " float result = float(my_storage_1[0][0][0][0]);\n"; |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = |
| this->prepare_compute_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, |
| false, false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, uniform_definition, uniform_use); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, uniform_definition, uniform_use); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| glw::GLuint buffer_object_id = 0; |
| glw::GLint my_storage_block_index = GL_INVALID_INDEX; |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| my_storage_block_index = |
| gl.getProgramResourceIndex(this->program_object_id, GL_SHADER_STORAGE_BLOCK, "storage_block_name"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramResourceIndex() failed."); |
| |
| if ((unsigned)my_storage_block_index == GL_INVALID_INDEX) |
| { |
| TCU_FAIL("Uniform block not found or is considered as not active."); |
| } |
| |
| gl.genBuffers(1, &buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed."); |
| |
| gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed."); |
| |
| switch (var_type_index) |
| { |
| case 0: //float type of uniform is considered |
| { |
| glw::GLfloat buffer_data[] = { 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, |
| 8.0f, 9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f }; |
| |
| gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* float case */ |
| case 1: //int type of uniform is considered |
| { |
| |
| glw::GLint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| |
| gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* int case */ |
| case 2: //uint type of uniform is considered |
| { |
| glw::GLuint buffer_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; |
| |
| gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* uint case */ |
| case 3: //double type of uniform is considered |
| { |
| glw::GLdouble buffer_data[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, |
| 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0 }; |
| |
| gl.bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(buffer_data), buffer_data, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| break; |
| } /* double case */ |
| default: |
| { |
| TCU_FAIL("Invalid variable-type index."); |
| |
| break; |
| } |
| } /* switch (var_type_index) */ |
| |
| gl.shaderStorageBlockBinding(this->program_object_id, my_storage_block_index, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformBlockBinding() failed."); |
| |
| gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed."); |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type) |
| { |
| execute_draw_test(tested_shader_type); |
| } |
| else |
| { |
| execute_dispatch_test(); |
| } |
| |
| /* Deallocate any resources used. */ |
| gl.deleteBuffers(1, &buffer_object_id); |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Executes test for compute program |
| * |
| * @tparam API Tested API descriptor |
| **/ |
| template <class API> |
| void InteractionStorageBuffers2<API>::execute_dispatch_test() |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| } |
| |
| /** Executes test for draw program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| **/ |
| template <class API> |
| void InteractionStorageBuffers2<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| glw::GLuint vao_id = 0; |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays() failed."); |
| } |
| |
| /* Generates the shader source code for the InteractionUniformBuffers3 |
| * array tests, and attempts to compile each test shader, for both |
| * vertex and fragment shaders. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * (either TestCaseBase<API>::VERTEX_SHADER_TYPE or TestCaseBase<API>::FRAGMENT_SHADER_TYPE). |
| */ |
| template <class API> |
| void InteractionStorageBuffers3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_FLOAT, VAR_TYPE_INT, VAR_TYPE_UINT, |
| VAR_TYPE_DOUBLE }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string invalid_size_declarations[] = { "[2][2][2][]", "[2][2][][2]", "[2][][2][2]", "[][2][2][2]", |
| "[2][2][][]", "[2][][2][]", "[][2][2][]", "[2][][][2]", |
| "[][2][][2]", "[][][2][2]", "[2][][][]", "[][2][][]", |
| "[][][2][]", "[][][][2]", "[][][][]" }; |
| const std::string array_initializers[] = { "float[2][2][2][2](float[2][2][2](float[2][2](float[2](1.0, 2.0)," |
| "float[2](3.0, 4.0))," |
| "float[2][2](float[2](5.0, 6.0)," |
| "float[2](7.0, 8.0)))," |
| "float[2][2][2](float[2][2](float[2](1.1, 2.1)," |
| "float[2](3.1, 4.1))," |
| "float[2][2](float[2](5.1, 6.1)," |
| "float[2](7.1, 8.1))));\n", |
| |
| "int[2][2][2][2](int[2][2][2](int[2][2](int[2]( 1, 2)," |
| "int[2]( 3, 4))," |
| "int[2][2](int[2]( 5, 6)," |
| "int[2]( 7, 8)))," |
| "int[2][2][2](int[2][2](int[2](11, 12)," |
| "int[2](13, 14))," |
| "int[2][2](int[2](15, 16)," |
| "int[2](17, 18))));\n", |
| |
| "uint[2][2][2][2](uint[2][2][2](uint[2][2](uint[2]( 1u, 2u)," |
| "uint[2]( 3u, 4u))," |
| "uint[2][2](uint[2]( 5u, 6u)," |
| "uint[2]( 7u, 8u)))," |
| "uint[2][2][2](uint[2][2](uint[2](11u, 12u)," |
| "uint[2](13u, 14u))," |
| "uint[2][2](uint[2](15u, 16u)," |
| "uint[2](17u, 18u))));\n", |
| |
| "double[2][2][2][2](double[2][2][2](double[2][2](double[2](1.0, 2.0)," |
| "double[2](3.0, 4.0))," |
| "double[2][2](double[2](5.0, 6.0)," |
| "double[2](7.0, 8.0)))," |
| "double[2][2][2](double[2][2](double[2](1.1, 2.1)," |
| "double[2](3.1, 4.1))," |
| "double[2][2](double[2](5.1, 6.1)," |
| "double[2](7.1, 8.1))));\n" }; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| /* Iterate through float/ int/ uint types. |
| * Case: without initializer. |
| */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t invalid_size_declarations_index = 0; |
| invalid_size_declarations_index < |
| sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]); |
| invalid_size_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = "layout (std140) buffer MyStorage {\n"; |
| shader_source += " " + var_iterator->second.type + |
| invalid_size_declarations[invalid_size_declarations_index] + " my_variable;\n"; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| EXECUTE_SHADER_TEST(API::ALLOW_UNSIZED_DECLARATION && invalid_size_declarations_index == 3, |
| tested_shader_type, shader_source); |
| } /* for (int invalid_size_declarations_index = 0; ...) */ |
| } |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| |
| /* Iterate through float/ int/ uint types. |
| * Case: with initializer. |
| */ |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| for (size_t invalid_size_declarations_index = 0; |
| invalid_size_declarations_index < |
| sizeof(invalid_size_declarations) / sizeof(invalid_size_declarations[0]); |
| invalid_size_declarations_index++) |
| { |
| std::string shader_source; |
| |
| shader_source = "layout (std140) buffer MyStorage {\n"; |
| shader_source += " " + var_iterator->second.type + |
| invalid_size_declarations[invalid_size_declarations_index] + |
| " my_variable = " + array_initializers[var_type_index]; |
| |
| var_iterator->second.type + invalid_size_declarations[invalid_size_declarations_index] + |
| " my_variable = " + array_initializers[var_type_index]; |
| shader_source += "};\n\n"; |
| shader_source += shader_start; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, shader_source); |
| |
| /* Execute test */ |
| this->execute_negative_test(tested_shader_type, shader_source); |
| } /* for (int invalid_size_declarations_index = 0; ...) */ |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the InteractionInterfaceArrays1 |
| * array test, and attempts to compile the test shader. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested. |
| */ |
| template <class API> |
| void InteractionInterfaceArrays1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| /* Shader source with invalid buffer (buffer cannot be of arrays of arrays type). */ |
| const std::string invalid_buffer_shader_source = "layout(std140) buffer MyBuffer\n" |
| "{\n" |
| " float f;\n" |
| " int i;\n" |
| " uint ui;\n" |
| "} myBuffers[2][2];\n\n" |
| "void main()\n" |
| "{\n"; |
| |
| /* Verify that buffer arrays of arrays type is rejected. */ |
| { |
| std::string source = invalid_buffer_shader_source; |
| |
| DEFAULT_MAIN_ENDING(tested_shader_type, source); |
| |
| EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source); |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionInterfaceArrays2 |
| * array test, and attempts to compile the test shader. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of shader that is being tested. |
| */ |
| template <class API> |
| void InteractionInterfaceArrays2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType input_shader_type) |
| { |
| /* Shader source with invalid input (input cannot be of arrays of arrays type). */ |
| const std::string input_variable_shader_source[] = { "in float inout_variable", "[2][2];\n" |
| "out float result", |
| ";\n\n" |
| "void main()\n" |
| "{\n" |
| " result", |
| " = inout_variable", "[0][0];\n" }; |
| /* Shader source with invalid output (output cannot be of arrays of arrays type). */ |
| const std::string output_variable_shader_source[] = { "out float inout_variable", |
| "[2][2];\n\n" |
| "void main()\n" |
| "{\n" |
| " inout_variable", |
| "[0][0] = 0.0;\n" |
| " inout_variable", |
| "[0][1] = 1.0;\n" |
| " inout_variable", |
| "[1][0] = 2.0;\n" |
| " inout_variable", |
| "[1][1] = 3.0;\n" }; |
| |
| const typename TestCaseBase<API>::TestShaderType& output_shader_type = |
| this->get_output_shader_type(input_shader_type); |
| std::string input_source; |
| std::string output_source; |
| |
| this->prepare_sources(input_shader_type, output_shader_type, input_variable_shader_source, |
| output_variable_shader_source, input_source, output_source); |
| |
| /* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */ |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type) |
| { |
| if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS) |
| { |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = empty_string; |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(input_shader_type, input_source, output_source); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(input_shader_type, input_source, output_source); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(input_shader_type, input_source, output_source); |
| |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, true, |
| false); |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(input_shader_type, input_source, output_source); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(input_shader_type, input_source, output_source); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false); |
| } |
| } |
| else |
| { |
| this->execute_negative_test(input_shader_type, input_source); |
| this->execute_negative_test(output_shader_type, output_source); |
| } |
| } |
| } |
| |
| /** Gets the shader type to test for the outputs |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| **/ |
| template <class API> |
| const typename TestCaseBase<API>::TestShaderType InteractionInterfaceArrays2<API>::get_output_shader_type( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| return TestCaseBase<API>::FRAGMENT_SHADER_TYPE; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| return TestCaseBase<API>::GEOMETRY_SHADER_TYPE; |
| } |
| else |
| { |
| return TestCaseBase<API>::VERTEX_SHADER_TYPE; |
| } |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| return TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| return TestCaseBase<API>::VERTEX_SHADER_TYPE; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| return TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return input_shader_type; |
| } |
| |
| /** Prepare fragment shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param input_source Shader in case we want to test inputs for this shader |
| * @param output_source Shader in case we want to test outputs for this shader |
| **/ |
| template <class API> |
| const std::string InteractionInterfaceArrays2<API>::prepare_fragment_shader( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source, |
| const std::string& output_source) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| return output_source; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| return input_source; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return default_fragment_shader_source; |
| } |
| |
| /** Prepare geometry shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param input_source Shader in case we want to test inputs for this shader |
| * @param output_source Shader in case we want to test outputs for this shader |
| **/ |
| template <class API> |
| const std::string InteractionInterfaceArrays2<API>::prepare_geometry_shader( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source, |
| const std::string& output_source) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| return output_source; |
| } |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| return input_source; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return default_geometry_shader_source; |
| } |
| |
| /** Prepare tessellation control shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param input_source Shader in case we want to test inputs for this shader |
| * @param output_source Shader in case we want to test outputs for this shader |
| **/ |
| template <class API> |
| const std::string InteractionInterfaceArrays2<API>::prepare_tess_ctrl_shader_source( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source, |
| const std::string& output_source) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| return input_source; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| return output_source; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return default_tc_shader_source; |
| } |
| |
| /** Prepare tessellation evaluation shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param input_source Shader in case we want to test inputs for this shader |
| * @param output_source Shader in case we want to test outputs for this shader |
| **/ |
| template <class API> |
| const std::string InteractionInterfaceArrays2<API>::prepare_tess_eval_shader_source( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source, |
| const std::string& output_source) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| return output_source; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| return input_source; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return default_te_shader_source; |
| } |
| |
| /** Prepare vertex shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param input_source Shader in case we want to test inputs for this shader |
| * @param output_source Shader in case we want to test outputs for this shader |
| **/ |
| template <class API> |
| const std::string InteractionInterfaceArrays2<API>::prepare_vertex_shader( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, const std::string& input_source, |
| const std::string& output_source) |
| { |
| switch (input_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| return input_source; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| if (!API::USE_ALL_SHADER_STAGES) |
| { |
| return output_source; |
| } |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| return output_source; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader type."); |
| break; |
| } |
| |
| return default_vertex_shader_source; |
| } |
| |
| /** Prepare the inputs and outputs shaders |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of input shader that is being tested |
| * @param output_shader_type The type of output shader that is being tested |
| * @param input_shader_source Snippet used to prepare the input shader |
| * @param output_shader_source Snippet used to prepare the output shader |
| * @param input_source Resulting input shader |
| * @param output_source Resulting output shader |
| **/ |
| template <class API> |
| void InteractionInterfaceArrays2<API>::prepare_sources( |
| const typename TestCaseBase<API>::TestShaderType& input_shader_type, |
| const typename TestCaseBase<API>::TestShaderType& output_shader_type, const std::string* input_shader_source, |
| const std::string* output_shader_source, std::string& input_source, std::string& output_source) |
| { |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type) |
| { |
| input_source += input_shader_source[0]; |
| output_source += output_shader_source[0]; |
| |
| if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) || |
| (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) || |
| (TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type)) |
| { |
| input_source += "[]"; |
| } |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type) |
| { |
| output_source += "[]"; |
| } |
| |
| input_source += input_shader_source[1]; |
| output_source += output_shader_source[1]; |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) |
| { |
| input_source += "[]"; |
| } |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type) |
| { |
| output_source += "[gl_InvocationID]"; |
| } |
| |
| input_source += input_shader_source[2]; |
| output_source += output_shader_source[2]; |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) |
| { |
| input_source += "[gl_InvocationID]"; |
| } |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type) |
| { |
| output_source += "[gl_InvocationID]"; |
| } |
| |
| input_source += input_shader_source[3]; |
| output_source += output_shader_source[3]; |
| |
| if ((TestCaseBase<API>::GEOMETRY_SHADER_TYPE == input_shader_type) || |
| (TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE == input_shader_type)) |
| { |
| input_source += "[0]"; |
| } |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == input_shader_type) |
| { |
| input_source += "[gl_InvocationID]"; |
| } |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type) |
| { |
| output_source += "[gl_InvocationID]"; |
| } |
| |
| input_source += input_shader_source[4]; |
| output_source += output_shader_source[4]; |
| |
| if (TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE == output_shader_type) |
| { |
| output_source += "[gl_InvocationID]"; |
| } |
| |
| output_source += output_shader_source[5]; |
| |
| DEFAULT_MAIN_ENDING(input_shader_type, input_source); |
| DEFAULT_MAIN_ENDING(output_shader_type, output_source); |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionInterfaceArrays3 |
| * array test, and attempts to compile the test shader. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested. |
| */ |
| template <class API> |
| void InteractionInterfaceArrays3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| /* Shader source with invalid uniform block (uniform block cannot be of arrays of arrays type). */ |
| const std::string invalid_uniform_block_shader_source = "layout(std140) uniform MyUniformBlock\n" |
| "{\n" |
| " float f;\n" |
| " int i;\n" |
| " uint ui;\n" |
| "} myUniformBlocks[2][2];\n\n" |
| "void main()\n" |
| "{\n"; |
| |
| /* Verify that uniform block arrays of arrays type is rejected. */ |
| { |
| std::string source = invalid_uniform_block_shader_source; |
| |
| DEFAULT_MAIN_ENDING(tested_shader_type, source); |
| |
| EXECUTE_SHADER_TEST(API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS, tested_shader_type, source); |
| } |
| } |
| |
| /* Generates the shader source code for the InteractionInterfaceArrays4 |
| * array test, and attempts to compile the test shader. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param input_shader_type The type of shader that is being tested. |
| */ |
| template <class API> |
| void InteractionInterfaceArrays4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType input_shader_type) |
| { |
| /* Shader source with invalid input (input cannot be of arrays of arrays type). */ |
| const std::string input_block_shader_source[] = { "in InOutBlock {\n" |
| " float inout_variable;\n" |
| "} inout_block", |
| "[2][2];\n" |
| "out float result", |
| ";\n\n" |
| "void main()\n" |
| "{\n" |
| " result", |
| " = inout_block", "[0][0].inout_variable;\n" }; |
| /* Shader source with invalid output (output cannot be of arrays of arrays type). */ |
| const std::string output_block_shader_source[] = { "out InOutBlock {\n" |
| " float inout_variable;\n" |
| "} inout_block", |
| "[2][2];\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " inout_block", |
| "[0][0].inout_variable = 0.0;\n" |
| " inout_block", |
| "[0][1].inout_variable = 1.0;\n" |
| " inout_block", |
| "[1][0].inout_variable = 2.0;\n" |
| " inout_block", |
| "[1][1].inout_variable = 3.0;\n" }; |
| |
| const typename TestCaseBase<API>::TestShaderType& output_shader_type = |
| this->get_output_shader_type(input_shader_type); |
| std::string input_source; |
| std::string output_source; |
| |
| this->prepare_sources(input_shader_type, output_shader_type, input_block_shader_source, output_block_shader_source, |
| input_source, output_source); |
| |
| /* Verify that INPUTs and OUTPUTs arrays of arrays type is rejected. */ |
| if ((TestCaseBase<API>::VERTEX_SHADER_TYPE != input_shader_type) && |
| (TestCaseBase<API>::COMPUTE_SHADER_TYPE != input_shader_type)) |
| { |
| if (API::ALLOW_A_OF_A_ON_INTERFACE_BLOCKS && API::ALLOW_IN_OUT_INTERFACE_BLOCKS) |
| { |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = empty_string; |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(input_shader_type, input_source, output_source); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(input_shader_type, input_source, output_source); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader_source(input_shader_type, input_source, output_source); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader_source(input_shader_type, input_source, output_source); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(input_shader_type, input_source, output_source); |
| |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, true, |
| false); |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(input_shader_type, input_source, output_source); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(input_shader_type, input_source, output_source); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, true, false); |
| } |
| } |
| else |
| { |
| this->execute_negative_test(input_shader_type, input_source); |
| this->execute_negative_test(output_shader_type, output_source); |
| } |
| } |
| } |
| |
| /** Calulate smallest denominator for values over 1 |
| * |
| * @param value Value in question |
| * |
| * @return Smallest denominator |
| **/ |
| size_t findSmallestDenominator(const size_t value) |
| { |
| /* Skip 0 and 1 */ |
| for (size_t i = 2; i < value; ++i) |
| { |
| if (0 == value % i) |
| { |
| return i; |
| } |
| } |
| |
| return value; |
| } |
| |
| /** Check if left is bigger than right |
| * |
| * @tparam T Type of values |
| |
| * @param l Left value |
| * @param r Right value |
| * |
| * @return true if l > r, false otherwise |
| **/ |
| template <class T> |
| bool more(const T& l, const T& r) |
| { |
| return l > r; |
| } |
| |
| /** Prepare dimensions of array with given number of entries |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param n_entries Number of entries |
| * @param dimensions Storage for dimesnions |
| **/ |
| template <class API> |
| void prepareDimensions(size_t n_entries, std::vector<size_t>& dimensions) |
| { |
| if (dimensions.empty()) |
| return; |
| |
| const size_t last = dimensions.size() - 1; |
| |
| /* Calculate */ |
| for (size_t i = 0; i < last; ++i) |
| { |
| const size_t denom = findSmallestDenominator(n_entries); |
| |
| n_entries /= denom; |
| |
| dimensions[i] = denom; |
| } |
| |
| dimensions[last] = n_entries; |
| |
| /* Sort */ |
| std::sort(dimensions.begin(), dimensions.end(), more<size_t>); |
| } |
| |
| /* Generates the shader source code for the AtomicDeclarationTest |
| * and attempts to compile each shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void AtomicDeclarationTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const char* indent_step = " "; |
| static const char* uniform_atomic_uint = "layout(binding = 0) uniform atomic_uint"; |
| |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| std::string comment; |
| std::vector<size_t> dimensions; |
| std::string indent; |
| std::string indexing; |
| std::string invalid_definition = uniform_atomic_uint; |
| std::string invalid_iteration; |
| std::string invalid_shader_source; |
| std::string loop_end; |
| glw::GLint max_atomics = 0; |
| glw::GLenum pname = 0; |
| std::string valid_shader_source; |
| std::string valid_definition = uniform_atomic_uint; |
| std::string valid_iteration; |
| |
| /* Select pname of max for stage */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| pname = GL_MAX_VERTEX_ATOMIC_COUNTERS; |
| break; |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| /* Get maximum */ |
| gl.getIntegerv(pname, &max_atomics); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); |
| |
| if (0 == max_atomics) |
| { |
| /* Not supported - skip */ |
| return; |
| } |
| else |
| { |
| dimensions.resize(API::MAX_ARRAY_DIMENSIONS); |
| prepareDimensions<API>(max_atomics, dimensions); |
| } |
| |
| /* Prepare parts of shader */ |
| for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i) |
| { |
| char it[16]; |
| char max[16]; |
| |
| indent += indent_step; |
| |
| loop_end.insert(0, "}\n"); |
| loop_end.insert(0, indent); |
| |
| sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i)); |
| |
| indexing += "["; |
| indexing += it; |
| indexing += "]"; |
| |
| sprintf(max, "%u", (unsigned int)(dimensions[i - 1])); |
| |
| valid_definition += "["; |
| valid_definition += max; |
| valid_definition += "]"; |
| |
| valid_iteration += indent; |
| valid_iteration += "for (uint "; |
| valid_iteration += it; |
| valid_iteration += " = 0; "; |
| valid_iteration += it; |
| valid_iteration += " < "; |
| valid_iteration += max; |
| valid_iteration += "; ++"; |
| valid_iteration += it; |
| valid_iteration += ")\n"; |
| valid_iteration += indent; |
| valid_iteration += "{\n"; |
| |
| if (1 == i) |
| { |
| sprintf(max, "%u", (unsigned int)(dimensions[i - 1] + 1)); |
| } |
| invalid_definition += "["; |
| invalid_definition += max; |
| invalid_definition += "]"; |
| |
| invalid_iteration += indent; |
| invalid_iteration += "for (uint "; |
| invalid_iteration += it; |
| invalid_iteration += " = 0; "; |
| invalid_iteration += it; |
| invalid_iteration += " < "; |
| invalid_iteration += max; |
| invalid_iteration += "; ++"; |
| invalid_iteration += it; |
| invalid_iteration += ")\n"; |
| invalid_iteration += indent; |
| invalid_iteration += "{\n"; |
| } |
| |
| { |
| char max[16]; |
| |
| sprintf(max, "%u", (unsigned int)(max_atomics)); |
| comment += "/* MAX_*_ATOMIC_COUNTERS = "; |
| comment += max; |
| comment += " */\n"; |
| } |
| |
| /* Prepare invalid source */ |
| invalid_shader_source += comment; |
| invalid_shader_source += invalid_definition; |
| invalid_shader_source += " a;\n\nvoid main()\n{\n"; |
| invalid_shader_source += invalid_iteration; |
| invalid_shader_source += indent; |
| invalid_shader_source += indent_step; |
| invalid_shader_source += "atomicCounterIncrement( a"; |
| invalid_shader_source += indexing; |
| invalid_shader_source += " );\n"; |
| invalid_shader_source += loop_end; |
| |
| /* Prepare valid source */ |
| valid_shader_source += comment; |
| valid_shader_source += valid_definition; |
| valid_shader_source += " a;\n\nvoid main()\n{\n"; |
| valid_shader_source += valid_iteration; |
| valid_shader_source += indent; |
| valid_shader_source += indent_step; |
| valid_shader_source += "atomicCounterIncrement( a"; |
| valid_shader_source += indexing; |
| valid_shader_source += " );\n"; |
| valid_shader_source += loop_end; |
| |
| /* End main */ |
| DEFAULT_MAIN_ENDING(tested_shader_type, invalid_shader_source); |
| DEFAULT_MAIN_ENDING(tested_shader_type, valid_shader_source); |
| |
| /* Execute test */ |
| EXECUTE_POSITIVE_TEST(tested_shader_type, valid_shader_source, true, false); |
| |
| /* Expect build failure for invalid shader source */ |
| { |
| bool negative_build_test_result = false; |
| |
| try |
| { |
| EXECUTE_POSITIVE_TEST(tested_shader_type, invalid_shader_source, true, false); |
| } |
| catch (...) |
| { |
| negative_build_test_result = true; |
| } |
| |
| if (false == negative_build_test_result) |
| { |
| TCU_FAIL("It was expected that build process will fail"); |
| } |
| } |
| } |
| |
| /* Generates the shader source code for the AtomicUsageTest |
| * and attempts to compile each shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void AtomicUsageTest<API>::test_shader_compilation(typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| glw::GLint max_atomics = 0; |
| glw::GLint max_bindings = 0; |
| glw::GLint max_size = 0; |
| glw::GLenum pname = 0; |
| |
| /* Select pname of max for stage */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| pname = GL_MAX_COMPUTE_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| pname = GL_MAX_FRAGMENT_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| pname = GL_MAX_GEOMETRY_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| pname = GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| pname = GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS; |
| break; |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| pname = GL_MAX_VERTEX_ATOMIC_COUNTERS; |
| break; |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| /* Get limits */ |
| gl.getIntegerv(pname, &max_atomics); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); |
| |
| gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); |
| |
| gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE, &max_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); |
| |
| if (0 == max_atomics) |
| { |
| /* Not supported - skip */ |
| return; |
| } |
| |
| const glw::GLuint last_binding = (glw::GLuint)max_bindings - 1; |
| const glw::GLuint offset = (glw::GLuint)max_size / 2; |
| glw::GLuint n_entries = |
| std::min((glw::GLuint)(max_size - offset) / (glw::GLuint)sizeof(glw::GLuint), (glw::GLuint)max_atomics); |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type) |
| { |
| glw::GLint max_uniform_locations = 0; |
| |
| gl.getIntegerv(GL_MAX_UNIFORM_LOCATIONS, &max_uniform_locations); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv"); |
| |
| max_atomics = std::min(max_atomics, (max_uniform_locations - 1)); |
| n_entries = (glw::GLuint)std::min((glw::GLint)n_entries, (max_uniform_locations - 1)); |
| } |
| |
| execute(tested_shader_type, last_binding, 0 /* offset */, max_atomics); |
| execute(tested_shader_type, last_binding, offset, n_entries); |
| } |
| |
| /* Generates the shader source code for the AtomicUsageTest |
| * and attempts to compile each shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param binding Binding index |
| * @param offset Offset of data |
| * @param n_entries Number of entries in array |
| */ |
| template <class API> |
| void AtomicUsageTest<API>::execute(typename TestCaseBase<API>::TestShaderType tested_shader_type, glw::GLuint binding, |
| glw::GLuint offset, glw::GLuint n_entries) |
| { |
| static const char* indent_step = " "; |
| static const char* layout_binding = "layout(binding = "; |
| static const char* layout_offset = ", offset = "; |
| static const char* uniform_atomic_uint = ") uniform atomic_uint"; |
| |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| std::string comment; |
| std::vector<size_t> dimensions; |
| std::string indent; |
| std::string indexing; |
| std::string loop_end; |
| std::string result; |
| std::string valid_shader_source; |
| std::string valid_definition = layout_binding; |
| std::string valid_iteration; |
| std::string varying_definition; |
| |
| dimensions.resize(API::MAX_ARRAY_DIMENSIONS); |
| prepareDimensions<API>(n_entries, dimensions); |
| |
| /* Prepare parts of shader */ |
| |
| /* Append binding */ |
| { |
| char buffer[16]; |
| sprintf(buffer, "%u", static_cast<unsigned int>(binding)); |
| valid_definition += buffer; |
| valid_definition += layout_offset; |
| sprintf(buffer, "%u", static_cast<unsigned int>(offset)); |
| valid_definition += buffer; |
| valid_definition += uniform_atomic_uint; |
| } |
| |
| for (size_t i = API::MAX_ARRAY_DIMENSIONS; i != 0; --i) |
| { |
| char it[16]; |
| char max[16]; |
| |
| indent += indent_step; |
| |
| loop_end.insert(0, "}\n"); |
| loop_end.insert(0, indent); |
| |
| sprintf(it, "i%u", (unsigned int)(API::MAX_ARRAY_DIMENSIONS - i)); |
| |
| indexing += "["; |
| indexing += it; |
| indexing += "]"; |
| |
| sprintf(max, "%u", (unsigned int)(dimensions[i - 1])); |
| valid_definition += "["; |
| valid_definition += max; |
| valid_definition += "]"; |
| |
| valid_iteration += indent; |
| valid_iteration += "for (uint "; |
| valid_iteration += it; |
| valid_iteration += " = 0; "; |
| valid_iteration += it; |
| valid_iteration += " < "; |
| valid_iteration += max; |
| valid_iteration += "; ++"; |
| valid_iteration += it; |
| valid_iteration += ")\n"; |
| valid_iteration += indent; |
| valid_iteration += "{\n"; |
| } |
| |
| { |
| char max[16]; |
| |
| sprintf(max, "%u", (unsigned int)(n_entries)); |
| comment += "/* Number of atomic counters = "; |
| comment += max; |
| comment += " */\n"; |
| } |
| |
| /* Select varyings and result */ |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| result = " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n"; |
| varying_definition = "writeonly uniform image2D uni_image;\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| result = " color = vec4(result);\n"; |
| varying_definition = "out vec4 color;\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| result = " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n"; |
| varying_definition = "out float fs_result;\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| result = " tcs_result[gl_InvocationID] = result;\n" |
| "\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n"; |
| varying_definition = "out float tcs_result[];\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| result = " fs_result = result;\n"; |
| varying_definition = "out float fs_result;\n" |
| "\n"; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| result = " fs_result = result;\n"; |
| varying_definition = "out float fs_result;\n" |
| "\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| }; |
| |
| /* Prepare valid source */ |
| valid_shader_source += varying_definition; |
| valid_shader_source += comment; |
| valid_shader_source += valid_definition; |
| valid_shader_source += " a;\n\nvoid main()\n{\n uint sum = 0u;\n"; |
| valid_shader_source += valid_iteration; |
| valid_shader_source += indent; |
| valid_shader_source += indent_step; |
| valid_shader_source += "sum += atomicCounterIncrement( a"; |
| valid_shader_source += indexing; |
| valid_shader_source += " );\n"; |
| valid_shader_source += loop_end; |
| valid_shader_source += "\n" |
| " float result = 0.0;\n" |
| "\n" |
| " if (16u < sum)\n" |
| " {\n" |
| " result = 1.0;\n" |
| " }\n"; |
| valid_shader_source += result; |
| valid_shader_source += shader_end; |
| |
| /* Build program */ |
| { |
| const std::string* cs = &empty_string; |
| const std::string* vs = &default_vertex_shader_source; |
| const std::string* tcs = &empty_string; |
| const std::string* tes = &empty_string; |
| const std::string* gs = &empty_string; |
| const std::string* fs = &pass_fragment_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| cs = &valid_shader_source; |
| vs = &empty_string; |
| fs = &empty_string; |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| fs = &valid_shader_source; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gs = &valid_shader_source; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tcs = &valid_shader_source; |
| tes = &pass_te_shader_source; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tcs = &default_tc_shader_source; |
| tes = &valid_shader_source; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| vs = &valid_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| }; |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| this->execute_positive_test(*vs, *tcs, *tes, *gs, *fs, *cs, false, false); |
| } |
| else |
| { |
| this->execute_positive_test(*vs, *fs, false, false); |
| } |
| } |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| /* Prepare buffer */ |
| glw::GLuint buffer_object_id = 0; |
| std::vector<glw::GLuint> buffer_data; |
| const size_t start_pos = offset / 4; |
| const size_t last_pos = start_pos + n_entries; |
| const size_t buffer_data_size = last_pos * sizeof(glw::GLuint); |
| |
| gl.genBuffers(1, &buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() failed."); |
| |
| gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() failed."); |
| |
| buffer_data.resize(start_pos + n_entries); |
| for (size_t i = 0; i < n_entries; ++i) |
| { |
| buffer_data[start_pos + i] = (glw::GLuint)i; |
| } |
| |
| gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, buffer_data_size, &buffer_data[0], GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() failed."); |
| |
| gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, binding, buffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() failed."); |
| |
| /* Run program */ |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE != tested_shader_type) |
| { |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| gl.memoryBarrier(GL_ALL_BARRIER_BITS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| gl.bindVertexArray(0); |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| gl.deleteVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| else |
| { |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| |
| gl.memoryBarrier(GL_ALL_BARRIER_BITS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "MemoryBarrier."); |
| } |
| |
| /* Verify results */ |
| bool test_result = true; |
| |
| const glw::GLuint* results = |
| (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /* offset */, buffer_data_size, GL_MAP_READ_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "MapBufferRange"); |
| |
| /* Anything before start position should be 0 */ |
| for (size_t i = 0; i < start_pos; ++i) |
| { |
| if (0 != results[i]) |
| { |
| test_result = false; |
| break; |
| } |
| } |
| |
| /* Anything from start_pos should be incremented by 1 */ |
| int diff = 0; |
| for (size_t i = 0; i < n_entries; ++i) |
| { |
| /* Tesselation evaluation can be called several times |
| In here, check the increment is consistent over all results. |
| */ |
| if (tested_shader_type == TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE) |
| { |
| if (i == 0) |
| { |
| diff = static_cast<int>(results[i + start_pos]) - static_cast<int>(i); |
| if (diff <= 0) |
| { |
| test_result = false; |
| break; |
| } |
| } |
| else if ((static_cast<int>(results[i + start_pos]) - static_cast<int>(i)) != diff) |
| { |
| test_result = false; |
| break; |
| } |
| } |
| else |
| { |
| if (i + 1 != results[i + start_pos]) |
| { |
| test_result = false; |
| break; |
| } |
| } |
| } |
| |
| gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "UnmapBuffer"); |
| |
| /* Deallocate any resources used. */ |
| gl.deleteBuffers(1, &buffer_object_id); |
| this->delete_objects(); |
| |
| if (false == test_result) |
| { |
| TCU_FAIL("Invalid results."); |
| } |
| } |
| |
| /* Generates the shader source code for the SubroutineFunctionCalls1 |
| * array tests, attempts to build and execute test program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineFunctionCalls1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string iterator_declaration = " " + var_iterator->second.iterator_type + |
| " iterator = " + var_iterator->second.iterator_initialization + ";\n"; |
| |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine void out_routine_type(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " output_array[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(out_routine_type) void original_routine(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " output_array[2][2][2][2]) {\n"; |
| function_definition += iterator_declaration; |
| function_definition += iteration_loop_start; |
| function_definition += " output_array[a][b][c][d] = " + |
| var_iterator->second.variable_type_initializer1 + ";\n"; |
| function_definition += |
| " iterator += " + var_iterator->second.iterator_type + "(1);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}\n\n"; |
| function_definition += "subroutine(out_routine_type) void new_routine(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " output_array[2][2][2][2]) {\n"; |
| function_definition += iterator_declaration; |
| function_definition += iteration_loop_start; |
| function_definition += " output_array[a][b][c][d] = " + |
| var_iterator->second.variable_type_initializer1 + ";\n"; |
| function_definition += |
| " iterator -= " + var_iterator->second.iterator_type + "(1);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform out_routine_type routine;\n"; |
| |
| function_use = " " + var_iterator->second.type + " my_array[2][2][2][2];\n"; |
| function_use += " routine(my_array);"; |
| |
| verification = iterator_declaration; |
| verification += " float result = 1.0;\n"; |
| verification += iteration_loop_start; |
| verification += " if (my_array[a][b][c][d] " + |
| var_iterator->second.specific_element + |
| " != iterator)\n" |
| " {\n" |
| " result = 0.0;\n" |
| " }\n" |
| " iterator += " + |
| var_iterator->second.iterator_type + "(1);\n"; |
| verification += iteration_loop_end; |
| |
| if (false == test_compute) |
| { |
| execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, true); |
| execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, false); |
| } |
| else |
| { |
| execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, true); |
| execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Executes test for compute program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| * @param use_original Selects if "original_routine" - true or "new_routine" is choosen |
| * @param expect_invalid_result Does test expects invalid results |
| **/ |
| template <class API> |
| void SubroutineFunctionCalls1<API>::execute_dispatch_test(typename TestCaseBase<API>::TestShaderType tested_shader_type, |
| const std::string& function_definition, |
| const std::string& function_use, |
| const std::string& verification, bool use_original, |
| bool expect_invalid_result) |
| { |
| const std::string& compute_shader_source = |
| prepare_compute_shader(tested_shader_type, function_definition, function_use, verification); |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| this->execute_positive_test(empty_string, empty_string, empty_string, empty_string, empty_string, |
| compute_shader_source, false, false); |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLint location = -1; |
| glw::GLuint routine_index = -1; |
| glw::GLuint routine_location = -1; |
| const glw::GLchar* routine_name = "original_routine"; |
| const glw::GLenum shader_type = GL_COMPUTE_SHADER; |
| glw::GLuint texture_object_id = 0; |
| |
| if (false == use_original) |
| { |
| routine_name = "new_routine"; |
| } |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| /* Select subroutine */ |
| routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed."); |
| |
| routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed."); |
| |
| if (0 != routine_location) |
| { |
| TCU_FAIL("Subroutine location is invalid"); |
| } |
| |
| gl.uniformSubroutinesuiv(shader_type, 1, &routine_index); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed."); |
| |
| /* Prepare texture */ |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| gl.bindImageTexture(0 /* image unit */, texture_object_id, 0 /* level */, GL_FALSE /* layered */, 0 /* layer */, |
| GL_WRITE_ONLY, GL_RGBA8); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() failed."); |
| |
| location = gl.getUniformLocation(this->program_object_id, "uni_image"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() failed."); |
| |
| if (-1 == location) |
| { |
| TCU_FAIL("Uniform is inactive"); |
| } |
| |
| gl.uniform1i(location, 0 /* image unit */); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() failed."); |
| |
| /* Execute */ |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| |
| /* Verify */ |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| if ((buffer[0] != 255) != expect_invalid_result) |
| { |
| TCU_FAIL("Invalid result was returned."); |
| } |
| |
| /* Delete generated objects. */ |
| gl.useProgram(0); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| |
| gl.deleteProgram(this->program_object_id); |
| this->program_object_id = 0; |
| |
| gl.deleteTextures(1, &texture_object_id); |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| } |
| |
| /** Executes test for draw program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| * @param use_original Selects if "original_routine" - true or "new_routine" is choosen |
| * @param expect_invalid_result Does test expects invalid results |
| **/ |
| template <class API> |
| void SubroutineFunctionCalls1<API>::execute_draw_test(typename TestCaseBase<API>::TestShaderType tested_shader_type, |
| const std::string& function_definition, |
| const std::string& function_use, const std::string& verification, |
| bool use_original, bool expect_invalid_result) |
| { |
| const glw::Functions& gl = this->context_id.getRenderContext().getFunctions(); |
| |
| if (API::USE_ALL_SHADER_STAGES) |
| { |
| const std::string& compute_shader_source = empty_string; |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& geometry_shader_source = |
| this->prepare_geometry_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& tess_ctrl_shader_source = |
| this->prepare_tess_ctrl_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& tess_eval_shader_source = |
| this->prepare_tess_eval_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| break; |
| |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| this->execute_positive_test(vertex_shader_source, tess_ctrl_shader_source, tess_eval_shader_source, |
| geometry_shader_source, fragment_shader_source, compute_shader_source, false, |
| false); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| } |
| else |
| { |
| const std::string& fragment_shader_source = |
| this->prepare_fragment_shader(tested_shader_type, function_definition, function_use, verification); |
| const std::string& vertex_shader_source = |
| this->prepare_vertex_shader(tested_shader_type, function_definition, function_use, verification); |
| |
| this->execute_positive_test(vertex_shader_source, fragment_shader_source, false, false); |
| } |
| |
| /* We are now ready to verify whether the returned size is correct. */ |
| unsigned char buffer[4] = { 0 }; |
| glw::GLuint framebuffer_object_id = 0; |
| glw::GLuint routine_index = -1; |
| glw::GLuint routine_location = -1; |
| const glw::GLchar* routine_name = "original_routine"; |
| glw::GLenum shader_type = 0; |
| glw::GLuint texture_object_id = 0; |
| glw::GLuint vao_id = 0; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| shader_type = GL_FRAGMENT_SHADER; |
| break; |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| shader_type = GL_VERTEX_SHADER; |
| break; |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| shader_type = GL_COMPUTE_SHADER; |
| break; |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| shader_type = GL_GEOMETRY_SHADER; |
| break; |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| shader_type = GL_TESS_CONTROL_SHADER; |
| break; |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| shader_type = GL_TESS_EVALUATION_SHADER; |
| break; |
| default: |
| TCU_FAIL("Invalid shader type"); |
| break; |
| } |
| |
| if (false == use_original) |
| { |
| routine_name = "new_routine"; |
| } |
| |
| gl.useProgram(this->program_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() failed."); |
| |
| /* Select subroutine */ |
| routine_index = gl.getSubroutineIndex(this->program_object_id, shader_type, routine_name); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineIndex() failed."); |
| |
| routine_location = gl.getSubroutineUniformLocation(this->program_object_id, shader_type, "routine"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetSubroutineUniformLocation() failed."); |
| |
| if (0 != routine_location) |
| { |
| TCU_FAIL("Subroutine location is invalid"); |
| } |
| |
| gl.uniformSubroutinesuiv(shader_type, 1, &routine_index); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniformSubroutinesuiv() failed."); |
| |
| /* Prepre texture */ |
| assert(0 == texture_object_id); |
| gl.genTextures(1, &texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed."); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed."); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed."); |
| |
| /* Prepare framebuffer */ |
| assert(0 == framebuffer_object_id); |
| gl.genFramebuffers(1, &framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer_object_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_object_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed."); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() failed."); |
| |
| /* Set VAO */ |
| assert(0 == vao_id); |
| gl.genVertexArrays(1, &vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() failed."); |
| |
| gl.bindVertexArray(vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() failed."); |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| gl.drawArrays(GL_TRIANGLE_FAN, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| /* Tesselation patch set up */ |
| gl.patchParameteri(GL_PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "PatchParameteri"); |
| |
| gl.drawArrays(GL_PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() failed."); |
| break; |
| |
| default: |
| TCU_FAIL("Invalid enum"); |
| break; |
| } |
| |
| /* Verify */ |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer() failed."); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed."); |
| |
| const bool result = ((buffer[0] != 255) == expect_invalid_result); |
| |
| /* Delete generated objects. */ |
| gl.useProgram(0); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| gl.bindVertexArray(0); |
| |
| gl.deleteProgram(this->program_object_id); |
| this->program_object_id = 0; |
| |
| gl.deleteTextures(1, &texture_object_id); |
| texture_object_id = 0; |
| |
| gl.deleteFramebuffers(1, &framebuffer_object_id); |
| framebuffer_object_id = 0; |
| |
| gl.deleteVertexArrays(1, &vao_id); |
| vao_id = 0; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "An error ocurred while deleting generated objects."); |
| |
| if (!result) |
| { |
| TCU_FAIL("Invalid result was returned."); |
| } |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_compute_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string compute_shader_source; |
| |
| if (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type) |
| { |
| compute_shader_source = "writeonly uniform image2D uni_image;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| compute_shader_source += function_definition; |
| compute_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| compute_shader_source += shader_start; |
| compute_shader_source += function_use; |
| compute_shader_source += "\n\n"; |
| compute_shader_source += verification; |
| compute_shader_source += "\n\n"; |
| compute_shader_source += "\n" |
| " imageStore(uni_image, ivec2(gl_GlobalInvocationID.xy), vec4(result, 0, 0, 0));\n" |
| "}\n" |
| "\n"; |
| } |
| |
| return compute_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_fragment_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string fragment_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| fragment_shader_source = "out vec4 colour;\n\n"; |
| |
| /* User-defined function definition. */ |
| fragment_shader_source += function_definition; |
| fragment_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| fragment_shader_source += shader_start; |
| fragment_shader_source += function_use; |
| fragment_shader_source += "\n\n"; |
| fragment_shader_source += verification; |
| fragment_shader_source += "\n\n"; |
| fragment_shader_source += " colour = vec4(result);\n"; |
| fragment_shader_source += shader_end; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| fragment_shader_source = "in float fs_result;\n\n" |
| "out vec4 colour;\n\n" |
| "void main()\n" |
| "{\n" |
| " colour = vec4(fs_result);\n" |
| "}\n" |
| "\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return fragment_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_geometry_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string geometry_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: /* Fall through */ |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "in float tes_result[];\n" |
| "out float fs_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = tes_result[0];\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| geometry_shader_source = "layout(points) in;\n" |
| "layout(triangle_strip, max_vertices = 4) out;\n" |
| "\n" |
| "out float fs_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| geometry_shader_source += function_definition; |
| geometry_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| geometry_shader_source += shader_start; |
| geometry_shader_source += function_use; |
| geometry_shader_source += "\n\n"; |
| geometry_shader_source += verification; |
| geometry_shader_source += "\n\n"; |
| geometry_shader_source += "\n gl_Position = vec4(-1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(-1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, -1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| " gl_Position = vec4(1, 1, 0, 1);\n" |
| " fs_result = result;\n" |
| " EmitVertex();\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return geometry_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_tess_ctrl_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string tess_ctrl_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_ctrl_shader_source = "layout(vertices = 1) out;\n" |
| "\n" |
| "out float tcs_result[];\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_ctrl_shader_source += function_definition; |
| tess_ctrl_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_ctrl_shader_source += shader_start; |
| tess_ctrl_shader_source += function_use; |
| tess_ctrl_shader_source += "\n\n"; |
| tess_ctrl_shader_source += verification; |
| tess_ctrl_shader_source += "\n\n"; |
| tess_ctrl_shader_source += " tcs_result[gl_InvocationID] = result;\n" |
| "\n" |
| " gl_TessLevelOuter[0] = 1.0;\n" |
| " gl_TessLevelOuter[1] = 1.0;\n" |
| " gl_TessLevelOuter[2] = 1.0;\n" |
| " gl_TessLevelOuter[3] = 1.0;\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_ctrl_shader_source = default_tc_shader_source; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_ctrl_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_tess_eval_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string tess_eval_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "in float tcs_result[];\n" |
| "out float tes_result;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " tes_result = tcs_result[0];\n" |
| "}\n"; |
| break; |
| |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| tess_eval_shader_source = "layout(isolines, point_mode) in;\n" |
| "\n" |
| "out float tes_result;\n" |
| "\n"; |
| |
| /* User-defined function definition. */ |
| tess_eval_shader_source += function_definition; |
| tess_eval_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| tess_eval_shader_source += shader_start; |
| tess_eval_shader_source += function_use; |
| tess_eval_shader_source += "\n\n"; |
| tess_eval_shader_source += verification; |
| tess_eval_shader_source += "\n\n"; |
| tess_eval_shader_source += " tes_result = result;\n" |
| "}\n"; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return tess_eval_shader_source; |
| } |
| |
| /** Prepare shader |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| * @param function_definition Definition used to prepare shader |
| * @param function_use Use of definition |
| * @param verification Result verification |
| **/ |
| template <class API> |
| std::string SubroutineFunctionCalls1<API>::prepare_vertex_shader( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type, const std::string& function_definition, |
| const std::string& function_use, const std::string& verification) |
| { |
| std::string vertex_shader_source; |
| |
| switch (tested_shader_type) |
| { |
| case TestCaseBase<API>::COMPUTE_SHADER_TYPE: |
| break; |
| |
| case TestCaseBase<API>::FRAGMENT_SHADER_TYPE: |
| vertex_shader_source = "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vertex_positions[gl_VertexID];" |
| "}\n\n"; |
| break; |
| |
| case TestCaseBase<API>::GEOMETRY_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_CONTROL_SHADER_TYPE: |
| case TestCaseBase<API>::TESSELATION_EVALUATION_SHADER_TYPE: |
| vertex_shader_source = default_vertex_shader_source; |
| break; |
| |
| case TestCaseBase<API>::VERTEX_SHADER_TYPE: |
| /* Vertex shader source. */ |
| vertex_shader_source = "out float fs_result;\n\n"; |
| vertex_shader_source += "/** GL_TRIANGLE_FAN-type quad vertex data. */\n" |
| "const vec4 vertex_positions[4] = vec4[4](vec4( 1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, -1.0, 0.0, 1.0),\n" |
| " vec4(-1.0, 1.0, 0.0, 1.0),\n" |
| " vec4( 1.0, 1.0, 0.0, 1.0) );\n\n"; |
| |
| /* User-defined function definition. */ |
| vertex_shader_source += function_definition; |
| vertex_shader_source += "\n\n"; |
| |
| /* Main function definition. */ |
| vertex_shader_source += shader_start; |
| vertex_shader_source += function_use; |
| vertex_shader_source += "\n\n"; |
| vertex_shader_source += verification; |
| vertex_shader_source += "\n\n"; |
| vertex_shader_source += " fs_result = result;\n" |
| " gl_Position = vertex_positions[gl_VertexID];\n"; |
| vertex_shader_source += shader_end; |
| break; |
| |
| default: |
| TCU_FAIL("Unrecognized shader object type."); |
| break; |
| } |
| |
| return vertex_shader_source; |
| } |
| |
| /* Generates the shader source code for the InteractionFunctionCalls2 |
| * array tests, and attempts to build and execute test program. |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineFunctionCalls2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const std::string multiplier_array = "const int[] multiplier_array = int[]( 1, 2, 3, 4, 5, 6, 7, 8,\n" |
| " 11, 12, 13, 14, 15, 16, 17, 18,\n" |
| " 21, 22, 23, 24, 25, 26, 27, 28,\n" |
| " 31, 32, 33, 34, 35, 36, 37, 38,\n" |
| " 41, 42, 43, 44, 45, 46, 47, 48,\n" |
| " 51, 52, 53, 54, 55, 56, 57, 58,\n" |
| " 61, 62, 63, 64, 65, 66, 67, 68,\n" |
| " 71, 72, 73, 74, 75, 76, 77, 78,\n" |
| " 81, 82, 83, 84, 85, 86, 87, 88);\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += multiplier_array; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine void inout_routine_type(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " inout_array[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(inout_routine_type) void original_routine(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " inout_array[2][2][2][2]) {\n" |
| " uint i = 0u;\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " inout_array[a][b][c][d] *= " + |
| var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n"; |
| function_definition += " i+= 1u;\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}\n\n" |
| "subroutine(inout_routine_type) void new_routine(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " inout_array[2][2][2][2]) {\n" |
| " uint i = 0u;\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " inout_array[a][b][c][d] /= " + |
| var_iterator->second.iterator_type + "(multiplier_array[i % 64u]);\n"; |
| function_definition += " i+= 1u;\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform inout_routine_type routine;\n"; |
| |
| function_use += " float result = 1.0;\n"; |
| function_use += " uint iterator = 0u;\n"; |
| function_use += " " + var_iterator->second.type + " my_array[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " my_array[a][b][c][d] = " + |
| var_iterator->second.variable_type_initializer2 + ";\n"; |
| function_use += iteration_loop_end; |
| function_use += " routine(my_array);"; |
| |
| verification += iteration_loop_start; |
| verification += " if (my_array[a][b][c][d] " + |
| var_iterator->second.specific_element + "!= " + var_iterator->second.iterator_type + |
| "(multiplier_array[iterator % 64u]))\n" |
| " {\n" |
| " result = 0.0;\n" |
| " }\n" |
| " iterator += 1u;\n"; |
| verification += iteration_loop_end; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, |
| true); |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, |
| true); |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the SubroutineArgumentAliasing1 |
| * array tests, attempts to build and execute test program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineArgumentAliasing1<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine bool in_routine_type("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(in_routine_type) bool original_routine("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "subroutine(in_routine_type) bool new_routine("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform in_routine_type routine;\n"; |
| |
| function_use += " " + var_iterator->second.type + " z[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += iteration_loop_end; |
| |
| verification = " float result = 0.0;\n" |
| " if(routine(z, z) == true)\n" |
| " {\n" |
| " result = 1.0;\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " result = 0.5;\n" |
| " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the SubroutineArgumentAliasing1 |
| * array tests, attempts to build and execute test program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineArgumentAliasing2<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine bool inout_routine_type(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(inout_routine_type) bool original_routine(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "subroutine(inout_routine_type) bool new_routine(inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], inout "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform inout_routine_type routine;\n"; |
| |
| function_use += " " + var_iterator->second.type + " z[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += iteration_loop_end; |
| |
| verification = " float result = 0.0;\n" |
| " if(routine(z, z) == true)\n" |
| " {\n" |
| " result = 1.0;\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " result = 0.5;\n" |
| " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the SubroutineArgumentAliasing1 |
| * array tests, attempts to build and execute test program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineArgumentAliasing3<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine bool out_routine_type(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(out_routine_type) bool original_routine(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "subroutine(out_routine_type) bool new_routine(out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " x[a][b][c][d] = " + var_iterator->second.type + "(321);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(y[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform out_routine_type routine;\n"; |
| |
| function_use += " " + var_iterator->second.type + " z[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += iteration_loop_end; |
| |
| verification = " float result = 0.0;\n" |
| " if(routine(z, z) == true)\n" |
| " {\n" |
| " result = 1.0;\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " result = 0.5;\n" |
| " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /* Generates the shader source code for the SubroutineArgumentAliasing1 |
| * array tests, attempts to build and execute test program |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param tested_shader_type The type of shader that is being tested |
| */ |
| template <class API> |
| void SubroutineArgumentAliasing4<API>::test_shader_compilation( |
| typename TestCaseBase<API>::TestShaderType tested_shader_type) |
| { |
| static const glcts::test_var_type var_types_set_es[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4 }; |
| static const size_t num_var_types_es = sizeof(var_types_set_es) / sizeof(var_types_set_es[0]); |
| |
| static const glcts::test_var_type var_types_set_gl[] = { VAR_TYPE_INT, VAR_TYPE_FLOAT, VAR_TYPE_IVEC2, |
| VAR_TYPE_IVEC3, VAR_TYPE_IVEC4, VAR_TYPE_VEC2, |
| VAR_TYPE_VEC3, VAR_TYPE_VEC4, VAR_TYPE_MAT2, |
| VAR_TYPE_MAT3, VAR_TYPE_MAT4, VAR_TYPE_DOUBLE, |
| VAR_TYPE_DMAT2, VAR_TYPE_DMAT3, VAR_TYPE_DMAT4 }; |
| static const size_t num_var_types_gl = sizeof(var_types_set_gl) / sizeof(var_types_set_gl[0]); |
| |
| const std::string iteration_loop_end = " }\n" |
| " }\n" |
| " }\n" |
| " }\n"; |
| const std::string iteration_loop_start = " for (uint a = 0u; a < 2u; a++)\n" |
| " {\n" |
| " for (uint b = 0u; b < 2u; b++)\n" |
| " {\n" |
| " for (uint c = 0u; c < 2u; c++)\n" |
| " {\n" |
| " for (uint d = 0u; d < 2u; d++)\n" |
| " {\n"; |
| const glcts::test_var_type* var_types_set = var_types_set_es; |
| size_t num_var_types = num_var_types_es; |
| const bool test_compute = (TestCaseBase<API>::COMPUTE_SHADER_TYPE == tested_shader_type); |
| |
| if (API::USE_DOUBLE) |
| { |
| var_types_set = var_types_set_gl; |
| num_var_types = num_var_types_gl; |
| } |
| |
| for (size_t var_type_index = 0; var_type_index < num_var_types; var_type_index++) |
| { |
| _supported_variable_types_map_const_iterator var_iterator = |
| supported_variable_types_map.find(var_types_set[var_type_index]); |
| |
| if (var_iterator != supported_variable_types_map.end()) |
| { |
| std::string function_definition; |
| std::string function_use; |
| std::string verification; |
| |
| function_definition += "// Subroutine types\n" |
| "subroutine bool out_routine_type("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2]);\n\n" |
| "// Subroutine definitions\n" |
| "subroutine(out_routine_type) bool original_routine("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + "(123);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "subroutine(out_routine_type) bool new_routine("; |
| function_definition += var_iterator->second.type; |
| function_definition += " x[2][2][2][2], out "; |
| function_definition += var_iterator->second.type; |
| function_definition += " y[2][2][2][2])\n{\n"; |
| function_definition += iteration_loop_start; |
| function_definition += |
| " y[a][b][c][d] = " + var_iterator->second.type + "(321);\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n"; |
| function_definition += iteration_loop_start; |
| function_definition += " if(x[a][b][c][d]"; |
| if (var_iterator->second.type == "mat4") // mat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != float"; |
| } |
| else if (var_iterator->second.type == "dmat4") // dmat4 comparison |
| { |
| function_definition += "[0][0]"; |
| function_definition += " != double"; |
| } |
| else |
| { |
| function_definition += " != "; |
| function_definition += var_iterator->second.type; |
| } |
| function_definition += "(((a*8u)+(b*4u)+(c*2u)+d))) {return false;}\n"; |
| function_definition += iteration_loop_end; |
| function_definition += "\n return true;\n"; |
| function_definition += "}\n\n" |
| "// Subroutine uniform\n" |
| "subroutine uniform out_routine_type routine;\n"; |
| |
| function_use += " " + var_iterator->second.type + " z[2][2][2][2];\n"; |
| function_use += iteration_loop_start; |
| function_use += " z[a][b][c][d] = "; |
| function_use += var_iterator->second.type; |
| function_use += "(((a*8u)+(b*4u)+(c*2u)+d));\n"; |
| function_use += iteration_loop_end; |
| |
| verification = " float result = 0.0;\n" |
| " if(routine(z, z) == true)\n" |
| " {\n" |
| " result = 1.0;\n" |
| " }\n" |
| " else\n" |
| " {\n" |
| " result = 0.5;\n" |
| " }\n"; |
| |
| if (false == test_compute) |
| { |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_draw_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| else |
| { |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, false, |
| false); |
| this->execute_dispatch_test(tested_shader_type, function_definition, function_use, verification, true, |
| false); |
| } |
| |
| /* Deallocate any resources used. */ |
| this->delete_objects(); |
| } /* if var_type iterator found */ |
| else |
| { |
| TCU_FAIL("Type not found."); |
| } |
| } /* for (int var_type_index = 0; ...) */ |
| } |
| |
| /** Instantiates all tests and adds them as children to the node |
| * |
| * @tparam API Tested API descriptor |
| * |
| * @param context CTS context |
| **/ |
| template <class API> |
| void initTests(TestCaseGroup& group, glcts::Context& context) |
| { |
| // Set up the map |
| ArraysOfArrays::initializeMap<API>(); |
| |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsPrimitive<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsStructTypes4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsTypenameStyle5<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SizedDeclarationsFunctionParams<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::sized_declarations_invalid_sizes4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructors2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedConstructors<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConst<API>(context)); |
| |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclInvalidConstructors4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclConstructorSizing2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclStructConstructors<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ConstructorsAndUnsizedDeclUnsizedArrays4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsAssignment3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsTypeRestrictions2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingScalar4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsIndexingArray3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsDynamicIndexing2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsEquality2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsLength1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsLength2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsLength3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::ExpressionsInvalid2<API>(context)); |
| |
| group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionFunctionCalls2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing4<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing5<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionArgumentAliasing6<API>(context)); |
| |
| group.addChild(new glcts::ArraysOfArrays::InteractionUniforms1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionUniforms2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionUniformBuffers3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionInterfaceArrays4<API>(context)); |
| |
| if (API::USE_STORAGE_BLOCK) |
| { |
| group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::InteractionStorageBuffers3<API>(context)); |
| } |
| |
| if (API::USE_ATOMIC) |
| { |
| group.addChild(new glcts::ArraysOfArrays::AtomicDeclarationTest<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::AtomicUsageTest<API>(context)); |
| } |
| |
| if (API::USE_SUBROUTINE) |
| { |
| group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SubroutineFunctionCalls2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing1<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing2<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing3<API>(context)); |
| group.addChild(new glcts::ArraysOfArrays::SubroutineArgumentAliasing4<API>(context)); |
| } |
| } |
| } /* namespace ArraysOfArrays */ |
| |
| /** Constructor |
| * |
| * @param context CTS context |
| **/ |
| ArrayOfArraysTestGroup::ArrayOfArraysTestGroup(Context& context) |
| : TestCaseGroup(context, "arrays_of_arrays", "Groups all tests that verify 'arrays of arrays' functionality.") |
| { |
| /* Left blank on purpose */ |
| } |
| |
| /* Instantiates all tests and adds them as children to the node */ |
| void ArrayOfArraysTestGroup::init(void) |
| { |
| ArraysOfArrays::initTests<ArraysOfArrays::Interface::ES>(*this, m_context); |
| } |
| |
| /** Constructor |
| * |
| * @param context CTS context |
| **/ |
| ArrayOfArraysTestGroupGL::ArrayOfArraysTestGroupGL(Context& context) |
| : TestCaseGroup(context, "arrays_of_arrays_gl", "Groups all tests that verify 'arrays of arrays' functionality.") |
| { |
| /* Left blank on purpose */ |
| } |
| |
| /* Instantiates all tests and adds them as children to the node */ |
| void ArrayOfArraysTestGroupGL::init(void) |
| { |
| ArraysOfArrays::initTests<ArraysOfArrays::Interface::GL>(*this, m_context); |
| } |
| } /* namespace glcts */ |