| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2015-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 gl4cDirectStateAccessTexturesTests.cpp |
| * \brief Conformance tests for the Direct State Access feature functionality (Texture access part). |
| */ /*-----------------------------------------------------------------------------------------------------------*/ |
| |
| /* Uncomment this if SubImageErrorsTest crashes during negative test of TextureSubImage (negative value width/height/depth passed to the function). */ |
| /* #define TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH */ |
| |
| /* Includes. */ |
| #include "gl4cDirectStateAccessTests.hpp" |
| |
| #include "deSharedPtr.hpp" |
| |
| #include "gluContextInfo.hpp" |
| #include "gluDefs.hpp" |
| #include "gluPixelTransfer.hpp" |
| #include "gluStrUtil.hpp" |
| |
| #include "tcuFuzzyImageCompare.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuSurface.hpp" |
| #include "tcuTestLog.hpp" |
| |
| #include "glw.h" |
| #include "glwFunctions.hpp" |
| |
| #include <algorithm> |
| #include <climits> |
| #include <set> |
| #include <sstream> |
| #include <stack> |
| #include <string> |
| |
| namespace gl4cts |
| { |
| namespace DirectStateAccess |
| { |
| namespace Textures |
| { |
| /******************************** Creation Test Implementation ********************************/ |
| |
| /** @brief Creation Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| CreationTest::CreationTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_creation", "Texture Objects Creation Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Creation Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult CreationTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Textures' objects */ |
| static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D, |
| GL_TEXTURE_2D, |
| GL_TEXTURE_3D, |
| GL_TEXTURE_1D_ARRAY, |
| GL_TEXTURE_2D_ARRAY, |
| GL_TEXTURE_RECTANGLE, |
| GL_TEXTURE_CUBE_MAP, |
| GL_TEXTURE_CUBE_MAP_ARRAY, |
| GL_TEXTURE_BUFFER, |
| GL_TEXTURE_2D_MULTISAMPLE, |
| GL_TEXTURE_2D_MULTISAMPLE_ARRAY }; |
| static const glw::GLuint texture_targets_count = sizeof(texture_targets) / sizeof(texture_targets[0]); |
| static const glw::GLuint textures_count = 2; |
| |
| glw::GLuint textures_legacy[textures_count] = {}; |
| glw::GLuint textures_dsa[texture_targets_count][textures_count] = {}; |
| |
| try |
| { |
| /* Check legacy state creation. */ |
| gl.genTextures(textures_count, textures_legacy); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| for (glw::GLuint i = 0; i < textures_count; ++i) |
| { |
| if (gl.isTexture(textures_legacy[i])) |
| { |
| is_ok = false; |
| |
| /* Log. */ |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "GenTextures has created default objects, but it should create only a names." |
| << tcu::TestLog::EndMessage; |
| } |
| } |
| |
| /* Check direct state creation. */ |
| for (glw::GLuint j = 0; j < texture_targets_count; ++j) |
| { |
| gl.createTextures(texture_targets[j], textures_count, textures_dsa[j]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| for (glw::GLuint i = 0; i < textures_count; ++i) |
| { |
| if (!gl.isTexture(textures_dsa[j][i])) |
| { |
| is_ok = false; |
| |
| /* Log. */ |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "CreateTextures has not created default objects for target " |
| << glu::getTextureTargetStr(texture_targets[j]) << "." << tcu::TestLog::EndMessage; |
| } |
| } |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| for (glw::GLuint i = 0; i < textures_count; ++i) |
| { |
| if (textures_legacy[i]) |
| { |
| gl.deleteTextures(1, &textures_legacy[i]); |
| |
| textures_legacy[i] = 0; |
| } |
| |
| for (glw::GLuint j = 0; j < texture_targets_count; ++j) |
| { |
| if (textures_dsa[j][i]) |
| { |
| gl.deleteTextures(1, &textures_dsa[j][i]); |
| |
| textures_dsa[j][i] = 0; |
| } |
| } |
| } |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Reference Data Implementation *****************************/ |
| |
| /** @brief Internal Format selector. |
| * |
| * @tparam T Type. |
| * @tparam S Size (# of components). |
| * @tparam N Is normalized. |
| * |
| * @return Internal format. |
| */ |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLbyte, 1, false>() |
| { |
| return GL_R8I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLbyte, 2, false>() |
| { |
| return GL_RG8I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLbyte, 3, false>() |
| { |
| return GL_RGB8I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLbyte, 4, false>() |
| { |
| return GL_RGBA8I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, false>() |
| { |
| return GL_R8UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, false>() |
| { |
| return GL_RG8UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, false>() |
| { |
| return GL_RGB8UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, false>() |
| { |
| return GL_RGBA8UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLshort, 1, false>() |
| { |
| return GL_R16I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLshort, 2, false>() |
| { |
| return GL_RG16I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLshort, 3, false>() |
| { |
| return GL_RGB16I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLshort, 4, false>() |
| { |
| return GL_RGBA16I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 1, false>() |
| { |
| return GL_R16UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 2, false>() |
| { |
| return GL_RG16UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 3, false>() |
| { |
| return GL_RGB16UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 4, false>() |
| { |
| return GL_RGBA16UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLint, 1, false>() |
| { |
| return GL_R32I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLint, 2, false>() |
| { |
| return GL_RG32I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLint, 3, false>() |
| { |
| return GL_RGB32I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLint, 4, false>() |
| { |
| return GL_RGBA32I; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLuint, 1, false>() |
| { |
| return GL_R32UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLuint, 2, false>() |
| { |
| return GL_RG32UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLuint, 3, false>() |
| { |
| return GL_RGB32UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLuint, 4, false>() |
| { |
| return GL_RGBA32UI; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 1, true>() |
| { |
| return GL_R8; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 2, true>() |
| { |
| return GL_RG8; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 3, true>() |
| { |
| return GL_RGB8; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLubyte, 4, true>() |
| { |
| return GL_RGBA8; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 1, true>() |
| { |
| return GL_R16; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 2, true>() |
| { |
| return GL_RG16; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 3, true>() |
| { |
| return GL_RGB16; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLushort, 4, true>() |
| { |
| return GL_RGBA16; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLfloat, 1, true>() |
| { |
| return GL_R32F; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLfloat, 2, true>() |
| { |
| return GL_RG32F; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLfloat, 3, true>() |
| { |
| return GL_RGB32F; |
| } |
| |
| template <> |
| glw::GLenum Reference::InternalFormat<glw::GLfloat, 4, true>() |
| { |
| return GL_RGBA32F; |
| } |
| |
| /** @brief Format selector. |
| * |
| * @tparam S Size (# of components). |
| * @tparam N Is normalized. |
| * |
| * @return format. |
| */ |
| template <> |
| glw::GLenum Reference::Format<1, false>() |
| { |
| return GL_RED_INTEGER; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<2, false>() |
| { |
| return GL_RG_INTEGER; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<3, false>() |
| { |
| return GL_RGB_INTEGER; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<4, false>() |
| { |
| return GL_RGBA_INTEGER; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<1, true>() |
| { |
| return GL_RED; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<2, true>() |
| { |
| return GL_RG; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<3, true>() |
| { |
| return GL_RGB; |
| } |
| |
| template <> |
| glw::GLenum Reference::Format<4, true>() |
| { |
| return GL_RGBA; |
| } |
| |
| /** @brief Type selector. |
| * |
| * @tparam T Type. |
| * |
| * @return Type. |
| */ |
| template <> |
| glw::GLenum Reference::Type<glw::GLbyte>() |
| { |
| return GL_BYTE; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLubyte>() |
| { |
| return GL_UNSIGNED_BYTE; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLshort>() |
| { |
| return GL_SHORT; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLushort>() |
| { |
| return GL_UNSIGNED_SHORT; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLint>() |
| { |
| return GL_INT; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLuint>() |
| { |
| return GL_UNSIGNED_INT; |
| } |
| |
| template <> |
| glw::GLenum Reference::Type<glw::GLfloat>() |
| { |
| return GL_FLOAT; |
| } |
| |
| /** @brief Reference data selector. |
| * |
| * @tparam T Type. |
| * @tparam N Is normalized. |
| * |
| * @return Reference data. |
| */ |
| |
| /* RGBA8I */ |
| template <> |
| const glw::GLbyte* Reference::ReferenceData<glw::GLbyte, false>() |
| { |
| static const glw::GLbyte reference[s_reference_count] = { |
| 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, |
| 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, |
| 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, |
| 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA8UI */ |
| template <> |
| const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, false>() |
| { |
| static const glw::GLubyte reference[s_reference_count] = { |
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, |
| 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
| 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, |
| 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA16I */ |
| template <> |
| const glw::GLshort* Reference::ReferenceData<glw::GLshort, false>() |
| { |
| static const glw::GLshort reference[s_reference_count] = { |
| 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, |
| 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, |
| 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, |
| 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA16UI */ |
| template <> |
| const glw::GLushort* Reference::ReferenceData<glw::GLushort, false>() |
| { |
| static const glw::GLushort reference[s_reference_count] = { |
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, |
| 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
| 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, |
| 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA32I */ |
| template <> |
| const glw::GLint* Reference::ReferenceData<glw::GLint, false>() |
| { |
| static const glw::GLint reference[s_reference_count] = { |
| 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, |
| 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, |
| 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, |
| 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA32UI */ |
| template <> |
| const glw::GLuint* Reference::ReferenceData<glw::GLuint, false>() |
| { |
| static const glw::GLuint reference[s_reference_count] = { |
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, |
| 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, |
| 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, |
| 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 |
| }; |
| return reference; |
| } |
| |
| /* RGBA8 */ |
| template <> |
| const glw::GLubyte* Reference::ReferenceData<glw::GLubyte, true>() |
| { |
| static const glw::GLubyte reference[s_reference_count] = { |
| 0, 2, 5, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 34, 37, 40, 42, 45, 48, 51, |
| 53, 56, 59, 61, 64, 67, 69, 72, 75, 77, 80, 83, 85, 88, 91, 93, 96, 99, 102, 104, |
| 107, 110, 112, 115, 118, 120, 123, 126, 128, 131, 134, 136, 139, 142, 144, 147, 150, 153, 155, 158, |
| 161, 163, 166, 169, 171, 174, 177, 179, 182, 185, 187, 190, 193, 195, 198, 201, 204, 206, 209, 212, |
| 214, 217, 220, 222, 225, 228, 230, 233, 236, 238, 241, 244, 246, 249, 252, 255 |
| }; |
| return reference; |
| } |
| |
| /* RGBA16 */ |
| template <> |
| const glw::GLushort* Reference::ReferenceData<glw::GLushort, true>() |
| { |
| static const glw::GLushort reference[s_reference_count] = { |
| 0, 689, 1379, 2069, 2759, 3449, 4139, 4828, 5518, 6208, 6898, 7588, 8278, 8967, 9657, 10347, |
| 11037, 11727, 12417, 13107, 13796, 14486, 15176, 15866, 16556, 17246, 17935, 18625, 19315, 20005, 20695, 21385, |
| 22074, 22764, 23454, 24144, 24834, 25524, 26214, 26903, 27593, 28283, 28973, 29663, 30353, 31042, 31732, 32422, |
| 33112, 33802, 34492, 35181, 35871, 36561, 37251, 37941, 38631, 39321, 40010, 40700, 41390, 42080, 42770, 43460, |
| 44149, 44839, 45529, 46219, 46909, 47599, 48288, 48978, 49668, 50358, 51048, 51738, 52428, 53117, 53807, 54497, |
| 55187, 55877, 56567, 57256, 57946, 58636, 59326, 60016, 60706, 61395, 62085, 62775, 63465, 64155, 64845, 65535 |
| }; |
| return reference; |
| } |
| |
| /* RGBA32F */ |
| template <> |
| const glw::GLfloat* Reference::ReferenceData<glw::GLfloat, true>() |
| { |
| static const glw::GLfloat reference[s_reference_count] = { |
| 0.f, 0.0105263158f, 0.0210526316f, 0.0315789474f, 0.0421052632f, 0.0526315789f, |
| 0.0631578947f, 0.0736842105f, 0.0842105263f, 0.0947368421f, 0.1052631579f, 0.1157894737f, |
| 0.1263157895f, 0.1368421053f, 0.1473684211f, 0.1578947368f, 0.1684210526f, 0.1789473684f, |
| 0.1894736842f, 0.2f, 0.2105263158f, 0.2210526316f, 0.2315789474f, 0.2421052632f, |
| 0.2526315789f, 0.2631578947f, 0.2736842105f, 0.2842105263f, 0.2947368421f, 0.3052631579f, |
| 0.3157894737f, 0.3263157895f, 0.3368421053f, 0.3473684211f, 0.3578947368f, 0.3684210526f, |
| 0.3789473684f, 0.3894736842f, 0.4f, 0.4105263158f, 0.4210526316f, 0.4315789474f, |
| 0.4421052632f, 0.4526315789f, 0.4631578947f, 0.4736842105f, 0.4842105263f, 0.4947368421f, |
| 0.5052631579f, 0.5157894737f, 0.5263157895f, 0.5368421053f, 0.5473684211f, 0.5578947368f, |
| 0.5684210526f, 0.5789473684f, 0.5894736842f, 0.6f, 0.6105263158f, 0.6210526316f, |
| 0.6315789474f, 0.6421052632f, 0.6526315789f, 0.6631578947f, 0.6736842105f, 0.6842105263f, |
| 0.6947368421f, 0.7052631579f, 0.7157894737f, 0.7263157895f, 0.7368421053f, 0.7473684211f, |
| 0.7578947368f, 0.7684210526f, 0.7789473684f, 0.7894736842f, 0.8f, 0.8105263158f, |
| 0.8210526316f, 0.8315789474f, 0.8421052632f, 0.8526315789f, 0.8631578947f, 0.8736842105f, |
| 0.8842105263f, 0.8947368421f, 0.9052631579f, 0.9157894737f, 0.9263157895f, 0.9368421053f, |
| 0.9473684211f, 0.9578947368f, 0.9684210526f, 0.9789473684f, 0.9894736842f, 1.f |
| }; |
| return reference; |
| } |
| |
| /* Total number of reference components. */ |
| glw::GLuint Reference::ReferenceDataCount() |
| { |
| return s_reference_count; |
| } |
| |
| /* Total number of reference size in basic machine units. */ |
| template <typename T> |
| glw::GLuint Reference::ReferenceDataSize() |
| { |
| return Reference::ReferenceDataCount() * sizeof(T); |
| } |
| |
| /** @brief Comparison function (for floats). |
| * |
| * @param [in] a First element. |
| * @param [in] b Second element. |
| * |
| * @return Comparison result. |
| */ |
| template <> |
| bool Reference::Compare<glw::GLfloat>(const glw::GLfloat a, const glw::GLfloat b) |
| { |
| if (de::abs(a - b) < 1.f / 256.f) |
| { |
| return true; |
| } |
| return false; |
| } |
| |
| /** @brief Comparison function (integer). |
| * |
| * @param [in] a First element. |
| * @param [in] b Second element. |
| * |
| * @return Comparison result. |
| */ |
| template <typename T> |
| bool Reference::Compare(const T a, const T b) |
| { |
| return a == b; |
| } |
| |
| /******************************** Buffer Test Implementation ********************************/ |
| |
| /** @brief Buffer Test constructor. |
| * |
| * @tparam T Type. |
| * @tparam S Size. |
| * @tparam N Is normalized. |
| * |
| * @param [in] context OpenGL context. |
| * @param [in] name Name of the test. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| BufferTest<T, S, N>::BufferTest(deqp::Context& context, const char* name) |
| : deqp::TestCase(context, name, "Texture Buffer Objects Test") |
| , m_fbo(0) |
| , m_rbo(0) |
| , m_po(0) |
| , m_to(0) |
| , m_bo(0) |
| , m_vao(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Count of reference data to be teted. |
| * |
| * @return Count. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| glw::GLuint BufferTest<T, S, N>::TestReferenceDataCount() |
| { |
| return s_fbo_size_x * S; |
| } |
| |
| /** @brief Size of reference data to be teted.. |
| * |
| * @return Size. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| glw::GLuint BufferTest<T, S, N>::TestReferenceDataSize() |
| { |
| return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T)); |
| } |
| |
| /** @brief Create buffer textuew. |
| * |
| * @param [in] use_range_version Uses TextureBufferRange instead TextureBuffer. |
| * |
| * @return True if succeded, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| bool BufferTest<T, S, N>::CreateBufferTexture(bool use_range_version) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Objects creation. */ |
| gl.genTextures(1, &m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_BUFFER, m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.genBuffers(1, &m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed"); |
| |
| gl.bindBuffer(GL_TEXTURE_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| /* Data setup. */ |
| if (use_range_version) |
| { |
| glw::GLint alignment = 1; |
| |
| gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &alignment); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| |
| const glw::GLuint b_offset = alignment; |
| const glw::GLuint b_size = TestReferenceDataSize() + b_offset; |
| |
| gl.bufferData(GL_TEXTURE_BUFFER, b_size, NULL, GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData has failed"); |
| |
| gl.bufferSubData(GL_TEXTURE_BUFFER, b_offset, TestReferenceDataSize(), ReferenceData<T, N>()); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubdata has failed"); |
| |
| gl.textureBufferRange(m_to, InternalFormat<T, S, N>(), m_bo, b_offset, TestReferenceDataSize()); |
| } |
| else |
| { |
| gl.bufferData(GL_TEXTURE_BUFFER, TestReferenceDataSize(), ReferenceData<T, N>(), GL_STATIC_DRAW); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed"); |
| |
| gl.textureBuffer(m_to, InternalFormat<T, S, N>(), m_bo); |
| } |
| |
| /* Error checking. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| /* Log. */ |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << (use_range_version ? ("glTextureBufferRange") : ("glTextureBuffer")) |
| << " unexpectedly generated error " << glu::getErrorStr(error) << " during test of internal format " |
| << glu::getTextureFormatStr(InternalFormat<T, S, N>()) << "." << tcu::TestLog::EndMessage; |
| |
| CleanBufferTexture(); |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Function prepares framebuffer with internal format color attachment. |
| * Viewport is set up. Content of the framebuffer is cleared. |
| * |
| * @note The function may throw if unexpected error has occured. |
| * |
| * @return if the framebuffer returned is supported |
| */ |
| template <typename T, glw::GLint S, bool N> |
| bool BufferTest<T, S, N>::PrepareFramebuffer(const glw::GLenum internal_format) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.genRenderbuffers(1, &m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, s_fbo_size_x, s_fbo_size_y); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed."); |
| |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED) |
| throw tcu::NotSupportedError("unsupported framebuffer configuration"); |
| else |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_fbo_size_x, s_fbo_size_y); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| /* Clear framebuffer's content. */ |
| gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| |
| return true; |
| } |
| |
| /** @brief Create program. |
| * |
| * @param [in] variable_declaration Choose variable declaration of the fragment shader. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::PrepareProgram(const glw::GLchar* variable_declaration) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| struct Shader |
| { |
| glw::GLchar const* source[3]; |
| glw::GLsizei const count; |
| glw::GLenum const type; |
| glw::GLuint id; |
| } shader[] = { |
| { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 }, |
| { { s_fragment_shader_head, variable_declaration, s_fragment_shader_tail }, 3, GL_FRAGMENT_SHADER, 0 } |
| }; |
| |
| glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); |
| |
| try |
| { |
| /* Create program. */ |
| m_po = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); |
| |
| /* Shader compilation. */ |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| { |
| shader[i].id = gl.createShader(shader[i].type); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); |
| |
| gl.attachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); |
| |
| gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); |
| |
| gl.compileShader(shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| if (GL_FALSE == status) |
| { |
| glw::GLint log_size = 0; |
| gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Shader compilation has failed.\n" |
| << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n" |
| << "Shader compilation error log:\n" |
| << log_text << "\n" |
| << "Shader source code:\n" |
| << shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "") |
| << (shader[i].source[2] ? shader[i].source[2] : "") << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| } |
| |
| /* Link. */ |
| gl.linkProgram(m_po); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getProgramiv(m_po, GL_LINK_STATUS, &status); |
| |
| if (GL_TRUE == status) |
| { |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (shader[i].id) |
| { |
| gl.detachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); |
| } |
| } |
| } |
| else |
| { |
| glw::GLint log_size = 0; |
| |
| gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" |
| << log_text << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| catch (...) |
| { |
| if (m_po) |
| { |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| } |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (0 != shader[i].id) |
| { |
| gl.deleteShader(shader[i].id); |
| |
| shader[i].id = 0; |
| } |
| } |
| |
| if (0 == m_po) |
| { |
| throw 0; |
| } |
| } |
| |
| /** @brief Create VAO. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::PrepareVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genVertexArrays(1, &m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed"); |
| |
| gl.bindVertexArray(m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed"); |
| } |
| |
| /** @brief Test's draw function. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::Draw() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.useProgram(m_po); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed"); |
| |
| gl.activeTexture(GL_TEXTURE0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.bindTextureUnit(0, m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed"); |
| } |
| |
| /** @brief Compre results with the reference. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| bool BufferTest<T, S, N>::Check() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Fetching data. */ |
| std::vector<T> result(TestReferenceDataCount()); |
| |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.readnPixels(0, 0, s_fbo_size_x, s_fbo_size_y, Format<S, N>(), Type<T>(), TestReferenceDataSize(), |
| (glw::GLvoid*)(&result[0])); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed"); |
| |
| /* Comparison. */ |
| bool is_ok = true; |
| |
| for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i) |
| { |
| if (!Compare<T>(result[i], ReferenceData<T, N>()[i])) |
| { |
| is_ok = false; |
| |
| break; |
| } |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test function. |
| * |
| * @param [in] use_range_version Uses TextureBufferRange instead TextureBuffer. |
| * |
| * @return True if succeeded, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| bool BufferTest<T, S, N>::Test(bool use_range_version) |
| { |
| /* Setup. */ |
| if (!PrepareFramebuffer(InternalFormat<T, S, N>())) |
| { |
| /** |
| * If the framebuffer it not supported, means that the |
| * tested combination is unsupported for this driver, |
| * but allowed to be unsupported by OpenGL spec, so we |
| * just skip. |
| */ |
| CleanFramebuffer(); |
| CleanErrors(); |
| |
| return true; |
| } |
| |
| if (!CreateBufferTexture(use_range_version)) |
| { |
| CleanFramebuffer(); |
| CleanErrors(); |
| |
| return false; |
| } |
| |
| /* Action. */ |
| Draw(); |
| |
| /* Compare results with reference. */ |
| bool result = Check(); |
| |
| /* Cleanup. */ |
| CleanFramebuffer(); |
| CleanBufferTexture(); |
| CleanErrors(); |
| |
| /* Pass result. */ |
| return result; |
| } |
| |
| /** @brief Clean GL objects |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::CleanBufferTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Texture. */ |
| if (m_to) |
| { |
| gl.deleteTextures(1, &m_to); |
| |
| m_to = 0; |
| } |
| |
| /* Texture buffer. */ |
| if (m_bo) |
| { |
| gl.deleteBuffers(1, &m_bo); |
| |
| m_bo = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::CleanFramebuffer() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Framebuffer. */ |
| if (m_fbo) |
| { |
| gl.deleteFramebuffers(1, &m_fbo); |
| |
| m_fbo = 0; |
| } |
| |
| /* Renderbuffer. */ |
| if (m_rbo) |
| { |
| gl.deleteRenderbuffers(1, &m_rbo); |
| |
| m_rbo = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::CleanProgram() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Program. */ |
| if (m_po) |
| { |
| gl.useProgram(0); |
| |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| } |
| |
| /** @brief Clean errors. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::CleanErrors() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Query all errors until GL_NO_ERROR occure. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Clean GL objects |
| */ |
| template <typename T, glw::GLint S, bool N> |
| void BufferTest<T, S, N>::CleanVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_vao) |
| { |
| gl.bindVertexArray(0); |
| |
| gl.deleteVertexArrays(1, &m_vao); |
| |
| m_vao = 0; |
| } |
| } |
| |
| /** @brief Iterate Buffer Test cases. |
| * |
| * @return Iteration result. |
| */ |
| template <typename T, glw::GLint S, bool N> |
| tcu::TestNode::IterateResult BufferTest<T, S, N>::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| PrepareVertexArray(); |
| |
| PrepareProgram(FragmentShaderDeclaration()); |
| |
| for (glw::GLuint i = 0; i < 2; ++i) |
| { |
| bool use_range = (i == 1); |
| is_ok &= Test(use_range); |
| CleanErrors(); |
| } |
| |
| CleanProgram(); |
| } |
| catch (tcu::NotSupportedError& e) |
| { |
| throw e; |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanBufferTexture(); |
| CleanFramebuffer(); |
| CleanProgram(); |
| CleanErrors(); |
| CleanVertexArray(); |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /* Vertex shader source code. */ |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_vertex_shader = "#version 450\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " switch(gl_VertexID)\n" |
| " {\n" |
| " case 0:\n" |
| " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 1:\n" |
| " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 2:\n" |
| " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 3:\n" |
| " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " }\n" |
| "}\n"; |
| |
| /* Fragment shader source program. */ |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_head = "#version 450\n" |
| "\n" |
| "layout(pixel_center_integer) in vec4 gl_FragCoord;\n" |
| "\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_lowp = "uniform samplerBuffer texture_input;\n" |
| "out vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_lowp = "uniform isamplerBuffer texture_input;\n" |
| "out ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_lowp = "uniform usamplerBuffer texture_input;\n" |
| "out uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_mediump = "uniform samplerBuffer texture_input;\n" |
| "out vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_mediump = "uniform isamplerBuffer texture_input;\n" |
| "out ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_mediump = "uniform usamplerBuffer texture_input;\n" |
| "out uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_fdecl_highp = "uniform samplerBuffer texture_input;\n" |
| "out vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_idecl_highp = "uniform isamplerBuffer texture_input;\n" |
| "out ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_udecl_highp = "uniform usamplerBuffer texture_input;\n" |
| "out uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N> |
| const glw::GLchar* BufferTest<T, S, N>::s_fragment_shader_tail = |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, int(gl_FragCoord.x));\n" |
| "}\n"; |
| |
| template class BufferTest<glw::GLbyte, 1, false>; |
| template class BufferTest<glw::GLbyte, 2, false>; |
| template class BufferTest<glw::GLbyte, 4, false>; |
| |
| template class BufferTest<glw::GLubyte, 1, false>; |
| template class BufferTest<glw::GLubyte, 2, false>; |
| template class BufferTest<glw::GLubyte, 4, false>; |
| template class BufferTest<glw::GLubyte, 1, true>; |
| template class BufferTest<glw::GLubyte, 2, true>; |
| template class BufferTest<glw::GLubyte, 4, true>; |
| |
| template class BufferTest<glw::GLshort, 1, false>; |
| template class BufferTest<glw::GLshort, 2, false>; |
| template class BufferTest<glw::GLshort, 4, false>; |
| |
| template class BufferTest<glw::GLushort, 1, false>; |
| template class BufferTest<glw::GLushort, 2, false>; |
| template class BufferTest<glw::GLushort, 4, false>; |
| template class BufferTest<glw::GLushort, 1, true>; |
| template class BufferTest<glw::GLushort, 2, true>; |
| template class BufferTest<glw::GLushort, 4, true>; |
| |
| template class BufferTest<glw::GLint, 1, false>; |
| template class BufferTest<glw::GLint, 2, false>; |
| template class BufferTest<glw::GLint, 3, false>; |
| template class BufferTest<glw::GLint, 4, false>; |
| |
| template class BufferTest<glw::GLuint, 1, false>; |
| template class BufferTest<glw::GLuint, 2, false>; |
| template class BufferTest<glw::GLuint, 3, false>; |
| template class BufferTest<glw::GLuint, 4, false>; |
| |
| template class BufferTest<glw::GLfloat, 1, true>; |
| template class BufferTest<glw::GLfloat, 2, true>; |
| template class BufferTest<glw::GLfloat, 3, true>; |
| template class BufferTest<glw::GLfloat, 4, true>; |
| |
| /******************************** Storage and SubImage Test Implementation ********************************/ |
| |
| /** @brief Storage Test constructor. |
| * |
| * @tparam T Type. |
| * @tparam S Size. |
| * @tparam N Is normalized. |
| * @tparam D Texture dimension. |
| * @tparam I Choose between SubImage and Storage tests. |
| * |
| * @param [in] context OpenGL context. |
| * @param [in] name Name of the test. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| StorageAndSubImageTest<T, S, N, D, I>::StorageAndSubImageTest(deqp::Context& context, const char* name) |
| : deqp::TestCase(context, name, "Texture Storage and SubImage Test") |
| , m_fbo(0) |
| , m_rbo(0) |
| , m_po(0) |
| , m_to(0) |
| , m_vao(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Count of reference data to be teted. |
| * |
| * @return Count. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataCount() |
| { |
| return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */; |
| } |
| |
| /** @brief Size of reference data to be teted. |
| * |
| * @tparam T Type. |
| * @tparam S Size (# of components). |
| * @tparam D Texture dimenisons. |
| * |
| * @return Size. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataSize() |
| { |
| return static_cast<glw::GLint>(TestReferenceDataCount() * sizeof(T)); |
| } |
| |
| /** @brief Height, width or depth of reference data to be teted. |
| * |
| * @return Height, width or depth. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataHeight() |
| { |
| switch (D) |
| { |
| case 2: |
| case 3: |
| return 3; |
| default: |
| return 1; |
| } |
| } |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataDepth() |
| { |
| switch (D) |
| { |
| case 3: |
| return 4; |
| default: |
| return 1; |
| } |
| } |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLuint StorageAndSubImageTest<T, S, N, D, I>::TestReferenceDataWidth() |
| { |
| return 2; |
| } |
| |
| /** @brief Fragment shader declaration selector. |
| * |
| * @return Frgment shader source code part. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderDeclaration() |
| { |
| if (typeid(T) == typeid(glw::GLbyte)) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_idecl_lowp; |
| case 2: |
| return s_fragment_shader_2D_idecl_lowp; |
| case 3: |
| return s_fragment_shader_3D_idecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLubyte)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_fdecl_lowp; |
| case 2: |
| return s_fragment_shader_2D_fdecl_lowp; |
| case 3: |
| return s_fragment_shader_3D_fdecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_udecl_lowp; |
| case 2: |
| return s_fragment_shader_2D_udecl_lowp; |
| case 3: |
| return s_fragment_shader_3D_udecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLshort)) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_idecl_mediump; |
| case 2: |
| return s_fragment_shader_2D_idecl_mediump; |
| case 3: |
| return s_fragment_shader_3D_idecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLushort)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_fdecl_mediump; |
| case 2: |
| return s_fragment_shader_2D_fdecl_mediump; |
| case 3: |
| return s_fragment_shader_3D_fdecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_udecl_mediump; |
| case 2: |
| return s_fragment_shader_2D_udecl_mediump; |
| case 3: |
| return s_fragment_shader_3D_udecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLint)) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_idecl_highp; |
| case 2: |
| return s_fragment_shader_2D_idecl_highp; |
| case 3: |
| return s_fragment_shader_3D_idecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLuint)) |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_udecl_highp; |
| case 2: |
| return s_fragment_shader_2D_udecl_highp; |
| case 3: |
| return s_fragment_shader_3D_udecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_fdecl_highp; |
| case 2: |
| return s_fragment_shader_2D_fdecl_highp; |
| case 3: |
| return s_fragment_shader_3D_fdecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief Fragment shader tail selector. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return Frgment shader source code part. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::FragmentShaderTail() |
| { |
| switch (D) |
| { |
| case 1: |
| return s_fragment_shader_1D_tail; |
| case 2: |
| return s_fragment_shader_2D_tail; |
| case 3: |
| return s_fragment_shader_3D_tail; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief Texture target selector. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return Texture target. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| glw::GLenum StorageAndSubImageTest<T, S, N, D, I>::TextureTarget() |
| { |
| switch (D) |
| { |
| case 1: |
| return GL_TEXTURE_1D; |
| case 2: |
| return GL_TEXTURE_2D; |
| case 3: |
| return GL_TEXTURE_3D; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief TextureStorage* wrapper. |
| * |
| * @return true if succeed (in legacy always or throw), false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| bool StorageAndSubImageTest<T, S, N, D, I>::TextureStorage(glw::GLenum target, glw::GLuint texture, glw::GLsizei levels, |
| glw::GLenum internalformat, glw::GLsizei width, |
| glw::GLsizei height, glw::GLsizei depth) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (I) |
| { |
| switch (D) |
| { |
| case 1: |
| gl.texStorage1D(target, levels, internalformat, width); |
| break; |
| case 2: |
| gl.texStorage2D(target, levels, internalformat, width, height); |
| break; |
| case 3: |
| gl.texStorage3D(target, levels, internalformat, width, height, depth); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| |
| /* TextureSubImage* (not TextureStorage*) is tested */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage*() has failed"); |
| return true; |
| } |
| else |
| { |
| switch (D) |
| { |
| case 1: |
| gl.textureStorage1D(texture, levels, internalformat, width); |
| break; |
| case 2: |
| gl.textureStorage2D(texture, levels, internalformat, width, height); |
| break; |
| case 3: |
| gl.textureStorage3D(texture, levels, internalformat, width, height, depth); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| |
| glw::GLenum error; |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glTextureStorage" << D << "D unexpectedly generated error " << glu::getErrorStr(error) |
| << " during test with levels " << levels << ", internal format " << internalformat |
| << " width=" << width << " height=" << height << " depth=" << depth |
| << "." << tcu::TestLog::EndMessage; |
| |
| CleanTexture(); |
| CleanErrors(); |
| |
| return false; |
| } |
| |
| return true; |
| } |
| } |
| |
| /** @brief TextureSubImage* wrapper. |
| * |
| * @return true if suuceed (in legacy always or throw), false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| bool StorageAndSubImageTest<T, S, N, D, I>::TextureSubImage(glw::GLenum target, glw::GLuint texture, glw::GLint level, |
| glw::GLsizei width, glw::GLsizei height, glw::GLsizei depth, |
| glw::GLenum format, glw::GLenum type, const glw::GLvoid* data) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (I) |
| { |
| switch (D) |
| { |
| case 1: |
| gl.textureSubImage1D(texture, level, 0, width, format, type, data); |
| break; |
| case 2: |
| gl.textureSubImage2D(texture, level, 0, 0, width, height, format, type, data); |
| break; |
| case 3: |
| gl.textureSubImage3D(texture, level, 0, 0, 0, width, height, depth, format, type, data); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| |
| glw::GLenum error; |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glTextureSubImage" << D << "D unexpectedly generated error " << glu::getErrorStr(error) |
| << " during test with level " << level << ", width=" << width << ", height=" << height << ", depth=" << depth |
| << " format " << glu::getTextureFormatStr(format) << " and type " << glu::getTypeStr(type) << "." |
| << tcu::TestLog::EndMessage; |
| |
| CleanTexture(); |
| CleanErrors(); |
| |
| return false; |
| } |
| |
| return true; |
| } |
| else |
| { |
| switch (D) |
| { |
| case 1: |
| gl.texSubImage1D(target, level, 0, width, format, type, data); |
| break; |
| case 2: |
| gl.texSubImage2D(target, level, 0, 0, width, height, format, type, data); |
| break; |
| case 3: |
| gl.texSubImage3D(target, level, 0, 0, 0, width, height, depth, format, type, data); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| |
| /* TextureStorage* (not TextureSubImage) is tested */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage*() has failed"); |
| return true; |
| } |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam T Type. |
| * @tparam S Size (# of components). |
| * @tparam N Is normalized. |
| * @tparam D Dimmensions. |
| * @tparam I Test SubImage or Storage. |
| * |
| * @return True if succeded, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| bool StorageAndSubImageTest<T, S, N, D, I>::CreateTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Objects creation. */ |
| gl.genTextures(1, &m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(TextureTarget(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| /* Storage creation. */ |
| if (TextureStorage(TextureTarget(), m_to, 1, InternalFormat<T, S, N>(), TestReferenceDataWidth(), |
| TestReferenceDataHeight(), TestReferenceDataDepth())) |
| { |
| /* Data setup. */ |
| if (TextureSubImage(TextureTarget(), m_to, 0, TestReferenceDataWidth(), TestReferenceDataHeight(), TestReferenceDataDepth(), |
| Format<S, N>(), Type<T>(), ReferenceData<T, N>())) |
| { |
| glTexParameteri(TextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri(TextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| return true; |
| } |
| } |
| |
| CleanTexture(); |
| |
| return false; |
| } |
| |
| /** @brief Compre results with the reference. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| bool StorageAndSubImageTest<T, S, N, D, I>::Check() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Fetching data. */ |
| std::vector<T> result(TestReferenceDataCount()); |
| |
| glw::GLuint fbo_size_x = 0; |
| |
| switch (D) |
| { |
| case 1: |
| fbo_size_x = 2; |
| break; |
| case 2: |
| fbo_size_x = 2 * 3; |
| break; |
| case 3: |
| fbo_size_x = 2 * 3 * 4; |
| break; |
| default: |
| throw 0; |
| } |
| |
| gl.readnPixels(0, 0, fbo_size_x, 1, Format<S, N>(), Type<T>(), TestReferenceDataSize(), |
| (glw::GLvoid*)(&result[0])); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed"); |
| |
| /* Comparison. */ |
| for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i) |
| { |
| if (!Compare<T>(result[i], ReferenceData<T, N>()[i])) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** @brief Test case function. |
| * |
| * @return True if test succeeded, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| bool StorageAndSubImageTest<T, S, N, D, I>::Test() |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| /* Setup. */ |
| PrepareFramebuffer(InternalFormat<T, S, N>()); |
| |
| if (!CreateTexture()) |
| { |
| return false; |
| } |
| |
| /* Action. */ |
| Draw(); |
| |
| /* Compare results with reference. */ |
| bool result = Check(); |
| |
| /* Cleanup. */ |
| CleanTexture(); |
| CleanFramebuffer(); |
| CleanErrors(); |
| |
| /* Pass result. */ |
| return result; |
| } |
| |
| /** @brief Function prepares framebuffer with internal format color attachment. |
| * Viewport is set up. Content of the framebuffer is cleared. |
| * |
| * @note The function may throw if unexpected error has occured. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::PrepareFramebuffer(const glw::GLenum internal_format) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.genRenderbuffers(1, &m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| glw::GLuint fbo_size_x = 0; |
| |
| switch (D) |
| { |
| case 1: |
| fbo_size_x = 2; |
| break; |
| case 2: |
| fbo_size_x = 2 * 3; |
| break; |
| case 3: |
| fbo_size_x = 2 * 3 * 4; |
| break; |
| default: |
| throw 0; |
| } |
| |
| gl.renderbufferStorage(GL_RENDERBUFFER, internal_format, fbo_size_x, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed."); |
| |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED) |
| throw tcu::NotSupportedError("unsupported framebuffer configuration"); |
| else |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, fbo_size_x, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| /* Clear framebuffer's content. */ |
| gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| } |
| |
| /** @brief Prepare program |
| * |
| * @param [in] variable_declaration Variables declaration part of fragment shader source code. |
| * @param [in] tail Tail part of fragment shader source code. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| struct Shader |
| { |
| glw::GLchar const* source[3]; |
| glw::GLsizei const count; |
| glw::GLenum const type; |
| glw::GLuint id; |
| } shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 }, |
| { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } }; |
| |
| glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); |
| |
| try |
| { |
| /* Create program. */ |
| m_po = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); |
| |
| /* Shader compilation. */ |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| { |
| shader[i].id = gl.createShader(shader[i].type); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); |
| |
| gl.attachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); |
| |
| gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); |
| |
| gl.compileShader(shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| if (GL_FALSE == status) |
| { |
| glw::GLint log_size = 0; |
| gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Shader compilation has failed.\n" |
| << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n" |
| << "Shader compilation error log:\n" |
| << log_text << "\n" |
| << "Shader source code:\n" |
| << shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "") |
| << (shader[i].source[2] ? shader[i].source[2] : "") << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| } |
| |
| /* Link. */ |
| gl.linkProgram(m_po); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getProgramiv(m_po, GL_LINK_STATUS, &status); |
| |
| if (GL_TRUE == status) |
| { |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (shader[i].id) |
| { |
| gl.detachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); |
| } |
| } |
| } |
| else |
| { |
| glw::GLint log_size = 0; |
| |
| gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" |
| << log_text << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| catch (...) |
| { |
| if (m_po) |
| { |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| } |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (0 != shader[i].id) |
| { |
| gl.deleteShader(shader[i].id); |
| |
| shader[i].id = 0; |
| } |
| } |
| |
| if (0 == m_po) |
| { |
| throw 0; |
| } |
| } |
| |
| /** @brief Prepare VAO. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::PrepareVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genVertexArrays(1, &m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed"); |
| |
| gl.bindVertexArray(m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed"); |
| } |
| |
| /** @brief Test's draw call. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::Draw() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.useProgram(m_po); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed"); |
| |
| gl.activeTexture(GL_TEXTURE0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.bindTextureUnit(0, m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed"); |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::CleanTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Texture. */ |
| if (m_to) |
| { |
| gl.deleteTextures(1, &m_to); |
| |
| m_to = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::CleanFramebuffer() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Framebuffer. */ |
| if (m_fbo) |
| { |
| gl.deleteFramebuffers(1, &m_fbo); |
| |
| m_fbo = 0; |
| } |
| |
| /* Renderbuffer. */ |
| if (m_rbo) |
| { |
| gl.deleteRenderbuffers(1, &m_rbo); |
| |
| m_rbo = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::CleanProgram() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Program. */ |
| if (m_po) |
| { |
| gl.useProgram(0); |
| |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::CleanErrors() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Query all errors until GL_NO_ERROR occure. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| void StorageAndSubImageTest<T, S, N, D, I>::CleanVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_vao) |
| { |
| gl.bindVertexArray(0); |
| |
| gl.deleteVertexArrays(1, &m_vao); |
| |
| m_vao = 0; |
| } |
| } |
| |
| /** @brief Iterate Storage Test cases. |
| * |
| * @return Iteration result. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| tcu::TestNode::IterateResult StorageAndSubImageTest<T, S, N, D, I>::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| PrepareVertexArray(); |
| PrepareProgram(FragmentShaderDeclaration(), FragmentShaderTail()); |
| is_ok = Test(); |
| } |
| catch (tcu::NotSupportedError& e) |
| { |
| throw e; |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanTexture(); |
| CleanFramebuffer(); |
| CleanProgram(); |
| CleanErrors(); |
| CleanVertexArray(); |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /* Vertex shader source code. */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_vertex_shader = |
| "#version 450\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " switch(gl_VertexID)\n" |
| " {\n" |
| " case 0:\n" |
| " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 1:\n" |
| " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 2:\n" |
| " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 3:\n" |
| " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " }\n" |
| "}\n"; |
| |
| /* Fragment shader source program. */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_head = |
| "#version 450\n" |
| "\n" |
| "layout(pixel_center_integer) in vec4 gl_FragCoord;\n" |
| "\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_lowp = |
| "uniform sampler1D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_lowp = |
| "uniform isampler1D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_lowp = |
| "uniform usampler1D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_mediump = |
| "uniform sampler1D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_mediump = |
| "uniform isampler1D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_mediump = |
| "uniform usampler1D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_fdecl_highp = |
| "uniform sampler1D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_idecl_highp = |
| "uniform isampler1D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_udecl_highp = |
| "uniform usampler1D texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_lowp = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_lowp = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_lowp = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_mediump = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_mediump = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_mediump = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_fdecl_highp = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_idecl_highp = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_udecl_highp = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_lowp = |
| "uniform sampler3D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_lowp = |
| "uniform isampler3D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_lowp = |
| "uniform usampler3D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_mediump = |
| "uniform sampler3D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_mediump = |
| "uniform isampler3D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_mediump = |
| "uniform usampler3D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_fdecl_highp = |
| "uniform sampler3D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_idecl_highp = |
| "uniform isampler3D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_udecl_highp = |
| "uniform usampler3D texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_1D_tail = |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, int(gl_FragCoord.x), 0);\n" |
| "}\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_2D_tail = |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, ivec2(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2))), " |
| "0);\n" |
| "}\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D, bool I> |
| const glw::GLchar* StorageAndSubImageTest<T, S, N, D, I>::s_fragment_shader_3D_tail = |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, ivec3(int(gl_FragCoord.x) % 2, int(floor(gl_FragCoord.x / 2)) % 3, " |
| "int(floor(gl_FragCoord.x / 2 / 3))), 0);\n" |
| "}\n"; |
| |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, false>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, false>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, false>; |
| |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLbyte, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 1, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 2, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLubyte, 4, true, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLshort, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 1, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 2, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLushort, 4, true, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLint, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLint, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLint, 3, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLint, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 1, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 2, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 1, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 2, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 3, false, 3, true>; |
| template class StorageAndSubImageTest<glw::GLuint, 4, false, 3, true>; |
| |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 1, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 2, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 1, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 2, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 3, true, 3, true>; |
| template class StorageAndSubImageTest<glw::GLfloat, 4, true, 3, true>; |
| |
| /******************************** Storage Multisample Test Implementation ********************************/ |
| |
| /** @brief Storage Multisample Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| StorageMultisampleTest<T, S, N, D>::StorageMultisampleTest(deqp::Context& context, const char* name) |
| : deqp::TestCase(context, name, "Texture Storage Multisample Test") |
| , m_fbo_ms(0) |
| , m_fbo_aux(0) |
| , m_to_ms(0) |
| , m_po_ms(0) |
| , m_po_aux(0) |
| , m_to(0) |
| , m_to_aux(0) |
| , m_vao(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Count of reference data to be teted. |
| * |
| * @return Count. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataCount() |
| { |
| return 2 /* 1D */ * ((D > 1) ? 3 : 1) /* 2D */ * ((D > 2) ? 4 : 1) /* 3D */ * S /* components */; |
| } |
| |
| /** @brief Size of reference data to be teted. |
| * |
| * @return Size. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataSize() |
| { |
| return TestReferenceDataCount() * sizeof(T); |
| } |
| |
| /** @brief Height, width or depth of reference data to be teted. |
| * |
| * @return Height, width or depth. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataHeight() |
| { |
| switch(D) |
| { |
| case 3: |
| case 2: |
| return 3; |
| default: |
| return 1; |
| } |
| } |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataDepth() |
| { |
| switch(D) |
| { |
| case 3: |
| return 4; |
| default: |
| return 1; |
| } |
| } |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::TestReferenceDataWidth() |
| { |
| return 2; |
| } |
| |
| /** @brief Fragment shader declaration selector. |
| * |
| * @return Frgment shader source code part. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationMultisample() |
| { |
| if (typeid(T) == typeid(glw::GLbyte)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_idecl_lowp; |
| case 3: |
| return s_fragment_shader_ms_3D_idecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLubyte)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_fdecl_lowp; |
| case 3: |
| return s_fragment_shader_ms_3D_fdecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_udecl_lowp; |
| case 3: |
| return s_fragment_shader_ms_3D_udecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLshort)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_idecl_mediump; |
| case 3: |
| return s_fragment_shader_ms_3D_idecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLushort)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_fdecl_mediump; |
| case 3: |
| return s_fragment_shader_ms_3D_fdecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_udecl_mediump; |
| case 3: |
| return s_fragment_shader_ms_3D_udecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLint)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_idecl_highp; |
| case 3: |
| return s_fragment_shader_ms_3D_idecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLuint)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_udecl_highp; |
| case 3: |
| return s_fragment_shader_ms_3D_udecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLfloat)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_ms_2D_fdecl_highp; |
| case 3: |
| return s_fragment_shader_ms_3D_fdecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| DE_FATAL("invalid type"); |
| return DE_NULL; |
| } |
| |
| /** @brief Fragment shader declaration selector. |
| * |
| * @return Frgment shader source code part. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderDeclarationAuxiliary() |
| { |
| if (typeid(T) == typeid(glw::GLbyte)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_idecl_lowp; |
| case 3: |
| return s_fragment_shader_aux_3D_idecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLubyte)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_fdecl_lowp; |
| case 3: |
| return s_fragment_shader_aux_3D_fdecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_udecl_lowp; |
| case 3: |
| return s_fragment_shader_aux_3D_udecl_lowp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLshort)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_idecl_mediump; |
| case 3: |
| return s_fragment_shader_aux_3D_idecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLushort)) |
| { |
| if (N) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_fdecl_mediump; |
| case 3: |
| return s_fragment_shader_aux_3D_fdecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| else |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_udecl_mediump; |
| case 3: |
| return s_fragment_shader_aux_3D_udecl_mediump; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLint)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_idecl_highp; |
| case 3: |
| return s_fragment_shader_aux_3D_idecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLuint)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_udecl_highp; |
| case 3: |
| return s_fragment_shader_aux_3D_udecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| if (typeid(T) == typeid(glw::GLfloat)) |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_aux_2D_fdecl_highp; |
| case 3: |
| return s_fragment_shader_aux_3D_fdecl_highp; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| DE_FATAL("invalid type"); |
| return DE_NULL; |
| } |
| |
| /** @brief Fragment shader tail selector. |
| * |
| * @return Frgment shader source code part. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::FragmentShaderTail() |
| { |
| switch (D) |
| { |
| case 2: |
| return s_fragment_shader_tail_2D; |
| case 3: |
| return s_fragment_shader_tail_3D; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief Multisample texture target selector. |
| * |
| * @return Texture target. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLenum StorageMultisampleTest<T, S, N, D>::MultisampleTextureTarget() |
| { |
| switch (D) |
| { |
| case 2: |
| return GL_TEXTURE_2D_MULTISAMPLE; |
| case 3: |
| return GL_TEXTURE_2D_MULTISAMPLE_ARRAY; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief Input texture target selector. |
| * |
| * @return Texture target. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLenum StorageMultisampleTest<T, S, N, D>::InputTextureTarget() |
| { |
| switch (D) |
| { |
| case 2: |
| return GL_TEXTURE_2D; |
| case 3: |
| return GL_TEXTURE_2D_ARRAY; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return DE_NULL; |
| } |
| } |
| |
| /** @brief Prepare texture data for input texture. |
| * |
| * @note parameters as passed to texImage* |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::InputTextureImage(const glw::GLenum internal_format, const glw::GLuint width, |
| const glw::GLuint height, const glw::GLuint depth, |
| const glw::GLenum format, const glw::GLenum type, |
| const glw::GLvoid* data) |
| { |
| (void)depth; |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Data setup. */ |
| switch (D) |
| { |
| case 2: |
| gl.texImage2D(InputTextureTarget(), 0, internal_format, width, height, 0, format, type, data); |
| break; |
| case 3: |
| gl.texImage3D(InputTextureTarget(), 0, internal_format, width, height, depth, 0, format, type, data); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage has failed"); |
| } |
| |
| /** @brief Create texture. |
| * |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CreateInputTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Objects creation. */ |
| gl.genTextures(1, &m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(InputTextureTarget(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| /* Data setup. */ |
| InputTextureImage(InternalFormat<T, S, N>(), TestReferenceDataWidth(), TestReferenceDataHeight(), |
| TestReferenceDataDepth(), Format<S, N>(), Type<T>(), ReferenceData<T, N>()); |
| |
| /* Parameter setup. */ |
| gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(InputTextureTarget(), GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| } |
| |
| /** @brief Compre results with the reference. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| bool StorageMultisampleTest<T, S, N, D>::Check() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Fetching data fro auxiliary texture. */ |
| std::vector<T> result(TestReferenceDataCount()); |
| |
| gl.bindTexture(InputTextureTarget() /* Auxiliary target is the same as input. */, m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.getTexImage(InputTextureTarget() /* Auxiliary target is the same as input. */, 0, Format<S, N>(), Type<T>(), |
| (glw::GLvoid*)(&result[0])); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed"); |
| |
| /* Comparison. */ |
| for (glw::GLuint i = 0; i < TestReferenceDataCount(); ++i) |
| { |
| if (!Compare<T>(result[i], ReferenceData<T, N>()[i])) |
| { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** @brief Test case function. |
| * |
| * @return True if test succeeded, false otherwise. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| bool StorageMultisampleTest<T, S, N, D>::Test() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Setup. */ |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(T)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| CreateInputTexture(); |
| |
| if (!PrepareFramebufferMultisample(InternalFormat<T, S, N>())) |
| { |
| CleanInputTexture(); |
| |
| return false; |
| } |
| |
| PrepareFramebufferAuxiliary(InternalFormat<T, S, N>()); |
| |
| /* Action. */ |
| Draw(); |
| |
| /* Compare results with reference. */ |
| bool result = Check(); |
| |
| /* Cleanup. */ |
| CleanAuxiliaryTexture(); |
| CleanFramebuffers(); |
| CleanInputTexture(); |
| CleanErrors(); |
| |
| /* Pass result. */ |
| return result; |
| } |
| |
| /** @brief Function prepares framebuffer with internal format color attachment. |
| * Viewport is set up. Content of the framebuffer is cleared. |
| * |
| * @note The function may throw if unexpected error has occured. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| bool StorageMultisampleTest<T, S, N, D>::PrepareFramebufferMultisample(const glw::GLenum internal_format) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.genTextures(1, &m_to_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.bindTexture(MultisampleTextureTarget(), m_to_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| switch (D) |
| { |
| case 2: |
| gl.textureStorage2DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(), |
| TestReferenceDataHeight(), false); |
| break; |
| case 3: |
| gl.textureStorage3DMultisample(m_to_ms, 1, internal_format, TestReferenceDataWidth(), |
| TestReferenceDataHeight(), TestReferenceDataDepth(), false); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return false; |
| } |
| |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| CleanFramebuffers(); |
| |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glTextureStorageMultisample unexpectedly generated error " |
| << glu::getErrorStr(error) << " during the test of internal format " |
| << glu::getTextureFormatStr(internal_format) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| switch (D) |
| { |
| case 2: |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_ms, 0); |
| break; |
| case 3: |
| for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i) |
| { |
| gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_ms, 0, i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed."); |
| } |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| return false; |
| } |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED) |
| throw tcu::NotSupportedError("unsupported framebuffer configuration"); |
| else |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight()); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| /* Clear framebuffer's content. */ |
| gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| |
| return true; |
| } |
| |
| /** @brief Function prepares framebuffer with internal format color attachment. |
| * Viewport is set up. Content of the framebuffer is cleared. |
| * |
| * @note The function may throw if unexpected error has occured. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::PrepareFramebufferAuxiliary(const glw::GLenum internal_format) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.genTextures(1, &m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.bindTexture(InputTextureTarget(), m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| switch (D) |
| { |
| case 2: |
| gl.textureStorage2D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight()); |
| break; |
| case 3: |
| gl.textureStorage3D(m_to_aux, 1, internal_format, TestReferenceDataWidth(), TestReferenceDataHeight(), |
| TestReferenceDataDepth()); |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D call failed."); |
| |
| /* Parameter setup. */ |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| |
| switch (D) |
| { |
| case 2: |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_aux, 0); |
| break; |
| case 3: |
| for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i) |
| { |
| gl.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, m_to_aux, 0, i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer call failed."); |
| } |
| break; |
| default: |
| DE_FATAL("invalid texture dimension"); |
| } |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNSUPPORTED) |
| throw tcu::NotSupportedError("unsupported framebuffer configuration"); |
| else |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, TestReferenceDataWidth(), TestReferenceDataHeight()); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| /* Clear framebuffer's content. */ |
| gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| } |
| |
| /** @brief Prepare program |
| * |
| * @param [in] variable_declaration Variables declaration part of fragment shader source code. |
| * @param [in] tail Tail part of fragment shader source code. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| glw::GLuint StorageMultisampleTest<T, S, N, D>::PrepareProgram(const glw::GLchar* variable_declaration, const glw::GLchar* tail) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| struct Shader |
| { |
| glw::GLchar const* source[3]; |
| glw::GLsizei const count; |
| glw::GLenum const type; |
| glw::GLuint id; |
| } shader[] = { { { s_vertex_shader, NULL, NULL }, 1, GL_VERTEX_SHADER, 0 }, |
| { { s_fragment_shader_head, variable_declaration, tail }, 3, GL_FRAGMENT_SHADER, 0 } }; |
| |
| glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); |
| |
| glw::GLuint po = 0; |
| |
| try |
| { |
| /* Create program. */ |
| po = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); |
| |
| /* Shader compilation. */ |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| { |
| shader[i].id = gl.createShader(shader[i].type); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); |
| |
| gl.attachShader(po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); |
| |
| gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); |
| |
| gl.compileShader(shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| if (GL_FALSE == status) |
| { |
| glw::GLint log_size = 0; |
| gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Shader compilation has failed.\n" |
| << "Shader type: " << glu::getShaderTypeStr(shader[i].type) << "\n" |
| << "Shader compilation error log:\n" |
| << log_text << "\n" |
| << "Shader source code:\n" |
| << shader[i].source[0] << (shader[i].source[1] ? shader[i].source[1] : "") |
| << (shader[i].source[2] ? shader[i].source[2] : "") << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| } |
| |
| /* Link. */ |
| gl.linkProgram(po); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getProgramiv(po, GL_LINK_STATUS, &status); |
| |
| if (GL_TRUE == status) |
| { |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (shader[i].id) |
| { |
| gl.detachShader(po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); |
| } |
| } |
| } |
| else |
| { |
| glw::GLint log_size = 0; |
| |
| gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" |
| << log_text << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| catch (...) |
| { |
| if (po) |
| { |
| gl.deleteProgram(po); |
| |
| po = 0; |
| } |
| } |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (0 != shader[i].id) |
| { |
| gl.deleteShader(shader[i].id); |
| |
| shader[i].id = 0; |
| } |
| } |
| |
| if (0 == po) |
| { |
| throw 0; |
| } |
| |
| return po; |
| } |
| |
| /** @brief Prepare VAO. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::PrepareVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genVertexArrays(1, &m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays has failed"); |
| |
| gl.bindVertexArray(m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray has failed"); |
| } |
| |
| /** @brief Draw call |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::Draw() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare multisample texture using draw call. */ |
| |
| /* Prepare framebuffer with multisample texture. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed"); |
| |
| /* Use first program program. */ |
| gl.useProgram(m_po_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed"); |
| |
| /* Prepare texture to be drawn with. */ |
| gl.activeTexture(GL_TEXTURE0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.bindTexture(InputTextureTarget(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.uniform1i(gl.getUniformLocation(m_po_ms, "texture_input"), 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed"); |
| |
| for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i) |
| { |
| /* Select layer. */ |
| gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed"); |
| |
| if (D == 3) |
| { |
| gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed"); |
| } |
| |
| /* Draw. */ |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed"); |
| } |
| |
| /* Copy multisample texture to auxiliary texture using draw call. */ |
| |
| /* Prepare framebuffer with auxiliary texture. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed"); |
| |
| /* Use first program program. */ |
| gl.useProgram(m_po_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram has failed"); |
| |
| /* Prepare texture to be drawn with. */ |
| gl.activeTexture(GL_TEXTURE0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.bindTexture(MultisampleTextureTarget(), m_to_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture has failed"); |
| |
| gl.bindTextureUnit(0, m_to); |
| |
| gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_input"), 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed"); |
| |
| /* For each texture layer. */ |
| for (glw::GLuint i = 0; i < TestReferenceDataDepth(); ++i) |
| { |
| /* Select layer. */ |
| gl.drawBuffer(GL_COLOR_ATTACHMENT0 + i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed"); |
| |
| if (D == 3) |
| { |
| gl.uniform1i(gl.getUniformLocation(m_po_aux, "texture_layer"), i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i or glGetUniformLocation has failed"); |
| } |
| |
| /* Draw. */ |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays has failed"); |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanInputTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Texture. */ |
| if (m_to) |
| { |
| gl.deleteTextures(1, &m_to); |
| |
| m_to = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanAuxiliaryTexture() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_to_aux) |
| { |
| gl.deleteTextures(1, &m_to_aux); |
| |
| m_to_aux = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanFramebuffers() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Mulitsample framebuffer. */ |
| if (m_fbo_ms) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_ms); |
| |
| m_fbo_ms = 0; |
| } |
| |
| /* Mulitsample texture. */ |
| if (m_to_ms) |
| { |
| gl.deleteTextures(1, &m_to_ms); |
| |
| m_to_ms = 0; |
| } |
| |
| /* Auxiliary framebuffer. */ |
| if (m_fbo_aux) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_aux); |
| |
| m_fbo_aux = 0; |
| } |
| |
| /* Auxiliary texture. */ |
| if (m_to_aux) |
| { |
| gl.deleteTextures(1, &m_to_aux); |
| |
| m_to_aux = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanPrograms() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Binding point. */ |
| gl.useProgram(0); |
| |
| /* Multisample texture preparation program. */ |
| if (m_po_ms) |
| { |
| gl.deleteProgram(m_po_ms); |
| |
| m_po_ms = 0; |
| } |
| |
| /* Auxiliary texture preparation program. */ |
| if (m_po_aux) |
| { |
| gl.deleteProgram(m_po_aux); |
| |
| m_po_aux = 0; |
| } |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanErrors() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Query all errors until GL_NO_ERROR occure. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| void StorageMultisampleTest<T, S, N, D>::CleanVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_vao) |
| { |
| gl.bindVertexArray(0); |
| |
| gl.deleteVertexArrays(1, &m_vao); |
| |
| m_vao = 0; |
| } |
| } |
| |
| /** @brief Iterate Storage Multisample Test cases. |
| * |
| * @return Iteration result. |
| */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| tcu::TestNode::IterateResult StorageMultisampleTest<T, S, N, D>::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| PrepareVertexArray(); |
| |
| // gl.enable(GL_MULTISAMPLE); |
| |
| m_po_ms = PrepareProgram(FragmentShaderDeclarationMultisample(), FragmentShaderTail()); |
| m_po_aux = PrepareProgram(FragmentShaderDeclarationAuxiliary(), FragmentShaderTail()); |
| |
| is_ok = Test(); |
| } |
| catch (tcu::NotSupportedError& e) |
| { |
| throw e; |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanInputTexture(); |
| CleanAuxiliaryTexture(); |
| CleanFramebuffers(); |
| CleanPrograms(); |
| CleanErrors(); |
| CleanVertexArray(); |
| gl.disable(GL_MULTISAMPLE); |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /* Vertex shader source code. */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_vertex_shader = |
| "#version 450\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " switch(gl_VertexID)\n" |
| " {\n" |
| " case 0:\n" |
| " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 1:\n" |
| " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 2:\n" |
| " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 3:\n" |
| " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " }\n" |
| "}\n"; |
| |
| /* Fragment shader source program. */ |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_head = |
| "#version 450\n" |
| "\n" |
| "layout(pixel_center_integer) in vec4 gl_FragCoord;\n" |
| "\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_lowp = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_lowp = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_lowp = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_mediump = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_mediump = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_mediump = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_fdecl_highp = |
| "uniform sampler2D texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_idecl_highp = |
| "uniform isampler2D texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_2D_udecl_highp = |
| "uniform usampler2D texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_lowp = |
| "uniform sampler2DArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_lowp = |
| "uniform isampler2DArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_lowp = |
| "uniform usampler2DArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_mediump = |
| "uniform sampler2DArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_mediump = |
| "uniform isampler2DArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_mediump = |
| "uniform usampler2DArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_fdecl_highp = |
| "uniform sampler2DArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_idecl_highp = |
| "uniform isampler2DArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_ms_3D_udecl_highp = |
| "uniform usampler2DArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_lowp = |
| "uniform sampler2DMS texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_lowp = |
| "uniform isampler2DMS texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_lowp = |
| "uniform usampler2DMS texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_mediump = |
| "uniform sampler2DMS texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_mediump = |
| "uniform isampler2DMS texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_mediump = |
| "uniform usampler2DMS texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_fdecl_highp = |
| "uniform sampler2DMS texture_input;\nout vec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_idecl_highp = |
| "uniform isampler2DMS texture_input;\nout ivec4 texture_output;\n"; |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_2D_udecl_highp = |
| "uniform usampler2DMS texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_lowp = |
| "uniform sampler2DMSArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_lowp = |
| "uniform isampler2DMSArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_lowp = |
| "uniform usampler2DMSArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_mediump = |
| "uniform sampler2DMSArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_mediump = |
| "uniform isampler2DMSArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_mediump = |
| "uniform usampler2DMSArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_fdecl_highp = |
| "uniform sampler2DMSArray texture_input;\nout vec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_idecl_highp = |
| "uniform isampler2DMSArray texture_input;\nout ivec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_aux_3D_udecl_highp = |
| "uniform usampler2DMSArray texture_input;\nout uvec4 texture_output;\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_2D = |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, ivec2(gl_FragCoord.xy), 0);\n" |
| "}\n"; |
| |
| template <typename T, glw::GLint S, bool N, glw::GLuint D> |
| const glw::GLchar* StorageMultisampleTest<T, S, N, D>::s_fragment_shader_tail_3D = |
| "\n" |
| "uniform int texture_layer;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " texture_output = texelFetch(texture_input, ivec3(gl_FragCoord.xy, texture_layer), 0);\n" |
| "}\n"; |
| |
| template class StorageMultisampleTest<glw::GLbyte, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLbyte, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLbyte, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLbyte, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLbyte, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLbyte, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLubyte, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLubyte, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLubyte, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLubyte, 1, true, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 2, true, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 4, true, 2>; |
| template class StorageMultisampleTest<glw::GLubyte, 1, true, 3>; |
| template class StorageMultisampleTest<glw::GLubyte, 2, true, 3>; |
| template class StorageMultisampleTest<glw::GLubyte, 4, true, 3>; |
| |
| template class StorageMultisampleTest<glw::GLshort, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLshort, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLshort, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLshort, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLshort, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLshort, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLushort, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLushort, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLushort, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLushort, 1, true, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 2, true, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 4, true, 2>; |
| template class StorageMultisampleTest<glw::GLushort, 1, true, 3>; |
| template class StorageMultisampleTest<glw::GLushort, 2, true, 3>; |
| template class StorageMultisampleTest<glw::GLushort, 4, true, 3>; |
| |
| template class StorageMultisampleTest<glw::GLint, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLint, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLint, 3, false, 2>; |
| template class StorageMultisampleTest<glw::GLint, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLint, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLint, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLint, 3, false, 3>; |
| template class StorageMultisampleTest<glw::GLint, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLuint, 1, false, 2>; |
| template class StorageMultisampleTest<glw::GLuint, 2, false, 2>; |
| template class StorageMultisampleTest<glw::GLuint, 3, false, 2>; |
| template class StorageMultisampleTest<glw::GLuint, 4, false, 2>; |
| template class StorageMultisampleTest<glw::GLuint, 1, false, 3>; |
| template class StorageMultisampleTest<glw::GLuint, 2, false, 3>; |
| template class StorageMultisampleTest<glw::GLuint, 3, false, 3>; |
| template class StorageMultisampleTest<glw::GLuint, 4, false, 3>; |
| |
| template class StorageMultisampleTest<glw::GLfloat, 1, true, 2>; |
| template class StorageMultisampleTest<glw::GLfloat, 2, true, 2>; |
| template class StorageMultisampleTest<glw::GLfloat, 3, true, 2>; |
| template class StorageMultisampleTest<glw::GLfloat, 4, true, 2>; |
| template class StorageMultisampleTest<glw::GLfloat, 1, true, 3>; |
| template class StorageMultisampleTest<glw::GLfloat, 2, true, 3>; |
| template class StorageMultisampleTest<glw::GLfloat, 3, true, 3>; |
| template class StorageMultisampleTest<glw::GLfloat, 4, true, 3>; |
| |
| /******************************** Compressed SubImage Test Implementation ********************************/ |
| |
| /* Compressed m_reference data for unsupported compression formats */ |
| |
| static const unsigned char data_0x8dbb_2D_8[] = { |
| 34, 237, 94, 207, |
| 252, 29, 75, 25 |
| }; |
| |
| static const unsigned char data_0x8dbb_3D_32[] = { |
| 34, 237, 94, 207, |
| 252, 29, 75, 25, |
| 34, 237, 44, 173, |
| 101, 230, 139, 254, |
| 34, 237, 176, 88, |
| 174, 127, 248, 206, |
| 34, 237, 127, 209, |
| 211, 203, 100, 150 |
| }; |
| |
| static const unsigned char data_0x8dbc_2D_8[] = { |
| 127, 0, 233, 64, |
| 0, 42, 71, 231 |
| }; |
| |
| static const unsigned char data_0x8dbc_3D_32[] = { |
| 127, 0, 233, 64, |
| 0, 42, 71, 231, |
| 127, 0, 20, 227, |
| 162, 33, 246, 1, |
| 127, 0, 143, 57, |
| 86, 0, 136, 53, |
| 127, 0, 192, 62, |
| 48, 69, 29, 138 |
| }; |
| |
| static const unsigned char data_0x8dbd_2D_16[] = { |
| 34, 237, 94, 207, |
| 252, 29, 75, 25, |
| 28, 242, 94, 111, |
| 44, 101, 35, 145 |
| }; |
| |
| static const unsigned char data_0x8dbd_3D_64[] = { |
| 34, 237, 94, 207, |
| 252, 29, 75, 25, |
| 28, 242, 94, 111, |
| 44, 101, 35, 145, |
| 34, 237, 44, 173, |
| 101, 230, 139, 254, |
| 28, 242, 170, 45, |
| 98, 236, 202, 228, |
| 34, 237, 176, 88, |
| 174, 127, 248, 206, |
| 28, 242, 164, 148, |
| 178, 25, 252, 206, |
| 34, 237, 127, 209, |
| 211, 203, 100, 150, |
| 28, 242, 79, 216, |
| 149, 3, 101, 87 |
| }; |
| |
| static const unsigned char data_0x8dbe_2D_16[] = { |
| 127, 0, 233, 64, |
| 0, 42, 71, 231, |
| 127, 0, 233, 144, |
| 23, 163, 100, 115 |
| }; |
| |
| static const unsigned char data_0x8dbe_3D_64[] = { |
| 127, 0, 233, 64, |
| 0, 42, 71, 231, |
| 127, 0, 233, 144, |
| 23, 163, 100, 115, |
| 127, 0, 20, 227, |
| 162, 33, 246, 1, |
| 127, 0, 94, 98, |
| 190, 84, 55, 1, |
| 127, 0, 143, 57, |
| 86, 0, 136, 53, |
| 127, 0, 163, 45, |
| 113, 232, 131, 53, |
| 127, 0, 192, 62, |
| 48, 69, 29, 138, |
| 127, 0, 128, 182, |
| 138, 61, 157, 204 |
| }; |
| |
| static const unsigned char data_0x8e8c_2D_16[] = { |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 89, 143, |
| 140, 166, 183, 113 |
| }; |
| |
| static const unsigned char data_0x8e8c_3D_64[] = { |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 89, 143, |
| 140, 166, 183, 113, |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 55, 48, |
| 102, 244, 186, 241, |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 231, 54, |
| 211, 92, 240, 14, |
| 144, 121, 253, 241, |
| 193, 15, 152, 153, |
| 153, 153, 25, 41, |
| 102, 244, 248, 135 |
| }; |
| |
| static const unsigned char data_0x8e8d_2D_16[] = { |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 89, 143, |
| 140, 166, 183, 113 |
| }; |
| |
| static const unsigned char data_0x8e8d_3D_64[] = { |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 89, 143, |
| 140, 166, 183, 113, |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 55, 48, |
| 102, 244, 186, 241, |
| 144, 43, 143, 15, |
| 254, 15, 152, 153, |
| 153, 153, 231, 54, |
| 211, 92, 240, 14, |
| 144, 121, 253, 241, |
| 193, 15, 152, 153, |
| 153, 153, 25, 41, |
| 102, 244, 248, 135 |
| }; |
| |
| static const unsigned char data_0x8e8e_2D_16[] = { |
| 67, 155, 82, 120, |
| 142, 7, 31, 124, |
| 224, 255, 165, 221, |
| 239, 223, 122, 223 |
| }; |
| |
| static const unsigned char data_0x8e8e_3D_64[] = { |
| 67, 155, 82, 120, |
| 142, 7, 31, 124, |
| 224, 255, 165, 221, |
| 239, 223, 122, 223, |
| 35, 30, 124, 240, |
| 209, 166, 20, 158, |
| 11, 250, 24, 21, |
| 0, 2, 34, 2, |
| 35, 30, 124, 240, |
| 209, 166, 20, 158, |
| 5, 88, 2, 1, |
| 34, 165, 0, 241, |
| 35, 30, 124, 240, |
| 209, 166, 20, 158, |
| 33, 34, 32, 0, |
| 81, 129, 175, 80 |
| }; |
| |
| static const unsigned char data_0x8e8f_2D_16[] = { |
| 131, 54, 165, 148, |
| 26, 47, 62, 248, |
| 176, 254, 149, 203, |
| 222, 206, 187, 173 |
| }; |
| |
| static const unsigned char data_0x8e8f_3D_64[] = { |
| 131, 54, 165, 148, |
| 26, 47, 62, 248, |
| 176, 254, 149, 203, |
| 222, 206, 187, 173, |
| 99, 188, 248, 224, |
| 163, 77, 41, 165, |
| 24, 250, 36, 70, |
| 18, 20, 53, 3, |
| 99, 188, 248, 224, |
| 163, 77, 41, 165, |
| 42, 68, 19, 18, |
| 67, 166, 16, 244, |
| 99, 188, 248, 224, |
| 163, 77, 41, 165, |
| 48, 83, 65, 33, |
| 100, 66, 175, 65 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_R11_EAC_2D_8[] = { |
| 146, 253, 99, 81, |
| 202, 222, 63, 243 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_R11_EAC_3D_32[] = { |
| 146, 253, 99, 81, |
| 202, 222, 63, 243, |
| 146, 253, 169, 188, |
| 102, 31, 246, 55, |
| 146, 253, 123, 247, |
| 62, 71, 139, 131, |
| 146, 253, 248, 63, |
| 248, 208, 230, 213 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RG11_EAC_2D_16[] = { |
| 146, 253, 99, 81, |
| 202, 222, 63, 243, |
| 140, 254, 110, 0, |
| 160, 130, 207, 180 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RG11_EAC_3D_64[] = { |
| 146, 253, 99, 81, |
| 202, 222, 63, 243, |
| 140, 254, 110, 0, |
| 160, 130, 207, 180, |
| 146, 253, 169, 188, |
| 102, 31, 246, 55, |
| 140, 254, 2, 73, |
| 46, 104, 102, 39, |
| 146, 253, 123, 247, |
| 62, 71, 139, 131, |
| 140, 254, 155, 121, |
| 68, 17, 1, 27, |
| 146, 253, 248, 63, |
| 248, 208, 230, 213, |
| 140, 254, 240, 60, |
| 19, 214, 73, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_2D_8[] = { |
| 168, 122, 150, 252, |
| 234, 35, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGB8_ETC2_3D_32[] = { |
| 168, 122, 150, 252, |
| 234, 35, 0, 0, |
| 168, 122, 150, 253, |
| 31, 140, 0, 0, |
| 138, 167, 105, 252, |
| 196, 87, 0, 0, |
| 138, 167, 105, 253, |
| 49, 248, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = { |
| 83, 83, 75, 252, |
| 240, 240, 15, 4 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = { |
| 83, 83, 75, 252, |
| 240, 240, 15, 4, |
| 107, 99, 99, 253, |
| 240, 240, 14, 15, |
| 135, 135, 135, 252, |
| 240, 240, 15, 15, |
| 108, 108, 108, 253, |
| 240, 248, 11, 11 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16[] = { |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 168, 122, 150, 252, |
| 234, 35, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64[] = { |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 168, 122, 150, 252, |
| 234, 35, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 168, 122, 150, 253, |
| 31, 140, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 138, 167, 105, 252, |
| 196, 87, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 138, 167, 105, 253, |
| 49, 248, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8[] = { |
| 73, 221, 99, 81, |
| 201, 222, 63, 241 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32[] = { |
| 73, 221, 99, 81, |
| 201, 222, 63, 241, |
| 73, 221, 165, 156, |
| 102, 31, 246, 55, |
| 73, 221, 59, 247, |
| 62, 39, 139, 131, |
| 73, 221, 248, 63, |
| 248, 208, 226, 205 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16[] = { |
| 73, 221, 99, 81, |
| 201, 222, 63, 241, |
| 66, 191, 110, 0, |
| 96, 131, 77, 180 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64[] = { |
| 73, 221, 99, 81, |
| 201, 222, 63, 241, |
| 66, 191, 110, 0, |
| 96, 131, 77, 180, |
| 73, 221, 165, 156, |
| 102, 31, 246, 55, |
| 66, 191, 2, 73, |
| 54, 100, 102, 38, |
| 73, 221, 59, 247, |
| 62, 39, 139, 131, |
| 66, 191, 155, 105, |
| 132, 16, 129, 27, |
| 73, 221, 248, 63, |
| 248, 208, 226, 205, |
| 66, 191, 208, 60, |
| 11, 218, 73, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16[] = { |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 150, 122, 168, 252, |
| 234, 35, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64[] = { |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 150, 122, 168, 252, |
| 234, 35, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 150, 122, 168, 253, |
| 31, 140, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 105, 167, 138, 252, |
| 196, 87, 0, 0, |
| 127, 245, 255, 244, |
| 146, 255, 244, 146, |
| 105, 167, 138, 253, |
| 49, 248, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_2D_8[] = { |
| 168, 122, 150, 252, |
| 234, 35, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_ETC2_3D_32[] = { |
| 168, 122, 150, 252, |
| 234, 35, 0, 0, |
| 168, 122, 150, 253, |
| 31, 140, 0, 0, |
| 138, 167, 105, 252, |
| 196, 87, 0, 0, |
| 138, 167, 105, 253, |
| 49, 248, 0, 0 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8[] = { |
| 75, 83, 83, 252, |
| 240, 240, 15, 4 |
| }; |
| |
| static const unsigned char data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32[] = { |
| 75, 83, 83, 252, |
| 240, 240, 15, 4, |
| 99, 99, 107, 253, |
| 240, 240, 14, 15, |
| 135, 135, 135, 252, |
| 240, 240, 15, 15, |
| 108, 108, 108, 253, |
| 240, 248, 11, 11 |
| }; |
| |
| /** @brief Compressed SubImage Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| CompressedSubImageTest::CompressedSubImageTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_compressed_subimage", "Texture Compressed SubImage Test") |
| , m_to(0) |
| , m_to_aux(0) |
| , m_compressed_texture_data(DE_NULL) |
| , m_reference(DE_NULL) |
| , m_result(DE_NULL) |
| , m_reference_size(0) |
| , m_reference_internalformat(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Create texture. |
| * |
| * @param [in] target Texture target. |
| */ |
| void CompressedSubImageTest::CreateTextures(glw::GLenum target) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Auxiliary texture (for content creation). */ |
| gl.genTextures(1, &m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(target, m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| /* Test texture (for data upload). */ |
| gl.genTextures(1, &m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(target, m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| } |
| |
| /** @brief Texture target selector. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return Texture target. |
| */ |
| template <> |
| glw::GLenum CompressedSubImageTest::TextureTarget<1>() |
| { |
| return GL_TEXTURE_1D; |
| } |
| |
| template <> |
| glw::GLenum CompressedSubImageTest::TextureTarget<2>() |
| { |
| return GL_TEXTURE_2D; |
| } |
| |
| template <> |
| glw::GLenum CompressedSubImageTest::TextureTarget<3>() |
| { |
| return GL_TEXTURE_2D_ARRAY; |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @note parameters as passed to texImage* |
| * |
| * @return False if the internal format is unsupported for online compression, True otherwise |
| */ |
| template <> |
| bool CompressedSubImageTest::TextureImage<1>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data); |
| |
| /* Online compression may be unsupported for some formats */ |
| GLenum error = gl.getError(); |
| if (error == GL_INVALID_OPERATION) |
| return false; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @note parameters as passed to texImage* |
| * |
| * @return False if the internal format is unsupported for online compression, True otherwise |
| */ |
| template <> |
| bool CompressedSubImageTest::TextureImage<2>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, s_texture_data); |
| |
| /* Online compression may be unsupported for some formats */ |
| GLenum error = gl.getError(); |
| if (error == GL_INVALID_OPERATION) |
| return false; |
| |
| GLU_EXPECT_NO_ERROR(error, "glTexImage2D has failed"); |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @note parameters as passed to texImage* |
| * |
| * @return False if the internal format is unsupported for online compression, True otherwise |
| */ |
| template <> |
| bool CompressedSubImageTest::TextureImage<3>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, s_texture_data); |
| |
| /* Online compression may be unsupported for some formats */ |
| GLenum error = gl.getError(); |
| if (error == GL_INVALID_OPERATION) |
| return false; |
| |
| GLU_EXPECT_NO_ERROR(error, "glTexImage3D has failed"); |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimensions. |
| * |
| * @note parameters as passed to compressedTexImage* |
| */ |
| template <> |
| void CompressedSubImageTest::CompressedTexImage<1>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width, 0, m_reference_size, |
| m_compressed_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed"); |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimensions. |
| * |
| * @note parameters as passed to compressedTexImage* |
| */ |
| template <> |
| void CompressedSubImageTest::CompressedTexImage<2>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width, s_texture_height, 0, |
| m_reference_size, m_compressed_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed"); |
| } |
| |
| /** @brief Prepare texture data for the auxiliary texture. |
| * |
| * @tparam D Texture dimensions. |
| * |
| * @note parameters as passed to compressedTexImage* |
| */ |
| template <> |
| void CompressedSubImageTest::CompressedTexImage<3>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width, s_texture_height, s_texture_depth, |
| 0, m_reference_size, m_compressed_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed"); |
| } |
| |
| /** @brief Prepare texture data for the compressed texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return True if tested function succeeded, false otherwise. |
| */ |
| template <> |
| bool CompressedSubImageTest::CompressedTextureSubImage<1>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Load texture image with tested function. */ |
| if (m_reference_size) |
| { |
| for (glw::GLuint block = 0; block < s_block_count; ++block) |
| { |
| gl.compressedTextureSubImage1D(m_to, 0, s_texture_width * block, s_texture_width, internalformat, |
| m_reference_size, m_compressed_texture_data); |
| } |
| } |
| else |
| { |
| /* For 1D version there is no specific compressed texture internal format spcified in OpenGL 4.5 core profile documentation. |
| Only implementation depended specific internalformats may provide this functionality. As a result there may be no reference data to be substituted. |
| Due to this reason there is no use of CompressedTextureSubImage1D and particulary it cannot be tested. */ |
| return true; |
| } |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCompressedTextureSubImage1D unexpectedly generated error " |
| << glu::getErrorStr(error) << " during the test with internal format " |
| << glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture data for the compressed texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @param [in] internalformat Texture internal format. |
| * |
| * @return True if tested function succeeded, false otherwise. |
| */ |
| template <> |
| bool CompressedSubImageTest::CompressedTextureSubImage<2>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| for (glw::GLuint y = 0; y < s_block_2d_size_y; ++y) |
| { |
| for (glw::GLuint x = 0; x < s_block_2d_size_x; ++x) |
| { |
| /* Load texture image with tested function. */ |
| gl.compressedTextureSubImage2D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_width, |
| s_texture_height, internalformat, m_reference_size, |
| m_compressed_texture_data); |
| } |
| } |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error " |
| << glu::getErrorStr(error) << " during the test with internal format " |
| << glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture data for the compressed texture. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @param [in] internalformat Texture internal format. |
| * |
| * @return True if tested function succeeded, false otherwise. |
| */ |
| template <> |
| bool CompressedSubImageTest::CompressedTextureSubImage<3>(glw::GLint internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| for (glw::GLuint z = 0; z < s_block_3d_size; ++z) |
| { |
| for (glw::GLuint y = 0; y < s_block_3d_size; ++y) |
| { |
| for (glw::GLuint x = 0; x < s_block_3d_size; ++x) |
| { |
| /* Load texture image with tested function. */ |
| gl.compressedTextureSubImage3D(m_to, 0, s_texture_width * x, s_texture_height * y, s_texture_depth * z, |
| s_texture_width, s_texture_height, s_texture_depth, internalformat, |
| m_reference_size, m_compressed_texture_data); |
| } |
| } |
| } |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCompressedTextureSubImage2D unexpectedly generated error " |
| << glu::getErrorStr(error) << " during the test with internal format " |
| << glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| return true; |
| } |
| |
| struct CompressedData |
| { |
| glw::GLenum iformat; |
| const unsigned char *data; |
| int data_size; |
| int dimensions; |
| }; |
| |
| static CompressedData compressed_images[] = |
| { |
| /* 2D images */ |
| |
| {GL_COMPRESSED_RED_RGTC1, data_0x8dbb_2D_8, sizeof data_0x8dbb_2D_8, 2}, |
| {GL_COMPRESSED_SIGNED_RED_RGTC1, data_0x8dbc_2D_8, sizeof data_0x8dbc_2D_8, 2}, |
| {GL_COMPRESSED_RG_RGTC2, data_0x8dbd_2D_16, sizeof data_0x8dbd_2D_16, 2}, |
| {GL_COMPRESSED_SIGNED_RG_RGTC2, data_0x8dbe_2D_16, sizeof data_0x8dbe_2D_16, 2}, |
| {GL_COMPRESSED_RGBA_BPTC_UNORM, data_0x8e8c_2D_16, sizeof data_0x8e8c_2D_16, 2}, |
| {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, data_0x8e8d_2D_16, sizeof data_0x8e8d_2D_16, 2}, |
| {GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, data_0x8e8e_2D_16, sizeof data_0x8e8e_2D_16, 2}, |
| {GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, data_0x8e8f_2D_16, sizeof data_0x8e8f_2D_16, 2}, |
| {GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_2D_8, |
| sizeof data_GL_COMPRESSED_RGB8_ETC2_2D_8, 2}, |
| {GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_2D_8, |
| sizeof data_GL_COMPRESSED_SRGB8_ETC2_2D_8, 2}, |
| {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, |
| sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2}, |
| {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, |
| sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_2D_8, 2}, |
| {GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16, |
| sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_2D_16, 2}, |
| {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16, |
| sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_2D_16, 2}, |
| {GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_2D_8, |
| sizeof data_GL_COMPRESSED_R11_EAC_2D_8, 2}, |
| {GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8, |
| sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_2D_8, 2}, |
| {GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_2D_16, |
| sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2}, |
| {GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, |
| sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_2D_16, 2}, |
| |
| /* 3D images */ |
| |
| {0x8dbb, data_0x8dbb_3D_32, sizeof data_0x8dbb_3D_32, 3}, |
| {0x8dbc, data_0x8dbc_3D_32, sizeof data_0x8dbc_3D_32, 3}, |
| {0x8dbd, data_0x8dbd_3D_64, sizeof data_0x8dbd_3D_64, 3}, |
| {0x8dbe, data_0x8dbe_3D_64, sizeof data_0x8dbe_3D_64, 3}, |
| {0x8e8c, data_0x8e8c_3D_64, sizeof data_0x8e8c_3D_64, 3}, |
| {0x8e8d, data_0x8e8d_3D_64, sizeof data_0x8e8d_3D_64, 3}, |
| {0x8e8e, data_0x8e8e_3D_64, sizeof data_0x8e8e_3D_64, 3}, |
| {0x8e8f, data_0x8e8f_3D_64, sizeof data_0x8e8f_3D_64, 3}, |
| {GL_COMPRESSED_RGB8_ETC2, data_GL_COMPRESSED_RGB8_ETC2_3D_32, |
| sizeof data_GL_COMPRESSED_RGB8_ETC2_3D_32, 3}, |
| {GL_COMPRESSED_SRGB8_ETC2, data_GL_COMPRESSED_SRGB8_ETC2_3D_32, |
| sizeof data_GL_COMPRESSED_SRGB8_ETC2_3D_32, 3}, |
| {GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, |
| sizeof data_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3}, |
| {GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, |
| sizeof data_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2_3D_32, 3}, |
| {GL_COMPRESSED_R11_EAC, data_GL_COMPRESSED_R11_EAC_3D_32, |
| sizeof data_GL_COMPRESSED_R11_EAC_3D_32, 3}, |
| {GL_COMPRESSED_SIGNED_R11_EAC, data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32, |
| sizeof data_GL_COMPRESSED_SIGNED_R11_EAC_3D_32, 3}, |
| |
| {GL_COMPRESSED_RGBA8_ETC2_EAC, data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64, |
| sizeof data_GL_COMPRESSED_RGBA8_ETC2_EAC_3D_64, 3}, |
| {GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64, |
| sizeof data_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC_3D_64, 3}, |
| {GL_COMPRESSED_RG11_EAC, data_GL_COMPRESSED_RG11_EAC_3D_64, |
| sizeof data_GL_COMPRESSED_RG11_EAC_3D_64, 3}, |
| {GL_COMPRESSED_SIGNED_RG11_EAC, data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64, |
| sizeof data_GL_COMPRESSED_SIGNED_RG11_EAC_3D_64, 3} |
| }; |
| |
| /** @brief Prepare the reference data. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return False if the internal format is unsupported for online compression, True otherwise |
| */ |
| template <glw::GLuint D> |
| bool CompressedSubImageTest::PrepareReferenceData(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Using OpenGL to compress raw data. */ |
| gl.bindTexture(TextureTarget<D>(), m_to_aux); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| glw::GLint is_compressed_texture = 0; |
| glw::GLint compressed_texture_size = 0; |
| |
| /* Sanity checks. */ |
| if ((DE_NULL != m_reference) || (DE_NULL != m_compressed_texture_data)) |
| { |
| throw 0; |
| } |
| |
| /* "if" path is taken when there is no support for online compression for the format |
| * and we upload compressed data directly */ |
| if (!TextureImage<D>(internalformat)) |
| { |
| for (unsigned int i=0; i<sizeof compressed_images / sizeof *compressed_images; i++) |
| { |
| if (internalformat == compressed_images[i].iformat |
| && D == compressed_images[i].dimensions) |
| { |
| is_compressed_texture = 1; |
| compressed_texture_size = compressed_images[i].data_size; |
| |
| m_reference_size = compressed_texture_size; |
| m_reference_internalformat = compressed_images[i].iformat; |
| |
| m_reference = new glw::GLubyte[compressed_texture_size]; |
| m_compressed_texture_data = new glw::GLubyte[compressed_texture_size]; |
| |
| memcpy(m_reference, compressed_images[i].data, compressed_texture_size); |
| memcpy(m_compressed_texture_data, compressed_images[i].data, compressed_texture_size); |
| } |
| } |
| |
| if (!is_compressed_texture) |
| return false; |
| |
| PrepareCompressedStorage<D>(m_reference_internalformat); |
| } |
| else |
| { |
| /* Check that really compressed texture. */ |
| gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED, &is_compressed_texture); |
| |
| if (is_compressed_texture) |
| { |
| /* Query texture size. */ |
| gl.getTexLevelParameteriv(TextureTarget<D>(), 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compressed_texture_size); |
| |
| /* If compressed then download. */ |
| if (compressed_texture_size) |
| { |
| /* Prepare storage. */ |
| m_compressed_texture_data = new glw::GLubyte[compressed_texture_size]; |
| |
| if (DE_NULL != m_compressed_texture_data) |
| { |
| m_reference_size = compressed_texture_size; |
| } |
| else |
| { |
| throw 0; |
| } |
| |
| /* Download the source compressed texture image. */ |
| gl.getCompressedTexImage(TextureTarget<D>(), 0, m_compressed_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| // Upload the source compressed texture image to the texture object. |
| // Some compressed texture format can be emulated by the driver (like the ETC2/EAC formats) |
| // The compressed data sent by CompressedTexImage will be stored uncompressed by the driver |
| // and will be re-compressed if the application call glGetCompressedTexImage. |
| // The compression/decompression is not lossless, so when this happen it's possible for the source |
| // and destination (from glGetCompressedTexImage) compressed data to be different. |
| // To avoid that we will store both the source (in m_compressed_texture_data) and the destination |
| // (in m_reference). The destination will be used later to make sure getCompressedTextureSubImage |
| // return the expected value |
| CompressedTexImage<D>(internalformat); |
| |
| m_reference = new glw::GLubyte[m_reference_size]; |
| |
| if (DE_NULL == m_reference) |
| { |
| throw 0; |
| } |
| |
| /* Download compressed texture image. */ |
| gl.getCompressedTexImage(TextureTarget<D>(), 0, m_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| } |
| } |
| |
| PrepareStorage<D>(internalformat); |
| } |
| |
| return true; |
| } |
| |
| /** @brief Prepare texture storage. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @param [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareStorage<1>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<1>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| } |
| |
| /** @brief Prepare texture storage. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @param [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareStorage<2>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<2>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(TextureTarget<2>(), 0, internalformat, s_texture_width * s_block_2d_size_x, |
| s_texture_height * s_block_2d_size_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| } |
| |
| /** @brief Prepare texture storage. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @param [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareStorage<3>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<3>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage3D(TextureTarget<3>(), 0, internalformat, s_texture_width * s_block_3d_size, |
| s_texture_height * s_block_3d_size, s_texture_depth * s_block_3d_size, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| } |
| |
| /** @brief Prepare compressed texture storage. |
| * @tparam D Texture dimensions. |
| * |
| * @tparam [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareCompressedStorage<1>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions &gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<1>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.compressedTexImage1D(TextureTarget<1>(), 0, internalformat, s_texture_width * s_block_count, |
| 0, s_texture_width * s_block_count, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage1D has failed"); |
| } |
| |
| /** @brief Prepare compressed texture storage. |
| * @tparam D Texture dimensions. |
| * |
| * @tparam [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareCompressedStorage<2>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions &gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<2>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| GLsizei size_x = s_texture_width * s_block_2d_size_x; |
| GLsizei size_y = s_texture_height * s_block_2d_size_y; |
| GLsizei size = m_reference_size * s_block_2d_size_x * s_block_2d_size_y; |
| |
| gl.compressedTexImage2D(TextureTarget<2>(), 0, internalformat, size_x, size_y, |
| 0, size, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed"); |
| } |
| |
| /** @brief Prepare compressed texture storage. |
| * @tparam D Texture dimensions. |
| * |
| * @tparam [in] internalformat Texture internal format. |
| */ |
| template <> |
| void CompressedSubImageTest::PrepareCompressedStorage<3>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions &gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.bindTexture(TextureTarget<3>(), m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| GLsizei size_x = s_texture_width * s_block_3d_size; |
| GLsizei size_y = s_texture_height * s_block_3d_size; |
| GLsizei size_z = s_texture_depth * s_block_3d_size; |
| GLsizei size = m_reference_size * s_block_3d_size * s_block_3d_size * s_block_3d_size; |
| |
| gl.compressedTexImage3D(TextureTarget<3>(), 0, internalformat, size_x, size_y, size_z, 0, |
| size, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage3D has failed"); |
| } |
| |
| /** @brief Compare results with the reference. |
| * |
| * @tparam T Type. |
| * @tparam S Size (# of components). |
| * @tparam N Is normalized. |
| * |
| * @param [in] internalformat Texture internal format. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| template <glw::GLuint D> |
| bool CompressedSubImageTest::CheckData(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Check texture content with reference. */ |
| m_result = new glw::GLubyte[m_reference_size * s_block_count]; |
| |
| if (DE_NULL == m_result) |
| { |
| throw 0; |
| } |
| |
| gl.getCompressedTexImage(TextureTarget<D>(), 0, m_result); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| for (glw::GLuint block = 0; block < s_block_count; ++block) |
| { |
| for (glw::GLuint i = 0; i < m_reference_size; ++i) |
| { |
| if (m_reference[i] != m_result[block * m_reference_size + i]) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCompressedTextureSubImage*D created texture with data " |
| << DataToString(m_reference_size, m_reference) << " however texture contains data " |
| << DataToString(m_reference_size, &(m_result[block * m_reference_size])) << ". Texture target was " |
| << glu::getTextureTargetStr(TextureTarget<D>()) << " and internal format was " |
| << glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare results with the reference. |
| * |
| * @tparam T Type. |
| * @tparam S Size (# of components). |
| * @tparam N Is normalized. |
| * |
| * @param [in] internalformat Texture internal format. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| template <> |
| bool CompressedSubImageTest::CheckData<3>(glw::GLenum internalformat) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Check texture content with reference. */ |
| m_result = new glw::GLubyte[m_reference_size * s_block_count]; |
| |
| if (DE_NULL == m_result) |
| { |
| throw 0; |
| } |
| |
| gl.getCompressedTexImage(TextureTarget<3>(), 0, m_result); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| glw::GLuint reference_layer_size = m_reference_size / s_texture_depth; |
| |
| for (glw::GLuint i = 0; i < m_reference_size * s_block_count; ++i) |
| { |
| // we will read the result one bytes at the time and compare with the reference |
| // for each bytes of the result image we need to figure out which byte in the reference image it corresponds to |
| glw::GLuint refIdx = i % reference_layer_size; |
| glw::GLuint refLayerIdx = (i / (reference_layer_size * s_block_3d_size * s_block_3d_size)) % s_texture_depth; |
| if (m_reference[refLayerIdx * reference_layer_size + refIdx] != m_result[i]) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCompressedTextureSubImage3D created texture with data " |
| << DataToString(reference_layer_size, &(m_reference[refLayerIdx * reference_layer_size])) |
| << " however texture contains data " |
| << DataToString(reference_layer_size, &(m_result[i % reference_layer_size])) << ". Texture target was " |
| << glu::getTextureTargetStr(TextureTarget<3>()) << " and internal format was " |
| << glu::getTextureFormatStr(internalformat) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| /** @brief Test case function. |
| * |
| * @tparam D Number of texture dimensions. |
| * |
| * @param [in] internal format Texture internal format. |
| * |
| * @param [in] can be unsupported If the format may not support online compression |
| * |
| * @return True if test succeeded, false otherwise. |
| */ |
| template <glw::GLuint D> |
| bool CompressedSubImageTest::Test(glw::GLenum internalformat, bool can_be_unsupported) |
| { |
| /* Create texture image. */ |
| CreateTextures(TextureTarget<D>()); |
| |
| if (!PrepareReferenceData<D>(internalformat)) |
| { |
| CleanAll(); |
| return can_be_unsupported; |
| } |
| |
| /* Setup data with CompressedTextureSubImage<D>D function and check for errors. */ |
| if (!CompressedTextureSubImage<D>(internalformat)) |
| { |
| CleanAll(); |
| |
| return false; |
| } |
| |
| /* If compressed reference data was generated than compare values. */ |
| if (m_reference) |
| { |
| if (!CheckData<D>(internalformat)) |
| { |
| CleanAll(); |
| |
| return false; |
| } |
| } |
| |
| CleanAll(); |
| |
| return true; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void CompressedSubImageTest::CleanAll() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Textures. */ |
| if (m_to) |
| { |
| gl.deleteTextures(1, &m_to); |
| |
| m_to = 0; |
| } |
| |
| if (m_to_aux) |
| { |
| gl.deleteTextures(1, &m_to_aux); |
| |
| m_to_aux = 0; |
| } |
| |
| /* Reference data storage. */ |
| if (DE_NULL != m_reference) |
| { |
| delete[] m_reference; |
| |
| m_reference = DE_NULL; |
| } |
| |
| if (DE_NULL != m_compressed_texture_data) |
| { |
| delete[] m_compressed_texture_data; |
| |
| m_compressed_texture_data = DE_NULL; |
| } |
| |
| if (DE_NULL != m_result) |
| { |
| delete[] m_result; |
| |
| m_result = DE_NULL; |
| } |
| |
| m_reference_size = 0; |
| |
| /* Errors. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Convert raw data into string for logging purposes. |
| * |
| * @param [in] count Count of the data. |
| * @param [in] data Raw data. |
| * |
| * @return String representation of data. |
| */ |
| std::string CompressedSubImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[]) |
| { |
| std::string data_str = "["; |
| |
| for (glw::GLuint i = 0; i < count; ++i) |
| { |
| std::stringstream int_sstream; |
| |
| int_sstream << unsigned(data[i]); |
| |
| data_str.append(int_sstream.str()); |
| |
| if (i + 1 < count) |
| { |
| data_str.append(", "); |
| } |
| else |
| { |
| data_str.append("]"); |
| } |
| } |
| |
| return data_str; |
| } |
| |
| /** @brief Iterate Compressed SubImage Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult CompressedSubImageTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| is_ok &= Test<1>(GL_COMPRESSED_RGB, false); |
| |
| is_ok &= Test<2>(GL_COMPRESSED_RED_RGTC1, false); |
| is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RED_RGTC1, false); |
| is_ok &= Test<2>(GL_COMPRESSED_RG_RGTC2, false); |
| is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG_RGTC2, false); |
| is_ok &= Test<2>(GL_COMPRESSED_RGBA_BPTC_UNORM, false); |
| is_ok &= Test<2>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false); |
| is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false); |
| is_ok &= Test<2>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false); |
| is_ok &= Test<2>(GL_COMPRESSED_RGB8_ETC2, true); |
| is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ETC2, true); |
| is_ok &= Test<2>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true); |
| is_ok &= Test<2>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true); |
| is_ok &= Test<2>(GL_COMPRESSED_RGBA8_ETC2_EAC, true); |
| is_ok &= Test<2>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true); |
| is_ok &= Test<2>(GL_COMPRESSED_R11_EAC, true); |
| is_ok &= Test<2>(GL_COMPRESSED_SIGNED_R11_EAC, true); |
| is_ok &= Test<2>(GL_COMPRESSED_RG11_EAC, true); |
| is_ok &= Test<2>(GL_COMPRESSED_SIGNED_RG11_EAC, true); |
| |
| is_ok &= Test<3>(GL_COMPRESSED_RED_RGTC1, false); |
| is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RED_RGTC1, false); |
| is_ok &= Test<3>(GL_COMPRESSED_RG_RGTC2, false); |
| is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG_RGTC2, false); |
| is_ok &= Test<3>(GL_COMPRESSED_RGBA_BPTC_UNORM, false); |
| is_ok &= Test<3>(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, false); |
| is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, false); |
| is_ok &= Test<3>(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, false); |
| is_ok &= Test<3>(GL_COMPRESSED_RGB8_ETC2, true); |
| is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ETC2, true); |
| is_ok &= Test<3>(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, true); |
| is_ok &= Test<3>(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, true); |
| is_ok &= Test<3>(GL_COMPRESSED_RGBA8_ETC2_EAC, true); |
| is_ok &= Test<3>(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, true); |
| is_ok &= Test<3>(GL_COMPRESSED_R11_EAC, true); |
| is_ok &= Test<3>(GL_COMPRESSED_SIGNED_R11_EAC, true); |
| is_ok &= Test<3>(GL_COMPRESSED_RG11_EAC, true); |
| is_ok &= Test<3>(GL_COMPRESSED_SIGNED_RG11_EAC, true); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanAll(); |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte CompressedSubImageTest::s_texture_data[] = { |
| 0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00, |
| 0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00, |
| 0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00, |
| 0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00, |
| |
| 0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00, |
| 0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00, |
| 0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00, |
| 0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, |
| |
| 0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00, |
| 0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00, |
| 0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00, |
| 0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, |
| |
| 0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00, |
| 0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00, |
| 0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00, |
| 0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00 |
| }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint CompressedSubImageTest::s_texture_width = 4; |
| const glw::GLuint CompressedSubImageTest::s_texture_height = 4; |
| const glw::GLuint CompressedSubImageTest::s_texture_depth = 4; |
| const glw::GLuint CompressedSubImageTest::s_block_count = 8; |
| const glw::GLuint CompressedSubImageTest::s_block_2d_size_x = 4; |
| const glw::GLuint CompressedSubImageTest::s_block_2d_size_y = 2; |
| const glw::GLuint CompressedSubImageTest::s_block_3d_size = 2; |
| |
| /******************************** Copy SubImage Test Implementation ********************************/ |
| |
| /** @brief Compressed SubImage Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| CopyTest::CopyTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_copy", "Texture Copy Test") |
| , m_fbo(0) |
| , m_to_src(0) |
| , m_to_dst(0) |
| , m_result(DE_NULL) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Texture target selector. |
| * |
| * @tparam D Texture dimenisons. |
| * |
| * @return Texture target. |
| */ |
| template <> |
| glw::GLenum CopyTest::TextureTarget<1>() |
| { |
| return GL_TEXTURE_1D; |
| } |
| template <> |
| glw::GLenum CopyTest::TextureTarget<2>() |
| { |
| return GL_TEXTURE_2D; |
| } |
| template <> |
| glw::GLenum CopyTest::TextureTarget<3>() |
| { |
| return GL_TEXTURE_3D; |
| } |
| |
| /** @brief Copy texture, check errors and log. |
| * |
| * @note Parameters as passed to CopyTextureSubImage*D |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool CopyTest::CopyTextureSubImage1DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset, |
| glw::GLint x, glw::GLint y, glw::GLsizei width) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| gl.copyTextureSubImage1D(texture, level, xoffset, x, y, width); |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message |
| << "glCopyTextureSubImage1D unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Copy texture, check errors and log. |
| * |
| * @note Parameters as passed to CopyTextureSubImage*D |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool CopyTest::CopyTextureSubImage2DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset, |
| glw::GLint yoffset, glw::GLint x, glw::GLint y, glw::GLsizei width, |
| glw::GLsizei height) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| gl.copyTextureSubImage2D(texture, level, xoffset, yoffset, x, y, width, height); |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message |
| << "glCopyTextureSubImage2D unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Copy texture, check errors and log. |
| * |
| * @note Parameters as passed to CopyTextureSubImage*D |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool CopyTest::CopyTextureSubImage3DAndCheckErrors(glw::GLuint texture, glw::GLint level, glw::GLint xoffset, |
| glw::GLint yoffset, glw::GLint zoffset, glw::GLint x, glw::GLint y, |
| glw::GLsizei width, glw::GLsizei height) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0 + zoffset); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| gl.copyTextureSubImage3D(texture, level, xoffset, yoffset, zoffset, x, y, width, height); |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message |
| << "glCopyTextureSubImage3D unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceTexture<1>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<1>(), m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceTexture<2>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<2>(), m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceTexture<3>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<3>(), m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateDestinationTexture<1>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<1>(), m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage1D(TextureTarget<1>(), 0, GL_RGBA8, s_texture_width, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateDestinationTexture<2>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<2>(), m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage2D(TextureTarget<2>(), 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| DE_NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create texture. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateDestinationTexture<3>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genTextures(1, &m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindTexture(TextureTarget<3>(), m_to_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.texImage3D(TextureTarget<3>(), 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, DE_NULL); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D call failed."); |
| } |
| |
| /** @brief Create framebuffer. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceFramebuffer<1>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.framebufferTexture1D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<1>(), m_to_src, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_texture_width, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| } |
| |
| /** @brief Create framebuffer. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceFramebuffer<2>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, TextureTarget<2>(), m_to_src, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_texture_width, s_texture_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| } |
| |
| /** @brief Create framebuffer. |
| * |
| * @tparam D Dimmensions. |
| */ |
| template <> |
| void CopyTest::CreateSourceFramebuffer<3>() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| for (glw::GLuint i = 0; i < s_texture_depth; ++i) |
| { |
| gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, TextureTarget<3>(), m_to_src, 0, i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed."); |
| } |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_texture_width, s_texture_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| } |
| |
| /** @brief Dispatch function to create test objects */ |
| template <glw::GLuint D> |
| void CopyTest::CreateAll() |
| { |
| CreateSourceTexture<D>(); |
| CreateSourceFramebuffer<D>(); |
| CreateDestinationTexture<D>(); |
| } |
| |
| /** @brief Test function */ |
| template <> |
| bool CopyTest::Test<1>() |
| { |
| CreateAll<1>(); |
| |
| bool result = true; |
| |
| result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, 0, 0, 0, s_texture_width / 2); |
| result &= CopyTextureSubImage1DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_width / 2, 0, |
| s_texture_width / 2); |
| |
| result &= CheckData(TextureTarget<1>(), 4 /* RGBA */ * s_texture_width); |
| |
| CleanAll(); |
| |
| return result; |
| } |
| |
| /** @brief Test function */ |
| template <> |
| bool CopyTest::Test<2>() |
| { |
| CreateAll<2>(); |
| |
| bool result = true; |
| |
| result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, 0, 0, 0, s_texture_width / 2, s_texture_height / 2); |
| result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, s_texture_width / 2, 0, |
| s_texture_width / 2, s_texture_height / 2); |
| result &= CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, 0, s_texture_height / 2, |
| s_texture_width / 2, s_texture_height / 2); |
| result &= |
| CopyTextureSubImage2DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, s_texture_width / 2, |
| s_texture_height / 2, s_texture_width / 2, s_texture_height / 2); |
| |
| result &= CheckData(TextureTarget<2>(), 4 /* RGBA */ * s_texture_width * s_texture_height); |
| |
| CleanAll(); |
| |
| return result; |
| } |
| |
| /** @brief Test function */ |
| template <> |
| bool CopyTest::Test<3>() |
| { |
| CreateAll<3>(); |
| |
| bool result = true; |
| |
| for (glw::GLuint i = 0; i < s_texture_depth; ++i) |
| { |
| result &= |
| CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, 0, i, 0, 0, s_texture_width / 2, s_texture_height / 2); |
| result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, 0, i, s_texture_width / 2, 0, |
| s_texture_width / 2, s_texture_height / 2); |
| result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, 0, s_texture_height / 2, i, 0, s_texture_height / 2, |
| s_texture_width / 2, s_texture_height / 2); |
| result &= CopyTextureSubImage3DAndCheckErrors(m_to_dst, 0, s_texture_width / 2, s_texture_height / 2, i, |
| s_texture_width / 2, s_texture_height / 2, s_texture_width / 2, |
| s_texture_height / 2); |
| } |
| |
| result &= CheckData(TextureTarget<3>(), 4 /* RGBA */ * s_texture_width * s_texture_height * s_texture_depth); |
| |
| CleanAll(); |
| |
| return result; |
| } |
| |
| /** @brief Compre results with the reference. |
| * |
| * @param [in] target Texture target. |
| * @param [in] size Size of the buffer. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| bool CopyTest::CheckData(glw::GLenum target, glw::GLuint size) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Check texture content with reference. */ |
| m_result = new glw::GLubyte[size]; |
| |
| if (DE_NULL == m_result) |
| { |
| throw 0; |
| } |
| |
| gl.getTexImage(target, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_result); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| |
| for (glw::GLuint i = 0; i < size; ++i) |
| { |
| if (s_texture_data[i] != m_result[i]) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "glCopyTextureSubImage*D created texture with data " |
| << DataToString(size, s_texture_data) << " however texture contains data " |
| << DataToString(size, m_result) << ". Texture target was " << glu::getTextureTargetStr(target) |
| << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** @brief Convert raw data into string for logging purposes. |
| * |
| * @param [in] count Count of the data. |
| * @param [in] data Raw data. |
| * |
| * @return String representation of data. |
| */ |
| std::string CopyTest::DataToString(glw::GLuint count, const glw::GLubyte data[]) |
| { |
| std::string data_str = "["; |
| |
| for (glw::GLuint i = 0; i < count; ++i) |
| { |
| std::stringstream int_sstream; |
| |
| int_sstream << unsigned(data[i]); |
| |
| data_str.append(int_sstream.str()); |
| |
| if (i + 1 < count) |
| { |
| data_str.append(", "); |
| } |
| else |
| { |
| data_str.append("]"); |
| } |
| } |
| |
| return data_str; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void CopyTest::CleanAll() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| if (m_fbo) |
| { |
| gl.deleteFramebuffers(1, &m_fbo); |
| |
| m_fbo = 0; |
| } |
| |
| if (m_to_src) |
| { |
| gl.deleteTextures(1, &m_to_src); |
| |
| m_to_src = 0; |
| } |
| |
| if (m_to_dst) |
| { |
| gl.deleteTextures(1, &m_to_dst); |
| |
| m_to_dst = 0; |
| } |
| |
| if (DE_NULL == m_result) |
| { |
| delete[] m_result; |
| |
| m_result = DE_NULL; |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Iterate Copy Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult CopyTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| is_ok &= Test<1>(); |
| is_ok &= Test<2>(); |
| is_ok &= Test<3>(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanAll(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte CopyTest::s_texture_data[] = { |
| 0x00, 0x00, 0x00, 0xFF, 0x7f, 0x7f, 0x7f, 0x00, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0x00, |
| 0x88, 0x00, 0x15, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x00, 0x00, |
| 0xc8, 0xbf, 0xe7, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0x00, |
| 0xa3, 0x49, 0xa4, 0xFF, 0x3f, 0x48, 0xcc, 0x00, 0x00, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0x00, |
| |
| 0xa3, 0x49, 0xa4, 0xFF, 0xc8, 0xbf, 0xe7, 0x00, 0x88, 0x00, 0x15, 0xff, 0x00, 0x00, 0x00, 0x00, |
| 0x3f, 0x48, 0xcc, 0xFF, 0x70, 0x92, 0xbe, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x7f, 0x7f, 0x7f, 0x00, |
| 0x00, 0xa2, 0xe8, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0xff, 0x7f, 0x27, 0xff, 0xc3, 0xc3, 0xc3, 0x00, |
| 0x22, 0xb1, 0x4c, 0xFF, 0xb5, 0xe6, 0x1d, 0x00, 0xff, 0xf2, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, |
| |
| 0x22, 0xb1, 0x4c, 0xFF, 0x00, 0xa2, 0xe8, 0x00, 0x3f, 0x48, 0xcc, 0xff, 0xa3, 0x49, 0xa4, 0x00, |
| 0xb5, 0xe6, 0x1d, 0xFF, 0x99, 0xd9, 0xea, 0x00, 0x70, 0x92, 0xbe, 0xff, 0xc8, 0xbf, 0xe7, 0x00, |
| 0xff, 0xf2, 0x00, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0xed, 0x1c, 0x24, 0xff, 0x88, 0x00, 0x15, 0x00, |
| 0xff, 0xff, 0xff, 0xFF, 0xc3, 0xc3, 0xc3, 0x00, 0x7f, 0x7f, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, |
| |
| 0xff, 0xff, 0xff, 0xFF, 0xff, 0xf2, 0x00, 0x00, 0xb5, 0xe6, 0x1d, 0xff, 0x22, 0xb1, 0x4c, 0x00, |
| 0xc3, 0xc3, 0xc3, 0xFF, 0xff, 0x7f, 0x27, 0x00, 0x99, 0xd9, 0xea, 0xff, 0x00, 0xa2, 0xe8, 0x00, |
| 0x7f, 0x7f, 0x7f, 0xFF, 0xed, 0x1c, 0x24, 0x00, 0x70, 0x92, 0xbe, 0xff, 0x3f, 0x48, 0xcc, 0x00, |
| 0x00, 0x00, 0x00, 0xFF, 0x88, 0x00, 0x15, 0x00, 0xc8, 0xbf, 0xe7, 0xff, 0xa3, 0x49, 0xa4, 0x00 |
| }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint CopyTest::s_texture_width = 4; |
| const glw::GLuint CopyTest::s_texture_height = 4; |
| const glw::GLuint CopyTest::s_texture_depth = 4; |
| |
| /******************************** Get Set Parameter Test Implementation ********************************/ |
| |
| /** @brief Get Set Parameter Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| GetSetParameterTest::GetSetParameterTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_get_set_parameter", "Texture Get Set Parameter Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Get Set Parameter Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult GetSetParameterTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Texture. */ |
| glw::GLuint texture = 0; |
| |
| try |
| { |
| gl.genTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_3D, texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| { |
| glw::GLenum name = GL_DEPTH_STENCIL_TEXTURE_MODE; |
| glw::GLint value_src = GL_DEPTH_COMPONENT; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BASE_LEVEL; |
| glw::GLint value_src = 2; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BORDER_COLOR; |
| glw::GLfloat value_src[4] = { 0.25, 0.5, 0.75, 1.0 }; |
| glw::GLfloat value_dst[4] = {}; |
| |
| gl.textureParameterfv(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameterfv", name); |
| |
| gl.getTextureParameterfv(texture, name, value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BORDER_COLOR; |
| glw::GLint value_src[4] = { 0, 64, -64, -32 }; |
| glw::GLint value_dst[4] = {}; |
| |
| gl.textureParameterIiv(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameterIiv", name); |
| |
| gl.getTextureParameterIiv(texture, name, value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameterIiv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BORDER_COLOR; |
| glw::GLuint value_src[4] = { 0, 64, 128, 192 }; |
| glw::GLuint value_dst[4] = {}; |
| |
| gl.textureParameterIuiv(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameterIuiv", name); |
| |
| gl.getTextureParameterIuiv(texture, name, value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameterIuiv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_COMPARE_FUNC; |
| glw::GLint value_src = GL_LEQUAL; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_COMPARE_MODE; |
| glw::GLint value_src = GL_COMPARE_REF_TO_TEXTURE; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_LOD_BIAS; |
| glw::GLfloat value_src = -2.f; |
| glw::GLfloat value_dst = 0.f; |
| |
| gl.textureParameterf(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameterf", name); |
| |
| gl.getTextureParameterfv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameterfv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MIN_FILTER; |
| glw::GLint value_src = GL_LINEAR_MIPMAP_NEAREST; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAG_FILTER; |
| glw::GLint value_src = GL_NEAREST; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MIN_LOD; |
| glw::GLint value_src = -100; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAX_LOD; |
| glw::GLint value_src = 100; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAX_LEVEL; |
| glw::GLint value_src = 100; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_R; |
| glw::GLint value_src = GL_BLUE; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_G; |
| glw::GLint value_src = GL_ALPHA; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_B; |
| glw::GLint value_src = GL_RED; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_A; |
| glw::GLint value_src = GL_GREEN; |
| glw::GLint value_dst = 0; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_RGBA; |
| glw::GLint value_src[4] = { GL_ZERO, GL_ONE, GL_ZERO, GL_ONE }; |
| glw::GLint value_dst[4] = {}; |
| |
| gl.textureParameteriv(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_S; |
| glw::GLint value_src = GL_MIRROR_CLAMP_TO_EDGE; |
| glw::GLint value_dst = 11; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_T; |
| glw::GLint value_src = GL_CLAMP_TO_EDGE; |
| glw::GLint value_dst = 11; |
| |
| gl.textureParameteri(texture, name, value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_R; |
| glw::GLint value_src = GL_CLAMP_TO_EDGE; |
| glw::GLint value_dst = 11; |
| |
| gl.textureParameteriv(texture, name, &value_src); |
| is_ok &= CheckErrorAndLog("glTextureParameteri", name); |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| is_ok &= CheckErrorAndLog("glGetTextureParameteriv", name); |
| |
| is_ok &= CompareAndLog(value_src, value_dst, name); |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Check for errors and log. |
| * |
| * @param [in] fname Name of the function (to be logged). |
| * @param [in] pname Parameter name with which function was called. |
| * |
| * @return True if no error, false otherwise. |
| */ |
| bool GetSetParameterTest::CheckErrorAndLog(const glw::GLchar* fname, glw::GLenum pname) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Check errors. */ |
| glw::GLenum error; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << fname << " unexpectedly generated error " |
| << glu::getErrorStr(error) << " during test of pname " |
| << glu::getTextureParameterStr(pname) << ". Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLint value_src, glw::GLint value_dst, glw::GLenum pname) |
| { |
| if (value_src != value_dst) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_src << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src, glw::GLuint value_dst, glw::GLenum pname) |
| { |
| if (value_src != value_dst) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_src << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src, glw::GLfloat value_dst, glw::GLenum pname) |
| { |
| if (de::abs(value_src - value_dst) > 0.0125 /* Precision */) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_src << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLint value_src[4], glw::GLint value_dst[4], glw::GLenum pname) |
| { |
| if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) || |
| (value_src[3] != value_dst[3])) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLuint value_src[4], glw::GLuint value_dst[4], glw::GLenum pname) |
| { |
| if ((value_src[0] != value_dst[0]) || (value_src[1] != value_dst[1]) || (value_src[2] != value_dst[2]) || |
| (value_src[3] != value_dst[3])) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool GetSetParameterTest::CompareAndLog(glw::GLfloat value_src[4], glw::GLfloat value_dst[4], glw::GLenum pname) |
| { |
| if ((de::abs(value_src[0] - value_dst[0]) > 0.0125 /* Precision */) || |
| (de::abs(value_src[1] - value_dst[1]) > 0.0125 /* Precision */) || |
| (de::abs(value_src[2] - value_dst[2]) > 0.0125 /* Precision */) || |
| (de::abs(value_src[3] - value_dst[3]) > 0.0125 /* Precision */)) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_src[0] << ", " << value_src[1] << ", " << value_src[2] << ", " << value_src[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /******************************** Defaults Test Implementation ********************************/ |
| |
| /** @brief Defaults Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| DefaultsTest::DefaultsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_defaults", "Texture Defaults Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Defaults Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult DefaultsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Texture. */ |
| glw::GLuint texture = 0; |
| |
| try |
| { |
| gl.createTextures(GL_TEXTURE_3D, 1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| { |
| glw::GLenum name = GL_DEPTH_STENCIL_TEXTURE_MODE; |
| glw::GLint value_ref = GL_DEPTH_COMPONENT; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BASE_LEVEL; |
| glw::GLint value_ref = 0; |
| glw::GLint value_dst = 1; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_BORDER_COLOR; |
| glw::GLfloat value_ref[4] = { 0.f, 0.f, 0.f, 0.f }; |
| glw::GLfloat value_dst[4] = {}; |
| |
| gl.getTextureParameterfv(texture, name, value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_COMPARE_FUNC; |
| glw::GLint value_ref = GL_LEQUAL; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_COMPARE_MODE; |
| glw::GLint value_ref = GL_NONE; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_LOD_BIAS; |
| glw::GLfloat value_ref = 0.f; |
| glw::GLfloat value_dst = 0.f; |
| |
| gl.getTextureParameterfv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MIN_FILTER; |
| glw::GLint value_ref = GL_NEAREST_MIPMAP_LINEAR; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAG_FILTER; |
| glw::GLint value_ref = GL_LINEAR; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MIN_LOD; |
| glw::GLint value_ref = -1000; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAX_LOD; |
| glw::GLint value_ref = 1000; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_MAX_LEVEL; |
| glw::GLint value_ref = 1000; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_R; |
| glw::GLint value_ref = GL_RED; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_G; |
| glw::GLint value_ref = GL_GREEN; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_B; |
| glw::GLint value_ref = GL_BLUE; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_SWIZZLE_A; |
| glw::GLint value_ref = GL_ALPHA; |
| glw::GLint value_dst = 0; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_S; |
| glw::GLint value_ref = GL_REPEAT; |
| glw::GLint value_dst = 11; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_T; |
| glw::GLint value_ref = GL_REPEAT; |
| glw::GLint value_dst = 11; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| |
| { |
| glw::GLenum name = GL_TEXTURE_WRAP_R; |
| glw::GLint value_ref = GL_REPEAT; |
| glw::GLint value_dst = 11; |
| |
| gl.getTextureParameteriv(texture, name, &value_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTextureParameter has failed"); |
| |
| is_ok &= CompareAndLog(value_ref, value_dst, name); |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLint value_ref, glw::GLint value_dst, glw::GLenum pname) |
| { |
| if (value_ref != value_dst) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_ref << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLuint value_ref, glw::GLuint value_dst, glw::GLenum pname) |
| { |
| if (value_ref != value_dst) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_ref << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref, glw::GLfloat value_dst, glw::GLenum pname) |
| { |
| if (de::abs(value_ref - value_dst) > 0.0125 /* Precision */) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Queried value of pname " |
| << glu::getTextureParameterStr(pname) << " is equal to " << value_dst |
| << ", however " << value_ref << " was expected. Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLint value_ref[4], glw::GLint value_dst[4], glw::GLenum pname) |
| { |
| if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) || |
| (value_ref[3] != value_dst[3])) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLuint value_ref[4], glw::GLuint value_dst[4], glw::GLenum pname) |
| { |
| if ((value_ref[0] != value_dst[0]) || (value_ref[1] != value_dst[1]) || (value_ref[2] != value_dst[2]) || |
| (value_ref[3] != value_dst[3])) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** @brief Compare queried value of parameter with the expected vale. |
| * |
| * @param [in] value_src First value. |
| * @param [in] value_dst Second value. |
| * @param [in] pname Parameter name. |
| * |
| * @return True if no error was generated by CopyTextureSubImage*D, false otherwise |
| */ |
| bool DefaultsTest::CompareAndLog(glw::GLfloat value_ref[4], glw::GLfloat value_dst[4], glw::GLenum pname) |
| { |
| if ((de::abs(value_ref[0] - value_dst[0]) > 0.0125 /* Precision */) || |
| (de::abs(value_ref[1] - value_dst[1]) > 0.0125 /* Precision */) || |
| (de::abs(value_ref[2] - value_dst[2]) > 0.0125 /* Precision */) || |
| (de::abs(value_ref[3] - value_dst[3]) > 0.0125 /* Precision */)) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Queried value of pname " << glu::getTextureParameterStr(pname) |
| << " is equal to [" << value_dst[0] << ", " << value_dst[1] << ", " << value_dst[2] << ", " << value_dst[3] |
| << "], however " << value_ref[0] << ", " << value_ref[1] << ", " << value_ref[2] << ", " << value_ref[3] |
| << "] was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /******************************** Generate Mipmap Test Implementation ********************************/ |
| |
| /** @brief Generate Mipmap Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| GenerateMipmapTest::GenerateMipmapTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_generate_mipmaps", "Textures Generate Mipmap Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Generate Mipmap Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult GenerateMipmapTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Texture and cpu results storage. */ |
| glw::GLuint texture = 0; |
| glw::GLubyte* result = DE_NULL; |
| |
| try |
| { |
| /* Prepare texture. */ |
| gl.genTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_1D, texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage1D(GL_TEXTURE_1D, 0, GL_R8, s_texture_width, 0, GL_RED, GL_UNSIGNED_BYTE, s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| /* Generate mipmaps with tested function. */ |
| gl.generateTextureMipmap(texture); |
| |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GenerateTextureMipmap unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| |
| /* Continue only if mipmaps has been generated. */ |
| if (is_ok) |
| { |
| result = new glw::GLubyte[s_texture_width]; |
| |
| if (DE_NULL == result) |
| { |
| throw 0; |
| } |
| |
| /* For each mipmap. */ |
| for (glw::GLuint i = 0, j = s_texture_width; |
| i < s_texture_width_log - 1 /* Do not test single pixel mipmap. */; ++i, j /= 2) |
| { |
| /* Check mipmap size. */ |
| glw::GLint mipmap_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, i, GL_TEXTURE_WIDTH, &mipmap_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| if (mipmap_size != (glw::GLint)j) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message |
| << "GenerateTextureMipmap unexpectedly generated mipmap with improper size. Mipmap size is " |
| << mipmap_size << ", but " << j << " was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| |
| break; |
| } |
| |
| /* Fetch data. */ |
| gl.getTexImage(GL_TEXTURE_1D, i, GL_RED, GL_UNSIGNED_BYTE, result); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage has failed"); |
| |
| /* Make comparison. */ |
| for (glw::GLuint k = 0; k < j - 1; ++k) |
| { |
| if (((glw::GLint)result[k + 1]) - ((glw::GLint)result[k]) < 0) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message |
| << "GenerateTextureMipmap unexpectedly generated improper " |
| "mipmap (not descending). Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| |
| break; |
| } |
| } |
| } |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| if (DE_NULL != result) |
| { |
| delete[] result; |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte GenerateMipmapTest::s_texture_data[] = { |
| 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, |
| 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, |
| 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, |
| 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, |
| 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, |
| 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, |
| 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, |
| 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, |
| 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, |
| 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, |
| 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, |
| 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 |
| }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint GenerateMipmapTest::s_texture_width = 256; |
| const glw::GLuint GenerateMipmapTest::s_texture_width_log = 8; |
| |
| /******************************** Bind Unit Test Implementation ********************************/ |
| |
| /** @brief Bind Unit Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| BindUnitTest::BindUnitTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_bind_unit", "Textures Bind Unit Test") |
| , m_po(0) |
| , m_fbo(0) |
| , m_rbo(0) |
| , m_vao(0) |
| , m_result(DE_NULL) |
| { |
| m_to[0] = 0; |
| m_to[1] = 0; |
| m_to[2] = 0; |
| m_to[3] = 0; |
| } |
| |
| /** @brief Bind Unit Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult BindUnitTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| CreateProgram(); |
| CreateTextures(); |
| CreateFrambuffer(); |
| CreateVertexArray(); |
| is_ok &= Draw(); |
| is_ok &= Check(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| CleanAll(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Create test program. |
| */ |
| void BindUnitTest::CreateProgram() |
| { |
| /* Shortcut for GL functionality */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| struct Shader |
| { |
| glw::GLchar const* source; |
| glw::GLenum const type; |
| glw::GLuint id; |
| } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } }; |
| |
| glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]); |
| |
| try |
| { |
| /* Create program. */ |
| m_po = gl.createProgram(); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed."); |
| |
| /* Shader compilation. */ |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (DE_NULL != shader[i].source) |
| { |
| shader[i].id = gl.createShader(shader[i].type); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed."); |
| |
| gl.attachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed."); |
| |
| gl.shaderSource(shader[i].id, 1, &shader[i].source, NULL); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed."); |
| |
| gl.compileShader(shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| if (GL_FALSE == status) |
| { |
| glw::GLint log_size = 0; |
| gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n" |
| << "Shader type: " << glu::getShaderTypeStr(shader[i].type) |
| << "\n" |
| << "Shader compilation error log:\n" |
| << log_text << "\n" |
| << "Shader source code:\n" |
| << shader[i].source << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| } |
| |
| /* Link. */ |
| gl.linkProgram(m_po); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed."); |
| |
| glw::GLint status = GL_FALSE; |
| |
| gl.getProgramiv(m_po, GL_LINK_STATUS, &status); |
| |
| if (GL_TRUE == status) |
| { |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (shader[i].id) |
| { |
| gl.detachShader(m_po, shader[i].id); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed."); |
| } |
| } |
| } |
| else |
| { |
| glw::GLint log_size = 0; |
| |
| gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed."); |
| |
| glw::GLchar* log_text = new glw::GLchar[log_size]; |
| |
| gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n" |
| << log_text << "\n" |
| << tcu::TestLog::EndMessage; |
| |
| delete[] log_text; |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed."); |
| |
| throw 0; |
| } |
| } |
| catch (...) |
| { |
| if (m_po) |
| { |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| } |
| |
| for (glw::GLuint i = 0; i < shader_count; ++i) |
| { |
| if (0 != shader[i].id) |
| { |
| gl.deleteShader(shader[i].id); |
| |
| shader[i].id = 0; |
| } |
| } |
| |
| if (0 == m_po) |
| { |
| throw 0; |
| } |
| } |
| |
| /** @brief Create texture. |
| */ |
| void BindUnitTest::CreateTextures() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare texture. */ |
| gl.genTextures(4, m_to); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| /* Setup pixel sotre modes.*/ |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| /* Red texture. */ |
| gl.bindTexture(GL_TEXTURE_2D, m_to[0]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, |
| s_texture_data_r); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| |
| /* Green texture. */ |
| gl.bindTexture(GL_TEXTURE_2D, m_to[1]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, |
| s_texture_data_g); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| |
| /* Blue texture. */ |
| gl.bindTexture(GL_TEXTURE_2D, m_to[2]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, |
| s_texture_data_b); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| |
| /* Alpha texture. */ |
| gl.bindTexture(GL_TEXTURE_2D, m_to[3]); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_R8, s_texture_width, s_texture_height, 0, GL_RED, GL_UNSIGNED_BYTE, |
| s_texture_data_a); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri call failed."); |
| } |
| |
| /** @brief Create framebuffer. |
| */ |
| void BindUnitTest::CreateFrambuffer() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Prepare framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.genRenderbuffers(1, &m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer call failed."); |
| |
| gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, s_texture_width, s_texture_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage call failed."); |
| |
| gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_texture_width, s_texture_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| /* Clear framebuffer's content. */ |
| gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| } |
| |
| /** @brief Create vertex array object. |
| */ |
| void BindUnitTest::CreateVertexArray() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| gl.genVertexArrays(1, &m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call has failed."); |
| |
| gl.bindVertexArray(m_vao); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call has failed."); |
| } |
| |
| bool BindUnitTest::Draw() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Setup program. */ |
| gl.useProgram(m_po); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call has failed."); |
| |
| /* Bind textures to proper units and setup program's samplers. */ |
| for (glw::GLuint i = 0; i < 4; ++i) |
| { |
| /* Tested binding funcion. */ |
| gl.bindTextureUnit(i, m_to[i]); |
| |
| /* Check for errors. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "BindTextureUnit unexpectedly generated error " << glu::getErrorStr(error) |
| << " when binding texture " << m_to[i] << " to texture unit " << i << ". Test fails." |
| << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| /* Sampler setup. */ |
| gl.uniform1i(gl.getUniformLocation(m_po, s_fragment_shader_samplers[i]), i); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation or glUniform1i call has failed."); |
| } |
| |
| /* Draw call. */ |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed."); |
| |
| return true; |
| } |
| |
| /** @brief Compare results with reference. |
| * |
| * @return True if equal, false otherwise. |
| */ |
| bool BindUnitTest::Check() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Setup storage for results. */ |
| m_result = new glw::GLubyte[s_texture_count_rgba]; |
| |
| /* Setup pixel sotre modes.*/ |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, sizeof(glw::GLubyte)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| gl.pixelStorei(GL_PACK_ALIGNMENT, sizeof(glw::GLubyte)); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei has failed"); |
| |
| /* Query framebuffer's image. */ |
| gl.readPixels(0, 0, s_texture_width, s_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_result); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call has failed."); |
| |
| /* Compare values with reference. */ |
| for (glw::GLuint i = 0; i < s_texture_count_rgba; ++i) |
| { |
| if (s_texture_data_rgba[i] != m_result[i]) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "Framebuffer data " << DataToString(s_texture_count_rgba, m_result) |
| << " does not match the reference values " << DataToString(s_texture_count_rgba, s_texture_data_rgba) |
| << "." << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void BindUnitTest::CleanAll() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Release GL objects. */ |
| if (m_po) |
| { |
| gl.useProgram(0); |
| |
| gl.deleteProgram(m_po); |
| |
| m_po = 0; |
| } |
| |
| if (m_to[0] || m_to[1] || m_to[2] || m_to[3]) |
| { |
| gl.deleteTextures(4, m_to); |
| |
| m_to[0] = 0; |
| m_to[1] = 0; |
| m_to[2] = 0; |
| m_to[3] = 0; |
| } |
| |
| if (m_fbo) |
| { |
| gl.deleteFramebuffers(1, &m_fbo); |
| |
| m_fbo = 0; |
| } |
| |
| if (m_rbo) |
| { |
| gl.deleteRenderbuffers(1, &m_rbo); |
| |
| m_rbo = 0; |
| } |
| |
| /* Release heap. */ |
| if (DE_NULL != m_result) |
| { |
| delete[] m_result; |
| } |
| |
| /* Erros clean-up. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** @brief Convert raw data into string for logging purposes. |
| * |
| * @param [in] count Count of the data. |
| * @param [in] data Raw data. |
| * |
| * @return String representation of data. |
| */ |
| std::string BindUnitTest::DataToString(glw::GLuint count, const glw::GLubyte data[]) |
| { |
| std::string data_str = "["; |
| |
| for (glw::GLuint i = 0; i < count; ++i) |
| { |
| std::stringstream int_sstream; |
| |
| int_sstream << unsigned(data[i]); |
| |
| data_str.append(int_sstream.str()); |
| |
| if (i + 1 < count) |
| { |
| data_str.append(", "); |
| } |
| else |
| { |
| data_str.append("]"); |
| } |
| } |
| |
| return data_str; |
| } |
| |
| /** Reference data and parameters. */ |
| const glw::GLubyte BindUnitTest::s_texture_data_r[] = { 0, 4, 8, 12, 16, 20 }; |
| const glw::GLubyte BindUnitTest::s_texture_data_g[] = { 1, 5, 9, 13, 17, 21 }; |
| const glw::GLubyte BindUnitTest::s_texture_data_b[] = { 2, 6, 10, 14, 18, 22 }; |
| const glw::GLubyte BindUnitTest::s_texture_data_a[] = { 3, 7, 11, 15, 19, 23 }; |
| const glw::GLubyte BindUnitTest::s_texture_data_rgba[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, |
| 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; |
| const glw::GLuint BindUnitTest::s_texture_width = 2; |
| const glw::GLuint BindUnitTest::s_texture_height = 3; |
| const glw::GLuint BindUnitTest::s_texture_count_rgba = sizeof(s_texture_data_rgba) / sizeof(s_texture_data_rgba[0]); |
| |
| /* Vertex shader source code. */ |
| const glw::GLchar* BindUnitTest::s_vertex_shader = "#version 450\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " switch(gl_VertexID)\n" |
| " {\n" |
| " case 0:\n" |
| " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 1:\n" |
| " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 2:\n" |
| " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " case 3:\n" |
| " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" |
| " break;\n" |
| " }\n" |
| "}\n"; |
| |
| /* Fragment shader source program. */ |
| const glw::GLchar* BindUnitTest::s_fragment_shader = |
| "#version 450\n" |
| "\n" |
| "layout(pixel_center_integer) in vec4 gl_FragCoord;\n" |
| "\n" |
| "uniform sampler2D texture_input_r;\n" |
| "uniform sampler2D texture_input_g;\n" |
| "uniform sampler2D texture_input_b;\n" |
| "uniform sampler2D texture_input_a;\n" |
| "\n" |
| "out vec4 color_output;\n" |
| "\n" |
| "void main()\n" |
| "{\n" |
| " color_output = vec4(texelFetch(texture_input_r, ivec2(gl_FragCoord.xy), 0).r,\n" |
| " texelFetch(texture_input_g, ivec2(gl_FragCoord.xy), 0).r,\n" |
| " texelFetch(texture_input_b, ivec2(gl_FragCoord.xy), 0).r,\n" |
| " texelFetch(texture_input_a, ivec2(gl_FragCoord.xy), 0).r);\n" |
| "}\n"; |
| |
| const glw::GLchar* BindUnitTest::s_fragment_shader_samplers[4] = { "texture_input_r", "texture_input_g", |
| "texture_input_b", "texture_input_a" }; |
| |
| /******************************** Get Image Test Implementation ********************************/ |
| |
| /** @brief Get Image Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| GetImageTest::GetImageTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_get_image", "Textures Get Image Test") |
| { |
| /* Intentionally left blank */ |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte GetImageTest::s_texture_data[] = { 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, |
| 0xff, 0xff, 0xff, 0xff, 0xff, 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, |
| 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, 0xc8, |
| 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, |
| 0xb5, 0xe6, 0x1d, 0xff, 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, |
| 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff }; |
| |
| /** Reference data (compressed). */ |
| const glw::GLubyte GetImageTest::s_texture_data_compressed[] = { 0x90, 0x2b, 0x8f, 0x0f, 0xfe, 0x0f, 0x98, 0x99, |
| 0x99, 0x99, 0x59, 0x8f, 0x8c, 0xa6, 0xb7, 0x71 }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint GetImageTest::s_texture_width = 4; |
| const glw::GLuint GetImageTest::s_texture_height = 4; |
| const glw::GLuint GetImageTest::s_texture_size = sizeof(s_texture_data); |
| const glw::GLuint GetImageTest::s_texture_size_compressed = sizeof(s_texture_data_compressed); |
| const glw::GLuint GetImageTest::s_texture_count = s_texture_size / sizeof(s_texture_data[0]); |
| const glw::GLuint GetImageTest::s_texture_count_compressed = |
| s_texture_size_compressed / sizeof(s_texture_data_compressed[0]); |
| |
| /** @brief Get Image Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult GetImageTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture = 0; |
| glw::GLubyte result[s_texture_count] = {}; |
| glw::GLubyte result_compressed[s_texture_count_compressed] = {}; |
| |
| try |
| { |
| /* Uncompressed case. */ |
| { |
| /* Texture initiation. */ |
| gl.genTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, s_texture_width, s_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, |
| s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* Quering image with tested function. */ |
| gl.getTextureImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, sizeof(result), result); |
| |
| /* Check for errors. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GetTextureImage unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| else |
| { |
| /* No error, so compare images. */ |
| for (glw::GLuint i = 0; i < s_texture_count; ++i) |
| { |
| if (s_texture_data[i] != result[i]) |
| { |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetTextureImage returned " |
| << DataToString(s_texture_count, result) << ", but " |
| << DataToString(s_texture_count, s_texture_data) |
| << " was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| |
| break; |
| } |
| } |
| } |
| } |
| |
| /* Clean up texture .*/ |
| gl.deleteTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| texture = 0; |
| |
| /* Compressed case. */ |
| { |
| /* Texture initiation. */ |
| gl.genTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM, s_texture_width, s_texture_height, |
| 0, s_texture_size_compressed, s_texture_data_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D has failed"); |
| |
| /* Quering image with tested function. */ |
| gl.getCompressedTextureImage(texture, 0, s_texture_count_compressed * sizeof(result_compressed[0]), |
| result_compressed); |
| |
| /* Check for errors. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GetCompressedTextureImage unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| else |
| { |
| /* No error, so compare images. */ |
| for (glw::GLuint i = 0; i < s_texture_count_compressed; ++i) |
| { |
| if (s_texture_data_compressed[i] != result_compressed[i]) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GetCompressedTextureImage returned " |
| << DataToString(s_texture_count_compressed, result_compressed) << ", but " |
| << DataToString(s_texture_count_compressed, s_texture_data_compressed) |
| << " was expected. Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| |
| break; |
| } |
| } |
| } |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Convert raw data into string for logging purposes. |
| * |
| * @param [in] count Count of the data. |
| * @param [in] data Raw data. |
| * |
| * @return String representation of data. |
| */ |
| std::string GetImageTest::DataToString(glw::GLuint count, const glw::GLubyte data[]) |
| { |
| std::string data_str = "["; |
| |
| for (glw::GLuint i = 0; i < count; ++i) |
| { |
| std::stringstream int_sstream; |
| |
| int_sstream << unsigned(data[i]); |
| |
| data_str.append(int_sstream.str()); |
| |
| if (i + 1 < count) |
| { |
| data_str.append(", "); |
| } |
| else |
| { |
| data_str.append("]"); |
| } |
| } |
| |
| return data_str; |
| } |
| |
| /******************************** Get Level Parameter Test Implementation ********************************/ |
| |
| /** @brief Get Level Parameter Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| GetLevelParameterTest::GetLevelParameterTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_get_level_parameter", "Textures Get Level Parameter Test") |
| { |
| /* Intentionally left blank */ |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte GetLevelParameterTest::s_texture_data[] = { |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff |
| }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint GetLevelParameterTest::s_texture_width = 4; |
| const glw::GLuint GetLevelParameterTest::s_texture_height = 4; |
| const glw::GLuint GetLevelParameterTest::s_texture_depth = 4; |
| |
| /** @brief Get Level Parameter Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult GetLevelParameterTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture = 0; |
| |
| try |
| { |
| /* Texture initiation. */ |
| gl.genTextures(1, &texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_3D, texture); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, s_texture_width, s_texture_height, s_texture_depth, 0, GL_RGBA, |
| GL_UNSIGNED_BYTE, s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| gl.texImage3D(GL_TEXTURE_3D, 1, GL_RGBA8, s_texture_width / 2, s_texture_height / 2, s_texture_depth / 2, 0, |
| GL_RGBA, GL_UNSIGNED_BYTE, s_texture_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| static const glw::GLenum pnames[] = { |
| GL_TEXTURE_WIDTH, GL_TEXTURE_HEIGHT, GL_TEXTURE_DEPTH, GL_TEXTURE_INTERNAL_FORMAT, |
| GL_TEXTURE_RED_TYPE, GL_TEXTURE_GREEN_TYPE, GL_TEXTURE_BLUE_TYPE, GL_TEXTURE_ALPHA_TYPE, |
| GL_TEXTURE_DEPTH_TYPE, GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, |
| GL_TEXTURE_ALPHA_SIZE, GL_TEXTURE_DEPTH_SIZE, GL_TEXTURE_COMPRESSED |
| }; |
| static const glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]); |
| |
| /* Test GetTextureLevelParameteriv. */ |
| for (glw::GLuint i = 0; i < 2 /* levels */; ++i) |
| { |
| for (glw::GLuint j = 0; j < pnames_count; ++j) |
| { |
| glw::GLint result_legacy = 0; |
| glw::GLint result_dsa = 0; |
| |
| /* Quering reference value. */ |
| gl.getTexLevelParameteriv(GL_TEXTURE_3D, i, pnames[j], &result_legacy); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| /* Quering using DSA function. */ |
| gl.getTextureLevelParameteriv(texture, i, pnames[j], &result_dsa); |
| |
| /* Check for errors. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GetTextureLevelParameteriv unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| else |
| { |
| /* Compare values. */ |
| if (result_legacy != result_dsa) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "For parameter name " |
| << glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameteriv returned " |
| << result_dsa << ", but reference value (queried using GetTexLevelParameteriv) was " |
| << result_legacy << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| } |
| } |
| } |
| |
| /* Test GetTextureLevelParameterfv. */ |
| for (glw::GLuint i = 0; i < 2 /* levels */; ++i) |
| { |
| for (glw::GLuint j = 0; j < pnames_count; ++j) |
| { |
| glw::GLfloat result_legacy = 0.f; |
| glw::GLfloat result_dsa = 0.f; |
| |
| /* Quering reference value. */ |
| gl.getTexLevelParameterfv(GL_TEXTURE_3D, i, pnames[j], &result_legacy); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameterfv has failed"); |
| |
| /* Quering using DSA function. */ |
| gl.getTextureLevelParameterfv(texture, i, pnames[j], &result_dsa); |
| |
| /* Check for errors. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (GL_NO_ERROR != (error = gl.getError())) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "GetTextureLevelParameterfv unexpectedly generated error " |
| << glu::getErrorStr(error) << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| else |
| { |
| /* Compare values. */ |
| if (de::abs(result_legacy - result_dsa) > 0.125 /* Precision. */) |
| { |
| m_context.getTestContext().getLog() |
| << tcu::TestLog::Message << "For parameter name " |
| << glu::getTextureLevelParameterStr(pnames[j]) << " GetTextureLevelParameterfv returned " |
| << result_dsa << ", but reference value (queried using GetTexLevelParameterfv) was " |
| << result_legacy << ". Test fails." << tcu::TestLog::EndMessage; |
| |
| is_ok = false; |
| } |
| } |
| } |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /*********************************** Errors Utility Class *****************************************************/ |
| |
| /** @brief Check for errors and log. |
| * |
| * @param [in] context Test's context. |
| * @param [in] expected_error Expected error value. |
| * @param [in] function_name Name of the function (to be logged). |
| * @param [in] log Log message. |
| * |
| * @return True if error is equal to expected, false otherwise. |
| */ |
| bool ErrorsUtilities::CheckErrorAndLog(deqp::Context& context, glw::GLuint expected_error, |
| const glw::GLchar* function_name, const glw::GLchar* log) |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = context.getRenderContext().getFunctions(); |
| |
| /* Check error. */ |
| glw::GLenum error = GL_NO_ERROR; |
| |
| if (expected_error != (error = gl.getError())) |
| { |
| context.getTestContext().getLog() << tcu::TestLog::Message << function_name << " generated error " |
| << glu::getErrorStr(error) << " but, " << glu::getErrorStr(expected_error) |
| << " was expected if " << log << tcu::TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /******************************** Creation Errors Test Implementation ********************************/ |
| |
| /** @brief Creation Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| CreationErrorsTest::CreationErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_creation_errors", "Texture Objects Creation Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Creation Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult CreationErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Textures' objects */ |
| glw::GLuint texture = 0; |
| |
| try |
| { |
| /* Not a target test. */ |
| gl.createTextures(NotATarget(), 1, &texture); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCreateTextures", |
| "target is not one of the allowable values."); |
| |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| |
| texture = 0; |
| } |
| |
| /* Negative number of textures. */ |
| gl.createTextures(GL_TEXTURE_2D, -1, &texture); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCreateTextures", "n is negative."); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture) |
| { |
| gl.deleteTextures(1, &texture); |
| } |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Function retruns enum which is not a texture target. |
| */ |
| glw::GLenum CreationErrorsTest::NotATarget() |
| { |
| static const glw::GLenum texture_targets[] = { GL_TEXTURE_1D, |
| GL_TEXTURE_2D, |
| GL_TEXTURE_3D, |
| GL_TEXTURE_1D_ARRAY, |
| GL_TEXTURE_2D_ARRAY, |
| GL_TEXTURE_RECTANGLE, |
| GL_TEXTURE_CUBE_MAP, |
| GL_TEXTURE_CUBE_MAP_ARRAY, |
| GL_TEXTURE_BUFFER, |
| GL_TEXTURE_2D_MULTISAMPLE, |
| GL_TEXTURE_2D_MULTISAMPLE_ARRAY }; |
| |
| glw::GLenum not_a_target = 0; |
| bool is_target = true; |
| |
| while (is_target) |
| { |
| not_a_target++; |
| |
| is_target = false; |
| |
| for (glw::GLuint i = 0; i < sizeof(texture_targets) / sizeof(texture_targets[0]); ++i) |
| { |
| if (texture_targets[i] == not_a_target) |
| { |
| is_target = true; |
| break; |
| } |
| } |
| } |
| |
| return not_a_target; |
| } |
| |
| /******************************** Texture Buffer Errors Test Implementation ********************************/ |
| |
| /** @brief Texture Buffer Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| BufferErrorsTest::BufferErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_buffer_errors", "Texture Buffer Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Texture Buffer Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult BufferErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Textures' objects */ |
| glw::GLuint texture_buffer = 0; |
| glw::GLuint texture_1D = 0; |
| glw::GLuint buffer = 0; |
| |
| static const glw::GLubyte data[4] = { 1, 2, 3, 4 }; |
| static const glw::GLuint data_size = sizeof(data); |
| |
| try |
| { |
| /* Auxiliary objects setup. */ |
| gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.createBuffers(1, &buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed"); |
| |
| gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed"); |
| |
| /* Check that INVALID_OPERATION is generated by glTextureBuffer if texture |
| is not the name of an existing texture object. */ |
| { |
| glw::GLuint not_a_texture = 0; |
| |
| while (gl.isTexture(++not_a_texture)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| |
| gl.textureBuffer(not_a_texture, GL_RGBA8, buffer); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by glTextureBuffer if the effective |
| target of texture is not TEXTURE_BUFFER. */ |
| { |
| gl.textureBuffer(texture_1D, GL_RGBA8, buffer); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer", |
| "the effective target of texture is not TEXTURE_BUFFER."); |
| } |
| |
| /* Check that INVALID_ENUM is generated if internalformat is not one of the |
| sized internal formats described above. */ |
| { |
| gl.textureBuffer(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBuffer", |
| "internalformat is not one of the sized internal formats described above.."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated if buffer is not zero and is |
| not the name of an existing buffer object. */ |
| { |
| glw::GLuint not_a_buffer = 0; |
| |
| while (gl.isBuffer(++not_a_buffer)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed"); |
| |
| gl.textureBuffer(texture_buffer, GL_RGBA8, not_a_buffer); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBuffer", |
| "buffer is not zero and is not the name of an existing buffer object."); |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture_1D) |
| { |
| gl.deleteTextures(1, &texture_1D); |
| } |
| |
| if (texture_buffer) |
| { |
| gl.deleteTextures(1, &texture_buffer); |
| } |
| |
| if (buffer) |
| { |
| gl.deleteBuffers(1, &buffer); |
| } |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Texture Buffer Range Errors Test Implementation ********************************/ |
| |
| /** @brief Texture Buffer Range Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| BufferRangeErrorsTest::BufferRangeErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_buffer_range_errors", "Texture Buffer Range Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Texture Buffer Range Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult BufferRangeErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Textures' objects */ |
| glw::GLuint texture_buffer = 0; |
| glw::GLuint texture_1D = 0; |
| glw::GLuint buffer = 0; |
| |
| static const glw::GLubyte data[4] = { 1, 2, 3, 4 }; |
| static const glw::GLuint data_size = sizeof(data); |
| |
| try |
| { |
| /* Auxiliary objects setup. */ |
| gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.createTextures(GL_TEXTURE_1D, 1, &texture_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.createBuffers(1, &buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed"); |
| |
| gl.namedBufferData(buffer, data_size, data, GL_STATIC_COPY); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed"); |
| |
| /* Check that INVALID_OPERATION is generated by TextureBufferRange if |
| texture is not the name of an existing texture object.*/ |
| { |
| glw::GLuint not_a_texture = 0; |
| |
| while (gl.isTexture(++not_a_texture)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| |
| gl.textureBufferRange(not_a_texture, GL_RGBA8, buffer, 0, data_size); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureBufferRange if the |
| effective target of texture is not TEXTURE_BUFFER. */ |
| { |
| gl.textureBufferRange(texture_1D, GL_RGBA8, buffer, 0, data_size); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange", |
| "the effective target of texture is not TEXTURE_BUFFER."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureBufferRange if |
| internalformat is not one of the sized internal formats described above. */ |
| { |
| gl.textureBufferRange(texture_buffer, GL_COMPRESSED_SIGNED_RED_RGTC1, buffer, 0, data_size); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureBufferRange", |
| "internalformat is not one of the supported sized internal formats."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureBufferRange if |
| buffer is not zero and is not the name of an existing buffer object. */ |
| { |
| glw::GLuint not_a_buffer = 0; |
| |
| while (gl.isBuffer(++not_a_buffer)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsBuffer has failed"); |
| |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, not_a_buffer, 0, data_size); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureBufferRange", |
| "buffer is not zero and is not the name of an existing buffer object."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureBufferRange if offset |
| is negative, if size is less than or equal to zero, or if offset + size |
| is greater than the value of BUFFER_SIZE for buffer. */ |
| { |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, -1, data_size); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "offset is negative."); |
| |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, 0); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is zero."); |
| |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, -1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", "size is negative."); |
| |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 0, data_size * 16); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureBufferRange", |
| "size is greater than the value of BUFFER_SIZE for buffer."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureBufferRange if offset is |
| not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT. */ |
| { |
| glw::GLint gl_texture_buffer_offset_alignment = 0; |
| |
| gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_texture_buffer_offset_alignment); |
| |
| /* If alignmet is 1 we cannot do anything. Error situtation is impossible then. */ |
| if (gl_texture_buffer_offset_alignment > 1) |
| { |
| gl.textureBufferRange(texture_buffer, GL_RGBA8, buffer, 1, data_size - 1); |
| |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureBufferRange", |
| "offset is not an integer multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."); |
| } |
| } |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture_1D) |
| { |
| gl.deleteTextures(1, &texture_1D); |
| } |
| |
| if (texture_buffer) |
| { |
| gl.deleteTextures(1, &texture_buffer); |
| } |
| |
| if (buffer) |
| { |
| gl.deleteBuffers(1, &buffer); |
| } |
| |
| /* Errors clean up. */ |
| while (gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Texture Storage Errors Test Implementation ********************************/ |
| |
| /** @brief Texture Storage Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| StorageErrorsTest::StorageErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_storage_errors", "Texture Storage Errors Test") |
| , m_to_1D(0) |
| , m_to_1D_array(0) |
| , m_to_2D(0) |
| , m_to_2D_array(0) |
| , m_to_3D(0) |
| , m_to_2D_ms(0) |
| , m_to_2D_ms_immutable(0) |
| , m_to_3D_ms(0) |
| , m_to_3D_ms_immutable(0) |
| , m_to_invalid(0) |
| , m_internalformat_invalid(0) |
| , m_max_texture_size(1) |
| , m_max_samples(1) |
| , m_max_array_texture_layers(1) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Texture Storage Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult StorageErrorsTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| Prepare(); |
| |
| is_ok &= Test1D(); |
| is_ok &= Test2D(); |
| is_ok &= Test3D(); |
| is_ok &= Test2DMultisample(); |
| is_ok &= Test3DMultisample(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| Clean(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Prepare test objects. |
| */ |
| void StorageErrorsTest::Prepare() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Auxiliary objects setup. */ |
| |
| /* 1D */ |
| gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 1D ARRAY */ |
| gl.createTextures(GL_TEXTURE_1D_ARRAY, 1, &m_to_1D_array); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D ARRAY */ |
| gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_2D_array); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 3D */ |
| gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D Multisample */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D Multisample with storage */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms_immutable); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 16, 16, false); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed"); |
| |
| /* 3D Multisample */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 3D Multisample with storage */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, &m_to_3D_ms_immutable); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 16, 16, 16, false); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed"); |
| |
| /* Invalid values */ |
| |
| /* invalid texture object */ |
| while (gl.isTexture(++m_to_invalid)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| |
| /* invalid internal format */ |
| static const glw::GLenum all_internal_formats[] = { GL_R8, |
| GL_R8_SNORM, |
| GL_R16, |
| GL_R16_SNORM, |
| GL_RG8, |
| GL_RG8_SNORM, |
| GL_RG16, |
| GL_RG16_SNORM, |
| GL_R3_G3_B2, |
| GL_RGB4, |
| GL_RGB5, |
| GL_RGB565, |
| GL_RGB8, |
| GL_RGB8_SNORM, |
| GL_RGB10, |
| GL_RGB12, |
| GL_RGB16, |
| GL_RGB16_SNORM, |
| GL_RGBA2, |
| GL_RGBA4, |
| GL_RGB5_A1, |
| GL_RGBA8, |
| GL_RGBA8_SNORM, |
| GL_RGB10_A2, |
| GL_RGB10_A2UI, |
| GL_RGBA12, |
| GL_RGBA16, |
| GL_RGBA16_SNORM, |
| GL_SRGB8, |
| GL_SRGB8_ALPHA8, |
| GL_R16F, |
| GL_RG16F, |
| GL_RGB16F, |
| GL_RGBA16F, |
| GL_R32F, |
| GL_RG32F, |
| GL_RGB32F, |
| GL_RGBA32F, |
| GL_R11F_G11F_B10F, |
| GL_RGB9_E5, |
| GL_R8I, |
| GL_R8UI, |
| GL_R16I, |
| GL_R16UI, |
| GL_R32I, |
| GL_R32UI, |
| GL_RG8I, |
| GL_RG8UI, |
| GL_RG16I, |
| GL_RG16UI, |
| GL_RG32I, |
| GL_RG32UI, |
| GL_RGB8I, |
| GL_RGB8UI, |
| GL_RGB16I, |
| GL_RGB16UI, |
| GL_RGB32I, |
| GL_RGB32UI, |
| GL_RGBA8I, |
| GL_RGBA8UI, |
| GL_RGBA16I, |
| GL_RGBA16UI, |
| GL_RGBA32I, |
| GL_RGBA32UI, |
| GL_COMPRESSED_RED, |
| GL_COMPRESSED_RG, |
| GL_COMPRESSED_RGB, |
| GL_COMPRESSED_RGBA, |
| GL_COMPRESSED_SRGB, |
| GL_COMPRESSED_SRGB_ALPHA, |
| GL_COMPRESSED_RED_RGTC1, |
| GL_COMPRESSED_SIGNED_RED_RGTC1, |
| GL_COMPRESSED_RG_RGTC2, |
| GL_COMPRESSED_SIGNED_RG_RGTC2, |
| GL_COMPRESSED_RGBA_BPTC_UNORM, |
| GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM, |
| GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT, |
| GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT, |
| GL_COMPRESSED_RGB8_ETC2, |
| GL_COMPRESSED_SRGB8_ETC2, |
| GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| GL_COMPRESSED_RGBA8_ETC2_EAC, |
| GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, |
| GL_COMPRESSED_R11_EAC, |
| GL_COMPRESSED_SIGNED_R11_EAC, |
| GL_COMPRESSED_RG11_EAC, |
| GL_COMPRESSED_SIGNED_RG11_EAC, |
| GL_DEPTH_COMPONENT16, |
| GL_DEPTH_COMPONENT24, |
| GL_DEPTH_COMPONENT32, |
| GL_DEPTH_COMPONENT32F, |
| GL_DEPTH24_STENCIL8, |
| GL_DEPTH32F_STENCIL8, |
| GL_STENCIL_INDEX1, |
| GL_STENCIL_INDEX4, |
| GL_STENCIL_INDEX8, |
| GL_STENCIL_INDEX16 }; |
| |
| static const glw::GLuint all_internal_formats_count = |
| sizeof(all_internal_formats) / sizeof(all_internal_formats[0]); |
| |
| bool is_valid = true; |
| m_internalformat_invalid = 0; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| m_internalformat_invalid++; |
| for (glw::GLuint i = 0; i < all_internal_formats_count; ++i) |
| { |
| if (all_internal_formats[i] == m_internalformat_invalid) |
| { |
| is_valid = true; |
| break; |
| } |
| } |
| } |
| |
| /* Maximum texture size.*/ |
| gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| |
| /* Maximum number of samples. */ |
| gl.getInternalformativ(GL_RENDERBUFFER, GL_R8, GL_SAMPLES, 1, &m_max_samples); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed"); |
| |
| /* Maximum number of array texture layers. */ |
| gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| } |
| |
| /** @brief Test TextureStorage1D |
| * |
| * @return Test result. |
| */ |
| bool StorageErrorsTest::Test1D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage1D if texture |
| is not the name of an existing texture object. */ |
| { |
| gl.textureStorage1D(m_to_invalid, 1, GL_R8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage1D if |
| internalformat is not a valid sized internal format. */ |
| { |
| gl.textureStorage1D(m_to_1D, 1, m_internalformat_invalid, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage1D", |
| "internalformat is not a valid sized internal format."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage1D if target or |
| the effective target of texture is not one of the accepted targets |
| described above. */ |
| { |
| gl.textureStorage1D(m_to_2D, 1, GL_R8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D", |
| "the effective target of texture is not one of the accepted targets."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage1D if width or |
| levels are less than 1. */ |
| { |
| gl.textureStorage1D(m_to_1D, 0, GL_R8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "levels is less than 1."); |
| |
| gl.textureStorage1D(m_to_1D, 1, GL_R8, 0); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage1D", "width is less than 1."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage1D if levels |
| is greater than log2(width)+1. */ |
| { |
| gl.textureStorage1D(m_to_1D, 8, GL_R8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage1D", |
| "levels is greater than log2(width)+1."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test TextureStorage2D |
| * |
| * @return Test result. |
| */ |
| bool StorageErrorsTest::Test2D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2D if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureStorage2D(m_to_invalid, 1, GL_R8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage2D if |
| internalformat is not a valid sized internal format. */ |
| { |
| gl.textureStorage2D(m_to_2D, 1, m_internalformat_invalid, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2D", |
| "internalformat is not a valid sized internal format."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage2D if target or |
| the effective target of texture is not one of the accepted targets |
| described above. */ |
| { |
| gl.textureStorage2D(m_to_1D, 1, GL_R8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D", |
| "the effective target of texture is not one of the accepted targets."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage2D if width, |
| height or levels are less than 1. */ |
| { |
| gl.textureStorage2D(m_to_2D, 0, GL_R8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "levels is less than 1."); |
| |
| gl.textureStorage2D(m_to_2D, 1, GL_R8, 0, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "width is less than 1."); |
| |
| gl.textureStorage2D(m_to_2D, 1, GL_R8, 8, 0); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2D", "height is less than 1."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2D if target |
| is TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater than |
| log2(width)+1. */ |
| { |
| gl.textureStorage2D(m_to_1D_array, 8, GL_R8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D", |
| "target is TEXTURE_1D_ARRAY and levels is greater than log2(width)+1."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2D if target |
| is not TEXTURE_1D_ARRAY or PROXY_TEXTURE_1D_ARRAY and levels is greater |
| than log2(max(width, height))+1. */ |
| { |
| gl.textureStorage2D(m_to_2D, 8, GL_R8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2D", |
| "target is TEXTURE_2D and levels is greater than log2(max(width, height))+1."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test TextureStorage3D |
| * |
| * @return Test result. |
| */ |
| bool StorageErrorsTest::Test3D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3D if texture |
| is not the name of an existing texture object. */ |
| { |
| gl.textureStorage3D(m_to_invalid, 1, GL_R8, 8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage3D if |
| internalformat is not a valid sized internal format. */ |
| { |
| gl.textureStorage3D(m_to_3D, 1, m_internalformat_invalid, 8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3D", |
| "internalformat is not a valid sized internal format."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage3D if target or |
| the effective target of texture is not one of the accepted targets |
| described above. */ |
| { |
| gl.textureStorage3D(m_to_1D, 1, GL_R8, 8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D", |
| "the effective target of texture is not one of the accepted targets."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage3D if width, |
| height, depth or levels are less than 1. */ |
| { |
| gl.textureStorage3D(m_to_3D, 0, GL_R8, 8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "levels is less than 1."); |
| |
| gl.textureStorage3D(m_to_3D, 1, GL_R8, 0, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "width is less than 1."); |
| |
| gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 0, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "height is less than 1."); |
| |
| gl.textureStorage3D(m_to_3D, 1, GL_R8, 8, 8, 0); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3D", "depth is less than 1."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3D if target |
| is TEXTURE_3D or PROXY_TEXTURE_3D and levels is greater than |
| log2(max(width, height, depth))+1. */ |
| { |
| gl.textureStorage3D(m_to_3D, 8, GL_R8, 8, 8, 8); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D", |
| "target is TEXTURE_3D and levels is greater than log2(max(width, height, depth))+1."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3D if target |
| is TEXTURE_2D_ARRAY, PROXY_TEXTURE_2D_ARRAY, TEXURE_CUBE_ARRAY, |
| or PROXY_TEXTURE_CUBE_MAP_ARRAY and levels is greater than |
| log2(max(width, height))+1. */ |
| { |
| gl.textureStorage3D(m_to_2D_array, 6, GL_R8, 8, 8, 256); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3D", |
| "target is TEXTURE_2D_ARRAY and levels is greater than log2(max(width, height))+1."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test TextureStorage2DMultisample |
| * |
| * @return Test result. |
| */ |
| bool StorageErrorsTest::Test2DMultisample() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample |
| if texture is not the name of an existing texture object. */ |
| { |
| gl.textureStorage2DMultisample(m_to_invalid, 1, GL_R8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage2DMultisample if |
| internalformat is not a valid color-renderable, depth-renderable or |
| stencil-renderable format. */ |
| { |
| gl.textureStorage2DMultisample(m_to_2D_ms, 1, m_internalformat_invalid, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage2DMultisample", |
| "internalformat is not a valid sized internal format."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if |
| target or the effective target of texture is not one of the accepted |
| targets described above. */ |
| { |
| gl.textureStorage2DMultisample(m_to_1D, 1, GL_R8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample", |
| "the effective target of texture is not one of the accepted targets."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage2DMultisample if |
| width or height are less than 1 or greater than the value of |
| MAX_TEXTURE_SIZE. */ |
| { |
| gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 0, 8, false); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "width is less than 1."); |
| |
| gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, 0, false); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", "height is less than 1."); |
| |
| gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, m_max_texture_size * 2, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", |
| "width is greater than the value of MAX_TEXTURE_SIZE."); |
| |
| gl.textureStorage2DMultisample(m_to_2D_ms, 1, GL_R8, 8, m_max_texture_size * 2, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage2DMultisample", |
| "height is greater than the value of MAX_TEXTURE_SIZE."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample if |
| samples is greater than the value of MAX_SAMPLES. */ |
| { |
| gl.textureStorage2DMultisample(m_to_2D_ms, m_max_samples * 2, GL_R8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample", |
| "samples is greater than the value of MAX_SAMPLES."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage2DMultisample |
| if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target |
| is not FALSE. */ |
| { |
| gl.textureStorage2DMultisample(m_to_2D_ms_immutable, 1, GL_R8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage2DMultisample", |
| "samples is greater than the value of MAX_SAMPLES."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test TextureStorage3DMultisample |
| * |
| * @return Test result. |
| */ |
| bool StorageErrorsTest::Test3DMultisample() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample |
| if texture is not the name of an existing texture object. */ |
| { |
| gl.textureStorage3DMultisample(m_to_invalid, 1, GL_R8, 8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureStorage3DMultisample if |
| internalformat is not a valid color-renderable, depth-renderable or |
| stencil-renderable format. */ |
| { |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, m_internalformat_invalid, 8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureStorage3DMultisample", |
| "internalformat is not a valid sized internal format."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample if |
| target or the effective target of texture is not one of the accepted |
| targets described above. */ |
| { |
| gl.textureStorage3DMultisample(m_to_1D, 1, GL_R8, 8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample", |
| "the effective target of texture is not one of the accepted targets."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if |
| width or height are less than 1 or greater than the value of |
| MAX_TEXTURE_SIZE. */ |
| { |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 0, 8, 8, false); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "width is less than 1."); |
| |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 0, 8, false); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "height is less than 1."); |
| |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, m_max_texture_size * 2, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", |
| "width is greater than the value of MAX_TEXTURE_SIZE."); |
| |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, m_max_texture_size * 2, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", |
| "height is greater than the value of MAX_TEXTURE_SIZE."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if |
| depth is less than 1 or greater than the value of |
| MAX_ARRAY_TEXTURE_LAYERS. */ |
| { |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, 0, false); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", "depth is less than 1."); |
| |
| gl.textureStorage3DMultisample(m_to_3D_ms, 1, GL_R8, 8, 8, m_max_array_texture_layers * 2, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureStorage3DMultisample", |
| "depth is greater than the value of MAX_ARRAY_TEXTURE_LAYERS."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureStorage3DMultisample if |
| samples is greater than the maximum number of samples reported for GL_R8 */ |
| { |
| gl.textureStorage3DMultisample(m_to_3D_ms, m_max_samples * 2, GL_R8, 8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample", |
| "samples is greater than the value of MAX_SAMPLES."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureStorage3DMultisample |
| if the value of TEXTURE_IMMUTABLE_FORMAT for the texture bound to target |
| is not FALSE. */ |
| { |
| gl.textureStorage3DMultisample(m_to_3D_ms_immutable, 1, GL_R8, 8, 8, 8, false); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureStorage3DMultisample", |
| "samples is greater than the value of MAX_SAMPLES."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void StorageErrorsTest::Clean() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Cleanup. */ |
| if (m_to_1D) |
| { |
| gl.deleteTextures(1, &m_to_1D); |
| |
| m_to_1D = 0; |
| } |
| |
| if (m_to_1D_array) |
| { |
| gl.deleteTextures(1, &m_to_1D_array); |
| |
| m_to_1D_array = 0; |
| } |
| |
| if (m_to_2D) |
| { |
| gl.deleteTextures(1, &m_to_2D); |
| |
| m_to_2D = 0; |
| } |
| |
| if (m_to_2D_array) |
| { |
| gl.deleteTextures(1, &m_to_2D_array); |
| |
| m_to_2D_array = 0; |
| } |
| |
| if (m_to_3D) |
| { |
| gl.deleteTextures(1, &m_to_3D); |
| |
| m_to_3D = 0; |
| } |
| |
| if (m_to_2D_ms) |
| { |
| gl.deleteTextures(1, &m_to_2D_ms); |
| |
| m_to_2D_ms = 0; |
| } |
| |
| if (m_to_2D_ms_immutable) |
| { |
| gl.deleteTextures(1, &m_to_2D_ms_immutable); |
| |
| m_to_2D_ms_immutable = 0; |
| } |
| |
| if (m_to_3D_ms) |
| { |
| gl.deleteTextures(1, &m_to_3D_ms); |
| |
| m_to_3D_ms = 0; |
| } |
| |
| if (m_to_3D_ms_immutable) |
| { |
| gl.deleteTextures(1, &m_to_3D_ms_immutable); |
| |
| m_to_3D_ms_immutable = 0; |
| } |
| |
| m_to_invalid = 0; |
| m_internalformat_invalid = 0; |
| m_max_texture_size = 1; |
| m_max_samples = 1; |
| m_max_array_texture_layers = 1; |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /******************************** Texture SubImage Errors Test Implementation ********************************/ |
| |
| /** @brief Texture SubImage Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| SubImageErrorsTest::SubImageErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_subimage_errors", "Texture SubImage Errors Test") |
| , m_to_1D_empty(0) |
| , m_to_2D_empty(0) |
| , m_to_3D_empty(0) |
| , m_to_1D(0) |
| , m_to_2D(0) |
| , m_to_3D(0) |
| , m_to_1D_compressed(0) |
| , m_to_2D_compressed(0) |
| , m_to_3D_compressed(0) |
| , m_to_rectangle_compressed(0) |
| , m_to_invalid(0) |
| , m_bo(0) |
| , m_format_invalid(0) |
| , m_type_invalid(0) |
| , m_max_texture_size(1) |
| , m_reference_compressed_1D(DE_NULL) |
| , m_reference_compressed_2D(DE_NULL) |
| , m_reference_compressed_3D(DE_NULL) |
| , m_reference_compressed_rectangle(DE_NULL) |
| , m_reference_compressed_1D_size(0) |
| , m_reference_compressed_2D_size(0) |
| , m_reference_compressed_3D_size(0) |
| , m_reference_compressed_rectangle_size(0) |
| , m_reference_compressed_1D_format(0) |
| , m_reference_compressed_2D_format(0) |
| , m_reference_compressed_3D_format(0) |
| , m_reference_compressed_rectangle_format(0) |
| , m_not_matching_compressed_1D_format(0) |
| , m_not_matching_compressed_1D_size(0) |
| , m_not_matching_compressed_2D_format(0) |
| , m_not_matching_compressed_2D_size(0) |
| , m_not_matching_compressed_3D_format(0) |
| , m_not_matching_compressed_3D_size(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Texture SubImage Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult SubImageErrorsTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| Prepare(); |
| |
| is_ok &= Test1D(); |
| is_ok &= Test2D(); |
| is_ok &= Test3D(); |
| is_ok &= Test1DCompressed(); |
| is_ok &= Test2DCompressed(); |
| is_ok &= Test3DCompressed(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| Clean(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Prepare test's objects. |
| */ |
| void SubImageErrorsTest::Prepare() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Auxiliary objects setup. */ |
| |
| /* 1D */ |
| gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_empty); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_empty); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 3D */ |
| gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_empty); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 1D */ |
| gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_1D, m_to_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat, s_reference_width, 0, s_reference_format, |
| GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| /* 2D */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, m_to_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0, |
| s_reference_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| /* 3D */ |
| gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_3D, m_to_3D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage3D(GL_TEXTURE_3D, 0, s_reference_internalformat, s_reference_width, s_reference_height, |
| s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| /* 1D Compressed */ |
| gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_1D, m_to_1D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage1D(GL_TEXTURE_1D, 0, s_reference_internalformat_compressed, s_reference_width, 0, s_reference_format, |
| GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| glw::GLint is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_1D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_reference_compressed_1D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_1D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| if (m_reference_compressed_1D_size) |
| { |
| m_reference_compressed_1D = new glw::GLubyte[m_reference_compressed_1D_size]; |
| |
| gl.getCompressedTexImage(GL_TEXTURE_1D, 0, m_reference_compressed_1D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| } |
| } |
| |
| /* 2D Compressed */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, m_to_2D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0, |
| s_reference_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_reference_compressed_2D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_reference_compressed_2D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &m_reference_compressed_2D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| if (m_reference_compressed_2D_size) |
| { |
| m_reference_compressed_2D = new glw::GLubyte[m_reference_compressed_2D_size]; |
| |
| gl.getCompressedTexImage(GL_TEXTURE_2D, 0, m_reference_compressed_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| } |
| } |
| |
| /* 3D Compressed */ |
| gl.createTextures(GL_TEXTURE_2D_ARRAY, 1, &m_to_3D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_3D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, |
| s_reference_depth, 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_INTERNAL_FORMAT, |
| &m_reference_compressed_3D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_reference_compressed_3D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D_ARRAY, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| &m_reference_compressed_3D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| if (m_reference_compressed_3D_size) |
| { |
| m_reference_compressed_3D = new glw::GLubyte[m_reference_compressed_3D_size]; |
| |
| gl.getCompressedTexImage(GL_TEXTURE_2D_ARRAY, 0, m_reference_compressed_3D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| } |
| } |
| |
| /* RECTANGLE Compressed */ |
| gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_rectangle_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, |
| 0, s_reference_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, |
| &m_reference_compressed_rectangle_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_reference_compressed_rectangle_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_RECTANGLE, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| &m_reference_compressed_rectangle_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| if (m_reference_compressed_rectangle_size) |
| { |
| m_reference_compressed_rectangle = new glw::GLubyte[m_reference_compressed_rectangle_size]; |
| |
| gl.getCompressedTexImage(GL_TEXTURE_RECTANGLE, 0, m_reference_compressed_rectangle); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetCompressedTexImage has failed"); |
| } |
| } |
| |
| /* Buffer object */ |
| gl.createBuffers(1, &m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers has failed"); |
| |
| gl.namedBufferData(m_bo, s_reference_size, s_reference, GL_STATIC_COPY); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed"); |
| |
| /* Invalid values */ |
| |
| /* invalid texture object */ |
| while (gl.isTexture(++m_to_invalid)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| |
| /* invalid internal format */ |
| static const glw::GLenum all_formats[] = { GL_STENCIL_INDEX, |
| GL_DEPTH_COMPONENT, |
| GL_DEPTH_STENCIL, |
| GL_RED, |
| GL_GREEN, |
| GL_BLUE, |
| GL_RG, |
| GL_RGB, |
| GL_RGBA, |
| GL_BGR, |
| GL_BGRA, |
| GL_RED_INTEGER, |
| GL_GREEN_INTEGER, |
| GL_BLUE_INTEGER, |
| GL_RG_INTEGER, |
| GL_RGB_INTEGER, |
| GL_RGBA_INTEGER, |
| GL_BGR_INTEGER, |
| GL_BGRA_INTEGER }; |
| |
| static const glw::GLuint all_internal_formats_count = sizeof(all_formats) / sizeof(all_formats[0]); |
| |
| bool is_valid = true; |
| m_format_invalid = 0; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| m_format_invalid++; |
| for (glw::GLuint i = 0; i < all_internal_formats_count; ++i) |
| { |
| if (all_formats[i] == m_format_invalid) |
| { |
| is_valid = true; |
| break; |
| } |
| } |
| } |
| |
| /* Invalid type. */ |
| static const glw::GLenum all_types[] = { GL_UNSIGNED_BYTE, |
| GL_BYTE, |
| GL_UNSIGNED_SHORT, |
| GL_SHORT, |
| GL_UNSIGNED_INT, |
| GL_INT, |
| GL_HALF_FLOAT, |
| GL_FLOAT, |
| GL_UNSIGNED_BYTE_3_3_2, |
| GL_UNSIGNED_BYTE_2_3_3_REV, |
| GL_UNSIGNED_SHORT_5_6_5, |
| GL_UNSIGNED_SHORT_5_6_5_REV, |
| GL_UNSIGNED_SHORT_4_4_4_4, |
| GL_UNSIGNED_SHORT_4_4_4_4_REV, |
| GL_UNSIGNED_SHORT_5_5_5_1, |
| GL_UNSIGNED_SHORT_1_5_5_5_REV, |
| GL_UNSIGNED_INT_8_8_8_8, |
| GL_UNSIGNED_INT_8_8_8_8_REV, |
| GL_UNSIGNED_INT_10_10_10_2, |
| GL_UNSIGNED_INT_2_10_10_10_REV, |
| GL_UNSIGNED_INT_24_8, |
| GL_UNSIGNED_INT_10F_11F_11F_REV, |
| GL_UNSIGNED_INT_5_9_9_9_REV, |
| GL_FLOAT_32_UNSIGNED_INT_24_8_REV }; |
| |
| static const glw::GLuint all_types_count = sizeof(all_types) / sizeof(all_types[0]); |
| |
| is_valid = true; |
| m_type_invalid = 0; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| m_type_invalid++; |
| for (glw::GLuint i = 0; i < all_types_count; ++i) |
| { |
| if (all_types[i] == m_type_invalid) |
| { |
| is_valid = true; |
| break; |
| } |
| } |
| } |
| |
| /* Maximum texture size.*/ |
| gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &m_max_texture_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| |
| glw::GLenum not_matching_format = GL_RED; |
| glw::GLenum not_matching_internalformat_compressed = GL_COMPRESSED_RED; |
| |
| /* 1D Compressed with a non matching format. We need to do all the allocation to get the correct image size */ |
| glw::GLuint to_1D_compressed_not_matching; |
| |
| gl.createTextures(GL_TEXTURE_1D, 1, &to_1D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_1D, to_1D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage1D(GL_TEXTURE_1D, 0, not_matching_internalformat_compressed, s_reference_width, 0, s_reference_format, |
| GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage1D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_1D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_not_matching_compressed_1D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_1D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| &m_not_matching_compressed_1D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| } |
| |
| gl.deleteTextures(1, &to_1D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 2D Compressed with a non matching format. We need to do all the allocation to get the correct image size */ |
| glw::GLuint to_2D_compressed_not_matching; |
| |
| gl.createTextures(GL_TEXTURE_2D, 1, &to_2D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, to_2D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height, 0, |
| not_matching_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_2D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_not_matching_compressed_2D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| &m_not_matching_compressed_2D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| } |
| |
| gl.deleteTextures(1, &to_2D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 3D Compressed with a non matching format. We need to do all the allocation to get the correct image size */ |
| glw::GLuint to_3D_compressed_not_matching; |
| |
| gl.createTextures(GL_TEXTURE_3D, 1, &to_3D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_3D, to_3D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage3D(GL_TEXTURE_3D, 0, not_matching_internalformat_compressed, s_reference_width, s_reference_height, |
| s_reference_depth, 0, not_matching_format, GL_UNSIGNED_BYTE, s_reference); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D has failed"); |
| |
| is_compressed = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED, &is_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTetTexLevelParameteriv has failed"); |
| |
| if (is_compressed) |
| { |
| gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &m_not_matching_compressed_3D_format); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| |
| m_not_matching_compressed_3D_size = 0; |
| |
| gl.getTexLevelParameteriv(GL_TEXTURE_3D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| &m_not_matching_compressed_3D_size); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv has failed"); |
| } |
| |
| gl.deleteTextures(1, &to_3D_compressed_not_matching); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| } |
| |
| /** @brief Test (negative) of TextureSubImage1D |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test1D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureSubImage1D(m_to_invalid, 0, 0, s_reference_width, s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage1D if format is |
| not an accepted format constant. */ |
| { |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, m_format_invalid, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D", |
| "format is not an accepted format constant."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage1D if type is not |
| an accepted type constant. */ |
| { |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, m_type_invalid, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage1D", |
| "type is not an accepted type constant."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureSubImage1D if level is |
| less than 0. */ |
| { |
| gl.textureSubImage1D(m_to_1D, -1, 0, s_reference_width, s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE may be generated by TextureSubImage1D if level |
| is greater than log2 max, where max is the returned value of |
| MAX_TEXTURE_SIZE. */ |
| { |
| gl.textureSubImage1D(m_to_1D, m_max_texture_size, 0, s_reference_width, s_reference_format, s_reference_type, |
| s_reference); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", |
| "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureSubImage1D if |
| xoffset<-b, or if (xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, |
| and b is the width of the TEXTURE_BORDER of the texture image being |
| modified. Note that w includes twice the border width. */ |
| { |
| gl.textureSubImage1D(m_to_1D, 0, -1, s_reference_width, s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", |
| "xoffset<-b, where b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 1, s_reference_width + 1, s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage1D", |
| "(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER."); |
| } |
| |
| /*Check that INVALID_VALUE is generated by TextureSubImage1D if width is less than 0. */ |
| { |
| #ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH |
| gl.textureSubImage1D(m_to_1D, 0, 0, -1, s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0."); |
| #endif |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if type |
| is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV, |
| UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */ |
| { |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_BYTE_3_3_2 and format is not RGB."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_5_6_5 and format is not RGB."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if type |
| is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV, |
| UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV, |
| UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2, |
| or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */ |
| { |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_10_10_10_2, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the data would be unpacked from the buffer object such that the |
| memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, |
| glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the " |
| "data would be unpacked from the buffer object such that the memory reads required " |
| "would exceed the data store size."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage1D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and pixels is not evenly divisible into the number of bytes needed to |
| store in memory a datum indicated by type. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage1D(m_to_1D, 0, 0, s_reference_width, s_reference_format, s_reference_type, |
| glu::BufferOffsetAsPointer(1)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage1D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels " |
| "is not evenly divisible into the number of bytes needed to store in memory a datum " |
| "indicated by type."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureSubImage2D |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test2D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage2D if format is |
| not an accepted format constant. */ |
| { |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, m_format_invalid, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D", |
| "format is not an accepted format constant."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage2D if type is not |
| an accepted type constant. */ |
| { |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| m_type_invalid, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage2D", |
| "type is not an accepted type constant."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureSubImage2D if level is |
| less than 0. */ |
| { |
| gl.textureSubImage2D(m_to_2D, -1, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE may be generated by TextureSubImage2D if level |
| is greater than log2 max, where max is the returned value of |
| MAX_TEXTURE_SIZE. */ |
| { |
| gl.textureSubImage2D(m_to_2D, m_max_texture_size, 0, 0, s_reference_width, s_reference_height, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", |
| "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE."); |
| } |
| |
| /* Check that INVALID_VALUE may be generated by TextureSubImage2D if level |
| is greater than log2 max, where max is the returned value of |
| MAX_TEXTURE_SIZE. |
| Check that INVALID_VALUE is generated by TextureSubImage2D if |
| xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or |
| (yoffset+height)>(h-b), where w is the TEXTURE_WIDTH, h is the |
| TEXTURE_HEIGHT, and b is the border width of the texture image being |
| modified. Note that w and h include twice the border width. */ |
| { |
| gl.textureSubImage2D(m_to_2D, 0, -1, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", |
| "xoffset<-b, where b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage2D", |
| "(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, -1, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", |
| "yoffset<-b, where b is the height of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage2D", |
| "(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER."); |
| } |
| |
| /*Check that INVALID_VALUE is generated by TextureSubImage2D if width or height is less than 0. */ |
| { |
| #ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, -1, s_reference_height, s_reference_format, s_reference_type, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "width is less than 0."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, -1, s_reference_format, s_reference_type, |
| s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage2D", "height is less than 0."); |
| #endif |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if type |
| is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV, |
| UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */ |
| { |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_BYTE_3_3_2, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_BYTE_3_3_2 and format is not RGB."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_BYTE_2_3_3_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_5_6_5, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_5_6_5 and format is not RGB."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_5_6_5_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if type |
| is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV, |
| UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV, |
| UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2, |
| or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */ |
| { |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_4_4_4_4, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_5_5_5_1, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_INT_8_8_8_8, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_INT_8_8_8_8_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_INT_10_10_10_2, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| GL_UNSIGNED_INT_2_10_10_10_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the data would be unpacked from the buffer object such that the |
| memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the " |
| "data would be unpacked from the buffer object such that the memory reads required " |
| "would exceed the data store size."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage2D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and pixels is not evenly divisible into the number of bytes needed to |
| store in memory a datum indicated by type. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage2D(m_to_2D, 0, 0, 0, s_reference_width, s_reference_height, s_reference_format, |
| s_reference_type, glu::BufferOffsetAsPointer(1)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage2D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels " |
| "is not evenly divisible into the number of bytes needed to store in memory a datum " |
| "indicated by type."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureSubImage3D |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test3D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage3D if format is |
| not an accepted format constant. */ |
| { |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| m_format_invalid, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D", |
| "format is not an accepted format constant."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureSubImage3D if type is not |
| an accepted type constant. */ |
| { |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, m_type_invalid, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureSubImage3D", |
| "type is not an accepted type constant."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureSubImage3D if level is |
| less than 0. */ |
| { |
| gl.textureSubImage3D(m_to_3D, -1, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE may be generated by TextureSubImage1D if level |
| is greater than log2 max, where max is the returned value of |
| MAX_TEXTURE_SIZE. */ |
| { |
| gl.textureSubImage3D(m_to_3D, m_max_texture_size, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, s_reference_format, s_reference_type, s_reference); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureSubImage3D if |
| xoffset<-b, (xoffset+width)>(w-b), yoffset<-b, or |
| (yoffset+height)>(h-b), or zoffset<-b, or (zoffset+depth)>(d-b), where w |
| is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT, d is the TEXTURE_DEPTH |
| and b is the border width of the texture image being modified. Note |
| that w, h, and d include twice the border width. */ |
| { |
| gl.textureSubImage3D(m_to_3D, 0, -1, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "xoffset<-b, where b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 1, 0, 0, s_reference_width + 1, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "(xoffset+width)>(w-b), where w is the TEXTURE_WIDTH, b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, -1, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "yoffset<-b, where b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 1, 0, s_reference_width + 1, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "(yoffset+height)>(h-b), where h is the TEXTURE_HEIGHT, b is the width of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, -1, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "zoffset<-b, where b is the depth of the TEXTURE_BORDER."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 1, s_reference_width + 1, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_VALUE, "glTextureSubImage3D", |
| "(zoffset+width)>(d-b), where d is the TEXTURE_DEPTH, b is the width of the TEXTURE_BORDER."); |
| } |
| |
| /*Check that INVALID_VALUE is generated by TextureSubImage3D if width or height or depth is less than 0. */ |
| { |
| #ifndef TURN_OFF_SUB_IMAGE_ERRORS_TEST_OF_NEGATIVE_WIDTH_HEIGHT_OR_DEPTH |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, -1, s_reference_height, s_reference_depth, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "width is less than 0."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, -1, s_reference_depth, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "height is less than 0."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, -1, s_reference_format, |
| s_reference_type, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureSubImage1D", "depth is less than 0."); |
| #endif |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if type |
| is one of UNSIGNED_BYTE_3_3_2, UNSIGNED_BYTE_2_3_3_REV, |
| UNSIGNED_SHORT_5_6_5, or UNSIGNED_SHORT_5_6_5_REV and format is not RGB. */ |
| { |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_BYTE_3_3_2, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_BYTE_3_3_2 and format is not RGB."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_BYTE_2_3_3_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_BYTE_2_3_3_REV and format is not RGB."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_5_6_5, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_5_6_5 and format is not RGB."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_5_6_5_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_5_6_5_REV and format is not RGB."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if type |
| is one of UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_4_4_4_4_REV, |
| UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_1_5_5_5_REV, |
| UNSIGNED_INT_8_8_8_8, UNSIGNED_INT_8_8_8_8_REV, UNSIGNED_INT_10_10_10_2, |
| or UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA. */ |
| { |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_4_4_4_4 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_4_4_4_4_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_4_4_4_4_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_5_5_5_1, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_5_5_5_1 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_SHORT_1_5_5_5_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_SHORT_1_5_5_5_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_INT_8_8_8_8, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_INT_8_8_8_8 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_INT_8_8_8_8_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_INT_8_8_8_8_REV and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_INT_10_10_10_2, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_INT_10_10_10_2 and format is neither RGBA nor BGRA."); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, GL_UNSIGNED_INT_2_10_10_10_REV, s_reference); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "type is UNSIGNED_INT_2_10_10_10_REV and format is neither RGBA nor BGRA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and the data would be unpacked from the buffer object such that the |
| memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and the " |
| "data would be unpacked from the buffer object such that the memory reads required " |
| "would exceed the data store size."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureSubImage3D if a |
| non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target |
| and pixels is not evenly divisible into the number of bytes needed to |
| store in memory a datum indicated by type. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.textureSubImage3D(m_to_3D, 0, 0, 0, 0, s_reference_width, s_reference_height, s_reference_depth, |
| s_reference_format, s_reference_type, glu::BufferOffsetAsPointer(1)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureSubImage3D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and pixels " |
| "is not evenly divisible into the number of bytes needed to store in memory a datum " |
| "indicated by type."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureSubImage1DCompressed |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test1DCompressed() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Do tests only if compressed 1D textures are supported. */ |
| if (DE_NULL != m_reference_compressed_1D) |
| { |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D |
| if texture is not the name of an existing texture object. */ |
| { |
| gl.compressedTextureSubImage1D(m_to_invalid, 0, 0, s_reference_width, m_reference_compressed_1D_format, |
| m_reference_compressed_1D_size, m_reference_compressed_1D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by CompressedTextureSubImage1D if |
| internalformat is not one of the generic compressed internal formats: |
| COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. |
| COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */ |
| { |
| /* GL_COMPRESSED_RG_RGTC2 is not 1D as specification says. */ |
| gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, GL_COMPRESSED_RG_RGTC2, |
| m_reference_compressed_1D_size, m_reference_compressed_1D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage1D", |
| "internalformat is of the generic compressed internal formats: COMPRESSED_RED, " |
| "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or " |
| "COMPRESSED_SRGB_ALPHA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated if format does not match the |
| internal format of the texture image being modified, since these |
| commands do not provide for image format conversion. */ |
| { |
| gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, |
| m_not_matching_compressed_1D_format, m_not_matching_compressed_1D_size, |
| m_reference_compressed_1D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D", |
| "format does not match the internal format of the texture image being modified, " |
| "since these commands do not provide for image format conversion."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CompressedTextureSubImage1D if |
| imageSize is not consistent with the format, dimensions, and contents of |
| the specified compressed image data. */ |
| { |
| gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, |
| m_reference_compressed_1D_format, m_reference_compressed_1D_size - 1, |
| m_reference_compressed_1D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage1D", |
| "imageSize is not consistent with the format, dimensions, and contents of the " |
| "specified compressed image data."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, |
| m_reference_compressed_1D_format, m_reference_compressed_1D_size, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target " |
| "and the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage1D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the data would be unpacked from the buffer object such that |
| the memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.compressedTextureSubImage1D(m_to_1D_compressed, 0, 0, s_reference_width, |
| m_reference_compressed_1D_format, m_reference_compressed_1D_size, |
| glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage1D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureSubImage2DCompressed |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test2DCompressed() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Do tests only if compressed 2D textures are supported. */ |
| if (DE_NULL != m_reference_compressed_2D) |
| { |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D |
| if texture is not the name of an existing texture object. */ |
| { |
| gl.compressedTextureSubImage2D(m_to_invalid, 0, 0, 0, s_reference_width, s_reference_height, |
| m_reference_compressed_2D_format, m_reference_compressed_2D_size, |
| m_reference_compressed_2D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by CompressedTextureSubImage2D if |
| internalformat is of the generic compressed internal formats: |
| COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. |
| COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */ |
| { |
| gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| GL_COMPRESSED_RG, m_reference_compressed_2D_size, m_reference_compressed_2D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage2D", |
| "internalformat is of the generic compressed internal formats: COMPRESSED_RED, " |
| "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or " |
| "COMPRESSED_SRGB_ALPHA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated if format does not match the |
| internal format of the texture image being modified, since these |
| commands do not provide for image format conversion. */ |
| { |
| gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| m_not_matching_compressed_2D_format, m_not_matching_compressed_2D_size, |
| m_reference_compressed_2D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D", |
| "format does not match the internal format of the texture image being modified, " |
| "since these commands do not provide for image format conversion."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CompressedTextureSubImage2D if |
| imageSize is not consistent with the format, dimensions, and contents of |
| the specified compressed image data. */ |
| { |
| gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| m_reference_compressed_2D_format, m_reference_compressed_2D_size - 1, |
| m_reference_compressed_2D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage2D", |
| "imageSize is not consistent with the format, dimensions, and contents of the " |
| "specified compressed image data."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| m_reference_compressed_2D_format, m_reference_compressed_2D_size, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target " |
| "and the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the data would be unpacked from the buffer object such that |
| the memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.compressedTextureSubImage2D(m_to_2D_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| m_reference_compressed_2D_format, m_reference_compressed_2D_size, |
| glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage2D |
| if the effective target is TEXTURE_RECTANGLE. */ |
| if (DE_NULL != |
| m_reference_compressed_rectangle) /* Do test only if rectangle compressed texture is supported by the implementation. */ |
| { |
| gl.compressedTextureSubImage2D(m_to_rectangle_compressed, 0, 0, 0, s_reference_width, s_reference_height, |
| m_reference_compressed_rectangle_format, |
| m_reference_compressed_rectangle_size, m_reference_compressed_rectangle); |
| |
| if (m_context.getContextInfo().isExtensionSupported("GL_NV_texture_rectangle_compressed")) |
| { |
| is_ok &= CheckErrorAndLog(m_context, GL_NO_ERROR, "glCompressedTextureSubImage2D", |
| "a rectangle texture object is used with this function."); |
| } |
| else |
| { |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage2D", |
| "a rectangle texture object is used with this function."); |
| } |
| } |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureSubImage3DCompressed |
| * |
| * @return Test result. |
| */ |
| bool SubImageErrorsTest::Test3DCompressed() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Do tests only if compressed 3D textures are supported. */ |
| if (DE_NULL != m_reference_compressed_3D) |
| { |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D |
| if texture is not the name of an existing texture object. */ |
| { |
| gl.compressedTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, m_reference_compressed_3D_format, |
| m_reference_compressed_3D_size, m_reference_compressed_3D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by CompressedTextureSubImage3D if |
| internalformat is of the generic compressed internal formats: |
| COMPRESSED_RED, COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. |
| COMPRESSED_SRGB, or COMPRESSED_SRGB_ALPHA. */ |
| { |
| gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, GL_COMPRESSED_RG, m_reference_compressed_3D_size, |
| m_reference_compressed_3D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glCompressedTextureSubImage3D", |
| "internalformat is of the generic compressed internal formats: COMPRESSED_RED, " |
| "COMPRESSED_RG, COMPRESSED_RGB, COMPRESSED_RGBA. COMPRESSED_SRGB, or " |
| "COMPRESSED_SRGB_ALPHA."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated if format does not match the |
| internal format of the texture image being modified, since these |
| commands do not provide for image format conversion. */ |
| { |
| gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, m_not_matching_compressed_3D_format, |
| m_not_matching_compressed_3D_size, m_reference_compressed_3D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D", |
| "format does not match the internal format of the texture image being modified, " |
| "since these commands do not provide for image format conversion."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CompressedTextureSubImage3D if |
| imageSize is not consistent with the format, dimensions, and contents of |
| the specified compressed image data. */ |
| { |
| gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, m_reference_compressed_3D_format, |
| m_reference_compressed_3D_size - 1, m_reference_compressed_3D); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCompressedTextureSubImage3D", |
| "imageSize is not consistent with the format, dimensions, and contents of the " |
| "specified compressed image data."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the buffer object's data store is currently mapped. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, m_reference_compressed_3D_format, |
| m_reference_compressed_3D_size, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target " |
| "and the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CompressedTextureSubImage3D |
| if a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER |
| target and the data would be unpacked from the buffer object such that |
| the memory reads required would exceed the data store size. */ |
| { |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_bo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.compressedTextureSubImage3D(m_to_3D_compressed, 0, 0, 0, 0, s_reference_width, s_reference_height, |
| s_reference_depth, m_reference_compressed_3D_format, |
| m_reference_compressed_3D_size, glu::BufferOffsetAsPointer(s_reference_size * 2)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCompressedTextureSubImage3D", |
| "a non-zero buffer object name is bound to the PIXEL_UNPACK_BUFFER target and " |
| "the buffer object's data store is currently mapped."); |
| |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void SubImageErrorsTest::Clean() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Cleanup. */ |
| if (m_to_1D_empty) |
| { |
| gl.deleteTextures(1, &m_to_1D_empty); |
| |
| m_to_1D_empty = 0; |
| } |
| |
| if (m_to_2D_empty) |
| { |
| gl.deleteTextures(1, &m_to_2D_empty); |
| |
| m_to_2D_empty = 0; |
| } |
| |
| if (m_to_3D_empty) |
| { |
| gl.deleteTextures(1, &m_to_3D_empty); |
| |
| m_to_3D_empty = 0; |
| } |
| |
| if (m_to_1D) |
| { |
| gl.deleteTextures(1, &m_to_1D); |
| |
| m_to_1D = 0; |
| } |
| |
| if (m_to_2D) |
| { |
| gl.deleteTextures(1, &m_to_2D); |
| |
| m_to_2D = 0; |
| } |
| |
| if (m_to_3D) |
| { |
| gl.deleteTextures(1, &m_to_3D); |
| |
| m_to_3D = 0; |
| } |
| |
| if (m_to_1D_compressed) |
| { |
| gl.deleteTextures(1, &m_to_1D_compressed); |
| |
| m_to_1D_compressed = 0; |
| } |
| |
| if (m_to_2D_compressed) |
| { |
| gl.deleteTextures(1, &m_to_2D_compressed); |
| |
| m_to_2D_compressed = 0; |
| } |
| |
| if (m_to_3D_compressed) |
| { |
| gl.deleteTextures(1, &m_to_3D_compressed); |
| |
| m_to_3D_compressed = 0; |
| } |
| |
| if (m_to_rectangle_compressed) |
| { |
| gl.deleteTextures(1, &m_to_rectangle_compressed); |
| |
| m_to_rectangle_compressed = 0; |
| } |
| |
| if (m_bo) |
| { |
| gl.deleteBuffers(1, &m_bo); |
| |
| m_bo = 0; |
| } |
| |
| m_to_invalid = 0; |
| m_format_invalid = 0; |
| m_type_invalid = 0; |
| m_max_texture_size = 1; |
| |
| if (DE_NULL != m_reference_compressed_1D) |
| { |
| delete[] m_reference_compressed_1D; |
| |
| m_reference_compressed_1D = NULL; |
| } |
| |
| if (DE_NULL != m_reference_compressed_2D) |
| { |
| delete[] m_reference_compressed_2D; |
| |
| m_reference_compressed_2D = NULL; |
| } |
| |
| if (DE_NULL != m_reference_compressed_3D) |
| { |
| delete[] m_reference_compressed_3D; |
| |
| m_reference_compressed_3D = NULL; |
| } |
| |
| if (DE_NULL != m_reference_compressed_rectangle) |
| { |
| delete[] m_reference_compressed_rectangle; |
| |
| m_reference_compressed_rectangle = NULL; |
| } |
| |
| m_reference_compressed_1D_format = 0; |
| m_reference_compressed_2D_format = 0; |
| m_reference_compressed_3D_format = 0; |
| m_reference_compressed_rectangle_format = 0; |
| m_reference_compressed_1D_size = 0; |
| m_reference_compressed_2D_size = 0; |
| m_reference_compressed_3D_size = 0; |
| m_reference_compressed_rectangle_size = 0; |
| m_not_matching_compressed_1D_format = 0; |
| m_not_matching_compressed_1D_size = 0; |
| m_not_matching_compressed_2D_format = 0; |
| m_not_matching_compressed_2D_size = 0; |
| m_not_matching_compressed_3D_format = 0; |
| m_not_matching_compressed_3D_size = 0; |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /** Reference data */ |
| const glw::GLushort SubImageErrorsTest::s_reference[] = { |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff, |
| |
| 0x0, 0x0, 0x0, 0xff, 0x7f, 0x7f, 0x7f, 0xff, 0xc3, 0xc3, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 0x88, 0x0, 0x15, 0xff, 0xed, 0x1c, 0x24, 0xff, 0xff, 0x7f, 0x27, 0xff, 0xff, 0xf2, 0x0, 0xff, |
| 0xc8, 0xbf, 0xe7, 0xff, 0x70, 0x92, 0xbe, 0xff, 0x99, 0xd9, 0xea, 0xff, 0xb5, 0xe6, 0x1d, 0xff, |
| 0xa3, 0x49, 0xa4, 0xff, 0x3f, 0x48, 0xcc, 0xff, 0x0, 0xa2, 0xe8, 0xff, 0x22, 0xb1, 0x4c, 0xff |
| }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint SubImageErrorsTest::s_reference_size = sizeof(s_reference); |
| const glw::GLuint SubImageErrorsTest::s_reference_width = 4; |
| const glw::GLuint SubImageErrorsTest::s_reference_height = 4; |
| const glw::GLuint SubImageErrorsTest::s_reference_depth = 4; |
| const glw::GLenum SubImageErrorsTest::s_reference_internalformat = GL_RG8; |
| const glw::GLenum SubImageErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RG; |
| const glw::GLenum SubImageErrorsTest::s_reference_format = GL_RG; /* !Must not be a RGB, RGBA, or BGRA */ |
| const glw::GLenum SubImageErrorsTest::s_reference_type = GL_UNSIGNED_SHORT; |
| |
| /******************************** Copy Errors Test Implementation ********************************/ |
| |
| /** @brief Copy Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| CopyErrorsTest::CopyErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_copy_errors", "Texture Copy Errors Test") |
| , m_fbo(0) |
| , m_fbo_ms(0) |
| , m_fbo_incomplete(0) |
| , m_to_src(0) |
| , m_to_src_ms(0) |
| , m_to_1D_dst(0) |
| , m_to_2D_dst(0) |
| , m_to_3D_dst(0) |
| , m_to_invalid(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Copy Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult CopyErrorsTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| Prepare(); |
| |
| is_ok &= Test1D(); |
| is_ok &= Test2D(); |
| is_ok &= Test3D(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| Clean(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Prepare test's objects and values. |
| */ |
| void CopyErrorsTest::Prepare() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Auxiliary objects setup. */ |
| |
| /* Framebuffer. */ |
| gl.genFramebuffers(1, &m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_src); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage2D(m_to_src, 1, s_internalformat, s_width, s_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed"); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_src, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_width, s_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| |
| /* Framebuffer Multisample. */ |
| gl.genFramebuffers(1, &m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers call failed."); |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_src_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage2DMultisample(m_to_src_ms, 1, s_internalformat, s_width, s_height, false); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed"); |
| |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_to_src_ms, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture1D call failed."); |
| |
| if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) |
| { |
| throw 0; |
| } |
| |
| gl.viewport(0, 0, s_width, s_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed."); |
| |
| gl.clear(GL_COLOR_BUFFER_BIT); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glClear call failed."); |
| |
| /* Framebuffer Incomplete. */ |
| gl.createFramebuffers(1, &m_fbo_incomplete); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glcreateFramebuffers call failed."); |
| |
| /* 1D */ |
| gl.createTextures(GL_TEXTURE_1D, 1, &m_to_1D_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage1D(m_to_1D_dst, 1, s_internalformat, s_width); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed"); |
| |
| /* 2D */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage2D(m_to_2D_dst, 1, s_internalformat, s_width, s_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed"); |
| |
| /* 3D */ |
| gl.createTextures(GL_TEXTURE_3D, 1, &m_to_3D_dst); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| gl.textureStorage3D(m_to_3D_dst, 1, s_internalformat, s_width, s_height, s_depth); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2D has failed"); |
| |
| /* invalid texture object */ |
| while (gl.isTexture(++m_to_invalid)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| } |
| |
| /** @brief Test (negative) of CopyTextureSubImage1D |
| * |
| * @return Test result. |
| */ |
| bool CopyErrorsTest::Test1D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_FRAMEBUFFER_OPERATION is generated by |
| CopyTextureSubImage1D if the object bound to READ_FRAMEBUFFER_BINDING is |
| not framebuffer complete. */ |
| { |
| gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage1D", |
| "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete."); |
| } |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if |
| texture is not the name of an existing texture object, or if the |
| effective target of texture is not TEXTURE_1D. */ |
| { |
| gl.copyTextureSubImage1D(m_to_invalid, 0, 0, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", |
| "texture is not the name of an existing texture object."); |
| |
| gl.copyTextureSubImage1D(m_to_2D_dst, 0, 0, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", |
| "the effective target of texture is not TEXTURE_1D."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if level is less than 0. */ |
| { |
| gl.copyTextureSubImage1D(m_to_1D_dst, -1, 0, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage1D if |
| xoffset<0, or (xoffset+width)>w, where w is the TEXTURE_WIDTH of the |
| texture image being modified. */ |
| { |
| gl.copyTextureSubImage1D(m_to_1D_dst, 0, -1, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", "xoffset<0."); |
| |
| gl.copyTextureSubImage1D(m_to_1D_dst, 0, 1, 0, 0, s_width); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage1D", |
| "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if |
| the read buffer is NONE. */ |
| gl.readBuffer(GL_NONE); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| { |
| gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", "the read buffer is NONE."); |
| } |
| |
| /* Bind multisample framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage1D if |
| the effective value of SAMPLE_BUFFERS for the read |
| framebuffer is one. */ |
| { |
| gl.copyTextureSubImage1D(m_to_1D_dst, 0, 0, 0, 0, s_width); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage1D", |
| "the effective value of SAMPLE_BUFFERS for the read framebuffer is one."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of CopyTextureSubImage2D |
| * |
| * @return Test result. |
| */ |
| bool CopyErrorsTest::Test2D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_FRAMEBUFFER_OPERATION is generated by |
| CopyTextureSubImage2D if the object bound to READ_FRAMEBUFFER_BINDING is |
| not framebuffer complete. */ |
| { |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage2D", |
| "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete."); |
| } |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if |
| texture is not the name of an existing texture object, or if the |
| effective target of texture is not TEXTURE_2D. */ |
| { |
| gl.copyTextureSubImage2D(m_to_invalid, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", |
| "texture is not the name of an existing texture object."); |
| |
| gl.copyTextureSubImage2D(m_to_1D_dst, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", |
| "the effective target of does not correspond to one of the texture targets supported by the function.."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if level is less than 0. */ |
| { |
| gl.copyTextureSubImage2D(m_to_2D_dst, -1, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage2D if |
| xoffset<0, (xoffset+width)>w, yoffset<0, or (yoffset+height)>0, where w |
| is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT and of the texture image |
| being modified. */ |
| { |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, -1, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "xoffset<0."); |
| |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 1, 0, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", |
| "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified."); |
| |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, -1, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", "yoffset<0."); |
| |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 1, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage2D", |
| "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if |
| the read buffer is NONE. */ |
| gl.readBuffer(GL_NONE); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| { |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", "the read buffer is NONE."); |
| } |
| |
| /* Bind multisample framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage2D if |
| the effective value of SAMPLE_BUFFERS for the read |
| framebuffer is one. */ |
| { |
| gl.copyTextureSubImage2D(m_to_2D_dst, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage2D", |
| "the effective value of SAMPLE_BUFFERS for the read framebuffer is one."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of CopyTextureSubImage3D |
| * |
| * @return Test result. |
| */ |
| bool CopyErrorsTest::Test3D() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_incomplete); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_FRAMEBUFFER_OPERATION is generated by |
| CopyTextureSubImage3D if the object bound to READ_FRAMEBUFFER_BINDING is |
| not framebuffer complete. */ |
| { |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_FRAMEBUFFER_OPERATION, "glCopyTextureSubImage3D", |
| "the object bound to READ_FRAMEBUFFER_BINDING is not framebuffer complete."); |
| } |
| |
| /* Bind framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if |
| texture is not the name of an existing texture object, or if the |
| effective target of texture is not supported by the function. */ |
| { |
| gl.copyTextureSubImage3D(m_to_invalid, 0, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", |
| "texture is not the name of an existing texture object."); |
| |
| gl.copyTextureSubImage3D(m_to_1D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", |
| "the effective target of does not correspond to one of the texture targets supported by the function.."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if level is less than 0. */ |
| { |
| gl.copyTextureSubImage3D(m_to_3D_dst, -1, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "level is less than 0."); |
| } |
| |
| /* Check that INVALID_VALUE is generated by CopyTextureSubImage3D if |
| xoffset<0, (xoffset+width)>w, yoffset<0, (yoffset+height)>h, zoffset<0, |
| or (zoffset+1)>d, where w is the TEXTURE_WIDTH, h is the TEXTURE_HEIGHT, |
| d is the TEXTURE_DEPTH and of the texture image being modified. Note |
| that w, h, and d include twice the border width. */ |
| { |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, -1, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "xoffset<0."); |
| |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 1, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", |
| "(xoffset+width)>w, where w is the TEXTURE_WIDTH of the texture image being modified."); |
| |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, -1, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "yoffset<0."); |
| |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 1, 0, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", |
| "(yoffset+height)>h, where h is the TEXTURE_HEIGHT of the texture image being modified."); |
| |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, -1, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", "zoffset<0."); |
| |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, s_depth + 1, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glCopyTextureSubImage3D", |
| "(zoffset+1)>d, where d is the TEXTURE_DEPTH of the texture image being modified."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if |
| the read buffer is NONE. */ |
| gl.readBuffer(GL_NONE); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| { |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", "the read buffer is NONE."); |
| } |
| |
| /* Bind multisample framebuffer. */ |
| gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| gl.readBuffer(GL_COLOR_ATTACHMENT0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed."); |
| |
| /* Check that INVALID_OPERATION is generated by CopyTextureSubImage3D if |
| the effective value of SAMPLE_BUFFERS for the read |
| framebuffer is one. */ |
| { |
| gl.copyTextureSubImage3D(m_to_3D_dst, 0, 0, 0, 0, 0, 0, s_width, s_height); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glCopyTextureSubImage3D", |
| "the effective value of SAMPLE_BUFFERS for the read framebuffer is one."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void CopyErrorsTest::Clean() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Cleanup. */ |
| if (m_fbo) |
| { |
| gl.deleteFramebuffers(1, &m_fbo); |
| |
| m_fbo = 0; |
| } |
| |
| if (m_fbo_ms) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_ms); |
| |
| m_fbo_ms = 0; |
| } |
| |
| if (m_fbo_incomplete) |
| { |
| gl.deleteFramebuffers(1, &m_fbo_incomplete); |
| |
| m_fbo_incomplete = 0; |
| } |
| |
| if (m_to_src) |
| { |
| gl.deleteTextures(1, &m_to_src); |
| |
| m_to_src = 0; |
| } |
| |
| if (m_to_src_ms) |
| { |
| gl.deleteTextures(1, &m_to_src_ms); |
| |
| m_to_src_ms = 0; |
| } |
| |
| if (m_to_1D_dst) |
| { |
| gl.deleteTextures(1, &m_to_1D_dst); |
| |
| m_to_1D_dst = 0; |
| } |
| |
| if (m_to_2D_dst) |
| { |
| gl.deleteTextures(1, &m_to_2D_dst); |
| |
| m_to_2D_dst = 0; |
| } |
| |
| if (m_to_3D_dst) |
| { |
| gl.deleteTextures(1, &m_to_3D_dst); |
| |
| m_to_3D_dst = 0; |
| } |
| |
| m_to_invalid = 0; |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /* Test's parameters. */ |
| const glw::GLuint CopyErrorsTest::s_width = 4; |
| const glw::GLuint CopyErrorsTest::s_height = 4; |
| const glw::GLuint CopyErrorsTest::s_depth = 4; |
| const glw::GLuint CopyErrorsTest::s_internalformat = GL_RGBA8; |
| |
| /******************************** Parameter Setup Errors Test Implementation ********************************/ |
| |
| /** @brief Parameter Setup Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| ParameterSetupErrorsTest::ParameterSetupErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_parameter_setup_errors", "Texture Parameter Setup Errors Test") |
| , m_to_2D(0) |
| , m_to_2D_ms(0) |
| , m_to_rectangle(0) |
| , m_to_invalid(0) |
| , m_pname_invalid(0) |
| , m_depth_stencil_mode_invalid(0) |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Parameter Setup Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult ParameterSetupErrorsTest::iterate() |
| { |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| try |
| { |
| Prepare(); |
| |
| is_ok &= Testf(); |
| is_ok &= Testi(); |
| is_ok &= Testfv(); |
| is_ok &= Testiv(); |
| is_ok &= TestIiv(); |
| is_ok &= TestIuiv(); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| Clean(); |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** @brief Test's preparations. |
| */ |
| void ParameterSetupErrorsTest::Prepare() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Auxiliary objects setup. */ |
| |
| /* 2D */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &m_to_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* 3D */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &m_to_2D_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* RECTANGLE */ |
| gl.createTextures(GL_TEXTURE_RECTANGLE, 1, &m_to_rectangle); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTextures has failed"); |
| |
| /* Invalid texture object. */ |
| while (gl.isTexture(++m_to_invalid)) |
| ; |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glIsTexture has failed"); |
| |
| /* Invalid parameter name. */ |
| glw::GLenum all_pnames[] = { GL_DEPTH_STENCIL_TEXTURE_MODE, |
| GL_TEXTURE_BASE_LEVEL, |
| GL_TEXTURE_COMPARE_FUNC, |
| GL_TEXTURE_COMPARE_MODE, |
| GL_TEXTURE_LOD_BIAS, |
| GL_TEXTURE_MIN_FILTER, |
| GL_TEXTURE_MAG_FILTER, |
| GL_TEXTURE_MIN_LOD, |
| GL_TEXTURE_MAX_LOD, |
| GL_TEXTURE_MAX_LEVEL, |
| GL_TEXTURE_SWIZZLE_R, |
| GL_TEXTURE_SWIZZLE_G, |
| GL_TEXTURE_SWIZZLE_B, |
| GL_TEXTURE_SWIZZLE_A, |
| GL_TEXTURE_WRAP_S, |
| GL_TEXTURE_WRAP_T, |
| GL_TEXTURE_WRAP_R, |
| GL_TEXTURE_BORDER_COLOR, |
| GL_TEXTURE_SWIZZLE_RGBA }; |
| glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]); |
| |
| bool is_valid = true; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| ++m_pname_invalid; |
| |
| for (glw::GLuint i = 0; i < all_pnames_count; ++i) |
| { |
| if (all_pnames[i] == m_pname_invalid) |
| { |
| is_valid = true; |
| |
| break; |
| } |
| } |
| } |
| |
| /* Invalid depth stencil mode name. */ |
| glw::GLenum all_depth_stencil_modes[] = { GL_DEPTH_COMPONENT, GL_STENCIL_INDEX }; |
| glw::GLuint all_depth_stencil_modes_count = sizeof(all_depth_stencil_modes) / sizeof(all_depth_stencil_modes[0]); |
| |
| is_valid = true; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| ++m_depth_stencil_mode_invalid; |
| |
| for (glw::GLuint i = 0; i < all_depth_stencil_modes_count; ++i) |
| { |
| if (all_depth_stencil_modes[i] == m_depth_stencil_mode_invalid) |
| { |
| is_valid = true; |
| |
| break; |
| } |
| } |
| } |
| } |
| |
| /** @brief Test (negative) of TextureParameterf |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::Testf() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameterf(m_to_2D, m_pname_invalid, 1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameterf(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, (glw::GLfloat)m_depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| /* Check that INVALID_ENUM is generated if TextureParameter{if} is called |
| for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or |
| TEXTURE_SWIZZLE_RGBA). */ |
| { |
| gl.textureParameterf(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1.f); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA)."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameterf(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameterf(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterf", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameterf(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1.f); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameterf(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameterf(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterf", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureParameter* if pname is |
| TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is |
| negative. */ |
| { |
| gl.textureParameterf(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf", |
| "pname is TEXTURE_BASE_LEVEL and param is negative."); |
| |
| gl.textureParameterf(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1.f); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterf", |
| "pname is TEXTURE_MAX_LEVEL and param is negative."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureParameteri |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::Testi() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameteri(m_to_2D, m_pname_invalid, 1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameteri(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, m_depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| /* Check that INVALID_ENUM is generated if TextureParameter{if} is called |
| for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or |
| TEXTURE_SWIZZLE_RGBA). */ |
| { |
| gl.textureParameteri(m_to_2D, GL_TEXTURE_BORDER_COLOR, 1); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "called for a non-scalar parameter (pname TEXTURE_BORDER_COLOR or TEXTURE_SWIZZLE_RGBA)."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, 1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameteri(m_to_rectangle, GL_TEXTURE_WRAP_S, GL_MIRROR_CLAMP_TO_EDGE); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameteri(m_to_rectangle, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteri", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameteri(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, 1); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameteri(m_to_invalid, GL_TEXTURE_LOD_BIAS, 1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameteri(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, 1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteri", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureParameter* if pname is |
| TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is |
| negative. */ |
| { |
| gl.textureParameteri(m_to_2D, GL_TEXTURE_BASE_LEVEL, -1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri", |
| "pname is TEXTURE_BASE_LEVEL and param is negative."); |
| |
| gl.textureParameteri(m_to_2D, GL_TEXTURE_MAX_LEVEL, -1); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteri", |
| "pname is TEXTURE_MAX_LEVEL and param is negative."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureParameterfv |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::Testfv() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| glw::GLfloat one = 1.f; |
| glw::GLfloat minus_one = -1.f; |
| glw::GLfloat depth_stencil_mode_invalid = (glw::GLfloat)m_depth_stencil_mode_invalid; |
| glw::GLfloat wrap_invalid = (glw::GLfloat)GL_MIRROR_CLAMP_TO_EDGE; |
| glw::GLfloat min_filter_invalid = (glw::GLfloat)GL_NEAREST_MIPMAP_NEAREST; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameterfv(m_to_2D, m_pname_invalid, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameterfv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterfv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameterfv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameterfv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameterfv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterfv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureParameter* if pname is |
| TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is |
| negative. */ |
| { |
| gl.textureParameterfv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv", |
| "pname is TEXTURE_BASE_LEVEL and param is negative."); |
| |
| gl.textureParameterfv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterfv", |
| "pname is TEXTURE_MAX_LEVEL and param is negative."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureParameteriv |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::Testiv() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| glw::GLint one = 1; |
| glw::GLint minus_one = -1; |
| glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid; |
| glw::GLint wrap_invalid = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE; |
| glw::GLint min_filter_invalid = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameteriv(m_to_2D, m_pname_invalid, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameteriv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameteriv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameteriv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameteriv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameteriv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameteriv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureParameter* if pname is |
| TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is |
| negative. */ |
| { |
| gl.textureParameteriv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv", |
| "pname is TEXTURE_BASE_LEVEL and param is negative."); |
| |
| gl.textureParameteriv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameteriv", |
| "pname is TEXTURE_MAX_LEVEL and param is negative."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureParameterIiv |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::TestIiv() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| glw::GLint one = 1; |
| glw::GLint minus_one = -1; |
| glw::GLint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid; |
| glw::GLint wrap_invalid = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE; |
| glw::GLint min_filter_invalid = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameterIiv(m_to_2D, m_pname_invalid, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameterIiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIiv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameterIiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameterIiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameterIiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIiv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| /* Check that INVALID_VALUE is generated by TextureParameter* if pname is |
| TEXTURE_BASE_LEVEL or TEXTURE_MAX_LEVEL, and param or params is |
| negative. */ |
| { |
| gl.textureParameterIiv(m_to_2D, GL_TEXTURE_BASE_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv", |
| "pname is TEXTURE_BASE_LEVEL and param is negative."); |
| |
| gl.textureParameterIiv(m_to_2D, GL_TEXTURE_MAX_LEVEL, &minus_one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glTextureParameterIiv", |
| "pname is TEXTURE_MAX_LEVEL and param is negative."); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Test (negative) of TextureParameterIuiv |
| * |
| * @return Test result. |
| */ |
| bool ParameterSetupErrorsTest::TestIuiv() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Result. */ |
| bool is_ok = true; |
| |
| glw::GLuint one = 1; |
| glw::GLuint depth_stencil_mode_invalid = (glw::GLint)m_depth_stencil_mode_invalid; |
| glw::GLuint wrap_invalid = (glw::GLint)GL_MIRROR_CLAMP_TO_EDGE; |
| glw::GLuint min_filter_invalid = (glw::GLint)GL_NEAREST_MIPMAP_NEAREST; |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if pname is |
| not one of the accepted defined values. */ |
| { |
| gl.textureParameterIuiv(m_to_2D, m_pname_invalid, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv", |
| "pname is not one of the accepted defined values."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if params |
| should have a defined constant value (based on the value of pname) and |
| does not. */ |
| { |
| gl.textureParameterIuiv(m_to_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, &depth_stencil_mode_invalid); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv", |
| "params should have a defined constant value (based on the value of pname) and does not."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states. */ |
| { |
| gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or " |
| "TEXTURE_2D_MULTISAMPLE_ARRAY, and pname is any of the sampler states."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and either of pnames |
| TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, |
| MIRRORED_REPEAT or REPEAT. */ |
| { |
| gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_WRAP_S, &wrap_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv", |
| "the effective target is TEXTURE_RECTANGLE and either of pnames TEXTURE_WRAP_S or " |
| "TEXTURE_WRAP_T is set to either MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT or REPEAT."); |
| } |
| |
| /* Check that INVALID_ENUM is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is |
| set to a value other than NEAREST or LINEAR (no mipmap filtering is |
| permitted). */ |
| { |
| gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_MIN_FILTER, &min_filter_invalid); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glTextureParameterIuiv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_MIN_FILTER is set to a " |
| "value other than NEAREST or LINEAR (no mipmap filtering is permitted)."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is either TEXTURE_2D_MULTISAMPLE or |
| TEXTURE_2D_MULTISAMPLE_ARRAY, and pname TEXTURE_BASE_LEVEL is set to a |
| value other than zero. */ |
| { |
| gl.textureParameterIuiv(m_to_2D_ms, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv", |
| "the effective target is either TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY, " |
| "and pname TEXTURE_BASE_LEVEL is set to a value other than zero."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if |
| texture is not the name of an existing texture object. */ |
| { |
| gl.textureParameterIuiv(m_to_invalid, GL_TEXTURE_LOD_BIAS, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv", |
| "texture is not the name of an existing texture object."); |
| } |
| |
| /* Check that INVALID_OPERATION is generated by TextureParameter* if the |
| effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is |
| set to any value other than zero. */ |
| { |
| gl.textureParameterIuiv(m_to_rectangle, GL_TEXTURE_BASE_LEVEL, &one); |
| |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glTextureParameterIuiv", |
| "the effective target is TEXTURE_RECTANGLE and pname TEXTURE_BASE_LEVEL is set to " |
| "any value other than zero. "); |
| } |
| |
| return is_ok; |
| } |
| |
| /** @brief Clean GL objects, test variables and GL errors. |
| */ |
| void ParameterSetupErrorsTest::Clean() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Cleanup. */ |
| if (m_to_2D) |
| { |
| gl.deleteTextures(1, &m_to_2D); |
| |
| m_to_2D = 0; |
| } |
| |
| if (m_to_2D_ms) |
| { |
| gl.deleteTextures(1, &m_to_2D_ms); |
| |
| m_to_2D_ms = 0; |
| } |
| |
| if (m_to_rectangle) |
| { |
| gl.deleteTextures(1, &m_to_rectangle); |
| |
| m_to_rectangle = 0; |
| } |
| |
| if (m_to_invalid) |
| { |
| gl.deleteTextures(1, &m_to_invalid); |
| |
| m_to_invalid = 0; |
| } |
| |
| m_to_invalid = 0; |
| m_pname_invalid = 0; |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| } |
| |
| /******************************** Generate Mipmap Errors Test Implementation ********************************/ |
| |
| /** @brief Generate Mipmap Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| GenerateMipmapErrorsTest::GenerateMipmapErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_generate_mipmap_errors", "Texture Generate Mipmap Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Generate Mipmap Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult GenerateMipmapErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture_invalid = 0; |
| glw::GLuint texture_cube = 0; |
| |
| try |
| { |
| /* Preparations. */ |
| |
| /* incomplete cube map */ |
| gl.genTextures(1, &texture_cube); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width, |
| s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* invalid texture */ |
| while (gl.isTexture(++texture_invalid)) |
| ; |
| |
| /* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if |
| texture is not the name of an existing texture object. */ |
| gl.generateTextureMipmap(texture_invalid); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap", |
| "texture is not the name of an existing texture object."); |
| |
| /* Check that INVALID_OPERATION is generated by GenerateTextureMipmap if |
| target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified |
| texture object is not cube complete or cube array complete, |
| respectively. */ |
| gl.generateTextureMipmap(texture_cube); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGenerateTextureMipmap", |
| "target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and the specified texture " |
| "object is not cube complete or cube array complete, respectively."); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture_cube) |
| { |
| gl.deleteTextures(1, &texture_cube); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /** Reference data. */ |
| const glw::GLubyte GenerateMipmapErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, |
| 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint GenerateMipmapErrorsTest::s_reference_width = 4; |
| const glw::GLuint GenerateMipmapErrorsTest::s_reference_height = 4; |
| const glw::GLenum GenerateMipmapErrorsTest::s_reference_internalformat = GL_R8; |
| const glw::GLenum GenerateMipmapErrorsTest::s_reference_format = GL_RED; |
| const glw::GLenum GenerateMipmapErrorsTest::s_reference_type = GL_UNSIGNED_BYTE; |
| |
| /******************************** Bind Unit Errors Test Implementation ********************************/ |
| |
| /** @brief Bind Unit Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| BindUnitErrorsTest::BindUnitErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_bind_unit_errors", "Texture Bind Unit Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief IterateBind Unit Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult BindUnitErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture_invalid = 0; |
| |
| try |
| { |
| /* Prepare invalid texture */ |
| while (gl.isTexture(++texture_invalid)) |
| ; |
| |
| /* incomplete cube map */ |
| |
| /* Check that INVALID_OPERATION error is generated if texture is not zero |
| or the name of an existing texture object. */ |
| gl.bindTextureUnit(0, texture_invalid); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glBindTextureUnit", |
| "texture is not zero or the name of an existing texture object."); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Image Query Errors Test Implementation ********************************/ |
| |
| /** @brief Image Query Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| ImageQueryErrorsTest::ImageQueryErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_image_query_errors", "Texture Image Query Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** Reference data. */ |
| const glw::GLuint ImageQueryErrorsTest::s_reference_data[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, |
| 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF }; |
| |
| /** Reference data parameters. */ |
| const glw::GLuint ImageQueryErrorsTest::s_reference_width = 4; |
| const glw::GLuint ImageQueryErrorsTest::s_reference_height = 4; |
| const glw::GLuint ImageQueryErrorsTest::s_reference_size = sizeof(s_reference_data); |
| const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat = GL_R8; |
| const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_int = GL_R8I; |
| const glw::GLenum ImageQueryErrorsTest::s_reference_internalformat_compressed = GL_COMPRESSED_RED_RGTC1; |
| const glw::GLenum ImageQueryErrorsTest::s_reference_format = GL_RED; |
| const glw::GLenum ImageQueryErrorsTest::s_reference_type = GL_UNSIGNED_INT; |
| |
| /** @brief Iterate Image Query Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult ImageQueryErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint buffer = 0; |
| glw::GLuint texture_invalid = 0; |
| glw::GLuint texture_2D = 0; |
| glw::GLuint texture_2D_int = 0; |
| glw::GLuint texture_2D_ms = 0; |
| glw::GLuint texture_2D_stencil = 0; |
| glw::GLuint texture_2D_compressed = 0; |
| glw::GLuint texture_cube = 0; |
| glw::GLuint texture_rectangle = 0; |
| glw::GLint max_level = 0; |
| char store[s_reference_size * 6 /* for cubemap */] = {}; |
| |
| try |
| { |
| /* Preparations. */ |
| |
| /* Buffer. */ |
| gl.createBuffers(1, &buffer); |
| |
| gl.namedBufferData(buffer, s_reference_size + 1, NULL, GL_STATIC_COPY); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedBufferData has failed"); |
| |
| /* 2D texture */ |
| gl.genTextures(1, &texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0, |
| s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* 2D texture */ |
| gl.genTextures(1, &texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0, |
| s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* incomplete cube map */ |
| gl.genTextures(1, &texture_cube); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture_cube); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, s_reference_internalformat, s_reference_width, |
| s_reference_height, 0, s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* 2D multisample */ |
| gl.createTextures(GL_TEXTURE_2D_MULTISAMPLE, 1, &texture_2D_ms); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.textureStorage2DMultisample(texture_2D_ms, 1, s_reference_internalformat, s_reference_width, |
| s_reference_height, false); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed"); |
| |
| /* 2D stencil */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D_stencil); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.textureStorage2D(texture_2D_stencil, 1, GL_STENCIL_INDEX8, s_reference_width, s_reference_height); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTextureStorage2DMultisample has failed"); |
| |
| /* 2D compressed texture */ |
| gl.genTextures(1, &texture_2D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_2D_compressed); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_2D, 0, s_reference_internalformat_compressed, s_reference_width, s_reference_height, 0, |
| s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| |
| /* Rectangle texture */ |
| gl.genTextures(1, &texture_rectangle); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_RECTANGLE, texture_rectangle); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texImage2D(GL_TEXTURE_RECTANGLE, 0, s_reference_internalformat, s_reference_width, s_reference_height, 0, |
| s_reference_format, s_reference_type, s_reference_data); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* invalid texture */ |
| while (gl.isTexture(++texture_invalid)) |
| ; |
| |
| /* Tests. */ |
| |
| /* Check that INVALID_OPERATION is generated by GetTextureImage functions if |
| resulting texture target is not an accepted value TEXTURE_1D, |
| TEXTURE_2D, TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, |
| TEXTURE_CUBE_MAP_ARRAY, TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP. */ |
| gl.getTextureImage(texture_2D_ms, 0, s_reference_format, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "resulting texture target is not an accepted value TEXTURE_1D, TEXTURE_2D, " |
| "TEXTURE_3D, TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, " |
| "TEXTURE_RECTANGLE, and TEXTURE_CUBE_MAP."); |
| |
| /* Check that INVALID_OPERATION is generated by GetTextureImage |
| if texture is not the name of an existing texture object. */ |
| gl.getTextureImage(texture_invalid, 0, s_reference_format, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "texture is not the name of an existing texture object."); |
| |
| /* Check that INVALID_OPERATION error is generated by GetTextureImage if |
| the effective target is TEXTURE_CUBE_MAP or TEXTURE_CUBE_MAP_ARRAY, and |
| the texture object is not cube complete or cube array complete, |
| respectively. */ |
| gl.getTextureImage(texture_cube, 0, s_reference_format, s_reference_type, s_reference_size * 6, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "the effective target is TEXTURE_CUBE_MAP and the texture object is not cube " |
| "complete or cube array complete, respectively."); |
| |
| /* Check that GL_INVALID_VALUE is generated if level is less than 0 or |
| larger than the maximum allowable level. */ |
| gl.getTextureImage(texture_2D, -1, s_reference_format, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", "level is less than 0."); |
| |
| gl.getTextureImage(texture_2D, max_level, s_reference_format, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", |
| "level is larger than the maximum allowable level."); |
| |
| /* Check that INVALID_VALUE error is generated if level is non-zero and the |
| effective target is TEXTURE_RECTANGLE. */ |
| gl.getTextureImage(texture_rectangle, 1, s_reference_format, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureImage", |
| "level is non-zero and the effective target is TEXTURE_RECTANGLE."); |
| |
| /* Check that INVALID_OPERATION error is generated if any of the following |
| mismatches between format and the internal format of the texture image |
| exist: |
| - format is a color format (one of the formats in table 8.3 whose |
| target is the color buffer) and the base internal format of the |
| texture image is not a color format. |
| - format is DEPTH_COMPONENT and the base internal format is not |
| DEPTH_COMPONENT or DEPTH_STENCIL |
| - format is DEPTH_STENCIL and the base internal format is not |
| DEPTH_STENCIL |
| - format is STENCIL_INDEX and the base internal format is not |
| STENCIL_INDEX or DEPTH_STENCIL |
| - format is one of the integer formats in table 8.3 and the internal |
| format of the texture image is not integer, or format is not one of |
| the integer formats in table 8.3 and the internal format is integer. */ |
| gl.getTextureImage(texture_2D_stencil, 0, s_reference_format /* red */, s_reference_type, s_reference_size, |
| store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is a color format (one of the formats in table 8.3 whose target is the color " |
| "buffer) and the base internal format of the texture image is not a color format."); |
| |
| gl.getTextureImage(texture_2D, 0, GL_DEPTH_COMPONENT, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is DEPTH_COMPONENT and the base internal format is not DEPTH_COMPONENT or DEPTH_STENCIL."); |
| |
| gl.getTextureImage(texture_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is DEPTH_STENCIL and the base internal format is not DEPTH_STENCIL."); |
| |
| gl.getTextureImage(texture_2D, 0, GL_STENCIL_INDEX, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is STENCIL_INDEX and the base internal format is not STENCIL_INDEX or DEPTH_STENCIL."); |
| |
| gl.getTextureImage(texture_2D, 0, GL_RED_INTEGER, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is one of the integer formats in table 8.3 and the internal format of the " |
| "texture image is not integer."); |
| |
| gl.getTextureImage(texture_2D_int, 0, GL_RED, s_reference_type, s_reference_size, store); |
| is_ok &= CheckErrorAndLog( |
| m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "format is not one of the integer formats in table 8.3 and the internal format is integer."); |
| |
| /* Check that INVALID_OPERATION error is generated if a pixel pack buffer |
| object is bound and packing the texture image into the buffer's memory |
| would exceed the size of the buffer. */ |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size, |
| glu::BufferOffsetAsPointer(1 * sizeof(GLuint))); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "a pixel pack buffer object is bound and packing the texture image into the buffer's " |
| "memory would exceed the size of the buffer."); |
| |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| /* Check that INVALID_OPERATION error is generated if a pixel pack buffer |
| object is bound and pixels is not evenly divisible by the number of |
| basic machine units needed to store in memory the GL data type |
| corresponding to type (see table 8.2). */ |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, s_reference_size, |
| glu::BufferOffsetAsPointer(1)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "a pixel pack buffer object is bound and pixels is not evenly divisible by the " |
| "number of basic machine units needed to store in memory the GL data type " |
| "corresponding to type (see table 8.2)."); |
| |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| /* Check that INVALID_OPERATION error is generated by GetTextureImage if |
| the buffer size required to store the requested data is greater than |
| bufSize. */ |
| gl.getTextureImage(texture_2D, 0, s_reference_format, s_reference_type, |
| s_reference_size - sizeof(s_reference_data[0]), store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureImage", |
| "the buffer size required to store the requested data is greater than bufSize."); |
| |
| /* Check that INVALID_OPERATION is generated by GetCompressedTextureImage |
| if texture is not the name of an existing texture object. */ |
| gl.getCompressedTextureImage(texture_invalid, 0, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage", |
| "texture is not the name of an existing texture object."); |
| |
| /* Check that INVALID_VALUE is generated by GetCompressedTextureImage if |
| level is less than zero or greater than the maximum number of LODs |
| permitted by the implementation. */ |
| gl.getCompressedTextureImage(texture_2D_compressed, -1, s_reference_size, store); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage", "level is less than zero."); |
| |
| gl.getCompressedTextureImage(texture_2D_compressed, max_level, s_reference_size, store); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetCompressedTextureImage", |
| "level is greater than the maximum number of LODs permitted by the implementation."); |
| |
| /* Check that INVALID_OPERATION is generated if GetCompressedTextureImage |
| is used to retrieve a texture that is in an uncompressed internal |
| format. */ |
| gl.getCompressedTextureImage(texture_2D, 0, s_reference_size, store); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage", |
| "the function is used to retrieve a texture that is in an uncompressed internal format."); |
| |
| /* Check that INVALID_OPERATION is generated by GetCompressedTextureImage |
| if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER |
| target, the buffer storage was not initialized with BufferStorage using |
| MAP_PERSISTENT_BIT flag, and the buffer object's data store is currently |
| mapped. */ |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.mapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE); |
| |
| if (GL_NO_ERROR == gl.getError()) |
| { |
| gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, NULL); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage", |
| "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target, the " |
| "buffer storage was not initialized with BufferStorage using MAP_PERSISTENT_BIT " |
| "flag, and the buffer object's data store is currently mapped."); |
| |
| gl.unmapBuffer(GL_PIXEL_PACK_BUFFER); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer has failed"); |
| } |
| else |
| { |
| throw 0; |
| } |
| |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| /* Check that INVALID_OPERATION is generated by GetCompressedTextureImage |
| if a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER |
| target and the data would be packed to the buffer object such that the |
| memory writes required would exceed the data store size. */ |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| |
| gl.getCompressedTextureImage(texture_2D_compressed, 0, s_reference_size, glu::BufferOffsetAsPointer(s_reference_size - 1)); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetCompressedTextureImage", |
| "a non-zero buffer object name is bound to the PIXEL_PACK_BUFFER target and the data " |
| "would be packed to the buffer object such that the memory writes required would " |
| "exceed the data store size."); |
| |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer has failed"); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (buffer) |
| { |
| gl.deleteBuffers(1, &buffer); |
| } |
| |
| if (texture_2D) |
| { |
| gl.deleteTextures(1, &texture_2D); |
| } |
| |
| if (texture_2D_int) |
| { |
| gl.deleteTextures(1, &texture_2D_int); |
| } |
| |
| if (texture_2D_stencil) |
| { |
| gl.deleteTextures(1, &texture_2D_stencil); |
| } |
| |
| if (texture_2D_ms) |
| { |
| gl.deleteTextures(1, &texture_2D_ms); |
| } |
| |
| if (texture_2D_compressed) |
| { |
| gl.deleteTextures(1, &texture_2D_compressed); |
| } |
| |
| if (texture_cube) |
| { |
| gl.deleteTextures(1, &texture_cube); |
| } |
| |
| if (texture_rectangle) |
| { |
| gl.deleteTextures(1, &texture_rectangle); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Level Parameter Query Errors Test Implementation ********************************/ |
| |
| /** @brief Image Query Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| LevelParameterErrorsTest::LevelParameterErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_level_parameter_errors", "Texture Level Parameter Query Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Level Parameter Query Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult LevelParameterErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture_2D = 0; |
| glw::GLuint texture_invalid = 0; |
| glw::GLint max_level = 0; |
| glw::GLenum pname_invalid = 0; |
| |
| glw::GLfloat storef[4] = {}; |
| glw::GLint storei[4] = {}; |
| |
| try |
| { |
| /* Preparations. */ |
| |
| /* 2D texture */ |
| gl.genTextures(1, &texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| gl.bindTexture(GL_TEXTURE_2D, texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed"); |
| |
| gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D has failed"); |
| |
| /* Limits. */ |
| gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_level); /* assuming that x > log(x) */ |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed"); |
| |
| /* invalid texture */ |
| while (gl.isTexture(++texture_invalid)) |
| ; |
| |
| /* invalid pname */ |
| glw::GLenum all_pnames[] = { GL_TEXTURE_WIDTH, |
| GL_TEXTURE_HEIGHT, |
| GL_TEXTURE_DEPTH, |
| GL_TEXTURE_SAMPLES, |
| GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, |
| GL_TEXTURE_INTERNAL_FORMAT, |
| GL_TEXTURE_RED_SIZE, |
| GL_TEXTURE_GREEN_SIZE, |
| GL_TEXTURE_BLUE_SIZE, |
| GL_TEXTURE_ALPHA_SIZE, |
| GL_TEXTURE_DEPTH_SIZE, |
| GL_TEXTURE_STENCIL_SIZE, |
| GL_TEXTURE_SHARED_SIZE, |
| GL_TEXTURE_RED_TYPE, |
| GL_TEXTURE_GREEN_TYPE, |
| GL_TEXTURE_BLUE_TYPE, |
| GL_TEXTURE_ALPHA_TYPE, |
| GL_TEXTURE_DEPTH_TYPE, |
| GL_TEXTURE_COMPRESSED, |
| GL_TEXTURE_COMPRESSED_IMAGE_SIZE, |
| GL_TEXTURE_BUFFER_DATA_STORE_BINDING, |
| GL_TEXTURE_BUFFER_OFFSET, |
| GL_TEXTURE_BUFFER_SIZE }; |
| |
| glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]); |
| |
| bool is_valid = true; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| |
| ++pname_invalid; |
| |
| for (glw::GLuint i = 0; i < all_pnames_count; ++i) |
| { |
| if (all_pnames[i] == pname_invalid) |
| { |
| is_valid = true; |
| |
| break; |
| } |
| } |
| } |
| |
| /* Tests. */ |
| |
| /* Check that INVALID_OPERATION is generated by GetTextureLevelParameterfv |
| and GetTextureLevelParameteriv functions if texture is not the name of |
| an existing texture object. */ |
| gl.getTextureLevelParameterfv(texture_invalid, 0, GL_TEXTURE_WIDTH, storef); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv", |
| "texture is not the name of an existing texture object."); |
| |
| gl.getTextureLevelParameteriv(texture_invalid, 0, GL_TEXTURE_WIDTH, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv", |
| "texture is not the name of an existing texture object."); |
| |
| /* Check that INVALID_VALUE is generated by GetTextureLevelParameter* if |
| level is less than 0. */ |
| gl.getTextureLevelParameterfv(texture_2D, -1, GL_TEXTURE_WIDTH, storef); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv", "level is less than 0."); |
| |
| gl.getTextureLevelParameteriv(texture_2D, -1, GL_TEXTURE_WIDTH, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv", "level is less than 0."); |
| |
| /* Check that INVALID_ENUM error is generated by GetTextureLevelParameter* |
| if pname is not one of supported constants. */ |
| gl.getTextureLevelParameterfv(texture_2D, 0, pname_invalid, storef); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameterfv", |
| "pname is not one of supported constants."); |
| |
| gl.getTextureLevelParameteriv(texture_2D, 0, pname_invalid, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureLevelParameteriv", |
| "pname is not one of supported constants."); |
| |
| /* Check that INVALID_VALUE may be generated if level is greater than |
| log2 max, where max is the returned value of MAX_TEXTURE_SIZE. */ |
| gl.getTextureLevelParameterfv(texture_2D, max_level, GL_TEXTURE_WIDTH, storef); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameterfv", |
| "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE."); |
| |
| gl.getTextureLevelParameteriv(texture_2D, max_level, GL_TEXTURE_WIDTH, storei); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_VALUE, "glGetTextureLevelParameteriv", |
| "level is greater than log2 max, where max is the returned value of MAX_TEXTURE_SIZE."); |
| |
| /* Check that INVALID_OPERATION is generated by GetTextureLevelParameter* |
| if TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an |
| uncompressed internal format or on proxy targets. */ |
| gl.getTextureLevelParameterfv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storef); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameterfv", |
| "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed " |
| "internal format or on proxy targets."); |
| |
| gl.getTextureLevelParameteriv(texture_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureLevelParameteriv", |
| "TEXTURE_COMPRESSED_IMAGE_SIZE is queried on texture images with an uncompressed " |
| "internal format or on proxy targets."); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture_2D) |
| { |
| gl.deleteTextures(1, &texture_2D); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| /******************************** Parameter Query Errors Test Implementation ********************************/ |
| |
| /** @brief Parameter Query Errors Test constructor. |
| * |
| * @param [in] context OpenGL context. |
| */ |
| ParameterErrorsTest::ParameterErrorsTest(deqp::Context& context) |
| : deqp::TestCase(context, "textures_parameter_errors", "Texture Parameter Query Errors Test") |
| { |
| /* Intentionally left blank. */ |
| } |
| |
| /** @brief Iterate Parameter Query Errors Test cases. |
| * |
| * @return Iteration result. |
| */ |
| tcu::TestNode::IterateResult ParameterErrorsTest::iterate() |
| { |
| /* Shortcut for GL functionality. */ |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| /* Get context setup. */ |
| bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5))); |
| bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access"); |
| |
| if ((!is_at_least_gl_45) && (!is_arb_direct_state_access)) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported"); |
| |
| return STOP; |
| } |
| |
| /* Running tests. */ |
| bool is_ok = true; |
| bool is_error = false; |
| |
| /* Objects. */ |
| glw::GLuint texture_2D = 0; |
| glw::GLuint texture_buffer = 0; |
| glw::GLuint texture_invalid = 0; |
| glw::GLenum pname_invalid = 0; |
| |
| glw::GLfloat storef[4] = {}; |
| glw::GLint storei[4] = {}; |
| glw::GLuint storeu[4] = {}; |
| |
| try |
| { |
| /* Preparations. */ |
| |
| /* 2D texture */ |
| gl.createTextures(GL_TEXTURE_2D, 1, &texture_2D); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| /* Buffer texture */ |
| gl.createTextures(GL_TEXTURE_BUFFER, 1, &texture_buffer); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed"); |
| |
| /* invalid texture */ |
| while (gl.isTexture(++texture_invalid)) |
| ; |
| |
| /* invalid pname */ |
| glw::GLenum all_pnames[] = { GL_IMAGE_FORMAT_COMPATIBILITY_TYPE, |
| GL_TEXTURE_IMMUTABLE_FORMAT, |
| GL_TEXTURE_IMMUTABLE_LEVELS, |
| GL_TEXTURE_TARGET, |
| GL_TEXTURE_VIEW_MIN_LEVEL, |
| GL_TEXTURE_VIEW_NUM_LEVELS, |
| GL_TEXTURE_VIEW_MIN_LAYER, |
| GL_TEXTURE_VIEW_NUM_LAYERS, |
| GL_DEPTH_STENCIL_TEXTURE_MODE, |
| GL_DEPTH_COMPONENT, |
| GL_STENCIL_INDEX, |
| GL_TEXTURE_BASE_LEVEL, |
| GL_TEXTURE_BORDER_COLOR, |
| GL_TEXTURE_COMPARE_MODE, |
| GL_TEXTURE_COMPARE_FUNC, |
| GL_TEXTURE_LOD_BIAS, |
| GL_TEXTURE_MAG_FILTER, |
| GL_TEXTURE_MAX_LEVEL, |
| GL_TEXTURE_MAX_LOD, |
| GL_TEXTURE_MIN_FILTER, |
| GL_TEXTURE_MIN_LOD, |
| GL_TEXTURE_SWIZZLE_R, |
| GL_TEXTURE_SWIZZLE_G, |
| GL_TEXTURE_SWIZZLE_B, |
| GL_TEXTURE_SWIZZLE_A, |
| GL_TEXTURE_SWIZZLE_RGBA, |
| GL_TEXTURE_WRAP_S, |
| GL_TEXTURE_WRAP_T, |
| GL_TEXTURE_WRAP_R }; |
| |
| glw::GLuint all_pnames_count = sizeof(all_pnames) / sizeof(all_pnames[0]); |
| |
| bool is_valid = true; |
| |
| while (is_valid) |
| { |
| is_valid = false; |
| |
| ++pname_invalid; |
| |
| for (glw::GLuint i = 0; i < all_pnames_count; ++i) |
| { |
| if (all_pnames[i] == pname_invalid) |
| { |
| is_valid = true; |
| |
| break; |
| } |
| } |
| } |
| |
| /* Tests. */ |
| |
| /* Check that INVALID_ENUM is generated by glGetTextureParameter* if pname |
| is not an accepted value. */ |
| gl.getTextureParameterfv(texture_2D, pname_invalid, storef); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterfv", "pname is not an accepted value."); |
| |
| gl.getTextureParameterIiv(texture_2D, pname_invalid, storei); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIiv", "pname is not an accepted value."); |
| |
| gl.getTextureParameterIuiv(texture_2D, pname_invalid, storeu); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameterIuiv", |
| "pname is not an accepted value."); |
| |
| gl.getTextureParameteriv(texture_2D, pname_invalid, storei); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_ENUM, "glGetTextureParameteriv", "pname is not an accepted value."); |
| |
| /* Check that INVALID_OPERATION is generated by glGetTextureParameter* if |
| texture is not the name of an existing texture object. */ |
| gl.getTextureParameterfv(texture_invalid, GL_TEXTURE_TARGET, storef); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv", |
| "texture is not the name of an existing texture object."); |
| |
| gl.getTextureParameterIiv(texture_invalid, GL_TEXTURE_TARGET, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv", |
| "texture is not the name of an existing texture object."); |
| |
| gl.getTextureParameterIuiv(texture_invalid, GL_TEXTURE_TARGET, storeu); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv", |
| "texture is not the name of an existing texture object."); |
| |
| gl.getTextureParameteriv(texture_invalid, GL_TEXTURE_TARGET, storei); |
| is_ok &= CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv", |
| "texture is not the name of an existing texture object."); |
| |
| /* Check that INVALID_OPERATION error is generated if the effective target is |
| not one of the supported texture targets (eg. TEXTURE_BUFFER). */ |
| gl.getTextureParameterfv(texture_buffer, GL_TEXTURE_TARGET, storef); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterfv", |
| "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER)."); |
| |
| gl.getTextureParameterIiv(texture_buffer, GL_TEXTURE_TARGET, storei); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIiv", |
| "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER)."); |
| |
| gl.getTextureParameterIuiv(texture_buffer, GL_TEXTURE_TARGET, storeu); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameterIuiv", |
| "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER)."); |
| |
| gl.getTextureParameteriv(texture_buffer, GL_TEXTURE_TARGET, storei); |
| is_ok &= |
| CheckErrorAndLog(m_context, GL_INVALID_OPERATION, "glGetTextureParameteriv", |
| "the effective target is not one of the supported texture targets (eg. TEXTURE_BUFFER)."); |
| } |
| catch (...) |
| { |
| is_ok = false; |
| is_error = true; |
| } |
| |
| /* Cleanup. */ |
| if (texture_2D) |
| { |
| gl.deleteTextures(1, &texture_2D); |
| } |
| |
| if (texture_buffer) |
| { |
| gl.deleteTextures(1, &texture_buffer); |
| } |
| |
| while (GL_NO_ERROR != gl.getError()) |
| ; |
| |
| /* Result's setup. */ |
| if (is_ok) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| } |
| else |
| { |
| if (is_error) |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error"); |
| } |
| else |
| { |
| m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| } |
| } |
| |
| return STOP; |
| } |
| |
| } /* Textures namespace. */ |
| } /* DirectStateAccess namespace. */ |
| } /* gl4cts namespace. */ |