| /*------------------------------------------------------------------------- |
| * 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 |