| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2016 Google Inc. |
| * Copyright (c) 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 GLSL vector constructor tests. |
| */ /*-------------------------------------------------------------------*/ |
| #include "glcGLSLVectorConstructorTests.hpp" |
| |
| #include "gluDefs.hpp" |
| #include "gluTextureUtil.hpp" |
| #include "gluDrawUtil.hpp" |
| #include "gluShaderProgram.hpp" |
| |
| #include "glwDefs.hpp" |
| #include "glwFunctions.hpp" |
| #include "glwEnums.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuStringTemplate.hpp" |
| |
| #include <functional> |
| #include <map> |
| #include <vector> |
| #include <sstream> |
| #include <string> |
| #include <tuple> |
| |
| namespace deqp |
| { |
| |
| namespace |
| { |
| using std::string; |
| |
| using std::map; |
| using std::vector; |
| |
| using std::function; |
| using std::bind; |
| using namespace std::placeholders; |
| |
| using std::ostringstream; |
| |
| enum struct TestType |
| { |
| VERTEX_SHADER_ERROR = 0, |
| FRAGMENT_SHADER_ERROR, |
| VERTEX_SHADER, |
| FRAGMENT_SHADER |
| }; |
| |
| struct TestDefinition |
| { |
| vector<string> outputTypes; |
| vector<vector<string>> inputTypeLists; |
| string extraFields; |
| }; |
| |
| const TestDefinition tests[] = |
| { |
| { |
| { "vec2", "vec3", "vec4" }, // vector<string> outputTypes |
| { // vector<vector<string>> inputTypeLists |
| { "mat2" }, |
| { "mat2x3" }, |
| { "mat2x4" }, |
| { "mat3" }, |
| { "mat3x2" }, |
| { "mat3x4" }, |
| { "mat4" }, |
| { "mat4x2" }, |
| { "mat4x3" }, |
| { "float", "mat2" }, |
| { "float", "mat2x3" }, |
| { "float", "mat2x4" }, |
| { "float", "mat3" }, |
| { "float", "mat3x2" }, |
| { "float", "mat3x4" }, |
| { "float", "mat4" }, |
| { "float", "mat4x2" }, |
| { "float", "mat4x3" }, |
| }, |
| "const float errorBound = 1.0E-5;\n" // deUint32 extraFields; |
| }, |
| { |
| { "ivec2", "ivec3", "ivec4" }, // vector<string> outputTypes |
| { // vector<vector<string>> inputTypeLists |
| { "mat2" }, |
| { "mat2x3" }, |
| { "mat2x4" }, |
| { "mat3" }, |
| { "mat3x2" }, |
| { "mat3x4" }, |
| { "mat4" }, |
| { "mat4x2" }, |
| { "mat4x3" }, |
| { "int", "mat2" }, |
| { "int", "mat2x3" }, |
| { "int", "mat2x4" }, |
| { "int", "mat3" }, |
| { "int", "mat3x2" }, |
| { "int", "mat3x4" }, |
| { "int", "mat4" }, |
| { "int", "mat4x2" }, |
| { "int", "mat4x3" }, |
| }, |
| "" // deUint32 extraFields; |
| }, |
| { |
| { "bvec2", "bvec3", "bvec4" }, // vector<string> outputTypes |
| { // vector<vector<string>> inputTypeLists |
| { "mat2" }, |
| { "mat2x3" }, |
| { "mat2x4" }, |
| { "mat3" }, |
| { "mat3x2" }, |
| { "mat3x4" }, |
| { "mat4" }, |
| { "mat4x2" }, |
| { "mat4x3" }, |
| { "bool", "mat2" }, |
| { "bool", "mat2x3" }, |
| { "bool", "mat2x4" }, |
| { "bool", "mat3" }, |
| { "bool", "mat3x2" }, |
| { "bool", "mat3x4" }, |
| { "bool", "mat4" }, |
| { "bool", "mat4x2" }, |
| { "bool", "mat4x3" }, |
| }, |
| "" // deUint32 extraFields; |
| }, |
| }; |
| |
| struct TestParams |
| { |
| string name; |
| string description; |
| TestType testType; |
| string outputType; |
| vector<string> inputTypes; |
| string extraFields; |
| }; |
| |
| vector<TestParams> generateTestParams() |
| { |
| vector<TestParams> result; |
| result.reserve(64); |
| for(const auto& test : tests) |
| { |
| for(const auto& outputType : test.outputTypes) |
| { |
| for(const auto& inputTypes : test.inputTypeLists) |
| { |
| ostringstream testNameVs, testNameFs; |
| ostringstream testDescriptionVs, testDescriptionFs; |
| testNameVs << outputType << "_from"; |
| testNameFs << outputType << "_from"; |
| testDescriptionVs << outputType << "("; |
| testDescriptionFs << outputType << "("; |
| for(vector<string>::size_type i = 0; i < inputTypes.size(); ++i) |
| { |
| const auto& inputType = inputTypes[i]; |
| testNameVs << "_" << inputType; |
| testNameFs << "_" << inputType; |
| if (i > 0) { |
| testDescriptionVs << ","; |
| testDescriptionFs << ","; |
| } |
| testDescriptionVs << inputType; |
| } |
| ostringstream testNameInvalidVs, testNameInvalidFs; |
| testNameInvalidVs << testNameVs.str() << "_" << inputTypes[0] << "_invalid_vs"; |
| testNameInvalidFs << testNameFs.str() << "_" << inputTypes[0] << "_invalid_fs"; |
| |
| testNameVs << "_vs"; |
| testNameFs << "_fs"; |
| testDescriptionVs << ") vertex shader"; |
| testDescriptionFs << ") fragment shader"; |
| result.push_back({ testNameVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER, outputType, inputTypes, test.extraFields }); |
| result.push_back({ testNameFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER, outputType, inputTypes, test.extraFields }); |
| |
| vector<string> failInputTypes; |
| failInputTypes.insert(failInputTypes.end(), inputTypes.begin(), inputTypes.end()); |
| failInputTypes.push_back(inputTypes[0]); |
| testDescriptionVs << " invalid"; |
| testDescriptionFs << " invalid"; |
| result.push_back({ testNameInvalidVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER_ERROR, outputType, failInputTypes, test.extraFields }); |
| result.push_back({ testNameInvalidFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER_ERROR, outputType, failInputTypes, test.extraFields }); |
| |
| } |
| } |
| } |
| return result; |
| } |
| |
| const string defaultVertexShader = |
| "${GLSL_VERSION}\n" |
| "in vec4 vPosition;\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vPosition;\n" |
| "}\n"; |
| |
| const string defaultFragmentShader = |
| "${GLSL_VERSION}\n" |
| "precision mediump float;\n" |
| "in vec4 vColor;\n" |
| "out vec4 my_FragColor;\n" |
| "void main() {\n" |
| " my_FragColor = vColor;\n" |
| "}\n"; |
| |
| const string vertexShaderTemplate = |
| "${GLSL_VERSION}\n" |
| "in vec4 vPosition;\n" |
| "precision mediump int;\n" |
| "precision mediump float;\n" |
| "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" |
| "const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n" |
| "${TEST_CONSTANTS}" |
| "out vec4 vColor;\n" |
| "void main() {\n" |
| " ${TEST_CODE}\n" |
| " if ${TEST_CONDITION}\n" |
| " vColor = green;\n" |
| " else\n" |
| " vColor = red;\n" |
| " gl_Position = vPosition;\n" |
| "}\n"; |
| |
| const string fragmentShaderTemplate = |
| "${GLSL_VERSION}\n" |
| "precision mediump int;\n" |
| "precision mediump float;\n" |
| "const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n" |
| "const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n" |
| "${TEST_CONSTANTS}" |
| "out vec4 my_FragColor;\n" |
| "void main() {\n" |
| " ${TEST_CODE}\n" |
| " if ${TEST_CONDITION}\n" |
| " my_FragColor = green;\n" |
| " else\n" |
| " my_FragColor = red;\n" |
| "}\n"; |
| |
| const map<string, string> testConditions = |
| { |
| { "vec2" , "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound)" }, |
| { "vec3" , "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound)" }, |
| { "vec4" , "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound && abs(v[3] - 3.0) <= errorBound)" }, |
| { "ivec2" , "(v[0] == 0 && v[1] == 1)" }, |
| { "ivec3" , "(v[0] == 0 && v[1] == 1 && v[2] == 2)" }, |
| { "ivec4" , "(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)" }, |
| { "bvec2" , "(v[0] == false && v[1] == true)" }, |
| { "bvec3" , "(v[0] == false && v[1] == true && v[2] == true)" }, |
| { "bvec4" , "(v[0] == false && v[1] == true && v[2] == true && v[3] == true)" } |
| }; |
| |
| typedef function<void (ostringstream&, size_t)> GeneratorFn; |
| |
| struct DataTypeInfo |
| { |
| size_t numElements; |
| GeneratorFn valueFn; |
| GeneratorFn beforeValueFn; |
| GeneratorFn afterValueFn; |
| }; |
| |
| void generateValueFloat(ostringstream& out, const size_t index) |
| { |
| out << index << ".0"; |
| } |
| |
| void generateValueInt(ostringstream& out, const size_t index) |
| { |
| out << index; |
| } |
| |
| void generateValueBool(ostringstream& out, const size_t index) |
| { |
| out << ((index != 0) ? "true" : "false"); |
| } |
| |
| void generateCtorOpen(const char* className, ostringstream& out, const size_t) |
| { |
| out << className << "("; |
| } |
| |
| void generateCtorClose(ostringstream &out, const size_t) |
| { |
| out << ")"; |
| } |
| |
| const map<string, DataTypeInfo> dataTypeInfos = |
| { |
| // numElements , valueFn , beforeValueFn , afterValueFn |
| { "float" , { 1 , generateValueFloat, DE_NULL , DE_NULL } }, |
| { "vec2" , { 2 , generateValueFloat, bind(generateCtorOpen, "vec2", _1, _2) , generateCtorClose } }, |
| { "vec3" , { 3 , generateValueFloat, bind(generateCtorOpen, "vec3", _1, _2) , generateCtorClose } }, |
| { "vec4" , { 4 , generateValueFloat, bind(generateCtorOpen, "vec4", _1, _2) , generateCtorClose } }, |
| { "int" , { 1 , generateValueInt , DE_NULL , DE_NULL } }, |
| { "ivec2" , { 2 , generateValueInt , bind(generateCtorOpen, "ivec2", _1, _2) , generateCtorClose } }, |
| { "ivec3" , { 3 , generateValueInt , bind(generateCtorOpen, "ivec3", _1, _2) , generateCtorClose } }, |
| { "ivec4" , { 4 , generateValueInt , bind(generateCtorOpen, "ivec4", _1, _2) , generateCtorClose } }, |
| { "bool" , { 1 , generateValueBool , DE_NULL , DE_NULL } }, |
| { "bvec2" , { 2 , generateValueBool , bind(generateCtorOpen, "bvec2", _1, _2) , generateCtorClose } }, |
| { "bvec3" , { 3 , generateValueBool , bind(generateCtorOpen, "bvec3", _1, _2) , generateCtorClose } }, |
| { "bvec4" , { 4 , generateValueBool , bind(generateCtorOpen, "bvec4", _1, _2) , generateCtorClose } }, |
| { "mat2" , { 4 , generateValueFloat, bind(generateCtorOpen, "mat2", _1, _2) , generateCtorClose } }, |
| { "mat2x3" , { 6 , generateValueFloat, bind(generateCtorOpen, "mat2x3", _1, _2) , generateCtorClose } }, |
| { "mat2x4" , { 8 , generateValueFloat, bind(generateCtorOpen, "mat2x4", _1, _2) , generateCtorClose } }, |
| { "mat3" , { 9 , generateValueFloat, bind(generateCtorOpen, "mat3", _1, _2) , generateCtorClose } }, |
| { "mat3x2" , { 6 , generateValueFloat, bind(generateCtorOpen, "mat3x2", _1, _2) , generateCtorClose } }, |
| { "mat3x4" , { 12 , generateValueFloat, bind(generateCtorOpen, "mat3x4", _1, _2) , generateCtorClose } }, |
| { "mat4" , { 16 , generateValueFloat, bind(generateCtorOpen, "mat4", _1, _2) , generateCtorClose } }, |
| { "mat4x2" , { 8 , generateValueFloat, bind(generateCtorOpen, "mat4x2", _1, _2) , generateCtorClose } }, |
| { "mat4x3" , { 12 , generateValueFloat, bind(generateCtorOpen, "mat4x3", _1, _2) , generateCtorClose } }, |
| }; |
| |
| string generateTestCode(const string& outputType, const vector<string>& inputTypes) |
| { |
| ostringstream output; |
| const auto outputTypeInfo = dataTypeInfos.find(outputType); |
| DE_ASSERT(outputTypeInfo != dataTypeInfos.end()); |
| |
| output << outputType << " v = "; |
| if (outputTypeInfo->second.beforeValueFn != DE_NULL) |
| outputTypeInfo->second.beforeValueFn(output, -1); |
| int outputElementsRemaining = outputTypeInfo->second.numElements; |
| int outputElementIndex = 0; |
| for(size_t i = 0; i < inputTypes.size() && outputElementsRemaining > 0; ++i) |
| { |
| const auto& inputType = inputTypes[i]; |
| const auto inputTypeInfo = dataTypeInfos.find(inputType); |
| DE_ASSERT(inputTypeInfo != dataTypeInfos.end()); |
| |
| if (outputElementIndex > 0) |
| output << ", "; |
| if (inputTypeInfo->second.beforeValueFn != DE_NULL) |
| inputTypeInfo->second.beforeValueFn(output, i); |
| for(size_t j = 0; j < inputTypeInfo->second.numElements; ++j) |
| { |
| if (j > 0) |
| output << ", "; |
| |
| inputTypeInfo->second.valueFn(output, outputElementIndex++); |
| --outputElementsRemaining; |
| } |
| if (inputTypeInfo->second.afterValueFn != DE_NULL) |
| inputTypeInfo->second.afterValueFn(output, i); |
| } |
| if (outputTypeInfo->second.afterValueFn != DE_NULL) |
| outputTypeInfo->second.afterValueFn(output, -1); |
| output << ";"; |
| return output.str(); |
| } |
| |
| string replacePlaceholders(const string& shaderTemplate, const TestParams& params, const glu::GLSLVersion glslVersion) |
| { |
| const auto condition = testConditions.find(params.outputType); |
| return tcu::StringTemplate(shaderTemplate).specialize( |
| { |
| { "GLSL_VERSION" , glu::getGLSLVersionDeclaration(glslVersion) }, |
| { "TEST_CONSTANTS" , params.extraFields }, |
| { "TEST_CODE" , generateTestCode(params.outputType, params.inputTypes) }, |
| { "TEST_CONDITION" , (condition != testConditions.end()) ? condition->second : "" } |
| }); |
| } |
| |
| const vector<float> positions = |
| { |
| -1.0f, -1.0f, |
| 1.0f, -1.0f, |
| -1.0f, 1.0f, |
| 1.0f, 1.0f |
| }; |
| |
| const vector<deUint32> indices = { 0, 1, 2, 3 }; |
| |
| const int RENDERTARGET_WIDTH = 16; |
| const int RENDERTARGET_HEIGHT = 16; |
| |
| class GLSLVectorConstructorTestCase : public deqp::TestCase |
| { |
| public: |
| GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params); |
| |
| void init(void); |
| void deinit(void); |
| IterateResult iterate(); |
| |
| private: |
| void setupRenderTarget(); |
| void releaseRenderTarget(); |
| |
| const glu::GLSLVersion m_glslVersion; |
| const TestParams m_params; |
| glw::GLuint m_fboId; |
| glw::GLuint m_rboId; |
| |
| string m_vertexShader; |
| string m_fragmentShader; |
| }; |
| |
| GLSLVectorConstructorTestCase::GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params) |
| : TestCase(context, params.name.c_str(), params.description.c_str()) |
| , m_glslVersion(glslVersion) |
| , m_params(params) |
| , m_fboId(0) |
| , m_rboId(0) |
| { |
| switch(m_params.testType) |
| { |
| case TestType::VERTEX_SHADER_ERROR: |
| case TestType::VERTEX_SHADER: |
| m_vertexShader = replacePlaceholders(vertexShaderTemplate, m_params, m_glslVersion); |
| m_fragmentShader = replacePlaceholders(defaultFragmentShader, m_params, m_glslVersion); |
| break; |
| case TestType::FRAGMENT_SHADER_ERROR: |
| case TestType::FRAGMENT_SHADER: |
| m_vertexShader = replacePlaceholders(defaultVertexShader, m_params, m_glslVersion); |
| m_fragmentShader = replacePlaceholders(fragmentShaderTemplate, m_params, m_glslVersion); |
| break; |
| } |
| } |
| |
| void GLSLVectorConstructorTestCase::init(void) |
| { |
| deqp::TestCase::init(); |
| } |
| |
| void GLSLVectorConstructorTestCase::deinit(void) |
| { |
| deqp::TestCase::deinit(); |
| } |
| |
| GLSLVectorConstructorTestCase::IterateResult GLSLVectorConstructorTestCase::iterate() |
| { |
| const auto& renderContext = m_context.getRenderContext(); |
| const auto& gl = renderContext.getFunctions(); |
| const auto textureFormat = tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8); |
| const auto transferFormat = glu::getTransferFormat(textureFormat); |
| |
| setupRenderTarget(); |
| |
| glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader)); |
| if (!program.isOk()) |
| { |
| switch(m_params.testType) |
| { |
| case TestType::VERTEX_SHADER_ERROR: |
| case TestType::FRAGMENT_SHADER_ERROR: |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| return STOP; |
| default: |
| TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" + m_fragmentShader); |
| break; |
| } |
| } |
| |
| const vector<glu::VertexArrayBinding> vertexArrays = |
| { |
| glu::va::Float("vPosition", 2, positions.size(), 0, positions.data()), |
| }; |
| |
| gl.useProgram(program.getProgram()); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed"); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| |
| glu::draw(renderContext, program.getProgram(), |
| static_cast<int>(vertexArrays.size()), vertexArrays.data(), |
| glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data())); |
| |
| const auto pixelSize = tcu::getPixelSize(textureFormat); |
| vector<deUint8> fbData (RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize); |
| |
| if (pixelSize < 4) |
| gl.pixelStorei(GL_PACK_ALIGNMENT, 1); |
| |
| gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType, fbData.data()); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels"); |
| |
| tcu::ConstPixelBufferAccess fbAccess { textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data() }; |
| const auto expectedColor = tcu::RGBA::green().toVec(); |
| bool pass = true; |
| for(int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y) |
| for(int x = 0; x < RENDERTARGET_WIDTH; ++x) |
| if (fbAccess.getPixel(x,y) != expectedColor) |
| { |
| pass = false; |
| break; |
| } |
| |
| releaseRenderTarget(); |
| |
| const qpTestResult result = (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL); |
| const char* desc = (pass ? "Pass" : "Pixel mismatch; vector initialization failed"); |
| |
| m_testCtx.setTestResult(result, desc); |
| |
| return STOP; |
| } |
| |
| void GLSLVectorConstructorTestCase::setupRenderTarget() |
| { |
| const auto& renderContext = m_context.getRenderContext(); |
| const auto& gl = renderContext.getFunctions(); |
| |
| gl.genFramebuffers(1, &m_fboId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers"); |
| |
| gl.genRenderbuffers(1, &m_rboId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers"); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer"); |
| |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage"); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer"); |
| |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer"); |
| |
| glw::GLenum drawBuffer = GL_COLOR_ATTACHMENT0; |
| gl.drawBuffers(1, &drawBuffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers"); |
| |
| glw::GLfloat clearColor[4] = { 0, 0, 0, 0 }; |
| gl.clearBufferfv(GL_COLOR, 0, clearColor); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers"); |
| |
| gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport"); |
| } |
| |
| void GLSLVectorConstructorTestCase::releaseRenderTarget() |
| { |
| const auto& renderContext = m_context.getRenderContext(); |
| const auto& gl = renderContext.getFunctions(); |
| if (m_fboId != 0) |
| { |
| gl.deleteFramebuffers(1, &m_fboId); |
| m_fboId = 0; |
| } |
| if (m_rboId != 0) |
| { |
| gl.deleteRenderbuffers(1, &m_rboId); |
| m_rboId = 0; |
| } |
| } |
| |
| } |
| |
| GLSLVectorConstructorTests::GLSLVectorConstructorTests(Context& context, glu::GLSLVersion glslVersion) |
| : deqp::TestCaseGroup(context, "glsl_constructors", "GLSL vector constructor tests") |
| , m_glslVersion(glslVersion) |
| { |
| } |
| |
| GLSLVectorConstructorTests::~GLSLVectorConstructorTests() |
| { |
| } |
| |
| void GLSLVectorConstructorTests::init() |
| { |
| for(const auto& params : generateTestParams()) |
| addChild(new GLSLVectorConstructorTestCase(m_context, m_glslVersion, params)); |
| } |
| |
| } // deqp |