| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2017 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 glcTextureRepeatModeTests.cpp |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "glcTextureRepeatModeTests.hpp" |
| #include "deMath.h" |
| #include "gluContextInfo.hpp" |
| #include "gluDefs.hpp" |
| #include "gluShaderProgram.hpp" |
| #include "gluStrUtil.hpp" |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "tcuTestLog.hpp" |
| |
| using namespace glw; |
| |
| namespace glcts |
| { |
| |
| union InternalFormatBits { |
| struct Bits |
| { |
| int red; /* red bits */ |
| int green; /* green bits */ |
| int blue; /* blue bits */ |
| int alpha; /* alpha bits */ |
| int intensity; /* intensity bits */ |
| int luminance; /* luminance bits */ |
| int depth; /* depth bits */ |
| int stencil; /* stencil bits */ |
| int exponent; /* shared exponent bits */ |
| } bits; |
| int array[9]; /* all the bits */ |
| }; |
| |
| enum InternalFormatSamplerType |
| { |
| SAMPLER_UNORM = 0, /* unsigned normalized */ |
| SAMPLER_NORM, /* normalized */ |
| SAMPLER_UINT, /* unsigned integer */ |
| SAMPLER_INT, /* integer */ |
| SAMPLER_FLOAT /* floating-point */ |
| }; |
| |
| enum InternalFormatFlag |
| { |
| NO_FLAG = 0, |
| FLAG_PACKED = 1, /* Packed pixel format. */ |
| FLAG_COMPRESSED = 2, /* Compressed format. */ |
| FLAG_REQ_RBO_GL42 = 4, /* Required RBO & tex format in OpenGL 4.2. */ |
| FLAG_REQ_RBO_ES30 = 8, /* Required RBO & tex format in OpenGL ES 3.0. */ |
| FLAG_REQ_RBO = FLAG_REQ_RBO_GL42 | FLAG_REQ_RBO_ES30, /* Required RBO & tex format in both. */ |
| }; |
| |
| #define MAX_PIXEL_SIZE 16 |
| |
| /* Note that internal representation is in little endian - tests will fail on big endian, in particular RGB565 will fail */ |
| struct FormatInfo |
| { |
| /* internal format, indicating tested format */ |
| GLenum internalformat; |
| |
| const char* name; |
| |
| /* number of bytes per pixel */ |
| GLsizei pixelSize; |
| |
| /* RGBW colors' representation, specific for each internalformat */ |
| GLubyte internalred[MAX_PIXEL_SIZE]; |
| GLubyte internalgreen[MAX_PIXEL_SIZE]; |
| GLubyte internalblue[MAX_PIXEL_SIZE]; |
| GLubyte internalwhite[MAX_PIXEL_SIZE]; |
| |
| /* RGBW colors' mapped to RGBA, that are read from framebuffer */ |
| GLubyte RGBAred[4]; |
| GLubyte RGBAgreen[4]; |
| GLubyte RGBAblue[4]; |
| GLubyte RGBAwhite[4]; |
| }; |
| |
| static const FormatInfo testedFormats[] = { |
| { |
| GL_R8, |
| "r8", |
| 1, |
| { 0xFF }, |
| { 0xC7 }, |
| { 0x30 }, |
| { 0x00 }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0xC7, 0x00, 0x00, 0xFF }, |
| { 0x30, 0x00, 0x00, 0xFF }, |
| { 0x00, 0x00, 0x00, 0xFF }, |
| }, |
| { |
| GL_RGB565, |
| "rgb565", |
| 2, |
| { 0x00, 0xF8 }, |
| { 0xE0, 0x07 }, |
| { 0x1F, 0x00 }, |
| { 0xFF, 0xFF }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x00, 0xFF, 0x00, 0xFF }, |
| { 0x00, 0x00, 0xFF, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF }, |
| }, |
| { |
| GL_RGB8, |
| "rgb8", |
| 3, |
| { 0xFF, 0x00, 0x00 }, |
| { 0x00, 0xFF, 0x00 }, |
| { 0x00, 0x00, 0xFF }, |
| { 0xFF, 0xFF, 0xFF }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x00, 0xFF, 0x00, 0xFF }, |
| { 0x00, 0x00, 0xFF, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF }, |
| }, |
| { |
| GL_RGB10_A2, |
| "rgb10_a2", |
| 4, |
| { 0xFF, 0x03, 0x00, 0xC0 }, |
| { 0x00, 0xFC, 0x0F, 0xC0 }, |
| { 0x00, 0x00, 0xF0, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x00, 0xFF, 0x00, 0xFF }, |
| { 0x00, 0x00, 0xFF, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF }, |
| }, |
| { |
| /* unsigned integer texture formats : require an unsigned texture sampler in the fragment shader */ |
| GL_R32UI, |
| "r32ui", |
| 4, |
| { 0xFF, 0x00, 0x00, 0x00 }, |
| { 0x51, 0x00, 0x00, 0x00 }, |
| { 0xF3, 0x00, 0x00, 0x00 }, |
| { 0x00, 0x00, 0x00, 0x00 }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x51, 0x00, 0x00, 0xFF }, |
| { 0xF3, 0x00, 0x00, 0xFF }, |
| { 0x00, 0x00, 0x00, 0xFF }, |
| }, |
| { |
| GL_RG32UI, |
| "rg32ui", |
| 8, |
| { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, |
| { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, |
| { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
| { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x00, 0xFF, 0x00, 0xFF }, |
| { 0x00, 0x00, 0x00, 0xFF }, |
| { 0xFF, 0xFF, 0x00, 0xFF }, |
| }, |
| { |
| GL_RGBA32UI, |
| "rgba32ui", |
| 16, |
| { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, |
| { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, |
| { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, |
| /* expected values */ |
| { 0xFF, 0x00, 0x00, 0xFF }, |
| { 0x00, 0xFF, 0x00, 0xFF }, |
| { 0x00, 0x00, 0xFF, 0xFF }, |
| { 0xFF, 0xFF, 0xFF, 0xFF }, |
| }, |
| { |
| /* DEPTH formats are tested by comparing with reference values hard-coded in shaders */ |
| GL_DEPTH_COMPONENT16, |
| "depth_component16", |
| 2, |
| { 0xFF, 0xE8 }, /* ~ 0.91 */ |
| { 0xFF, 0xAB }, /* ~ 0.67 */ |
| { 0x00, 0x78 }, /* ~ 0.46 */ |
| { 0x00, 0x3C }, /* ~ 0.23 */ |
| /* expected values */ |
| { 0x00, 0x00, 0x00, 0xff }, |
| { 0x00, 0x00, 0xff, 0xff }, |
| { 0x00, 0xff, 0xff, 0xff }, |
| { 0xff, 0xff, 0xff, 0xff }, |
| }, |
| { |
| /* little-endian order, so the bytes are in reverse order: stencil first, then depth */ |
| GL_DEPTH24_STENCIL8, |
| "depth24_stencil8", |
| 4, |
| { 0x00, 0x00, 0xE8, 0xFF }, /* ~ 0.99 */ |
| { 0x88, 0x00, 0xAB, 0xAF }, /* ~ 0.68 */ |
| { 0xBB, 0x28, 0x55, 0x7F }, /* ~ 0.49 */ |
| { 0xFF, 0x78, 0x80, 0x02 }, /* ~ 0.01 */ |
| /* expected values */ |
| { 0x00, 0x00, 0x00, 0xff }, |
| { 0x00, 0x00, 0xff, 0xff }, |
| { 0x00, 0xff, 0xff, 0xff }, |
| { 0xff, 0xff, 0xff, 0xff }, |
| } |
| }; |
| |
| struct InternalFormat |
| { |
| GLenum sizedFormat; |
| GLenum baseFormat; |
| GLenum format; |
| GLenum type; |
| InternalFormatSamplerType sampler; |
| InternalFormatBits bits; |
| GLuint flags; // InternalFormatFlag |
| }; |
| |
| static const InternalFormat glInternalFormats[] = |
| { |
| { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, NO_FLAG } }, NO_FLAG }, |
| { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 8, NO_FLAG } }, NO_FLAG }, |
| |
| { GL_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| // Table 3.12 |
| { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_R16, GL_RED, GL_RED, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_R16_SNORM, GL_RED, GL_RED, GL_SHORT, SAMPLER_NORM, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RG16, GL_RG, GL_RG, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RG16_SNORM, GL_RG, GL_RG, GL_SHORT, SAMPLER_NORM, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_R3_G3_B2, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, SAMPLER_UNORM, { { 3, 3, 2, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED }, |
| { GL_RGB4, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 4, 4, 4, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB5, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 5, 5, 5, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB565, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, SAMPLER_UNORM, { { 5, 6, 5, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| { GL_RGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_ES30 }, |
| { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB10, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {10,10,10, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB12, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {12,12,12, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16_SNORM, GL_RGB, GL_RGB, GL_SHORT, SAMPLER_NORM, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA2, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 2, 2, 2, 2, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| { GL_RGBA4, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, SAMPLER_UNORM, { { 4, 4, 4, 4, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| { GL_RGB5_A1, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, SAMPLER_UNORM, { { 5, 5, 5, 1, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| |
| { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| { GL_RGB10_A2, GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, SAMPLER_UNORM, { {10,10,10, 2, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 }, |
| { GL_RGB10_A2UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, SAMPLER_UINT, { {10,10,10, 2, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 }, |
| |
| { GL_RGBA12, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {12,12,12,12, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA16, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RGBA16_SNORM, GL_RGBA, GL_RGBA, GL_SHORT, SAMPLER_NORM, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| { GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_SRGB8_ALPHA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| |
| { GL_R16F, GL_RED, GL_RED, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RG16F, GL_RG, GL_RG, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_R11F_G11F_B10F, GL_RGB, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, SAMPLER_FLOAT, { {11,11,10, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 }, |
| |
| { GL_RGB9_E5, GL_RGB, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, SAMPLER_FLOAT, { { 9, 9, 9, 0, 0, 0, 0, 0, 5 } }, FLAG_PACKED }, |
| |
| { GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R8UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R16UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R32UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG16UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG32UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA8UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA16UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA32UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| |
| // Table 3.13 |
| { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,32, 0, NO_FLAG } }, 0 }, |
| { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 8, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 8, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| |
| // Table 3.14 |
| { GL_COMPRESSED_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_SRGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_SRGB_ALPHA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_RED_RGTC1, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_RG_RGTC2, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| { GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, |
| }; |
| |
| static const InternalFormat esInternalFormats[] = |
| { |
| // Table 3.3 |
| { GL_LUMINANCE, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 8, 0, 0, NO_FLAG } }, 0 }, |
| { GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 8, 0, 8, 0, 0, NO_FLAG } }, 0 }, |
| |
| { GL_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| // Table 3.12 |
| { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_ES30 }, |
| { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB565, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, SAMPLER_UNORM, { { 5, 6, 5, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| |
| { GL_RGBA4, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, SAMPLER_UNORM, { { 4, 4, 4, 4, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| { GL_RGB5_A1, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, SAMPLER_UNORM, { { 5, 5, 5, 1, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| |
| { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| |
| { GL_RGB10_A2, GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, SAMPLER_UNORM, { {10,10,10, 2, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_ES30 }, |
| { GL_RGB10_A2UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, SAMPLER_UINT, { {10,10,10, 2, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_ES30 }, |
| |
| { GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_SRGB8_ALPHA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| |
| { GL_R16F, GL_RED, GL_RED, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RG16F, GL_RG, GL_RG, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, |
| { GL_R11F_G11F_B10F, GL_RGB, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, SAMPLER_FLOAT, { {11,11,10, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 }, |
| |
| { GL_RGB9_E5, GL_RGB, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, SAMPLER_FLOAT, { { 9, 9, 9, 0, 0, 0, 0, 0, 5 } }, FLAG_PACKED }, |
| |
| { GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R8UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R16UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_R32UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG8UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG16UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RG32UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, |
| { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA8UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA16UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_RGBA32UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| |
| // Table 3.13 |
| { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 0, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 8, NO_FLAG } }, FLAG_REQ_RBO }, |
| { GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 8, NO_FLAG } }, FLAG_PACKED|FLAG_REQ_RBO }, |
| }; |
| |
| const char* basic_vs = "precision mediump float;\n" |
| "out vec2 texCoord;\n" |
| "void main(void)\n" |
| "{\n" |
| " switch(gl_VertexID)\n" |
| " {\n" |
| " case 0:\n" |
| " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" |
| " texCoord = vec2(2.0, -1.0);\n" |
| " break;\n" |
| " case 1:\n" |
| " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" |
| " texCoord = vec2(2.0, 2.0);\n" |
| " break;\n" |
| " case 2:\n" |
| " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" |
| " texCoord = vec2(-1.0, -1.0);\n" |
| " break;\n" |
| " case 3:\n" |
| " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" |
| " texCoord = vec2(-1.0, 2.0);\n" |
| " break;\n" |
| " }\n" |
| "}"; |
| |
| const char* basic_fs = "precision mediump float;\n" |
| "uniform sampler2D texture0;\n" |
| "in vec2 texCoord;\n" |
| "out vec4 color;\n" |
| "void main(void)\n" |
| "{\n" |
| " color = texture(texture0, texCoord);\n" |
| "}"; |
| |
| const char* shadow_fs = "precision mediump float;\n" |
| "uniform mediump sampler2DShadow texture0;\n" |
| "in vec2 texCoord;\n" |
| "out vec4 color;\n" |
| "void main(void)\n" |
| "{\n" |
| " float r = texture(texture0, vec3(texCoord.xy, 0.3));\n" |
| " float g = texture(texture0, vec3(texCoord.xy, 0.5));\n" |
| " float b = texture(texture0, vec3(texCoord.xy, 0.8));\n" |
| " color = vec4(r, g, b, 1.0);\n" |
| "}\n"; |
| |
| const char* integer_fs = "precision mediump float;\n" |
| "uniform mediump usampler2D texture0;\n" |
| "in vec2 texCoord;\n" |
| "out vec4 color;\n" |
| "void main(void)\n" |
| "{\n" |
| " highp uvec4 ci = texture(texture0, texCoord);\n" |
| " color = vec4(ci) / 255.0; // we are using an integer texture format - so convert to float\n" |
| " if (ci.a > 0u)\n" |
| " color.a = 1.0;\n" |
| " else\n" |
| " color.a = 0.0;\n" |
| "}"; |
| |
| struct TestArea |
| { |
| GLsizei left; |
| GLsizei right; |
| GLsizei top; |
| GLsizei bottom; |
| }; |
| |
| class TestClampModeForInternalFormat : public deqp::TestCase |
| { |
| public: |
| /* Public methods */ |
| TestClampModeForInternalFormat(deqp::Context& context, const std::string& name, GLenum internalFormat, |
| GLenum clampMode, GLint lodLevel, GLsizei width, GLsizei height); |
| virtual ~TestClampModeForInternalFormat() |
| { |
| } |
| |
| /* Public methods inherited from TestCase */ |
| virtual tcu::TestNode::IterateResult iterate(void); |
| |
| private: |
| /* Private methods */ |
| const FormatInfo* findFormat(GLenum internalformat) const; |
| const InternalFormat& findInternalFormat(GLenum internalformat) const; |
| void clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod, GLenum internalformat, GLenum type, |
| GLenum format) const; |
| void fillTextureWithColor(GLubyte* texture_data, GLsizei tex_width, GLsizei tex_height, |
| GLenum internalformat) const; |
| void calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const; |
| GLsizei proportion(GLsizei a, GLsizei b, GLsizei c) const; |
| bool isEqual(const GLubyte* color1, const GLubyte* color2, GLubyte tolerance) const; |
| |
| bool verifyClampMode(GLubyte* buf, GLsizei width, GLsizei height, GLenum clampMode, GLenum internalformat) const; |
| bool verifyClampToEdge(GLubyte* buf, GLsizei width_init, GLsizei height_init, GLsizei width, GLsizei height, |
| GLenum internalformat) const; |
| bool verifyRepeat(GLubyte* buf, GLsizei width, GLsizei height, GLenum internalformat) const; |
| bool verifyMirroredRepeat(GLubyte* buf, GLsizei width, GLsizei height, GLenum internalformat) const; |
| |
| private: |
| /* Private attributes */ |
| GLenum m_internalFormat; |
| GLenum m_clampMode; |
| GLint m_lodLevel; |
| GLsizei m_width; |
| GLsizei m_height; |
| }; |
| |
| /** Constructor. |
| * |
| * @param context Rendering context. |
| **/ |
| TestClampModeForInternalFormat::TestClampModeForInternalFormat(deqp::Context& context, const std::string& name, |
| GLenum internalFormat, GLenum clampMode, GLint lodLevel, |
| GLsizei width, GLsizei height) |
| : deqp::TestCase(context, name.c_str(), "") |
| , m_internalFormat(internalFormat) |
| , m_clampMode(clampMode) |
| , m_lodLevel(lodLevel) |
| , m_width(width) |
| , m_height(height) |
| { |
| /* Left blank intentionally */ |
| } |
| |
| const InternalFormat& TestClampModeForInternalFormat::findInternalFormat(GLenum internalformat) const |
| { |
| const InternalFormat* internalFormats = glInternalFormats; |
| GLsizei internalFormatsCount = DE_LENGTH_OF_ARRAY(glInternalFormats); |
| |
| if (glu::isContextTypeES(m_context.getRenderContext().getType())) |
| { |
| internalFormats = esInternalFormats; |
| internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalFormats); |
| } |
| |
| for (GLsizei i = 0; i < internalFormatsCount; i++) |
| { |
| if (internalFormats[i].sizedFormat == internalformat) |
| return internalFormats[i]; |
| } |
| |
| TCU_FAIL("Internal format not found"); |
| } |
| |
| const FormatInfo* TestClampModeForInternalFormat::findFormat(GLenum internalformat) const |
| { |
| for (GLsizei i = 0; i < DE_LENGTH_OF_ARRAY(testedFormats); i++) |
| if (testedFormats[i].internalformat == internalformat) |
| return &testedFormats[i]; |
| return NULL; |
| } |
| |
| bool TestClampModeForInternalFormat::isEqual(const GLubyte* color1, const GLubyte* color2, GLubyte tolerance) const |
| { |
| for (int i = 0; i < 4; i++) |
| { |
| if (de::abs((int)color1[i] - (int)color2[i]) > tolerance) |
| return false; |
| } |
| return true; |
| } |
| |
| /** Fill texture with RGBW colors, according to the scheme: |
| * R R R G G G |
| * R R R G G G |
| * R R R G G G |
| * B B B W W W |
| * B B B W W W |
| * B B B W W W |
| * |
| * NOTE: width of the red and blue rectangles would be less than green and white ones for odd texture's widths |
| * height of the red and green rectangles would be less than blue and white ones for odd texture's heights |
| */ |
| void TestClampModeForInternalFormat::fillTextureWithColor(GLubyte* texture_data, GLsizei tex_width, GLsizei tex_height, |
| GLenum internalformat) const |
| { |
| const FormatInfo* testedFormat = findFormat(internalformat); |
| const GLubyte* red = testedFormat->internalred; |
| const GLubyte* green = testedFormat->internalgreen; |
| const GLubyte* blue = testedFormat->internalblue; |
| const GLubyte* white = testedFormat->internalwhite; |
| const GLsizei size = testedFormat->pixelSize; |
| |
| GLint i = 0; |
| GLint j = 0; |
| for (j = 0; j < tex_height / 2; j++) |
| { |
| for (i = 0; i < tex_width / 2; i++) |
| { |
| deMemcpy(texture_data, red, size); |
| texture_data += size; |
| } |
| for (; i < tex_width; i++) |
| { |
| deMemcpy(texture_data, green, size); |
| texture_data += size; |
| } |
| } |
| for (; j < tex_height; j++) |
| { |
| for (i = 0; i < tex_width / 2; i++) |
| { |
| deMemcpy(texture_data, blue, size); |
| texture_data += size; |
| } |
| for (; i < tex_width; i++) |
| { |
| deMemcpy(texture_data, white, size); |
| texture_data += size; |
| } |
| } |
| } |
| |
| void TestClampModeForInternalFormat::clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod, |
| GLenum internalformat, GLenum type, GLenum format) const |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| |
| GLint level; |
| for (level = lod; level > 0; level--) |
| { |
| width *= 2; |
| height *= 2; |
| } |
| |
| bool continueLoop = true; |
| std::vector<GLubyte> tex_buf(width * height * MAX_PIXEL_SIZE, 0); |
| do |
| { |
| if (level != lod) |
| gl.texImage2D(target, level, internalformat, width, height, 0, format, type, &tex_buf[0]); |
| level++; |
| |
| continueLoop = !((height == 1) && (width == 1)); |
| if (width > 1) |
| width /= 2; |
| if (height > 1) |
| height /= 2; |
| } while (continueLoop); |
| } |
| |
| /* Calculate error epsilons to the least accurate of either |
| ** frame buffer or texture precision. RGBA epsilons are |
| ** returned in textureEpsilon[]. target must be a valid |
| ** texture target. |
| */ |
| void TestClampModeForInternalFormat::calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const |
| { |
| GLint i, bits; |
| GLint bufferBits[4]; |
| |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| gl.getIntegerv(GL_RED_BITS, &bufferBits[0]); |
| gl.getIntegerv(GL_GREEN_BITS, &bufferBits[1]); |
| gl.getIntegerv(GL_BLUE_BITS, &bufferBits[2]); |
| gl.getIntegerv(GL_ALPHA_BITS, &bufferBits[3]); |
| |
| for (i = 0; i < 4; i++) |
| { |
| |
| if (textureBits[i] == 0) |
| { |
| /* 'exact' */ |
| bits = 1000; |
| } |
| else |
| { |
| bits = textureBits[i]; |
| } |
| |
| /* Some tests fail on RGB10_A2 pixelformat, because framebuffer precision calculated here is 10-bit, but these tests use 8-bit data types |
| for pixel transfers and 8-bit textures. Because of that, the required precision is limited to 8-bit only. */ |
| if (bits > 8) |
| { |
| bits = 8; |
| } |
| |
| /* frame buffer bits */ |
| if (bits > bufferBits[i]) |
| { |
| bits = bufferBits[i]; |
| } |
| |
| if (bits == 0) |
| { |
| /* infinity */ |
| textureEpsilon[i] = 2.0f; |
| } |
| else |
| { |
| const float zeroEpsilon = deFloatLdExp(1.0f, -13); |
| textureEpsilon[i] = (1.0f / (deFloatLdExp(1.0f, bits) - 1.0f)) + zeroEpsilon; |
| textureEpsilon[i] = (float)deMin(1.0f, textureEpsilon[i]); |
| } |
| |
| /* If we have 8 bits framebuffer, we should hit the right value within one intensity level. */ |
| if (bits == 8 && bufferBits[i] != 0) |
| { |
| textureEpsilon[i] /= 2.0; |
| } |
| } |
| } |
| |
| /* calculate (a * b) / c with rounding */ |
| GLsizei TestClampModeForInternalFormat::proportion(GLsizei a, GLsizei b, GLsizei c) const |
| { |
| float result = (float)a * b; |
| return (GLsizei)(0.5f + result / c); |
| } |
| |
| /* check out the read-back values for GL_CLAMP_TO_EDGE mode |
| * r r r g g g |
| * r r r g g g |
| * r r R G g g |
| * b b B W w w |
| * b b b w w w |
| * b b b w w w |
| |
| width_init, height_init arguments refer to the basic pattern texture, which describes proportions |
| between colors in the rendered rectangle (tex_width, tex_height) |
| */ |
| bool TestClampModeForInternalFormat::verifyClampToEdge(GLubyte* buf, GLsizei width_init, GLsizei height_init, |
| GLsizei width, GLsizei height, GLenum internalformat) const |
| { |
| GLint i, h; |
| const FormatInfo* testedFormat = findFormat(internalformat); |
| const GLubyte* red = testedFormat->RGBAred; |
| const GLubyte* green = testedFormat->RGBAgreen; |
| const GLubyte* blue = testedFormat->RGBAblue; |
| const GLubyte* white = testedFormat->RGBAwhite; |
| const GLsizei size = 4; |
| const GLsizei skip = 6; |
| |
| GLsizei red_w = proportion(width, width_init / 2, width_init); |
| GLsizei red_h = proportion(height, height_init / 2, height_init); |
| GLsizei bits[4] = { 8, 8, 8, 8 }; |
| GLfloat epsilonf[4]; |
| GLubyte epsilons[4]; |
| |
| TestArea check_area = { 0, width, 0, height }; |
| |
| calcTextureEpsilon(bits, epsilonf); |
| for (i = 0; i < 4; ++i) |
| { |
| epsilons[i] = (GLubyte)(epsilonf[i] * 255.0f); |
| } |
| |
| for (h = 0; h < red_h - skip / 2; h++) |
| { |
| for (i = 0; i < red_w - skip / 2; i++) |
| { |
| /* skip over corner pixel to avoid issues with mipmap selection */ |
| if (i >= check_area.left || h >= check_area.top) |
| if (!isEqual(buf, red, epsilons[0])) |
| TCU_FAIL("verifyClampToEdge failed"); |
| buf += size; |
| } |
| |
| /* skip over border pixels to avoid issues with rounding */ |
| i += skip; |
| buf += skip * size; |
| |
| for (; i < width; i++) |
| { |
| /* skip over corner pixel to avoid issues with mipmap selection */ |
| if (i < check_area.right || h >= check_area.top) |
| if (!isEqual(buf, green, epsilons[1])) |
| TCU_FAIL("verifyClampToEdge failed"); |
| buf += size; |
| } |
| } |
| |
| /* skip over border pixels to avoid issues with rounding */ |
| h += skip; |
| buf += skip * width * size; |
| |
| for (; h < height; h++) |
| { |
| for (i = 0; i < red_w - skip / 2; i++) |
| { |
| /* skip over corner pixel to avoid issues with mipmap selection */ |
| if (i >= check_area.left || h < check_area.bottom) |
| if (!isEqual(buf, blue, epsilons[2])) |
| TCU_FAIL("verifyClampToEdge failed"); |
| buf += size; |
| } |
| |
| /* skip over border pixels to avoid issues with rounding */ |
| i += skip; |
| buf += skip * size; |
| |
| for (; i < width; i++) |
| { |
| /* skip over corner pixel to avoid issues with mipmap selection */ |
| if (i < check_area.right || h < check_area.bottom) |
| if (!isEqual(buf, white, epsilons[0])) |
| TCU_FAIL("verifyClampToEdge failed"); |
| buf += size; |
| } |
| } |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyClampToEdge succeeded." |
| << tcu::TestLog::EndMessage; |
| return true; |
| } |
| |
| /* check out the read-back values for GL_REPEAT mode |
| * r g r g r g |
| * b w b w b w |
| * r g R G r g |
| * b w B W b w |
| * r g r g r g |
| * b w b w b w |
| */ |
| bool TestClampModeForInternalFormat::verifyRepeat(GLubyte* buf, GLsizei width, GLsizei height, |
| GLenum internalformat) const |
| { |
| GLint i, j, g, h; |
| const FormatInfo* testedFormat = findFormat(internalformat); |
| |
| const GLubyte* red = testedFormat->RGBAred; |
| const GLubyte* green = testedFormat->RGBAgreen; |
| const GLubyte* blue = testedFormat->RGBAblue; |
| const GLubyte* white = testedFormat->RGBAwhite; |
| const GLsizei size = 4; |
| const GLubyte tolerance = 0; |
| |
| GLsizei tex_w = width / 3; |
| GLsizei tex_h = height / 3; |
| |
| GLsizei red_w = tex_w / 2; |
| GLsizei red_h = tex_h / 2; |
| |
| GLsizei green_w = tex_w - red_w; |
| |
| GLsizei blue_w = red_w; |
| GLsizei blue_h = tex_h - red_h; |
| |
| GLsizei white_w = green_w; |
| |
| for (g = 0; g < 3; g++) |
| { |
| for (h = 0; h < red_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| for (i = 0; i < red_w; i++) |
| { |
| if (!isEqual(buf, red, tolerance)) |
| TCU_FAIL("verifyRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < green_w; i++) |
| { |
| if (!isEqual(buf, green, tolerance)) |
| TCU_FAIL("verifyRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| for (h = 0; h < blue_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| for (i = 0; i < blue_w; i++) |
| { |
| if (!isEqual(buf, blue, tolerance)) |
| TCU_FAIL("verifyRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < white_w; i++) |
| { |
| if (!isEqual(buf, white, tolerance)) |
| TCU_FAIL("verifyRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| } |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyRepeat succeeded." |
| << tcu::TestLog::EndMessage; |
| return true; |
| } |
| |
| /* check out the read-back values for GL_MIRRORED_REPEAT mode |
| * w b b w w b |
| * g r r g g r |
| * r g R G r g |
| * w b B W w b |
| * w b b w w b |
| * g r r g g r |
| */ |
| bool TestClampModeForInternalFormat::verifyMirroredRepeat(GLubyte* buf, GLsizei width, GLsizei height, |
| GLenum internalformat) const |
| { |
| GLint i, j, g, h; |
| const FormatInfo* testedFormat = findFormat(internalformat); |
| |
| const GLubyte* red = testedFormat->RGBAred; |
| const GLubyte* green = testedFormat->RGBAgreen; |
| const GLubyte* blue = testedFormat->RGBAblue; |
| const GLubyte* white = testedFormat->RGBAwhite; |
| |
| const GLsizei size = 4; |
| const GLubyte tolerance = 0; |
| |
| GLsizei tex_w = width / 3; |
| GLsizei tex_h = height / 3; |
| |
| GLsizei red_w = tex_w / 2; |
| GLsizei red_h = tex_h / 2; |
| |
| GLsizei green_w = tex_w - red_w; |
| GLsizei green_h = red_h; |
| |
| GLsizei blue_w = red_w; |
| GLsizei blue_h = tex_h - red_h; |
| |
| GLsizei white_w = green_w; |
| GLsizei white_h = blue_h; |
| |
| for (g = 0; g < 3; g++) |
| { |
| if (g % 2 == 0) |
| { |
| for (h = 0; h < white_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| if (j % 2 == 0) |
| { |
| for (i = 0; i < white_w; i++) |
| { |
| if (!isEqual(buf, white, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < blue_w; i++) |
| { |
| if (!isEqual(buf, blue, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| else |
| { |
| for (i = 0; i < blue_w; i++) |
| { |
| if (!isEqual(buf, blue, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < white_w; i++) |
| { |
| if (!isEqual(buf, white, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| } |
| for (h = 0; h < green_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| if (j % 2 == 0) |
| { |
| for (i = 0; i < green_w; i++) |
| { |
| if (!isEqual(buf, green, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < red_w; i++) |
| { |
| if (!isEqual(buf, red, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| else |
| { |
| for (i = 0; i < red_w; i++) |
| { |
| if (!isEqual(buf, red, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < green_w; i++) |
| { |
| if (!isEqual(buf, green, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| } |
| } |
| else |
| { |
| for (h = 0; h < green_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| if (j % 2 == 0) |
| { |
| for (i = 0; i < green_w; i++) |
| { |
| if (!isEqual(buf, green, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < red_w; i++) |
| { |
| if (!isEqual(buf, red, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| else |
| { |
| for (i = 0; i < red_w; i++) |
| { |
| if (!isEqual(buf, red, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < green_w; i++) |
| { |
| if (!isEqual(buf, green, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| } |
| for (h = 0; h < white_h; h++) |
| { |
| for (j = 0; j < 3; j++) |
| { |
| if (j % 2 == 0) |
| { |
| for (i = 0; i < white_w; i++) |
| { |
| if (!isEqual(buf, white, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < blue_w; i++) |
| { |
| if (!isEqual(buf, blue, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| else |
| { |
| for (i = 0; i < blue_w; i++) |
| { |
| if (!isEqual(buf, blue, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| for (i = 0; i < white_w; i++) |
| { |
| if (!isEqual(buf, white, tolerance)) |
| TCU_FAIL("verifyMirroredRepeat failed"); |
| |
| buf += size; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyMirroredRepeat succeeded." |
| << tcu::TestLog::EndMessage; |
| return true; |
| } |
| |
| bool TestClampModeForInternalFormat::verifyClampMode(GLubyte* buf, GLsizei width, GLsizei height, GLenum clampMode, |
| GLenum internalformat) const |
| { |
| switch (clampMode) |
| { |
| case GL_CLAMP_TO_EDGE: |
| return verifyClampToEdge(buf, width, height, width, height, internalformat); |
| case GL_REPEAT: |
| return verifyRepeat(buf, width, height, internalformat); |
| case GL_MIRRORED_REPEAT: |
| return verifyMirroredRepeat(buf, width, height, internalformat); |
| } |
| return false; |
| } |
| |
| /** Execute test |
| * |
| * Upload the texture, set up a quad 3 times the size of the |
| * texture. Coordinates should be integers to avoid spatial rounding |
| * differences. Set texture coordinates as shown below. |
| * |
| * (-1, 2, 0) --- (2, 2, 0) |
| * | | |
| * | | |
| * (-1, -1, 0) --- (2, -1, 0) |
| * |
| * Set TEXTURE_MIN_FILTER for the texture to NEAREST_MIPMAP_NEAREST. |
| * |
| * Repeat the test for each repeat mode, i.e., set the repeat mode to |
| * one of CLAMP_TO_EDGE, REPEAT, and MIRRORED_REPEAT for both S and |
| * T, depending on the iteration. |
| * |
| * For vertex shader, just pass on the vertices and texture |
| * coordinates for interpolation. For fragment shader, look up the |
| * fragment corresponding to given texture coordinates. |
| * |
| * Render the quad. |
| * |
| * Read back the pixels covering the quad. |
| * |
| * For CLAMP_TO_EDGE result should be (Each character has dimension |
| * half the original texture, original texture in capitals): |
| * |
| * rrrggg |
| * rrrggg |
| * rrRGgg |
| * bbBWww |
| * bbbwww |
| * bbbwww |
| * |
| * For REPEAT: |
| * |
| * rgrgrg |
| * bwbwbw |
| * rgRGrg |
| * bwBWbw |
| * rgrgrg |
| * bwbwbw |
| * |
| * For MIRRORED_REPEAT |
| * |
| * wbbwwb |
| * grrggr |
| * grRGgr |
| * wbBWwb |
| * wbbwwb |
| * grrggr |
| * |
| * If implementation under test is for OpenGL 3.2 Core specification, |
| * the test includes repeat mode of CLAMP_TO_BORDER. For this case, |
| * the TEXTURE_BORDER_COLOR is set to black (0, 0, 0, 1) (RGBA). Then |
| * the result will be (0 meaning black): |
| * |
| * 000000 |
| * 000000 |
| * 00RG00 |
| * 00BW00 |
| * 000000 |
| * 000000 |
| * |
| * Procedure: |
| * - allocate large enough memory buffer for the texture data - tex_width * tex_height * tex_depth * MAX_PIXEL_SIZE |
| * - fill the buffer with the pattern |
| * - upload the texture with glTexImage2D() to the requested level |
| * - upload black texture to other LOD levels |
| * - render a quad with size matching the texture LOD level |
| * - read back pixels |
| * - verify the results |
| * - free the buffer |
| **/ |
| tcu::TestNode::IterateResult TestClampModeForInternalFormat::iterate(void) |
| { |
| const glw::Functions& gl = m_context.getRenderContext().getFunctions(); |
| m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); |
| |
| /* Retrieve properties of the tested format */ |
| const InternalFormat& internalFormatStruct = findInternalFormat(m_internalFormat); |
| GLenum format = internalFormatStruct.format; |
| GLenum type = internalFormatStruct.type; |
| GLenum internalformat = internalFormatStruct.sizedFormat; |
| GLenum sampler = internalFormatStruct.sampler; |
| GLsizei viewWidth = 3 * m_width; |
| GLsizei viewHeight = 3 * m_height; |
| |
| /* Allocate buffers for texture data */ |
| GLsizei resultTextureSize = viewWidth * viewHeight; |
| std::vector<GLubyte> textureData(resultTextureSize * MAX_PIXEL_SIZE, 0); |
| std::fill(textureData.begin(), textureData.end(), 0); |
| |
| /* Set pixel storage modes */ |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); |
| gl.pixelStorei(GL_PACK_ALIGNMENT, 1); |
| |
| /* Generate and bind the texture object that will store test result*/ |
| GLuint resultTextureId; |
| gl.genTextures(1, &resultTextureId); |
| gl.bindTexture(GL_TEXTURE_2D, resultTextureId); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewWidth, viewHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]); |
| |
| /* Reuse textureData buffer to initialize source texture. |
| * Fill the buffer according to the color scheme */ |
| fillTextureWithColor(&textureData[0], m_width, m_height, internalformat); |
| |
| /* Generate and bind the texture object that will store color scheme*/ |
| GLuint sourceTextureId; |
| gl.genTextures(1, &sourceTextureId); |
| gl.bindTexture(GL_TEXTURE_2D, sourceTextureId); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| gl.texImage2D(GL_TEXTURE_2D, m_lodLevel, internalformat, m_width, m_height, 0, format, type, &textureData[0]); |
| |
| /* Set compare function used by shadow samplers */ |
| if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format)) |
| { |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GEQUAL); |
| } |
| |
| /* Clear the other source texture levels with black */ |
| clearTextures(GL_TEXTURE_2D, m_width, m_height, m_lodLevel, internalformat, type, format); |
| |
| /* Create and bind the FBO */ |
| GLuint fbId; |
| gl.genFramebuffers(1, &fbId); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbId); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resultTextureId, 0); |
| |
| /* Construct shaders */ |
| glu::ContextType contextType = m_context.getRenderContext().getType(); |
| glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType); |
| std::string version = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n"); |
| std::string vs = version + basic_vs; |
| std::string fs = version; |
| if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format)) |
| fs += shadow_fs; |
| else if ((SAMPLER_UINT == sampler) || (SAMPLER_INT == sampler)) |
| fs += integer_fs; |
| else |
| fs += basic_fs; |
| glu::ProgramSources sources = glu::makeVtxFragSources(vs, fs); |
| |
| /* Create program object */ |
| glu::ShaderProgram program(m_context.getRenderContext(), sources); |
| if (!program.isOk()) |
| TCU_FAIL("Compile failed"); |
| GLint programId = program.getProgram(); |
| GLint samplerLocation = gl.getUniformLocation(programId, "texture0"); |
| if (-1 == samplerLocation) |
| TCU_FAIL("Fragment shader does not have texture0 input."); |
| gl.useProgram(programId); |
| gl.uniform1i(samplerLocation, 0); |
| |
| m_context.getTestContext().getLog() << tcu::TestLog::Message << "NPOT [" << m_internalFormat << "] (" << viewWidth |
| << " x " << viewHeight << "), Level: " << m_lodLevel |
| << tcu::TestLog::EndMessage; |
| |
| /* Set the wrap parameters for texture coordinates s and t to the current clamp mode */ |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_clampMode); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_clampMode); |
| |
| /* Set viewport's width and height based on an overview */ |
| gl.viewport(0, 0, viewWidth, viewHeight); |
| |
| /* Draw rectangle */ |
| GLuint vaoId; |
| gl.genVertexArrays(1, &vaoId); |
| gl.bindVertexArray(vaoId); |
| gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); |
| gl.bindVertexArray(0); |
| gl.deleteVertexArrays(1, &vaoId); |
| |
| /* Read back pixels and verify that they have the proper values */ |
| std::vector<GLubyte> buffer(resultTextureSize * 4, 0); |
| gl.readPixels(0, 0, viewWidth, viewHeight, GL_RGBA, GL_UNSIGNED_BYTE, (void*)&(buffer[0])); |
| if (verifyClampMode(&buffer[0], viewWidth, viewHeight, m_clampMode, internalformat)) |
| m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); |
| |
| /* Cleanup */ |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.deleteTextures(1, &resultTextureId); |
| gl.deleteTextures(1, &sourceTextureId); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, fbId); |
| gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); |
| gl.bindFramebuffer(GL_FRAMEBUFFER, 0); |
| gl.deleteFramebuffers(1, &fbId); |
| |
| return STOP; |
| } |
| |
| /** Constructor. |
| * |
| * @param context Rendering context. |
| */ |
| TextureRepeatModeTests::TextureRepeatModeTests(deqp::Context& context) |
| : TestCaseGroup(context, "texture_repeat_mode", "Texture repeat mode tests") |
| { |
| } |
| |
| /** Initializes the test group contents. */ |
| void TextureRepeatModeTests::init() |
| { |
| /* Texture sizes to test */ |
| const struct TexSize |
| { |
| GLsizei width; |
| GLsizei height; |
| } textureSizes[] = { |
| { 49, 23 }, { 11, 131 }, |
| }; |
| |
| /* LOD levels to test */ |
| const GLint levelsOfDetail[] = { 0, 1, 2 }; |
| |
| for (GLint sizeIndex = 0; sizeIndex < DE_LENGTH_OF_ARRAY(textureSizes); sizeIndex++) |
| { |
| const TexSize& ts = textureSizes[sizeIndex]; |
| for (GLint formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(testedFormats); formatIndex++) |
| { |
| const FormatInfo& formatInfo = testedFormats[formatIndex]; |
| GLenum internalFormat = formatInfo.internalformat; |
| for (GLsizei lodIndex = 0; lodIndex < DE_LENGTH_OF_ARRAY(levelsOfDetail); lodIndex++) |
| { |
| GLint lod = levelsOfDetail[lodIndex]; |
| std::stringstream testBaseName; |
| testBaseName << formatInfo.name << "_" << ts.width << "x" << ts.height << "_" << lod << "_"; |
| std::string names[] = { testBaseName.str() + "clamp_to_edge", testBaseName.str() + "repeat", |
| testBaseName.str() + "mirrored_repeat" }; |
| addChild(new TestClampModeForInternalFormat(m_context, names[0], internalFormat, GL_CLAMP_TO_EDGE, lod, |
| ts.width, ts.height)); |
| addChild(new TestClampModeForInternalFormat(m_context, names[1], internalFormat, GL_REPEAT, lod, |
| ts.width, ts.height)); |
| addChild(new TestClampModeForInternalFormat(m_context, names[2], internalFormat, GL_MIRRORED_REPEAT, |
| lod, ts.width, ts.height)); |
| } |
| } |
| } |
| } |
| } /* glcts namespace */ |