| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2014-2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ /*! |
| * \file |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| /*! |
| * \file esextcTextureCubeMapArrayImageTextureSize.cpp |
| * \brief texture_cube_map_array extension - Image Texture Size (Test 10) |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "esextcTextureCubeMapArrayImageTextureSize.hpp" |
| |
| #include "gluContextInfo.hpp" |
| #include "gluStrUtil.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuTestLog.hpp" |
| #include <cmath> |
| #include <iostream> |
| |
| namespace glcts |
| { |
| /* Static const variables used for configuring tests */ |
| const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_dimensions = 3; |
| const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_resolutions = 4; |
| const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_layers_per_cube = 6; |
| const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_storage_types = 2; |
| const glw::GLuint TextureCubeMapArrayTextureSizeBase::m_n_texture_components = 4; |
| |
| /* Array with resolutions */ |
| glw::GLuint resolutionArray[TextureCubeMapArrayTextureSizeBase::m_n_resolutions] |
| [TextureCubeMapArrayTextureSizeBase::m_n_dimensions] = { { 32, 32, 18 }, |
| { 64, 64, 6 }, |
| { 128, 128, 12 }, |
| { 256, 256, 12 } }; |
| |
| /* Names of storage types */ |
| static const char* mutableStorage = "MUTABLE"; |
| static const char* imMutableStorage = "IMMUTABLE"; |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeBase::TextureCubeMapArrayTextureSizeBase(Context& context, const ExtParameters& extParams, |
| const char* name, const char* description) |
| : TestCaseBase(context, extParams, name, description), m_po_id(0), m_to_std_id(0), m_to_shw_id(0), m_vao_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Initialize test case */ |
| void TextureCubeMapArrayTextureSizeBase::initTest(void) |
| { |
| /* Check if texture_cube_map_array extension is supported */ |
| if (!m_is_texture_cube_map_array_supported) |
| { |
| throw tcu::NotSupportedError(TEXTURE_CUBE_MAP_ARRAY_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); |
| } |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Generate and bind VAO */ |
| gl.genVertexArrays(1, &m_vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate vertex array object"); |
| |
| gl.bindVertexArray(m_vao_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding vertex array object!"); |
| |
| /* Create program object */ |
| m_po_id = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object."); |
| |
| /* Create program object */ |
| configureProgram(); |
| |
| /* Create GLES objects specific for the test */ |
| configureTestSpecificObjects(); |
| } |
| |
| /** Deinitialize test case */ |
| void TextureCubeMapArrayTextureSizeBase::deinit(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset Opengl ES configuration */ |
| gl.useProgram(0); |
| gl.bindVertexArray(0); |
| |
| /* Delete GLES objects specific for the test */ |
| deleteTestSpecificObjects(); |
| |
| /* Delete shader objects */ |
| deleteProgram(); |
| |
| if (m_po_id != 0) |
| { |
| gl.deleteProgram(m_po_id); |
| m_po_id = 0; |
| } |
| |
| if (m_vao_id != 0) |
| { |
| gl.deleteVertexArrays(1, &m_vao_id); |
| m_vao_id = 0; |
| } |
| |
| /* Delete texture objects */ |
| deleteTextures(); |
| |
| /* Deinitialize base class */ |
| TestCaseBase::deinit(); |
| } |
| |
| /** Executes the test. |
| * |
| * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise. |
| * |
| * Note the function throws exception should an error occur! |
| * |
| * @return STOP if the test has finished, CONTINUE to indicate iterate() should be called once again. |
| **/ |
| tcu::TestCase::IterateResult TextureCubeMapArrayTextureSizeBase::iterate(void) |
| { |
| /* Initialize test case */ |
| initTest(); |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLboolean test_passed = true; |
| |
| /* Use program object */ |
| gl.useProgram(m_po_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set active program object."); |
| |
| glw::GLuint width = 0; |
| glw::GLuint height = 0; |
| glw::GLuint depth = 0; |
| |
| /* Go through IMMUTABLE AND MUTABLE storages */ |
| for (glw::GLuint i = 0; i < m_n_storage_types; ++i) |
| { |
| if (!isMutableTextureTestable() && (STORAGE_TYPE)i == ST_MUTABLE) |
| { |
| continue; |
| } |
| |
| /* Go through all resolutions */ |
| for (glw::GLuint j = 0; j < m_n_resolutions; ++j) |
| { |
| width = resolutionArray[j][0]; |
| height = resolutionArray[j][1]; |
| depth = resolutionArray[j][2]; |
| |
| /* Configure texture objects */ |
| configureTextures(width, height, depth, (STORAGE_TYPE)i); |
| |
| /* Configure uniforms */ |
| configureUniforms(); |
| |
| /* Run shaders to get texture size */ |
| runShaders(); |
| |
| /* Check if results are as expected */ |
| if (!checkResults(width, height, depth, (STORAGE_TYPE)i)) |
| { |
| test_passed = false; |
| } |
| |
| /* Delete texture objects used for this iteration */ |
| deleteTextures(); |
| } |
| } |
| |
| /* Set proper test result */ |
| if (test_passed) |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| else |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| return STOP; |
| } |
| |
| /** Method to check if the test supports mutable textures. |
| * |
| * @return return true if mutable textures work with the test |
| **/ |
| glw::GLboolean TextureCubeMapArrayTextureSizeBase::isMutableTextureTestable(void) |
| { |
| return true; |
| } |
| |
| /** Method to create texture cube map array with proper configuration |
| @param texId pointer to variable where texture id will be stored |
| @param width texture width |
| @param height texture height |
| @param depth texture depth |
| @param storType inform if texture should be mutable or immutable |
| @param shadow inform if texture should be shadow texture or not |
| */ |
| void TextureCubeMapArrayTextureSizeBase::createCubeMapArrayTexture(glw::GLuint& texId, glw::GLuint width, |
| glw::GLuint height, glw::GLuint depth, |
| STORAGE_TYPE storType, glw::GLboolean shadow) |
| { |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Save the current binding */ |
| glw::GLuint savedTexId = 0; |
| gl.getIntegerv(GL_TEXTURE_BINDING_CUBE_MAP_ARRAY, (glw::GLint*)&savedTexId); |
| |
| /* Generate Texture object */ |
| gl.genTextures(1, &texId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object."); |
| |
| /* Bind texture object */ |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, texId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object."); |
| |
| /* Create immutable texture storage */ |
| if (storType == ST_IMMUTABLE) |
| { |
| /* Create shadow texture object */ |
| if (shadow) |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter."); |
| |
| gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_DEPTH_COMPONENT32F, width, height, depth); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating immutable texture storage."); |
| } |
| /* Create texture object */ |
| else |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter."); |
| |
| gl.texStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA32F, width, height, depth); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating immutable texture storage."); |
| } |
| } |
| /* Create mutable texture storage */ |
| else |
| { |
| std::vector<glw::GLfloat> data(width * height * depth * m_n_texture_components, 0); |
| |
| /* Create shadow texture object */ |
| if (shadow) |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LESS); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter."); |
| |
| gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT32F, width, height, depth, 0, |
| GL_DEPTH_COMPONENT, GL_FLOAT, &data[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating mutable texture storage."); |
| } |
| /* Create texture object */ |
| else |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture parameter."); |
| |
| gl.texImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA32F, width, height, depth, 0, GL_RGBA, GL_FLOAT, |
| &data[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating mutable texture storage."); |
| } |
| } |
| |
| /* Restore the original texture binding */ |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, savedTexId); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object."); |
| } |
| |
| /** Configure textures used in the test for textureSize() and imageSize() calls |
| @param width texture width |
| @param height texture height |
| @param depth texture depth |
| @param storType inform if texture should be mutable or immutable |
| */ |
| void TextureCubeMapArrayTextureSizeBase::configureTextures(glw::GLuint width, glw::GLuint height, glw::GLuint depth, |
| STORAGE_TYPE storType) |
| { |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Create texture objects which will be tested */ |
| createCubeMapArrayTexture(m_to_std_id, width, height, depth, storType, false); |
| createCubeMapArrayTexture(m_to_shw_id, width, height, depth, storType, true); |
| |
| /* Binding texture object to texture unit */ |
| gl.activeTexture(GL_TEXTURE0); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_std_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| |
| /* Binding texture object to texture unit */ |
| gl.activeTexture(GL_TEXTURE1); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_shw_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| } |
| |
| /** Delete textures used in the test for textureSize() and imageSize() calls */ |
| void TextureCubeMapArrayTextureSizeBase::deleteTextures(void) |
| { |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset GLES state */ |
| gl.activeTexture(GL_TEXTURE0); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); |
| gl.activeTexture(GL_TEXTURE1); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); |
| gl.activeTexture(GL_TEXTURE0); |
| |
| /* Delete GLES objects */ |
| if (m_to_std_id != 0) |
| { |
| gl.deleteTextures(1, &m_to_std_id); |
| m_to_std_id = 0; |
| } |
| |
| if (m_to_shw_id != 0) |
| { |
| gl.deleteTextures(1, &m_to_shw_id); |
| m_to_shw_id = 0; |
| } |
| } |
| |
| /** Configure uniform variables */ |
| void TextureCubeMapArrayTextureSizeBase::configureUniforms(void) |
| { |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Bind uniform samplers to texture units */ |
| glw::GLint texture_std_location = gl.getUniformLocation(m_po_id, "texture_std_sampler"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting sampler location!"); |
| |
| gl.uniform1i(texture_std_location, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding sampler to texture unit!"); |
| |
| glw::GLint texture_shw_location = gl.getUniformLocation(m_po_id, "texture_shw_sampler"); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting sampler location!"); |
| |
| gl.uniform1i(texture_shw_location, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding sampler to texture unit!"); |
| } |
| |
| /* Static const variables used for configuring tests */ |
| const glw::GLsizei TextureCubeMapArrayTextureSizeTFBase::m_n_varyings = 2; |
| const glw::GLuint TextureCubeMapArrayTextureSizeTFBase::m_n_tf_components = 3; |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeTFBase::TextureCubeMapArrayTextureSizeTFBase(Context& context, |
| const ExtParameters& extParams, |
| const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeBase(context, extParams, name, description), m_tf_bo_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Configure GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeTFBase::configureTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genBuffers(1, &m_tf_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating buffer object."); |
| |
| gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_tf_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object."); |
| |
| std::vector<glw::GLint> buffer_data(m_n_varyings * m_n_tf_components, 0); |
| |
| gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, m_n_varyings * m_n_tf_components * sizeof(glw::GLint), &buffer_data[0], |
| GL_DYNAMIC_COPY); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating buffer object's data store."); |
| |
| gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tf_bo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding buffer object to transform feedback binding point."); |
| } |
| |
| /** Delete GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeTFBase::deleteTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); |
| gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0); |
| |
| /* Delete transform feedback buffer */ |
| if (m_tf_bo_id != 0) |
| { |
| gl.deleteBuffers(1, &m_tf_bo_id); |
| m_tf_bo_id = 0; |
| } |
| } |
| |
| /** Configure textures used in the test for textureSize() and imageSize() calls |
| @param width texture width |
| @param height texture height |
| @param depth texture depth |
| @param storType inform if texture should be mutable or immutable |
| */ |
| void TextureCubeMapArrayTextureSizeTFBase::configureTextures(glw::GLuint width, glw::GLuint height, glw::GLuint depth, |
| STORAGE_TYPE storType) |
| { |
| TextureCubeMapArrayTextureSizeBase::configureTextures(width, height, depth, storType); |
| |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| std::vector<glw::GLint> buffer_data(m_n_varyings * m_n_tf_components, 0); |
| |
| gl.bufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_n_varyings * m_n_tf_components * sizeof(glw::GLint), |
| &buffer_data[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling buffer object's data store with data."); |
| } |
| |
| /** Check textureSize() and imageSize() methods returned proper values |
| * @param width texture width |
| * @param height texture height |
| * @param depth texture depth |
| * @param storType inform if texture is mutable or immutable |
| * @return return true if result data is as expected |
| */ |
| glw::GLboolean TextureCubeMapArrayTextureSizeTFBase::checkResults(glw::GLuint width, glw::GLuint height, |
| glw::GLuint depth, STORAGE_TYPE storType) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Read results from transform feedback */ |
| glw::GLuint* temp_buff = (glw::GLuint*)gl.mapBufferRange( |
| GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_n_varyings * m_n_tf_components * sizeof(glw::GLuint), GL_MAP_READ_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error mapping buffer object's data store to client's address space."); |
| |
| /* Copy results to helper buffer */ |
| glw::GLuint read_size[m_n_varyings * m_n_tf_components]; |
| memcpy(read_size, temp_buff, m_n_varyings * m_n_tf_components * sizeof(glw::GLint)); |
| |
| gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error ummapping transform feedback buffer."); |
| |
| glw::GLboolean test_passed = true; |
| |
| /* Elements under index 0-2 contain result of textureSize called for samplerCubeArray sampler */ |
| if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube)) |
| { |
| getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n" |
| << "textureSize() for samplerCubeArray returned wrong values. [width][height][layers]. They are equal " |
| << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be " |
| << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]." |
| << tcu::TestLog::EndMessage; |
| test_passed = false; |
| } |
| |
| /* Elements under index 3-5 contain result of textureSize called for samplerCubeArrayShadow sampler */ |
| if (read_size[3] != width || read_size[4] != height || read_size[5] != (depth / m_n_layers_per_cube)) |
| { |
| getTestContext().getLog() << tcu::TestLog::Message |
| << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) |
| << "\n" |
| << "textureSize() for samplerCubeArrayShadow returned wrong values. " |
| "[width][height][layers]. They are equal " |
| << "[" << read_size[3] << "][" << read_size[4] << "][" << read_size[5] |
| << "] but should be " |
| << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]." |
| << tcu::TestLog::EndMessage; |
| test_passed = false; |
| } |
| |
| return test_passed; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeTFVertexShader::TextureCubeMapArrayTextureSizeTFVertexShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description), m_vs_id(0), m_fs_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /* Configure program object */ |
| void TextureCubeMapArrayTextureSizeTFVertexShader::configureProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Set transform feedback varyings */ |
| const char* varyings[] = { "texture_std_size", "texture_shw_size" }; |
| gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings."); |
| |
| const char* vsCode = getVertexShaderCode(); |
| const char* fsCode = getFragmentShaderCode(); |
| |
| m_vs_id = gl.createShader(GL_VERTEX_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| |
| if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode)) |
| { |
| TCU_FAIL("Could not compile/link program object from valid shader code."); |
| } |
| } |
| |
| /** Delete program object */ |
| void TextureCubeMapArrayTextureSizeTFVertexShader::deleteProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Delete shader objects */ |
| if (m_vs_id != 0) |
| { |
| gl.deleteShader(m_vs_id); |
| m_vs_id = 0; |
| } |
| |
| if (m_fs_id != 0) |
| { |
| gl.deleteShader(m_fs_id); |
| m_fs_id = 0; |
| } |
| } |
| |
| /** Render or dispatch compute */ |
| void TextureCubeMapArrayTextureSizeTFVertexShader::runShaders(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.beginTransformFeedback(GL_POINTS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback."); |
| |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); |
| |
| gl.endTransformFeedback(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback."); |
| } |
| |
| /** Returns code for Vertex Shader |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFVertexShader::getVertexShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "uniform highp samplerCubeArray texture_std_sampler;\n" |
| "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "\n" |
| "layout (location = 0) out flat uvec3 texture_std_size;\n" |
| "layout (location = 1) out flat uvec3 texture_shw_size;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_PointSize = 1.0f;\n" |
| "\n" |
| " texture_std_size = uvec3( textureSize(texture_std_sampler, 0) );\n" |
| " texture_shw_size = uvec3( textureSize(texture_shw_sampler, 0) );\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Return code for Fragment Shader |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFVertexShader::getFragmentShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeTFGeometryShader::TextureCubeMapArrayTextureSizeTFGeometryShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description), m_vs_id(0), m_gs_id(0), m_fs_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /* Configure program object */ |
| void TextureCubeMapArrayTextureSizeTFGeometryShader::configureProgram(void) |
| { |
| /* Check if geometry_shader extension is supported */ |
| if (!m_is_geometry_shader_extension_supported) |
| { |
| throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); |
| } |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Set transform feedback varyings */ |
| const char* varyings[] = { "texture_std_size", "texture_shw_size" }; |
| gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings."); |
| |
| const char* vsCode = getVertexShaderCode(); |
| const char* gsCode = getGeometryShaderCode(); |
| const char* fsCode = getFragmentShaderCode(); |
| |
| m_vs_id = gl.createShader(GL_VERTEX_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| |
| if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_gs_id, 1 /* part */, &gsCode, m_vs_id, 1 /* part */, |
| &vsCode)) |
| { |
| TCU_FAIL("Could not compile/link program object from valid shader code."); |
| } |
| } |
| |
| /** Delete program object */ |
| void TextureCubeMapArrayTextureSizeTFGeometryShader::deleteProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Delete shader objects */ |
| if (m_vs_id != 0) |
| { |
| gl.deleteShader(m_vs_id); |
| m_vs_id = 0; |
| } |
| |
| if (m_gs_id != 0) |
| { |
| gl.deleteShader(m_gs_id); |
| m_gs_id = 0; |
| } |
| |
| if (m_fs_id != 0) |
| { |
| gl.deleteShader(m_fs_id); |
| m_fs_id = 0; |
| } |
| } |
| |
| void TextureCubeMapArrayTextureSizeTFGeometryShader::runShaders(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.beginTransformFeedback(GL_POINTS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback."); |
| |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); |
| |
| gl.endTransformFeedback(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback."); |
| } |
| |
| /** Returns code for Vertex Shader |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFGeometryShader::getVertexShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Return code for Geometry Shader |
| * @return pointer to literal with Geometry Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFGeometryShader::getGeometryShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${GEOMETRY_SHADER_ENABLE}\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "uniform highp samplerCubeArray texture_std_sampler;\n" |
| "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "\n" |
| "layout (location = 0) out flat uvec3 texture_std_size;\n" |
| "layout (location = 1) out flat uvec3 texture_shw_size;\n" |
| "\n" |
| "layout(points) in;\n" |
| "layout(points, max_vertices=1) out;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_std_size = uvec3( textureSize(texture_std_sampler, 0) );\n" |
| " texture_shw_size = uvec3( textureSize(texture_shw_sampler, 0) );\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| " EmitVertex();\n" |
| " EndPrimitive();\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Return code for Fragment Shader |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFGeometryShader::getFragmentShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeTFTessControlShader::TextureCubeMapArrayTextureSizeTFTessControlShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeTFBase(context, extParams, name, description) |
| , m_vs_id(0) |
| , m_tcs_id(0) |
| , m_tes_id(0) |
| , m_fs_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /* Configure program object */ |
| void TextureCubeMapArrayTextureSizeTFTessControlShader::configureProgram(void) |
| { |
| /* Check if tessellation_shader extension is supported */ |
| if (!m_is_tessellation_shader_supported) |
| { |
| throw tcu::NotSupportedError(TESSELLATION_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__); |
| } |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Set transform feedback varyings */ |
| const char* varyings[] = { "texture_std_size", "texture_shw_size" }; |
| gl.transformFeedbackVaryings(m_po_id, m_n_varyings, varyings, GL_INTERLEAVED_ATTRIBS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting transform feedback varyings."); |
| |
| const char* vsCode = getVertexShaderCode(); |
| const char* tcsCode = getTessellationControlShaderCode(); |
| const char* tesCode = getTessellationEvaluationShaderCode(); |
| const char* fsCode = getFragmentShaderCode(); |
| |
| m_vs_id = gl.createShader(GL_VERTEX_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_tcs_id = gl.createShader(m_glExtTokens.TESS_CONTROL_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_tes_id = gl.createShader(m_glExtTokens.TESS_EVALUATION_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| |
| if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_tcs_id, 1 /* part */, &tcsCode, m_tes_id, 1 /* part */, |
| &tesCode, m_vs_id, 1 /* part */, &vsCode)) |
| { |
| TCU_FAIL("Could not compile/link program object from valid shader code."); |
| } |
| } |
| |
| /** Delete program object */ |
| void TextureCubeMapArrayTextureSizeTFTessControlShader::deleteProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Delete shader objects */ |
| if (m_vs_id != 0) |
| { |
| gl.deleteShader(m_vs_id); |
| m_vs_id = 0; |
| } |
| |
| if (m_tcs_id != 0) |
| { |
| gl.deleteShader(m_tcs_id); |
| m_tcs_id = 0; |
| } |
| |
| if (m_tes_id != 0) |
| { |
| gl.deleteShader(m_tes_id); |
| m_tes_id = 0; |
| } |
| |
| if (m_fs_id != 0) |
| { |
| gl.deleteShader(m_fs_id); |
| m_fs_id = 0; |
| } |
| } |
| |
| /** Render or dispatch compute */ |
| void TextureCubeMapArrayTextureSizeTFTessControlShader::runShaders(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.beginTransformFeedback(GL_POINTS); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error beginning transform feedback."); |
| |
| gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Setting number of vertices per patch failed"); |
| |
| gl.drawArrays(m_glExtTokens.PATCHES, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); |
| |
| gl.patchParameteri(m_glExtTokens.PATCH_VERTICES, 3); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Setting number of vertices per patch failed"); |
| |
| gl.endTransformFeedback(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error ending transform feedback."); |
| } |
| |
| /** Returns code for Vertex Shader |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessControlShader::getVertexShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Return code for Tessellation Control Shader |
| * @return pointer to literal with Tessellation Control Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessControlShader::getTessellationControlShaderCode(void) |
| { |
| static const char* result = |
| "${VERSION}\n" |
| "\n" |
| "${TESSELLATION_SHADER_ENABLE}\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "uniform highp samplerCubeArray texture_std_sampler;\n" |
| "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "\n" |
| "layout (location = 0) out flat uvec3 texture_std_size_array[];\n" |
| "layout (location = 1) out flat uvec3 texture_shw_size_array[];\n" |
| "\n" |
| "layout (vertices = 1) out;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\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" |
| " texture_std_size_array[gl_InvocationID] = uvec3( textureSize(texture_std_sampler, 0) );\n" |
| " texture_shw_size_array[gl_InvocationID] = uvec3( textureSize(texture_shw_sampler, 0) );\n" |
| " gl_out[gl_InvocationID].gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Returns code for Tessellation Evaluation Shader |
| * @return pointer to literal with Tessellation Evaluation code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessControlShader::getTessellationEvaluationShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${TESSELLATION_SHADER_REQUIRE}\n" |
| "\n" |
| "layout(isolines, point_mode) in;\n" |
| "\n" |
| "in layout(location = 0) flat uvec3 texture_std_size_array[];\n" |
| "in layout(location = 1) flat uvec3 texture_shw_size_array[];\n" |
| "\n" |
| "out flat uvec3 texture_std_size;\n" |
| "out flat uvec3 texture_shw_size;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_std_size = texture_std_size_array[0];\n" |
| " texture_shw_size = texture_shw_size_array[0];\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Return code for Fragment Shader |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessControlShader::getFragmentShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeTFTessEvaluationShader::TextureCubeMapArrayTextureSizeTFTessEvaluationShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeTFTessControlShader(context, extParams, name, description) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Return code for Tessellation Control Shader |
| * @return pointer to literal with Tessellation Control Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessEvaluationShader::getTessellationControlShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${TESSELLATION_SHADER_ENABLE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "layout (vertices = 1) out;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_TessLevelInner[0] = 1.0;\n" |
| " gl_TessLevelInner[1] = 1.0;\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_out[gl_InvocationID].gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| /** Returns code for Tessellation Evaluation Shader |
| * @return pointer to literal with Tessellation Evaluation code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeTFTessEvaluationShader::getTessellationEvaluationShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${TESSELLATION_SHADER_REQUIRE}\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "layout(isolines, point_mode) in;\n" |
| "\n" |
| "uniform highp samplerCubeArray texture_std_sampler;\n" |
| "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "\n" |
| "layout (location = 0) out flat uvec3 texture_std_size;\n" |
| "layout (location = 1) out flat uvec3 texture_shw_size;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_std_size = uvec3( textureSize(texture_std_sampler, 0) );\n" |
| " texture_shw_size = uvec3( textureSize(texture_shw_sampler, 0) );\n" |
| " gl_Position = vec4(0.0f,0.0f,0.0f,0.0f);\n" |
| "}\n"; |
| return result; |
| } |
| |
| const glw::GLuint TextureCubeMapArrayTextureSizeRTBase::m_n_rt_components = 4; |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeRTBase::TextureCubeMapArrayTextureSizeRTBase(Context& context, |
| const ExtParameters& extParams, |
| const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeBase(context, extParams, name, description) |
| , m_read_fbo_id(0) |
| , m_rt_std_id(0) |
| , m_rt_shw_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Configure GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLint rt_data[m_n_rt_components]; |
| memset(rt_data, 0, m_n_rt_components * sizeof(glw::GLuint)); |
| |
| /* Create texture which will store result of textureSize() for samplerCubeArray sampler */ |
| gl.genTextures(1, &m_rt_std_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!"); |
| |
| gl.activeTexture(GL_TEXTURE0); |
| gl.bindTexture(GL_TEXTURE_2D, m_rt_std_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!"); |
| |
| gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| |
| /* Create texture which will store result of textureSize() for samplerCubeArrayShadow sampler */ |
| gl.genTextures(1, &m_rt_shw_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!"); |
| |
| gl.activeTexture(GL_TEXTURE1); |
| gl.bindTexture(GL_TEXTURE_2D, m_rt_shw_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!"); |
| |
| gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| |
| /* Generate frame buffer object */ |
| gl.genFramebuffers(1, &m_read_fbo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!"); |
| } |
| |
| /** Delete GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset GL state */ |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, 0); |
| gl.activeTexture(GL_TEXTURE0); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.activeTexture(GL_TEXTURE1); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.activeTexture(GL_TEXTURE0); |
| |
| /* Delete GL objects */ |
| if (m_read_fbo_id != 0) |
| { |
| gl.deleteFramebuffers(1, &m_read_fbo_id); |
| m_read_fbo_id = 0; |
| } |
| |
| if (m_rt_std_id != 0) |
| { |
| gl.deleteTextures(1, &m_rt_std_id); |
| m_rt_std_id = 0; |
| } |
| |
| if (m_rt_shw_id != 0) |
| { |
| gl.deleteTextures(1, &m_rt_shw_id); |
| m_rt_shw_id = 0; |
| } |
| } |
| |
| /** Check textureSize() and imageSize() methods returned proper values |
| * @param width texture width |
| * @param height texture height |
| * @param depth texture depth |
| * @param storType inform if texture is mutable or immutable |
| * @return return true if result data is as expected |
| */ |
| glw::GLboolean TextureCubeMapArrayTextureSizeRTBase::checkResults(glw::GLuint width, glw::GLuint height, |
| glw::GLuint depth, STORAGE_TYPE storType) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLboolean test_passed = true; |
| |
| glw::GLuint read_size[m_n_rt_components]; |
| memset(read_size, 0, m_n_rt_components * sizeof(glw::GLuint)); |
| |
| gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_read_fbo_id); |
| |
| /* Compare returned results of textureSize() called for samplerCubeArray sampler*/ |
| gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_std_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer"); |
| |
| /* Check framebuffer status */ |
| checkFramebufferStatus(GL_READ_FRAMEBUFFER); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!"); |
| |
| if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube)) |
| { |
| getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n" |
| << "textureSize() for samplerCubeArray returned wrong values of [width][height][layers]. They are equal to" |
| << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be " |
| << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]." |
| << tcu::TestLog::EndMessage; |
| test_passed = false; |
| } |
| |
| /* Compare returned results of textureSize() for samplerCubeArrayShadow sampler*/ |
| gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_shw_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer"); |
| |
| /* Check framebuffer status */ |
| checkFramebufferStatus(GL_READ_FRAMEBUFFER); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!"); |
| |
| if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube)) |
| { |
| getTestContext().getLog() << tcu::TestLog::Message |
| << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) |
| << "\n" |
| << "textureSize() for samplerCubeArrayShadow returned wrong values of " |
| "[width][height][layers]. They are equal to" |
| << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] |
| << "] but should be " |
| << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]." |
| << tcu::TestLog::EndMessage; |
| test_passed = false; |
| } |
| |
| return test_passed; |
| } |
| |
| /** Check Framebuffer Status. Throws a TestError exception, should the framebuffer status |
| * be found incomplete. |
| * |
| * @param framebuffer - GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER |
| * |
| */ |
| void TextureCubeMapArrayTextureSizeRTBase::checkFramebufferStatus(glw::GLenum framebuffer) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLenum framebuffer_status = gl.checkFramebufferStatus(framebuffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error getting framebuffer status!"); |
| |
| if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) |
| { |
| switch (framebuffer_status) |
| { |
| case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: |
| { |
| TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); |
| } |
| |
| case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: |
| { |
| TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS"); |
| } |
| |
| case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: |
| { |
| TCU_FAIL("Framebuffer incomplete, status: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); |
| } |
| |
| case GL_FRAMEBUFFER_UNSUPPORTED: |
| { |
| TCU_FAIL("Framebuffer incomplete, status: Error: GL_FRAMEBUFFER_UNSUPPORTED"); |
| } |
| |
| default: |
| { |
| TCU_FAIL("Framebuffer incomplete, status not recognized"); |
| } |
| } /* switch (framebuffer_status) */ |
| } /* if (GL_FRAMEBUFFER_COMPLETE != framebuffer_status) */ |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeRTFragmentShader::TextureCubeMapArrayTextureSizeRTFragmentShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeRTBase(context, extParams, name, description) |
| , m_draw_fbo_id(0) |
| , m_vs_id(0) |
| , m_fs_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Configure GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTFragmentShader::configureTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects(); |
| |
| /* Generate frame buffer object */ |
| gl.genFramebuffers(1, &m_draw_fbo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating frame buffer object!"); |
| } |
| |
| /** Delete GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTFragmentShader::deleteTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset GLES state */ |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); |
| |
| /* Delete GLEs objects */ |
| if (m_draw_fbo_id != 0) |
| { |
| gl.deleteFramebuffers(1, &m_draw_fbo_id); |
| m_draw_fbo_id = 0; |
| } |
| |
| TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects(); |
| } |
| |
| /* Configure program object */ |
| void TextureCubeMapArrayTextureSizeRTFragmentShader::configureProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| const char* vsCode = getVertexShaderCode(); |
| const char* fsCode = getFragmentShaderCode(); |
| |
| m_vs_id = gl.createShader(GL_VERTEX_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| m_fs_id = gl.createShader(GL_FRAGMENT_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| |
| if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &fsCode, m_vs_id, 1 /* part */, &vsCode)) |
| { |
| TCU_FAIL("Could not compile/link program object from valid shader code."); |
| } |
| } |
| |
| /** Delete program object */ |
| void TextureCubeMapArrayTextureSizeRTFragmentShader::deleteProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Delete shader objects */ |
| if (m_vs_id != 0) |
| { |
| gl.deleteShader(m_vs_id); |
| m_vs_id = 0; |
| } |
| |
| if (m_fs_id != 0) |
| { |
| gl.deleteShader(m_fs_id); |
| m_fs_id = 0; |
| } |
| } |
| |
| /** Return code for bolierPlate Vertex Shader |
| * @return pointer to literal with Vertex Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeRTFragmentShader::getVertexShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " gl_PointSize = 1.0f;\n" |
| " gl_Position = vec4(0, 0, 0, 1.0f);\n" |
| "}\n"; |
| |
| return result; |
| } |
| |
| /** Return code for Fragment Shader |
| * @return pointer to literal with Fragment Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeRTFragmentShader::getFragmentShaderCode(void) |
| { |
| static const char* result = "${VERSION}\n" |
| "\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "uniform highp samplerCubeArray texture_std_sampler;\n" |
| "uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "\n" |
| "layout (location = 0) out uvec4 texture_std_size;\n" |
| "layout (location = 1) out uvec4 texture_shw_size;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_std_size = uvec4( textureSize(texture_std_sampler, 0), 0 );\n" |
| " texture_shw_size = uvec4( textureSize(texture_shw_sampler, 0), 0 );\n" |
| "}\n"; |
| |
| return result; |
| } |
| |
| void TextureCubeMapArrayTextureSizeRTFragmentShader::runShaders(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Configure draw framebuffer */ |
| gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_draw_fbo_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding framebuffer object"); |
| |
| gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_std_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to GL_COLOR_ATTACHMENT0"); |
| gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_rt_shw_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to GL_COLOR_ATTACHMENT0"); |
| |
| /* Check framebuffer status */ |
| checkFramebufferStatus(GL_DRAW_FRAMEBUFFER); |
| |
| /* Configure draw buffers for fragment shader */ |
| const glw::GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; |
| gl.drawBuffers(2, drawBuffers); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting draw buffers"); |
| |
| glw::GLint viewport_size[4]; |
| gl.getIntegerv(GL_VIEWPORT, viewport_size); |
| |
| gl.viewport(0, 0, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Setting viewport"); |
| |
| gl.drawArrays(GL_POINTS, 0, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed!"); |
| |
| gl.viewport(viewport_size[0], viewport_size[1], viewport_size[2], viewport_size[3]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Setting viewport"); |
| } |
| |
| /** Constructor |
| * |
| * @param context Test context |
| * @param name Test case's name |
| * @param description Test case's description |
| **/ |
| TextureCubeMapArrayTextureSizeRTComputeShader::TextureCubeMapArrayTextureSizeRTComputeShader( |
| Context& context, const ExtParameters& extParams, const char* name, const char* description) |
| : TextureCubeMapArrayTextureSizeRTBase(context, extParams, name, description) |
| , m_cs_id(0) |
| , m_to_img_id(0) |
| , m_rt_img_id(0) |
| { |
| /* Nothing to be done here */ |
| } |
| |
| /** Configure program object */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::configureProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| const char* csCode = getComputeShaderCode(); |
| |
| m_cs_id = gl.createShader(GL_COMPUTE_SHADER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create shader object."); |
| |
| /* Build program */ |
| if (!buildProgram(m_po_id, m_cs_id, 1 /* part */, &csCode)) |
| { |
| TCU_FAIL("Could not compile/link program object from valid shader code."); |
| } |
| } |
| |
| /** Delete program object */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::deleteProgram(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Delete shader objects */ |
| if (m_cs_id != 0) |
| { |
| gl.deleteShader(m_cs_id); |
| m_cs_id = 0; |
| } |
| } |
| |
| /** Returns code for Compute Shader |
| * @return pointer to literal with Compute Shader code |
| **/ |
| const char* TextureCubeMapArrayTextureSizeRTComputeShader::getComputeShaderCode(void) |
| { |
| static const char* result = |
| "${VERSION}\n" |
| "\n" |
| "${TEXTURE_CUBE_MAP_ARRAY_REQUIRE}\n" |
| "\n" |
| "precision highp float;\n" |
| "\n" |
| "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" |
| "\n" |
| " uniform highp samplerCubeArray texture_std_sampler;\n" |
| " uniform highp samplerCubeArrayShadow texture_shw_sampler;\n" |
| "layout(rgba32f, binding = 0) writeonly uniform highp imageCubeArray texture_img_sampler;\n" |
| "\n" |
| "layout (rgba32ui, binding = 1) uniform highp writeonly uimage2D image_std_size;\n" |
| "layout (rgba32ui, binding = 2) uniform highp writeonly uimage2D image_shw_size;\n" |
| "layout (rgba32ui, binding = 3) uniform highp writeonly uimage2D image_img_size;\n" |
| "\n" |
| "void main(void)\n" |
| "{\n" |
| " imageStore(image_std_size, ivec2(0,0), uvec4(uvec3( textureSize(texture_std_sampler, 0)), 0) );\n" |
| " imageStore(image_shw_size, ivec2(0,0), uvec4(uvec3( textureSize(texture_shw_sampler, 0)), 0) );\n" |
| " imageStore(image_img_size, ivec2(0,0), uvec4(uvec3( imageSize (texture_img_sampler)), 0) );\n" |
| "}\n"; |
| |
| return result; |
| } |
| |
| /** Configure GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::configureTestSpecificObjects(void) |
| { |
| TextureCubeMapArrayTextureSizeRTBase::configureTestSpecificObjects(); |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLuint rt_data[m_n_rt_components]; |
| memset(rt_data, 0, m_n_rt_components * sizeof(glw::GLuint)); |
| |
| /* Create texture which will store result of imageSize() for imageCubeArray image */ |
| gl.genTextures(1, &m_rt_img_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error generating texture object!"); |
| |
| gl.activeTexture(GL_TEXTURE2); |
| gl.bindTexture(GL_TEXTURE_2D, m_rt_img_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32UI, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error allocating storage for texture object!"); |
| |
| gl.texSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, rt_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error filling texture object's data store with data!"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting texture object's filter mode!"); |
| |
| /* Image unit binding start from index 1 for compute shader results */ |
| gl.bindImageTexture(1, m_rt_std_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit"); |
| gl.bindImageTexture(2, m_rt_shw_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit"); |
| gl.bindImageTexture(3, m_rt_img_id, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit"); |
| } |
| |
| /** Delete GLES objects specific for the test configuration */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::deleteTestSpecificObjects(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset GL state */ |
| gl.activeTexture(GL_TEXTURE2); |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| |
| /* Delete GL objects */ |
| if (m_rt_img_id != 0) |
| { |
| gl.deleteTextures(1, &m_rt_img_id); |
| m_rt_img_id = 0; |
| } |
| |
| TextureCubeMapArrayTextureSizeRTBase::deleteTestSpecificObjects(); |
| } |
| |
| /** Configure textures used in the test for textureSize() and imageSize() calls |
| @param width texture width |
| @param height texture height |
| @param depth texture depth |
| @param storType inform if texture should be mutable or immutable |
| */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::configureTextures(glw::GLuint width, glw::GLuint height, |
| glw::GLuint depth, STORAGE_TYPE storType) |
| { |
| TextureCubeMapArrayTextureSizeRTBase::configureTextures(width, height, depth, storType); |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| createCubeMapArrayTexture(m_to_img_id, width, height, depth, storType, false); |
| |
| /* Binding texture object to texture unit */ |
| gl.activeTexture(GL_TEXTURE2); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_img_id); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object!"); |
| |
| gl.bindImageTexture(0, m_to_img_id, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA32F); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error binding texture object to image unit"); |
| } |
| |
| /** Delete textures used in the test for textureSize() and imageSize() calls */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::deleteTextures(void) |
| { |
| /* Get Gl entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Reset GLES state */ |
| gl.activeTexture(GL_TEXTURE2); |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); |
| |
| /* Delete GLES objects */ |
| if (m_to_img_id != 0) |
| { |
| gl.deleteTextures(1, &m_to_img_id); |
| m_to_img_id = 0; |
| } |
| |
| TextureCubeMapArrayTextureSizeRTBase::deleteTextures(); |
| } |
| |
| /** Render or dispatch compute */ |
| void TextureCubeMapArrayTextureSizeRTComputeShader::runShaders(void) |
| { |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.dispatchCompute(1, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error executing compute shader"); |
| gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error setting memory barrier!"); |
| } |
| |
| /** Check textureSize() and imageSize() methods returned proper values |
| * @param width texture width |
| * @param height texture height |
| * @param depth texture depth |
| * @param storType inform if texture is mutable or immutable |
| * @return return true if result data is as expected |
| */ |
| glw::GLboolean TextureCubeMapArrayTextureSizeRTComputeShader::checkResults(glw::GLuint width, glw::GLuint height, |
| glw::GLuint depth, STORAGE_TYPE storType) |
| { |
| glw::GLboolean test_passed = TextureCubeMapArrayTextureSizeRTBase::checkResults(width, height, depth, storType); |
| |
| /* Get GL entry points */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| glw::GLuint read_size[m_n_rt_components]; |
| memset(read_size, 0, m_n_rt_components * sizeof(glw::GLuint)); |
| |
| /* Compare returned results of imageSize() for imageCubeArray image */ |
| gl.framebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_rt_img_id, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error attaching texture to frame buffer"); |
| |
| /* Check framebuffer status */ |
| checkFramebufferStatus(GL_READ_FRAMEBUFFER); |
| |
| gl.readPixels(0, 0, 1, 1, GL_RGBA_INTEGER, GL_UNSIGNED_INT, read_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Error reading pixles from frame buffer!"); |
| |
| if (read_size[0] != width || read_size[1] != height || read_size[2] != (depth / m_n_layers_per_cube)) |
| { |
| getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "Storage Type: " << ((storType == ST_MUTABLE) ? mutableStorage : imMutableStorage) << "\n" |
| << "imageSize() for imageCubeArray returned wrong values of [width][height][layers]. They are equal to" |
| << "[" << read_size[0] << "][" << read_size[1] << "][" << read_size[2] << "] but should be " |
| << "[" << width << "][" << height << "][" << depth / m_n_layers_per_cube << "]." |
| << tcu::TestLog::EndMessage; |
| test_passed = false; |
| } |
| |
| return test_passed; |
| } |
| |
| /** Method to check if the test supports mutable textures. |
| * |
| * @return return true if mutable textures work with the test |
| */ |
| glw::GLboolean TextureCubeMapArrayTextureSizeRTComputeShader::isMutableTextureTestable(void) |
| { |
| /** |
| * Mutable textures cannot be bound as image textures on ES, but can be on |
| * desktop GL. This check enables/disables testing of mutable image textures. |
| */ |
| if (!glu::isContextTypeES(m_context.getRenderContext().getType())) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| |
| } /* glcts */ |