/*------------------------------------------------------------------------- * 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 glcPackedPixelsTests.cpp * \brief */ /*-------------------------------------------------------------------*/ #include "glcPackedPixelsTests.hpp" #include "deMath.h" #include "glcMisc.hpp" #include "gluContextInfo.hpp" #include "gluShaderProgram.hpp" #include "gluStrUtil.hpp" #include "glwEnums.hpp" #include "glwFunctions.hpp" #include "tcuRenderTarget.hpp" #include "tcuTestLog.hpp" #include #include #include #include #include using namespace glw; using namespace glu; namespace glcts { enum { GRADIENT_WIDTH = 7, GRADIENT_HEIGHT = 3 }; enum InputOutputOperation { OUTPUT_GETTEXIMAGE, OUTPUT_READPIXELS, INPUT_TEXIMAGE, }; enum ComponentFormat { FORMAT_STENCIL, // stencil, unsigned int FORMAT_DEPTH, // depth, unsigned [fp|float] FORMAT_DEPTH_STENCIL, // depth+stencil, unsigned [fp|float] FORMAT_COLOR, // color, [signed|unsigned] fp FORMAT_COLOR_INTEGER, // color, [signed|unsigned] int }; enum TypeStorage { STORAGE_UNSIGNED, // unsigned fp/int STORAGE_SIGNED, // signed fp/int STORAGE_FLOAT, // signed/unsigned float }; 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 }; struct PixelType { GLenum type; int size; int storage; bool special; bool reversed; InternalFormatBits bits; bool clamp; }; struct PixelFormat { GLenum format; // format name int components; // number of components int componentFormat; // element meaning GLenum attachment; // target buffer InternalFormatBits componentOrder; // zero based element order, -1 for N/A }; enum InternalFormatSamplerType { SAMPLER_UNORM = 0, // unsigned normalized SAMPLER_NORM, // normalized SAMPLER_UINT, // unsigned integer SAMPLER_INT, // integer SAMPLER_FLOAT // floating-point }; enum InternalFormatFlag { 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 }; struct InternalFormat { GLenum sizedFormat; GLenum baseFormat; GLenum format; GLenum type; InternalFormatSamplerType sampler; InternalFormatBits bits; int flags; // InternalFormatFlag }; struct EnumFormats { GLenum internalformat; GLenum format; GLenum type; int size; bool bRenderable; }; #define PACK_DEFAULTI (0) #define PACK_DEFAULTUI (0) #define PACK_DEFAULTF (-2.0f) static const InternalFormat coreInternalformats[] = { { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, 0 }, { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, 0 }, { GL_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_R16, GL_RED, GL_RED, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_R16_SNORM, GL_RED, GL_RED, GL_SHORT, SAMPLER_NORM, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RG16, GL_RG, GL_RG, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RG16_SNORM, GL_RG, GL_RG, GL_SHORT, SAMPLER_NORM, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, 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, 0 } }, FLAG_PACKED }, { GL_RGB4, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 4, 4, 4, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB5, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 5, 5, 5, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_ES30 }, { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB10, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {10,10,10, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB12, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {12,12,12, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16_SNORM, GL_RGB, GL_RGB, GL_SHORT, SAMPLER_NORM, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA2, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 2, 2, 2, 2, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA4, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, SAMPLER_UNORM, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, 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, 0 } }, FLAG_PACKED|FLAG_REQ_RBO }, { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB10_A2, GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, SAMPLER_UNORM, { {10,10,10, 2, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 }, { GL_RGB10_A2UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT_10_10_10_2, SAMPLER_UINT, { {10,10,10, 2, 0, 0, 0, 0, 0 } }, 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, 0 } }, 0 }, { GL_RGBA16, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RGBA16_SNORM, GL_RGBA, GL_RGBA, GL_SHORT, SAMPLER_NORM, { {16,16,16,16, 0, 0, 0, 0, 0 } }, 0 }, { GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_SRGB8_ALPHA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16F, GL_RED, GL_RED, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RG16F, GL_RG, GL_RG, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, 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, 0 } }, 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, 0 } }, FLAG_REQ_RBO }, { GL_R8UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R32UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG16UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG32UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA8UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA16UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA32UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, 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, 0 } }, 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, 0 } }, 0 }, { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 0, 0 } }, 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, 0 } }, 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, 0 } }, FLAG_PACKED|FLAG_REQ_RBO }, { GL_COMPRESSED_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_SRGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_SRGB_ALPHA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_RED_RGTC1, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_RG_RGTC2, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, { GL_COMPRESSED_SIGNED_RG_RGTC2, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED }, }; static InternalFormat esInternalformats[] = { { GL_LUMINANCE, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 8, 0, 0, 0 } }, 0 }, { GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 8, 0, 0, 0, 0, 0 } }, 0 }, { GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 8, 0, 8, 0, 0, 0 } }, 0 }, { GL_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 0 }, { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_ES30 }, { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB565, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, SAMPLER_UNORM, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, 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, 0 } }, 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, 0 } }, FLAG_PACKED|FLAG_REQ_RBO }, { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 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, 0 } }, 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, 0 } }, 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, 0 } }, 0 }, { GL_SRGB8_ALPHA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16F, GL_RED, GL_RED, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RG16F, GL_RG, GL_RG, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA16F, GL_RGBA, GL_RGBA, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 }, { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, 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, 0 } }, 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, 0 } }, FLAG_REQ_RBO }, { GL_R8UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R16UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_R32UI, GL_RED, GL_RED_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG8UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG16UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RG32UI, GL_RG, GL_RG_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 }, { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA8UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA16UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_RGBA32UI, GL_RGBA, GL_RGBA_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO }, { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, 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, 0 } }, FLAG_REQ_RBO }, { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT, SAMPLER_FLOAT, { { 0, 0, 0, 0, 0, 0,32, 0, 0 } }, 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, 0 } }, 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, 0 } }, FLAG_PACKED|FLAG_REQ_RBO }, }; static const PixelFormat coreFormats[] = { { GL_STENCIL_INDEX, 1, FORMAT_STENCIL, GL_STENCIL_ATTACHMENT, { {-1,-1,-1,-1,-1,-1,-1, 0,-1} } }, { GL_DEPTH_COMPONENT, 1, FORMAT_DEPTH, GL_DEPTH_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0,-1,-1} } }, { GL_DEPTH_STENCIL, 2, FORMAT_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0, 1,-1} } }, { GL_RED, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_GREEN, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { {-1, 0,-1,-1,-1,-1,-1,-1,-1} } }, { GL_BLUE, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { {-1,-1, 0,-1,-1,-1,-1,-1,-1} } }, { GL_RG, 2, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RGB, 3, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } }, { GL_RGBA, 4, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } }, { GL_BGR, 3, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 2, 1, 0,-1,-1,-1,-1,-1,-1} } }, { GL_BGRA, 4, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 2, 1, 0, 3,-1,-1,-1,-1,-1} } }, { GL_RED_INTEGER, 1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_GREEN_INTEGER, 1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { {-1, 0,-1,-1,-1,-1,-1,-1,-1} } }, { GL_BLUE_INTEGER, 1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { {-1,-1, 0,-1,-1,-1,-1,-1,-1} } }, { GL_RG_INTEGER, 2, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RGB_INTEGER, 3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } }, { GL_RGBA_INTEGER, 4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } }, { GL_BGR_INTEGER, 3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 2, 1, 0,-1,-1,-1,-1,-1,-1} } }, { GL_BGRA_INTEGER, 4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 2, 1, 0, 3,-1,-1,-1,-1,-1} } }, }; static const PixelFormat esFormats[] = { { GL_DEPTH_COMPONENT, 1, FORMAT_DEPTH, GL_DEPTH_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0,-1,-1} } }, { GL_DEPTH_STENCIL, 2, FORMAT_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0, 1,-1} } }, { GL_RED, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RG, 2, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RGB, 3, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } }, { GL_RGBA, 4, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } }, { GL_LUMINANCE, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { {-1,-1,-1,-1,-1, 0,-1,-1,-1} } }, { GL_ALPHA, 1, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { {-1,-1,-1, 0,-1,-1,-1,-1,-1} } }, { GL_LUMINANCE_ALPHA, 2, FORMAT_COLOR, GL_COLOR_ATTACHMENT0, { {-1,-1,-1, 1,-1, 0,-1,-1,-1} } }, { GL_RED_INTEGER, 1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RG_INTEGER, 2, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } }, { GL_RGB_INTEGER, 3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } }, { GL_RGBA_INTEGER, 4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0, { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } }, }; static const PixelType coreTypes[] = { { GL_UNSIGNED_BYTE, sizeof(GLubyte), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_BYTE, sizeof(GLbyte), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_UNSIGNED_SHORT, sizeof(GLushort), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_SHORT, sizeof(GLshort), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_UNSIGNED_INT, sizeof(GLuint), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_INT, sizeof(GLint), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_HALF_FLOAT, sizeof(GLhalf), STORAGE_FLOAT, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_FLOAT, sizeof(GLfloat), STORAGE_FLOAT, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_5_6_5, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_4_4_4_4, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_5_5_5_1, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_2_10_10_10_REV, sizeof(GLuint), STORAGE_UNSIGNED, true, true, { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_24_8, sizeof(GLuint), STORAGE_UNSIGNED, true, false, { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, false }, { GL_UNSIGNED_INT_10F_11F_11F_REV, sizeof(GLuint), STORAGE_FLOAT, true, true, { { 6, 7, 7, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_5_9_9_9_REV, sizeof(GLuint), STORAGE_FLOAT, true, true, { { 9, 9, 9, 5, 0, 0, 0, 0, 0 } }, false }, { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, sizeof(GLfloat)+sizeof(GLuint), STORAGE_FLOAT, true, true, { { 0, 0, 0, 0, 0, 0,32, 8,24 } }, false }, { GL_UNSIGNED_BYTE_3_3_2, sizeof(GLubyte), STORAGE_UNSIGNED, true, false, { { 3, 3, 2, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_BYTE_2_3_3_REV, sizeof(GLubyte), STORAGE_UNSIGNED, true, true, { { 3, 3, 2, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_5_6_5_REV, sizeof(GLushort), STORAGE_UNSIGNED, true, true, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_4_4_4_4_REV, sizeof(GLushort), STORAGE_UNSIGNED, true, true, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_1_5_5_5_REV, sizeof(GLushort), STORAGE_UNSIGNED, true, true, { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_8_8_8_8, sizeof(GLuint), STORAGE_UNSIGNED, true, false, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_8_8_8_8_REV, sizeof(GLuint), STORAGE_UNSIGNED, true, true, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_10_10_10_2, sizeof(GLuint), STORAGE_UNSIGNED, true, true, { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false }, }; static const PixelType esTypes[] = { { GL_UNSIGNED_BYTE, sizeof(GLubyte), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_BYTE, sizeof(GLbyte), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_UNSIGNED_SHORT, sizeof(GLushort), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_SHORT, sizeof(GLshort), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true }, { GL_UNSIGNED_INT, sizeof(GLuint), STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_INT, sizeof(GLint), STORAGE_SIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_HALF_FLOAT, sizeof(GLhalf), STORAGE_FLOAT, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_FLOAT, sizeof(GLfloat), STORAGE_FLOAT, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_5_6_5, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_4_4_4_4, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_SHORT_5_5_5_1, sizeof(GLushort), STORAGE_UNSIGNED, true, false, { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_2_10_10_10_REV, sizeof(GLuint), STORAGE_UNSIGNED, true, true, { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_24_8, sizeof(GLuint), STORAGE_UNSIGNED, true, false, { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, false }, { GL_UNSIGNED_INT_10F_11F_11F_REV, sizeof(GLuint), STORAGE_FLOAT, true, true, { { 6, 7, 7, 0, 0, 0, 0, 0, 0 } }, false }, { GL_UNSIGNED_INT_5_9_9_9_REV, sizeof(GLuint), STORAGE_FLOAT, true, true, { { 9, 9, 9, 5, 0, 0, 0, 0, 0 } }, false }, { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, sizeof(GLfloat)+sizeof(GLuint), STORAGE_FLOAT, true, true, { { 0, 0, 0, 0, 0, 0,32, 8,24 } }, false }, }; static const EnumFormats esValidFormats[] = { { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, true }, { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE, 4, true }, { GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE, 4, true }, { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, true }, { GL_RGBA8_SNORM, GL_RGBA, GL_BYTE, 4, false }, { GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, true }, { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, true }, { GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, 8, false }, { GL_RGBA32F, GL_RGBA, GL_FLOAT, 16, false }, { GL_RGBA16F, GL_RGBA, GL_FLOAT, 16, false }, { GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, 4, true }, { GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE, 4, true }, { GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT, 8, true }, { GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT, 8, true }, { GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT, 16, true }, { GL_RGBA32I, GL_RGBA_INTEGER, GL_INT, 16, true }, { GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, 3, true }, { GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE, 3, true }, { GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE, 3, false }, { GL_RGB8_SNORM, GL_RGB, GL_BYTE, 3, false }, { GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, true }, { GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 4, false }, { GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT, 6, false }, { GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT, 12, false }, { GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, 4, false }, { GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT, 6, false }, { GL_RGB9_E5, GL_RGB, GL_FLOAT, 12, false }, { GL_RGB16F, GL_RGB, GL_HALF_FLOAT, 6, false }, { GL_RGB32F, GL_RGB, GL_FLOAT, 12, false }, { GL_RGB16F, GL_RGB, GL_FLOAT, 12, false }, { GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, 3, false }, { GL_RGB8I, GL_RGB_INTEGER, GL_BYTE, 3, false }, { GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, 6, false }, { GL_RGB16I, GL_RGB_INTEGER, GL_SHORT, 6, false }, { GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT, 12, false }, { GL_RGB32I, GL_RGB_INTEGER, GL_INT, 12, false }, { GL_RG8, GL_RG, GL_UNSIGNED_BYTE, 2, true }, { GL_RG8_SNORM, GL_RG, GL_BYTE, 2, false }, { GL_RG16F, GL_RG, GL_HALF_FLOAT, 4, false }, { GL_RG32F, GL_RG, GL_FLOAT, 8, false }, { GL_RG16F, GL_RG, GL_FLOAT, 8, false }, { GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE, 2, true }, { GL_RG8I, GL_RG_INTEGER, GL_BYTE, 2, true }, { GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT, 4, true }, { GL_RG16I, GL_RG_INTEGER, GL_SHORT, 4, true }, { GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT, 8, true }, { GL_RG32I, GL_RG_INTEGER, GL_INT, 8, true }, { GL_R8, GL_RED, GL_UNSIGNED_BYTE, 1, true }, { GL_R8_SNORM, GL_RED, GL_BYTE, 1, false }, { GL_R16F, GL_RED, GL_HALF_FLOAT, 2, false }, { GL_R32F, GL_RED, GL_FLOAT, 4, false }, { GL_R16F, GL_RED, GL_FLOAT, 4, false }, { GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 1, true }, { GL_R8I, GL_RED_INTEGER, GL_BYTE, 1, true }, { GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT, 2, true }, { GL_R16I, GL_RED_INTEGER, GL_SHORT, 2, true }, { GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT, 4, true }, { GL_R32I, GL_RED_INTEGER, GL_INT, 4, true }, { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, true }, { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 4, true }, { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 2, true }, { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT, 4, true }, { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 4, true }, { GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, 3, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, true }, { GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 2, false }, { GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, false }, { GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, 1, false }, }; static const EnumFormats coreValidFormats[] = { { GL_RGB, GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 3, true }, { GL_RGB_INTEGER, GL_RGB_INTEGER, GL_UNSIGNED_BYTE_3_3_2, 3, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 3, true }, { GL_RGB_INTEGER, GL_RGB_INTEGER, GL_UNSIGNED_BYTE_2_3_3_REV, 3, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 3, true }, { GL_RGB_INTEGER, GL_RGB_INTEGER, GL_UNSIGNED_SHORT_5_6_5, 3, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 3, true }, { GL_RGB_INTEGER, GL_RGB_INTEGER, GL_UNSIGNED_SHORT_5_6_5_REV, 3, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT_4_4_4_4, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT_4_4_4_4_REV, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_SHORT_4_4_4_4_REV, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_SHORT_4_4_4_4, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT_5_5_5_1, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_SHORT_5_5_5_1, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT_1_5_5_5_REV, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_SHORT_1_5_5_5_REV, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_INT_8_8_8_8, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_INT_8_8_8_8, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_INT_8_8_8_8_REV, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_INT_10_10_10_2, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_INT_10_10_10_2, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_INT_10_10_10_2, 4, true }, { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_BGRA, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_RGBA_INTEGER, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_BGRA_INTEGER, GL_BGRA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV, 4, true }, { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 2, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV, 3, true }, { GL_RGB, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV, 4, true }, { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 2, true }, }; static const EnumFormats validformats_EXT_texture_type_2_10_10_10_REV[] = { { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 4, false }, { GL_RGB, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 3, false } }; // Valid combinations given by GL_EXT_texture_type_2_10_10_10_REV and // GL_OES_required_internalformat extensions static const EnumFormats validformats_OES_required_internalformat[] = { { GL_RGB8_OES, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 3, true }, { GL_RGB565, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 4, true } }; // Companion type for GL_FLOAT_32_UNSIGNED_INT_24_8_REV. Stencil part was // not split into 24/8 to avoid any packing related issues from compiler. struct F_32_UINT_24_8_REV { GLfloat d; GLuint s; }; // custom pixel data type. holds both float and integer pixel data. memory consuming, but // it is not that relavant in this case. makes comparing more reliable and flexible struct FloatPixel { int i_r; int i_g; int i_b; int i_a; int i_d; int i_s; unsigned int ui_r; unsigned int ui_g; unsigned int ui_b; unsigned int ui_a; unsigned int ui_d; unsigned int ui_s; float r; float g; float b; float a; float d; float s; }; static const int NUM_FLOAT_PIXEL_COUNT = sizeof(FloatPixel) / sizeof(float); typedef int rawIntPixel[4]; typedef unsigned int rawUintPixel[4]; typedef float rawFloatPixel[4]; struct PackedPixelsBufferProperties { int elementsInGroup; // number of elements in a group int rowLength; // number of groups in the row int alignment; // alignment (in bytes) int elementSize; // size of an element (in bytes) int elementsInRow; // row size (in elements) int elementsInRowNoAlign; // row size (in elements) without alignment int rowCount; // number of rows in 2D image int imagesCount; // number of 2D images in 3D image int skipPixels; // (UN)PACK_SKIP_PIXELS int skipRows; // (UN)PACK_SKIP_ROWS int skipImages; // (UN)PACK_SKIP_IMAGES int swapBytes; int lsbFirst; }; std::string getTypeStr(GLenum type) { // this function extends glu::getTypeStr by types used in this tests typedef std::map TypeMap; static TypeMap typeMap; if (typeMap.empty()) { typeMap[GL_UNSIGNED_BYTE_3_3_2] = "GL_UNSIGNED_BYTE_3_3_2"; typeMap[GL_UNSIGNED_BYTE_2_3_3_REV] = "GL_UNSIGNED_BYTE_2_3_3_REV"; typeMap[GL_UNSIGNED_SHORT_5_6_5_REV] = "GL_UNSIGNED_SHORT_5_6_5_REV"; typeMap[GL_UNSIGNED_SHORT_4_4_4_4_REV] = "GL_UNSIGNED_SHORT_4_4_4_4_REV"; typeMap[GL_UNSIGNED_SHORT_1_5_5_5_REV] = "GL_UNSIGNED_SHORT_1_5_5_5_REV"; typeMap[GL_UNSIGNED_INT_8_8_8_8] = "GL_UNSIGNED_INT_8_8_8_8"; typeMap[GL_UNSIGNED_INT_8_8_8_8_REV] = "GL_UNSIGNED_INT_8_8_8_8_REV"; typeMap[GL_UNSIGNED_INT_10_10_10_2] = "GL_UNSIGNED_INT_10_10_10_2"; } TypeMap::iterator it = typeMap.find(type); if (it == typeMap.end()) { // if type is not in map use glu function return glu::getTypeStr(type).toString(); } return it->second; } std::string getFormatStr(GLenum format) { // this function extends glu::getTextureFormatStr by types used in this tests typedef std::map FormatMap; static FormatMap formatMap; if (formatMap.empty()) { formatMap[GL_GREEN] = "GL_GREEN"; formatMap[GL_BLUE] = "GL_BLUE"; formatMap[GL_GREEN_INTEGER] = "GL_GREEN_INTEGER"; formatMap[GL_BLUE_INTEGER] = "GL_BLUE_INTEGER"; formatMap[GL_BGR] = "GL_BGR"; formatMap[GL_BGR_INTEGER] = "GL_BGR_INTEGER"; formatMap[GL_BGRA_INTEGER] = "GL_BGRA_INTEGER"; formatMap[GL_R3_G3_B2] = "GL_R3_G3_B2"; formatMap[GL_RGB4] = "GL_RGB4"; formatMap[GL_RGB5] = "GL_RGB5"; formatMap[GL_RGB12] = "GL_RGB12"; formatMap[GL_RGBA2] = "GL_RGBA2"; formatMap[GL_RGBA12] = "GL_RGBA12"; formatMap[GL_COMPRESSED_RED] = "GL_COMPRESSED_RED"; formatMap[GL_COMPRESSED_RG] = "GL_COMPRESSED_RG"; formatMap[GL_COMPRESSED_RGB] = "GL_COMPRESSED_RGB"; formatMap[GL_COMPRESSED_RGBA] = "GL_COMPRESSED_RGBA"; formatMap[GL_COMPRESSED_SRGB] = "GL_COMPRESSED_SRGB"; formatMap[GL_COMPRESSED_SRGB_ALPHA] = "GL_COMPRESSED_SRGB_ALPHA"; formatMap[GL_COMPRESSED_RED_RGTC1] = "GL_COMPRESSED_RED_RGTC1"; formatMap[GL_COMPRESSED_SIGNED_RED_RGTC1] = "GL_COMPRESSED_SIGNED_RED_RGTC1"; formatMap[GL_COMPRESSED_RG_RGTC2] = "GL_COMPRESSED_RG_RGTC2"; formatMap[GL_COMPRESSED_SIGNED_RG_RGTC2] = "GL_COMPRESSED_SIGNED_RG_RGTC2"; formatMap[GL_STENCIL_INDEX] = "GL_STENCIL_INDEX"; } FormatMap::iterator it = formatMap.find(format); if (it == formatMap.end()) { // if format is not in map use glu function return glu::getTextureFormatStr(format).toString(); } return it->second; } std::string getModeStr(GLenum type) { typedef std::map ModeMap; static ModeMap modeMap; if (modeMap.empty()) { modeMap[GL_UNPACK_ROW_LENGTH] = "GL_UNPACK_ROW_LENGTH"; modeMap[GL_UNPACK_SKIP_ROWS] = "GL_UNPACK_SKIP_ROWS"; modeMap[GL_UNPACK_SKIP_PIXELS] = "GL_UNPACK_SKIP_PIXELS"; modeMap[GL_UNPACK_ALIGNMENT] = "GL_UNPACK_ALIGNMENT"; modeMap[GL_UNPACK_IMAGE_HEIGHT] = "GL_UNPACK_IMAGE_HEIGHT"; modeMap[GL_UNPACK_SKIP_IMAGES] = "GL_UNPACK_SKIP_IMAGES"; modeMap[GL_PACK_ROW_LENGTH] = "GL_PACK_ROW_LENGTH"; modeMap[GL_PACK_SKIP_ROWS] = "GL_PACK_SKIP_ROWS"; modeMap[GL_PACK_SKIP_PIXELS] = "GL_PACK_SKIP_PIXELS"; modeMap[GL_PACK_ALIGNMENT] = "GL_PACK_ALIGNMENT"; modeMap[GL_UNPACK_SWAP_BYTES] = "GL_UNPACK_SWAP_BYTES"; modeMap[GL_UNPACK_LSB_FIRST] = "GL_UNPACK_LSB_FIRST"; modeMap[GL_PACK_SWAP_BYTES] = "GL_PACK_SWAP_BYTES"; modeMap[GL_PACK_LSB_FIRST] = "GL_PACK_LSB_FIRST"; modeMap[GL_PACK_IMAGE_HEIGHT] = "GL_PACK_IMAGE_HEIGHT"; modeMap[GL_PACK_SKIP_IMAGES] = "GL_PACK_SKIP_IMAGES"; } ModeMap::iterator it = modeMap.find(type); if (it == modeMap.end()) TCU_FAIL("Unknown mode name"); return it->second; } class RectangleTest : public deqp::TestCase { public: RectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat); virtual ~RectangleTest(); void resetInitialStorageModes(); void applyInitialStorageModes(); void testAllFormatsAndTypes(); virtual tcu::TestNode::IterateResult iterate(void); protected: void createGradient(); void swapBytes(int typeSize, std::vector& dataBuffer); template void makeGradient(Type (*unpack)(float)); template static Type unpackSizedComponents(float value, int s1, int s2, int s3, int s4); template static Type unpackSizedComponentsRev(float value, int s1, int s2, int s3, int s4); static GLubyte unpack_UNSIGNED_BYTE(float value); static GLbyte unpack_BYTE(float value); static GLushort unpack_UNSIGNED_SHORT(float value); static GLshort unpack_SHORT(float value); static GLuint unpack_UNSIGNED_INT(float value); static GLint unpack_INT(float value); static GLhalf unpack_HALF_FLOAT(float value); static GLfloat unpack_FLOAT(float value); static GLubyte unpack_UNSIGNED_BYTE_3_3_2(float value); static GLubyte unpack_UNSIGNED_BYTE_2_3_3_REV(float value); static GLushort unpack_UNSIGNED_SHORT_5_6_5_REV(float value); static GLushort unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value); static GLushort unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value); static GLuint unpack_UNSIGNED_INT_8_8_8_8(float value); static GLuint unpack_UNSIGNED_INT_8_8_8_8_REV(float value); static GLuint unpack_UNSIGNED_INT_10_10_10_2(float value); static GLushort unpack_UNSIGNED_SHORT_5_6_5(float value); static GLushort unpack_UNSIGNED_SHORT_4_4_4_4(float value); static GLushort unpack_UNSIGNED_SHORT_5_5_5_1(float value); static GLuint unpack_UNSIGNED_INT_2_10_10_10_REV(float value); static GLuint unpack_UNSIGNED_INT_24_8(float value); static GLuint unpack_UNSIGNED_INT_5_9_9_9_REV(float value); static GLuint unpack_UNSIGNED_INT_10F_11F_11F_REV(float value); static F_32_UINT_24_8_REV unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value); bool isFormatValid(const PixelFormat& format, const PixelType& type, const struct InternalFormat& internalformat, bool checkInput, bool checkOutput, int operation) const; bool isUnsizedFormat(GLenum format) const; bool isSRGBFormat(const InternalFormat& internalFormat) const; bool isSNORMFormat(const InternalFormat& internalFormat) const; bool isCopyValid(const InternalFormat& copyInternalFormat, const InternalFormat& internalFormat) const; bool isFBOImageAttachValid(const InternalFormat& internalformat, GLenum format, GLenum type) const; const PixelFormat& getPixelFormat(GLenum format) const; const PixelType& getPixelType(GLenum type) const; const EnumFormats* getCanonicalFormat(const InternalFormat& internalformat, GLenum format, GLenum type) const; InternalFormatSamplerType getSampler(const PixelType& type, const PixelFormat& format) const; GLenum readOutputData(const PixelFormat& outputFormat, const PixelType& outputType, int operation); bool doCopy(); bool doCopyInner(); bool compare(GLvoid* gradient, GLvoid* data, const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy) const; void getFloatBuffer(GLvoid* gradient, int samplerIsIntUintFloat, const PixelFormat& format, const PixelType& type, int elementCount, std::vector& result) const; void getBits(const PixelType& type, const PixelFormat& format, std::vector& resultTable) const; template void makeBuffer(const GLvoid* gradient, const PixelFormat& format, int samplerIsIntUintFloat, int elementCount, int componentCount, float (*pack)(Type), std::vector& result) const; template void makeBufferPackedInt(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawIntPixel*, Type), std::vector& result) const; template void makeBufferPackedUint(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawUintPixel*, Type), std::vector& result) const; template void makeBufferPackedFloat(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawFloatPixel*, Type), std::vector& result) const; FloatPixel orderComponentsInt(rawIntPixel values, const PixelFormat& format) const; FloatPixel orderComponentsUint(rawUintPixel values, const PixelFormat& format) const; FloatPixel orderComponentsFloat(rawFloatPixel values, const PixelFormat& format) const; unsigned int getRealBitPrecision(int bits, bool isFloat) const; bool stripBuffer(const PackedPixelsBufferProperties& props, const GLubyte* orginalBuffer, std::vector& newBuffer, bool validate) const; int clampSignedValue(int bits, int value) const; unsigned int clampUnsignedValue(int bits, unsigned int value) const; static float pack_UNSIGNED_BYTE(GLubyte value); static float pack_BYTE(GLbyte value); static float pack_UNSIGNED_SHORT(GLushort value); static float pack_SHORT(GLshort value); static float pack_UNSIGNED_INT(GLuint value); static float pack_INT(GLint value); static float pack_HALF_FLOAT(GLhalf value); static float pack_FLOAT(GLfloat value); static void pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel* values, GLubyte value); static void pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel* values, GLubyte value); static void pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel* values, GLubyte value); static void pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel* values, GLubyte value); static void pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel* values, GLubyte value); static void pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel* values, GLubyte value); static void pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel* values, GLushort value); static void pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel* values, GLushort value); static void pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel* values, GLuint value); static void pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel* values, GLuint value); static void pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel* values, GLuint value); static void pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel* values, GLuint value); static void pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel* values, GLuint value); static void pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel* values, GLuint value); static void pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel* values, GLuint value); static void pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel* values, GLuint value); static void pack_UNSIGNED_INT_24_8(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel* values, GLuint value); static void pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel* values, GLuint value); static void pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel* values, F_32_UINT_24_8_REV value); bool getTexImage(); bool getTexImageInner(const PixelFormat& outputFormat, const PixelType& outputType); bool doRead(GLuint texture); bool readPixels(bool isCopy); bool readPixelsInner(const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy); protected: const InternalFormat m_internalFormat; bool m_usePBO; GLenum m_textureTarget; PackedPixelsBufferProperties m_initialPackProperties; PackedPixelsBufferProperties m_initialUnpackProperties; std::vector m_gradient; const GLubyte m_defaultFillValue; public: // debuf counters static int m_countReadPixels; static int m_countReadPixelsOK; static int m_countGetTexImage; static int m_countGetTexImageOK; static int m_countCompare; static int m_countCompareOK; private: // those attribute change multiple times during test execution PixelFormat m_inputFormat; PixelType m_inputType; InternalFormat m_copyInternalFormat; PackedPixelsBufferProperties m_packProperties; PackedPixelsBufferProperties m_unpackProperties; std::vector m_outputBuffer; }; int RectangleTest::m_countReadPixels = 0; int RectangleTest::m_countReadPixelsOK = 0; int RectangleTest::m_countGetTexImage = 0; int RectangleTest::m_countGetTexImageOK = 0; int RectangleTest::m_countCompare = 0; int RectangleTest::m_countCompareOK = 0; RectangleTest::RectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat) : deqp::TestCase(context, name.c_str(), "") , m_internalFormat(internalFormat) , m_usePBO(false) , m_textureTarget(GL_TEXTURE_2D) , m_defaultFillValue(0xaa) { } RectangleTest::~RectangleTest() { } void RectangleTest::resetInitialStorageModes() { m_initialPackProperties.skipPixels = 0; m_initialPackProperties.skipRows = 0; m_initialPackProperties.rowLength = 0; m_initialPackProperties.alignment = 4; m_initialPackProperties.rowCount = 0; m_initialPackProperties.skipImages = 0; m_initialPackProperties.lsbFirst = 0; m_initialPackProperties.swapBytes = 0; m_initialUnpackProperties.skipPixels = 0; m_initialUnpackProperties.skipRows = 0; m_initialUnpackProperties.rowLength = 0; m_initialUnpackProperties.alignment = 4; m_initialUnpackProperties.rowCount = 0; m_initialUnpackProperties.skipImages = 0; m_initialUnpackProperties.lsbFirst = 0; m_initialUnpackProperties.swapBytes = 0; } void RectangleTest::applyInitialStorageModes() { glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); PackedPixelsBufferProperties& up = m_initialUnpackProperties; PackedPixelsBufferProperties& pp = m_initialPackProperties; m_unpackProperties = up; m_packProperties = pp; gl.pixelStorei(GL_PACK_ROW_LENGTH, pp.rowLength); gl.pixelStorei(GL_PACK_SKIP_ROWS, pp.skipRows); gl.pixelStorei(GL_PACK_SKIP_PIXELS, pp.skipPixels); gl.pixelStorei(GL_PACK_ALIGNMENT, pp.alignment); gl.pixelStorei(GL_UNPACK_ROW_LENGTH, up.rowLength); gl.pixelStorei(GL_UNPACK_SKIP_ROWS, up.skipRows); gl.pixelStorei(GL_UNPACK_SKIP_PIXELS, up.skipPixels); gl.pixelStorei(GL_UNPACK_ALIGNMENT, up.alignment); gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT, up.rowCount); gl.pixelStorei(GL_UNPACK_SKIP_IMAGES, up.skipImages); if (!isContextTypeES(renderContext.getType())) { gl.pixelStorei(GL_PACK_IMAGE_HEIGHT, pp.rowCount); gl.pixelStorei(GL_PACK_SKIP_IMAGES, pp.skipImages); gl.pixelStorei(GL_PACK_SWAP_BYTES, pp.swapBytes); gl.pixelStorei(GL_PACK_LSB_FIRST, pp.lsbFirst); gl.pixelStorei(GL_UNPACK_SWAP_BYTES, up.swapBytes); gl.pixelStorei(GL_UNPACK_LSB_FIRST, up.lsbFirst); } } void RectangleTest::swapBytes(int typeSize, std::vector& dataBuffer) { int bufferSize = dataBuffer.size(); switch (typeSize) { case 1: break; // no swapping case 2: { GLushort* data = reinterpret_cast(&dataBuffer[0]); for (int i = 0; i < bufferSize / 2; i++) { GLushort v = data[i]; data[i] = ((v & 0xff) << 8) + ((v & 0xff00) >> 8); } break; } case 4: case 8: // typeSize is 2 x 32bit, behaves the same this time { GLuint* data = reinterpret_cast(&dataBuffer[0]); for (int i = 0; i < bufferSize / 4; i++) { GLuint v = data[i]; data[i] = ((v & 0xff) << 24) + ((v & 0xff00) << 8) + ((v & 0xff0000) >> 8) + ((v & 0xff000000) >> 24); } break; } default: TCU_FAIL("Invalid size for swapBytes"); } } const PixelFormat& RectangleTest::getPixelFormat(GLenum format) const { const PixelFormat* formats; int formatsCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { formats = esFormats; formatsCount = DE_LENGTH_OF_ARRAY(esFormats); } else { formats = coreFormats; formatsCount = DE_LENGTH_OF_ARRAY(coreFormats); } // Look up pixel format from a GL enum for (int i = 0; i < formatsCount; i++) { if (formats[i].format == format) return formats[i]; } TCU_FAIL("Unsuported format."); return formats[0]; } const PixelType& RectangleTest::getPixelType(GLenum type) const { const PixelType* types; int typesCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { types = esTypes; typesCount = DE_LENGTH_OF_ARRAY(esTypes); } else { types = coreTypes; typesCount = DE_LENGTH_OF_ARRAY(coreTypes); } for (int i = 0; i < typesCount; i++) { if (types[i].type == type) return types[i]; } TCU_FAIL("Unsuported type."); return types[0]; } const EnumFormats* RectangleTest::getCanonicalFormat(const InternalFormat& internalformat, GLenum format, GLenum type) const { // function returns a canonical format from internal format. for example // GL_RGBA16F => { GL_RGBA, GL_FLOAT }; used mostly for GLES tests if (glu::isContextTypeES(m_context.getRenderContext().getType())) { for (int i = 0; i < DE_LENGTH_OF_ARRAY(esValidFormats); ++i) { if ((esValidFormats[i].internalformat == internalformat.sizedFormat) && (esValidFormats[i].format == format) && (esValidFormats[i].type == type)) { return &(esValidFormats[i]); } } const glu::ContextInfo& contextInfo = m_context.getContextInfo(); if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV")) { for (int i = 0; i < DE_LENGTH_OF_ARRAY(validformats_EXT_texture_type_2_10_10_10_REV); ++i) { if (validformats_EXT_texture_type_2_10_10_10_REV[i].internalformat == internalformat.sizedFormat && validformats_EXT_texture_type_2_10_10_10_REV[i].format == format && validformats_EXT_texture_type_2_10_10_10_REV[i].type == type) { return &(validformats_EXT_texture_type_2_10_10_10_REV[i]); } } if (contextInfo.isExtensionSupported("GL_OES_required_internalformat")) { for (int i = 0; i < DE_LENGTH_OF_ARRAY(validformats_OES_required_internalformat); ++i) { if (validformats_OES_required_internalformat[i].internalformat == internalformat.sizedFormat && validformats_OES_required_internalformat[i].format == format && validformats_OES_required_internalformat[i].type == type) { return &(validformats_OES_required_internalformat[i]); } } } } } else { for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreValidFormats); ++i) { if ((coreValidFormats[i].internalformat == internalformat.sizedFormat) && (coreValidFormats[i].format == format) && (coreValidFormats[i].type == type)) { return &(coreValidFormats[i]); } } } return 0; } InternalFormatSamplerType RectangleTest::getSampler(const PixelType& type, const PixelFormat& format) const { switch (type.storage) { case STORAGE_FLOAT: return SAMPLER_FLOAT; case STORAGE_UNSIGNED: if ((format.componentFormat == FORMAT_COLOR_INTEGER) || (format.componentFormat == FORMAT_STENCIL)) return SAMPLER_UINT; return SAMPLER_UNORM; case STORAGE_SIGNED: if (format.componentFormat == FORMAT_COLOR_INTEGER) return SAMPLER_INT; return SAMPLER_NORM; default: TCU_FAIL("Invalid storage specifier"); } } void RectangleTest::createGradient() { switch (m_inputType.type) { case GL_UNSIGNED_BYTE: makeGradient(unpack_UNSIGNED_BYTE); break; case GL_BYTE: makeGradient(unpack_BYTE); break; case GL_UNSIGNED_SHORT: makeGradient(unpack_UNSIGNED_SHORT); break; case GL_SHORT: makeGradient(unpack_SHORT); break; case GL_UNSIGNED_INT: makeGradient(unpack_UNSIGNED_INT); break; case GL_INT: makeGradient(unpack_INT); break; case GL_HALF_FLOAT: makeGradient(unpack_HALF_FLOAT); break; case GL_FLOAT: makeGradient(unpack_FLOAT); break; case GL_UNSIGNED_SHORT_5_6_5: makeGradient(unpack_UNSIGNED_SHORT_5_6_5); break; case GL_UNSIGNED_SHORT_4_4_4_4: makeGradient(unpack_UNSIGNED_SHORT_4_4_4_4); break; case GL_UNSIGNED_SHORT_5_5_5_1: makeGradient(unpack_UNSIGNED_SHORT_5_5_5_1); break; case GL_UNSIGNED_INT_2_10_10_10_REV: makeGradient(unpack_UNSIGNED_INT_2_10_10_10_REV); break; case GL_UNSIGNED_INT_24_8: makeGradient(unpack_UNSIGNED_INT_24_8); break; case GL_UNSIGNED_INT_10F_11F_11F_REV: makeGradient(unpack_UNSIGNED_INT_10F_11F_11F_REV); break; case GL_UNSIGNED_INT_5_9_9_9_REV: makeGradient(unpack_UNSIGNED_INT_5_9_9_9_REV); break; case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: makeGradient(unpack_FLOAT_32_UNSIGNED_INT_24_8_REV); break; case GL_UNSIGNED_BYTE_3_3_2: makeGradient(unpack_UNSIGNED_BYTE_3_3_2); break; case GL_UNSIGNED_BYTE_2_3_3_REV: makeGradient(unpack_UNSIGNED_BYTE_2_3_3_REV); break; case GL_UNSIGNED_SHORT_5_6_5_REV: makeGradient(unpack_UNSIGNED_SHORT_5_6_5_REV); break; case GL_UNSIGNED_SHORT_4_4_4_4_REV: makeGradient(unpack_UNSIGNED_SHORT_4_4_4_4_REV); break; case GL_UNSIGNED_SHORT_1_5_5_5_REV: makeGradient(unpack_UNSIGNED_SHORT_1_5_5_5_REV); break; case GL_UNSIGNED_INT_8_8_8_8: makeGradient(unpack_UNSIGNED_INT_8_8_8_8); break; case GL_UNSIGNED_INT_8_8_8_8_REV: makeGradient(unpack_UNSIGNED_INT_8_8_8_8_REV); break; case GL_UNSIGNED_INT_10_10_10_2: makeGradient(unpack_UNSIGNED_INT_10_10_10_2); break; default: TCU_FAIL("Unsupported type"); }; } template void RectangleTest::makeGradient(Type (*unpack)(float)) { // number of elements in a group int elementsInGroup = m_inputFormat.components; if (m_inputType.special) elementsInGroup = 1; int rowCount = m_unpackProperties.rowCount; if (rowCount == 0) rowCount = GRADIENT_HEIGHT + m_unpackProperties.skipRows; // number of groups in the row int rowLength = m_unpackProperties.rowLength; if (rowLength == 0) rowLength = GRADIENT_WIDTH + m_unpackProperties.skipPixels; int elementSize = m_inputType.size; // row size (in elements) int elementsInRowNoAlign = elementsInGroup * rowLength; int elementsInRow = elementsInRowNoAlign; if (elementSize < m_unpackProperties.alignment) { int alignment = m_unpackProperties.alignment; elementsInRow = (int)(alignment * deFloatCeil(elementSize * elementsInGroup * rowLength / ((float)alignment))) / elementSize; } if (m_textureTarget == GL_TEXTURE_2D) m_unpackProperties.skipImages = 0; // "depth" will be 1 + skipped image layers. // We still want to work on a 2D-ish image later. int depth = 1 + m_unpackProperties.skipImages; m_unpackProperties.elementsInGroup = elementsInGroup; m_unpackProperties.rowCount = rowCount; m_unpackProperties.rowLength = rowLength; m_unpackProperties.elementSize = elementSize; m_unpackProperties.elementsInRowNoAlign = elementsInRowNoAlign; m_unpackProperties.elementsInRow = elementsInRow; m_unpackProperties.imagesCount = depth; // element size * elements in row * number of rows * number of 2d images std::size_t bufferSize = elementSize * elementsInRow * rowCount * depth; m_gradient.resize(bufferSize); Type* data = reinterpret_cast(&m_gradient[0]); std::size_t dataToSkip = m_unpackProperties.skipImages * rowCount * elementsInRow; std::size_t index = dataToSkip; const Type defaultValue = unpack(0.5f); std::fill(data, data + dataToSkip, defaultValue); for (int k = 0; k < depth; k++) { for (int j = 0; j < rowCount; j++) { for (int i = 0; i < elementsInRow; i++) { int x = i / elementsInGroup; if ((k == depth - 1) && (m_unpackProperties.skipRows <= j) && (j < m_unpackProperties.skipRows + GRADIENT_HEIGHT) && (m_unpackProperties.skipPixels <= x) && (x < m_unpackProperties.skipPixels + GRADIENT_WIDTH)) { float value = static_cast(x - m_unpackProperties.skipPixels) / GRADIENT_WIDTH; int channel = i - elementsInGroup * x; value *= 1.0f - 0.25f * channel; data[index] = unpack(value); } else { data[index] = defaultValue; } index++; } } } } template Type RectangleTest::unpackSizedComponents(float value, int s1, int s2, int s3, int s4) { int typeBits = sizeof(Type) * 8; double v = static_cast(value); Type c1 = static_cast(v * 1.00 * ((1 << s1) - 1)); Type c2 = static_cast(v * 0.75 * ((1 << s2) - 1)); Type c3 = static_cast(v * 0.50 * ((1 << s3) - 1)); Type c4 = static_cast(v * 0.25 * ((1 << s4) - 1)); return ((c1) << (typeBits - s1)) | ((c2) << (typeBits - s1 - s2)) | ((c3) << (typeBits - s1 - s2 - s3)) | ((c4) << (typeBits - s1 - s2 - s3 - s4)); } template Type RectangleTest::unpackSizedComponentsRev(float value, int s1, int s2, int s3, int s4) { int typeBits = sizeof(Type) * 8; double v = static_cast(value); Type c1 = static_cast(v * 1.00 * ((1 << s4) - 1)); Type c2 = static_cast(v * 0.75 * ((1 << s3) - 1)); Type c3 = static_cast(v * 0.50 * ((1 << s2) - 1)); Type c4 = static_cast(v * 0.25 * ((1 << s1) - 1)); return ((c4) << (typeBits - s1)) | ((c3) << (typeBits - s1 - s2)) | ((c2) << (typeBits - s1 - s2 - s3)) | ((c1) << (typeBits - s1 - s2 - s3 - s4)); } GLubyte RectangleTest::unpack_UNSIGNED_BYTE(float value) { return static_cast(value * std::numeric_limits::max()); } GLbyte RectangleTest::unpack_BYTE(float value) { return static_cast(value * std::numeric_limits::max()); } GLushort RectangleTest::unpack_UNSIGNED_SHORT(float value) { return static_cast(value * std::numeric_limits::max()); } GLshort RectangleTest::unpack_SHORT(float value) { return static_cast(value * std::numeric_limits::max()); } GLuint RectangleTest::unpack_UNSIGNED_INT(float value) { return static_cast(value * std::numeric_limits::max()); } GLint RectangleTest::unpack_INT(float value) { return static_cast(value * std::numeric_limits::max()); } GLhalf RectangleTest::unpack_HALF_FLOAT(float value) { return floatToHalfFloat(value); } GLfloat RectangleTest::unpack_FLOAT(float value) { return value; } GLubyte RectangleTest::unpack_UNSIGNED_BYTE_3_3_2(float value) { return unpackSizedComponents(value, 3, 3, 2, 0); } GLubyte RectangleTest::unpack_UNSIGNED_BYTE_2_3_3_REV(float value) { return unpackSizedComponentsRev(value, 2, 3, 3, 0); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5_REV(float value) { return unpackSizedComponentsRev(value, 5, 6, 5, 0); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value) { return unpackSizedComponentsRev(value, 4, 4, 4, 4); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value) { return unpackSizedComponentsRev(value, 1, 5, 5, 5); } GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8(float value) { return unpackSizedComponents(value, 8, 8, 8, 8); } GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8_REV(float value) { return unpackSizedComponentsRev(value, 8, 8, 8, 8); } GLuint RectangleTest::unpack_UNSIGNED_INT_10_10_10_2(float value) { return unpackSizedComponents(value, 10, 10, 10, 2); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5(float value) { return unpackSizedComponents(value, 5, 6, 5, 0); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4(float value) { return unpackSizedComponents(value, 4, 4, 4, 4); } GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_5_5_1(float value) { return unpackSizedComponents(value, 5, 5, 5, 1); } GLuint RectangleTest::unpack_UNSIGNED_INT_2_10_10_10_REV(float value) { return unpackSizedComponentsRev(value, 2, 10, 10, 10); } GLuint RectangleTest::unpack_UNSIGNED_INT_24_8(float value) { return unpackSizedComponents(value, 24, 8, 0, 0); } GLuint RectangleTest::unpack_UNSIGNED_INT_5_9_9_9_REV(float value) { const int N = 9; const int B = 15; const int E_max = 31; GLfloat red = value * 1.00f; GLfloat green = value * 0.75f; GLfloat blue = value * 0.50f; GLfloat sharedExpMax = (deFloatPow(2.0f, (float)N) - 1.0f) / deFloatPow(2.0f, (float)N) * deFloatPow(2.0f, (float)(E_max - B)); GLfloat red_c = deFloatMax(0, deFloatMin(sharedExpMax, red)); GLfloat green_c = deFloatMax(0, deFloatMin(sharedExpMax, green)); GLfloat blue_c = deFloatMax(0, deFloatMin(sharedExpMax, blue)); GLfloat max_c = deFloatMax(deFloatMax(red_c, green_c), blue_c); GLfloat exp_p = deFloatMax(-B - 1, deFloatFloor(deFloatLog2(max_c))) + 1 + B; GLfloat max_s = deFloatFloor(max_c / deFloatPow(2.0f, exp_p - (float)B - (float)N) + 0.5f); GLfloat exp_s; if (0 <= max_s && max_s < deFloatPow(2.0f, (float)N)) exp_s = exp_p; else exp_s = exp_p + 1; GLfloat red_s = deFloatFloor(red_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f); GLfloat green_s = deFloatFloor(green_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f); GLfloat blue_s = deFloatFloor(blue_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f); GLuint c1 = (static_cast(red_s)) & 511; GLuint c2 = (static_cast(green_s)) & 511; GLuint c3 = (static_cast(blue_s)) & 511; GLuint c4 = (static_cast(exp_s)) & 31; return (c1) | (c2 << 9) | (c3 << 18) | (c4 << 27); } GLuint RectangleTest::unpack_UNSIGNED_INT_10F_11F_11F_REV(float value) { GLuint c1 = floatToUnisgnedF11(value * 1.00f); GLuint c2 = floatToUnisgnedF11(value * 0.75f); GLuint c3 = floatToUnisgnedF10(value * 0.50f); return (c3 << 22) | (c2 << 11) | (c1); } F_32_UINT_24_8_REV RectangleTest::unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value) { F_32_UINT_24_8_REV ret; ret.d = value; ret.s = (GLuint)(value * 255.0 * 0.75); ret.s &= 0xff; return ret; } bool RectangleTest::isFormatValid(const PixelFormat& format, const PixelType& type, const struct InternalFormat& internalformat, bool checkInput, bool checkOutput, int operation) const { glu::RenderContext& renderContext = m_context.getRenderContext(); glu::ContextType contextType = renderContext.getType(); const glu::ContextInfo& contextInfo = m_context.getContextInfo(); const Functions& gl = renderContext.getFunctions(); int i; // Test the combination of input format, input type and internalFormat if (glu::isContextTypeES(contextType)) { if (checkInput) { // GLES30 has more restricted requirement on combination than GL for input for (i = 0; i < DE_LENGTH_OF_ARRAY(esValidFormats); ++i) { if (internalformat.sizedFormat == esValidFormats[i].internalformat && format.format == esValidFormats[i].format && type.type == esValidFormats[i].type) { break; } } if (i == DE_LENGTH_OF_ARRAY(esValidFormats)) { // Check for support of OES_texture_float extension if (((GL_LUMINANCE_ALPHA == format.format) && (GL_LUMINANCE_ALPHA == internalformat.sizedFormat)) || ((GL_LUMINANCE == format.format) && (GL_LUMINANCE == internalformat.sizedFormat)) || ((GL_ALPHA == format.format) && (GL_ALPHA == internalformat.sizedFormat)) || ((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) || ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat))) { if ((contextInfo.isExtensionSupported("GL_OES_texture_float") && (GL_FLOAT == type.type)) || (contextInfo.isExtensionSupported("GL_OES_texture_half_float") && (GL_HALF_FLOAT_OES == type.type))) { return true; } } // Check for support of EXT_texture_type_2_10_10_10_REV extension if (((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) || ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat))) { if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") && ((GL_UNSIGNED_INT_2_10_10_10_REV_EXT == type.type))) return true; } // Check for support of NV_packed_float extension if ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat)) { if (contextInfo.isExtensionSupported("GL_NV_packed_float") && ((GL_UNSIGNED_INT_10F_11F_11F_REV == type.type))) return true; } // Check for support of EXT_texture_type_2_10_10_10_REV and GL_OES_required_internalformat extensions if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") && contextInfo.isExtensionSupported("GL_OES_required_internalformat")) { for (i = 0; i < DE_LENGTH_OF_ARRAY(validformats_OES_required_internalformat); ++i) { if (internalformat.sizedFormat == validformats_OES_required_internalformat[i].internalformat && format.format == validformats_OES_required_internalformat[i].format && type.type == validformats_OES_required_internalformat[i].type) { return true; } } } return false; } if ((m_textureTarget == GL_TEXTURE_3D) && ((format.format == GL_DEPTH_COMPONENT) || (format.format == GL_DEPTH_STENCIL))) return false; } else if (checkOutput) { // GLES30 has more restricted requirement on combination than GL for output // As stated in Section Reading Pixels InternalFormatSamplerType sampler = internalformat.sampler; const PixelFormat& inputFormat = getPixelFormat(internalformat.format); if (inputFormat.attachment == GL_DEPTH_ATTACHMENT && contextInfo.isExtensionSupported("GL_NV_read_depth") && format.format == GL_DEPTH_COMPONENT && ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) || (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT || type.type == GL_UNSIGNED_INT_24_8)))) { return true; } if (inputFormat.attachment == GL_DEPTH_STENCIL_ATTACHMENT && contextInfo.isExtensionSupported("GL_NV_read_depth_stencil") && ((format.format == GL_DEPTH_STENCIL && ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) || (sampler != SAMPLER_FLOAT && type.type == GL_UNSIGNED_INT_24_8))) || (format.format == GL_DEPTH_COMPONENT && ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) || (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT || type.type == GL_UNSIGNED_INT_24_8)))))) { return true; } if (inputFormat.attachment != GL_COLOR_ATTACHMENT0) { return false; } if ((sampler == SAMPLER_UNORM) && (((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGB) && (internalformat.sizedFormat == GL_SRGB8)) || ((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA) && (internalformat.sizedFormat == GL_SRGB8_ALPHA8))) && contextInfo.isExtensionSupported("GL_NV_sRGB_formats")) { return true; } if ((sampler == SAMPLER_NORM) && (type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA) && ((internalformat.sizedFormat == GL_R8_SNORM) || (internalformat.sizedFormat == GL_RG8_SNORM) || (internalformat.sizedFormat == GL_RGBA8_SNORM) || (internalformat.sizedFormat == GL_R16_SNORM) || (internalformat.sizedFormat == GL_RG16_SNORM) || (internalformat.sizedFormat == GL_RGBA16_SNORM)) && contextInfo.isExtensionSupported("GL_EXT_render_snorm")) { return true; } if ((sampler == SAMPLER_NORM) && (type.type == GL_BYTE) && (format.format == GL_RGBA) && ((internalformat.sizedFormat == GL_R8_SNORM) || (internalformat.sizedFormat == GL_RG8_SNORM) || (internalformat.sizedFormat == GL_RGBA8_SNORM)) && contextInfo.isExtensionSupported("GL_EXT_render_snorm")) { return true; } GLint implementType; GLint implementFormat; gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &implementType); gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implementFormat); GLenum err = gl.getError(); GLenum implementTypeEnum = static_cast(implementType); GLenum implementFormatEnum = static_cast(implementFormat); if (((sampler == SAMPLER_UNORM) && (type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA)) || ((sampler == SAMPLER_UINT) && (type.type == GL_UNSIGNED_INT) && (format.format == GL_RGBA_INTEGER)) || ((sampler == SAMPLER_INT) && (type.type == GL_INT) && (format.format == GL_RGBA_INTEGER)) || ((sampler == SAMPLER_FLOAT) && (type.type == GL_FLOAT) && (format.format == GL_RGBA)) || ((err == GL_NO_ERROR) && (type.type == implementTypeEnum) && (format.format == implementFormatEnum)) || ((internalformat.sizedFormat == GL_RGB10_A2) && (type.type == GL_UNSIGNED_INT_2_10_10_10_REV) && (format.format == GL_RGBA))) { return true; } else { return false; } } } else { if (format.format == GL_DEPTH_STENCIL) { if (type.type != GL_UNSIGNED_INT_24_8 && type.type != GL_FLOAT_32_UNSIGNED_INT_24_8_REV) { return false; } } if ((format.componentFormat == FORMAT_COLOR_INTEGER) && (type.type == GL_FLOAT || type.type == GL_HALF_FLOAT)) { return false; } if ((internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_STENCIL_INDEX || internalformat.baseFormat == GL_DEPTH_COMPONENT) != (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX || format.format == GL_DEPTH_COMPONENT)) { return false; } if (operation == INPUT_TEXIMAGE) { if (format.format == GL_STENCIL_INDEX || internalformat.baseFormat == GL_STENCIL_INDEX) { return false; } if ((format.format == GL_DEPTH_COMPONENT || format.format == GL_DEPTH_STENCIL) && !(internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_DEPTH_COMPONENT)) { return false; } } else if (operation == OUTPUT_GETTEXIMAGE) { if ((format.format == GL_STENCIL_INDEX && ((internalformat.baseFormat != GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL) || !contextInfo.isExtensionSupported("GL_ARB_texture_stencil8")))) { return false; } if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL) { return false; } } else if (operation == OUTPUT_READPIXELS) { if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL) { return false; } if (format.format == GL_DEPTH_COMPONENT && internalformat.baseFormat != GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_COMPONENT) { return false; } if (format.format == GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL && internalformat.baseFormat != GL_STENCIL_INDEX) { return false; } } if (type.special == true) { bool valid = false; for (i = 0; i < DE_LENGTH_OF_ARRAY(coreValidFormats); ++i) { if (coreValidFormats[i].format == format.format && coreValidFormats[i].type == type.type) { valid = true; break; } } if (!valid) return false; } if ((format.componentFormat == FORMAT_COLOR_INTEGER) && !(internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT)) { return false; } if (!(format.componentFormat == FORMAT_COLOR_INTEGER) && (internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT)) { return false; } if ((m_textureTarget == GL_TEXTURE_3D) && ((internalformat.baseFormat == GL_DEPTH_COMPONENT) || (internalformat.baseFormat == GL_DEPTH_STENCIL) || (internalformat.sizedFormat == GL_COMPRESSED_RED_RGTC1) || (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RED_RGTC1) || (internalformat.sizedFormat == GL_COMPRESSED_RG_RGTC2) || (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RG_RGTC2))) { return false; } } return true; } bool RectangleTest::isUnsizedFormat(GLenum format) const { GLenum formats[] = { GL_RGBA, GL_RGB, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA }; GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats); return (std::find(formats, formatsEnd, format) < formatsEnd); } bool RectangleTest::isSRGBFormat(const InternalFormat& internalFormat) const { return (internalFormat.sizedFormat == GL_SRGB8) || (internalFormat.sizedFormat == GL_SRGB8_ALPHA8); } bool RectangleTest::isSNORMFormat(const InternalFormat& internalFormat) const { GLenum formats[] = { GL_R8_SNORM, GL_RG8_SNORM, GL_RGB8_SNORM, GL_RGBA8_SNORM, GL_R16_SNORM, GL_RG16_SNORM, GL_RGB16_SNORM, GL_RGBA16_SNORM }; GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats); return (std::find(formats, formatsEnd, internalFormat.sizedFormat) < formatsEnd); } bool RectangleTest::isCopyValid(const InternalFormat& copyInternalFormat, const InternalFormat& internalFormat) const { // check if copy between two internal formats is allowed int b1 = getPixelFormat(internalFormat.format).components; int b2 = getPixelFormat(copyInternalFormat.format).components; if (b2 > b1) return false; //Check that the types can be converted in CopyTexImage. if (((copyInternalFormat.sampler == SAMPLER_UINT) && (internalFormat.sampler != SAMPLER_UINT)) || ((copyInternalFormat.sampler == SAMPLER_INT) && (internalFormat.sampler != SAMPLER_INT)) || (((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) || (copyInternalFormat.sampler == SAMPLER_NORM)) && (!((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) || (internalFormat.sampler == SAMPLER_NORM))))) { return false; } // Core GL is less restricted then ES - check it first if (!glu::isContextTypeES(m_context.getRenderContext().getType())) { if ((copyInternalFormat.format == GL_DEPTH_COMPONENT && internalFormat.format != GL_DEPTH_COMPONENT) || (copyInternalFormat.format == GL_DEPTH_STENCIL && internalFormat.format != GL_DEPTH_STENCIL) || (copyInternalFormat.format == GL_ALPHA && internalFormat.format != GL_ALPHA) || (copyInternalFormat.format == GL_LUMINANCE && internalFormat.format != GL_LUMINANCE) || (copyInternalFormat.format == GL_LUMINANCE_ALPHA && internalFormat.format != GL_LUMINANCE_ALPHA)) { return false; } return true; } const glu::ContextInfo& contextInfo = m_context.getContextInfo(); // GLES30 has more restricted requirement on glCopyTexImage2D // As stated in Table 3.15 and comment to glCopyTexImage2D if ((internalFormat.baseFormat == GL_DEPTH_COMPONENT) || (internalFormat.baseFormat == GL_DEPTH_STENCIL) || (copyInternalFormat.baseFormat == GL_DEPTH_COMPONENT) || (copyInternalFormat.baseFormat == GL_DEPTH_STENCIL) || ((internalFormat.baseFormat != GL_RGBA && internalFormat.baseFormat != GL_ALPHA) && ((copyInternalFormat.baseFormat == GL_ALPHA) || (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA))) || ((internalFormat.baseFormat == GL_ALPHA) && ((copyInternalFormat.baseFormat != GL_RGBA) && (copyInternalFormat.baseFormat != GL_ALPHA) && (copyInternalFormat.baseFormat != GL_LUMINANCE_ALPHA))) || (isSRGBFormat(internalFormat) != isSRGBFormat(copyInternalFormat)) || // GLES30 does not define ReadPixels types for signed normalized fixed point formats in Table 3.14, // and conversions to SNORM internalformats are not allowed by Table 3.2 (copyInternalFormat.sampler == SAMPLER_NORM) || ((copyInternalFormat.sizedFormat == GL_RGB9_E5) && !contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float"))) { /* Some formats are activated by extensions, check. */ if (((internalFormat.baseFormat == GL_LUMINANCE && copyInternalFormat.baseFormat == GL_LUMINANCE) || (internalFormat.baseFormat == GL_ALPHA && copyInternalFormat.baseFormat == GL_ALPHA) || (internalFormat.baseFormat == GL_LUMINANCE_ALPHA && (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA || copyInternalFormat.baseFormat == GL_LUMINANCE || copyInternalFormat.baseFormat == GL_ALPHA))) && contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha")) { return true; } else if (contextInfo.isExtensionSupported("GL_EXT_render_snorm") && isSNORMFormat(copyInternalFormat) && (internalFormat.sampler == copyInternalFormat.sampler) && (((copyInternalFormat.baseFormat == GL_RED) && (internalFormat.baseFormat == GL_RED || internalFormat.baseFormat == GL_RG || internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA || copyInternalFormat.baseFormat == GL_LUMINANCE)) || ((copyInternalFormat.baseFormat == GL_RG) && (internalFormat.baseFormat == GL_RG || internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA)) || ((copyInternalFormat.baseFormat == GL_RGB) && (internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA)) || ((copyInternalFormat.baseFormat == GL_RGBA) && (internalFormat.baseFormat == GL_RGBA)))) { return true; } return false; } else { if (internalFormat.sampler != copyInternalFormat.sampler) { // You can't convert between different base types, for example NORM<->FLOAT. return false; } if (!isUnsizedFormat(copyInternalFormat.sizedFormat)) { if ((internalFormat.bits.bits.red && copyInternalFormat.bits.bits.red && internalFormat.bits.bits.red != copyInternalFormat.bits.bits.red) || (internalFormat.bits.bits.green && copyInternalFormat.bits.bits.green && internalFormat.bits.bits.green != copyInternalFormat.bits.bits.green) || (internalFormat.bits.bits.blue && copyInternalFormat.bits.bits.blue && internalFormat.bits.bits.blue != copyInternalFormat.bits.bits.blue) || (internalFormat.bits.bits.alpha && copyInternalFormat.bits.bits.alpha && internalFormat.bits.bits.alpha != copyInternalFormat.bits.bits.alpha)) { // If the destination internalFormat is sized we don't allow component size changes. return false; } } else { if (internalFormat.sizedFormat == GL_RGB10_A2) { // Not allowed to convert from a GL_RGB10_A2 surface. return false; } } } return true; } bool RectangleTest::isFBOImageAttachValid(const InternalFormat& internalformat, GLenum format, GLenum type) const { const glu::ContextInfo& contextInfo = m_context.getContextInfo(); if (glu::isContextTypeES(m_context.getRenderContext().getType())) { const EnumFormats* validFormat = getCanonicalFormat(internalformat, format, type); if (validFormat != 0) { if (!validFormat->bRenderable) { /* Some formats are activated by extensions, check. */ if ((GL_RGBA32F == validFormat->internalformat || GL_RGBA16F == validFormat->internalformat || GL_RG32F == validFormat->internalformat || GL_RG16F == validFormat->internalformat || GL_R32F == validFormat->internalformat || GL_R16F == validFormat->internalformat || GL_R11F_G11F_B10F == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_EXT_color_buffer_float")) { return true; } if ((GL_RGBA16F == validFormat->internalformat || GL_RGB16F == validFormat->internalformat || GL_RG16F == validFormat->internalformat || GL_R16F == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_EXT_color_buffer_half_float")) { return true; } if ((GL_R11F_G11F_B10F == validFormat->internalformat || GL_RGB9_E5 == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float")) { return true; } if ((GL_LUMINANCE == validFormat->internalformat || GL_ALPHA == validFormat->internalformat || GL_LUMINANCE_ALPHA == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha")) { return true; } if ((GL_SRGB8 == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_NV_sRGB_formats")) { return true; } if (((GL_R8_SNORM == validFormat->internalformat) || (GL_RG8_SNORM == validFormat->internalformat) || (GL_RGBA8_SNORM == validFormat->internalformat) || (GL_R16_SNORM == validFormat->internalformat) || (GL_RG16_SNORM == validFormat->internalformat) || (GL_RGBA16_SNORM == validFormat->internalformat)) && contextInfo.isExtensionSupported("GL_EXT_render_snorm")) { return true; } } return validFormat->bRenderable; } else { // Check for NV_packed_float if (GL_RGB == internalformat.sizedFormat && GL_RGB == format && GL_UNSIGNED_INT_10F_11F_11F_REV == type && contextInfo.isExtensionSupported("GL_NV_packed_float")) { return true; } return false; } } else { if (format == GL_DEPTH_STENCIL && internalformat.sizedFormat != GL_DEPTH24_STENCIL8 && internalformat.sizedFormat != GL_DEPTH32F_STENCIL8) { // We can't make a complete DEPTH_STENCIL attachment with a // texture that does not have both DEPTH and STENCIL components. return false; } GLenum colorRenderableFrmats[] = { GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI, GL_RGBA16, GL_RGBA16F, GL_RGBA16I, GL_RGBA16UI, GL_RGBA8, GL_RGBA8I, GL_RGBA8UI, GL_SRGB8_ALPHA8, GL_RGB10_A2, GL_RGB10_A2UI, GL_RGB5_A1, GL_RGBA4, GL_R11F_G11F_B10F, GL_RGB565, GL_RG32F, GL_RG32I, GL_RG32UI, GL_RG16, GL_RG16F, GL_RG16I, GL_RG16UI, GL_RG8, GL_RG8I, GL_RG8UI, GL_R32F, GL_R32I, GL_R32UI, GL_R16F, GL_R16I, GL_R16UI, GL_R16, GL_R8, GL_R8I, GL_R8UI }; GLenum* formatsEnd = colorRenderableFrmats + DE_LENGTH_OF_ARRAY(colorRenderableFrmats); if (std::find(colorRenderableFrmats, formatsEnd, internalformat.sizedFormat) < formatsEnd) return true; GLenum dsRenderableFormats[] = { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16, GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8, }; formatsEnd = dsRenderableFormats + DE_LENGTH_OF_ARRAY(dsRenderableFormats); if (std::find(dsRenderableFormats, formatsEnd, internalformat.sizedFormat) < formatsEnd) return true; return false; } } bool RectangleTest::doRead(GLuint texture) { glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); GLuint fboId; gl.genFramebuffers(1, &fboId); gl.bindFramebuffer(GL_FRAMEBUFFER, fboId); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer"); bool validImageAttach = isFBOImageAttachValid(m_internalFormat, m_inputFormat.format, m_inputType.type); if (m_textureTarget == GL_TEXTURE_2D) gl.framebufferTexture2D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_2D, texture, 0); else if (glu::isContextTypeES(renderContext.getType())) gl.framebufferTextureLayer(GL_FRAMEBUFFER, m_inputFormat.attachment, texture, 0, 0); else gl.framebufferTexture3D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_3D, texture, 0, 0); GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); bool result = true; if (status == GL_FRAMEBUFFER_COMPLETE) { if (!validImageAttach && glu::isContextTypeES(renderContext.getType())) { m_testCtx.getLog() << tcu::TestLog::Message << "FBO is complete but expected incomplete with sizedFormat: " << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage; result = false; } else { result &= readPixels(false); result &= doCopy(); } } else if (validImageAttach) { m_testCtx.getLog() << tcu::TestLog::Message << "FBO is not complete but expected complete with sizedFormat: " << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage; result = false; } gl.deleteFramebuffers(1, &fboId); return result; } bool RectangleTest::readPixels(bool isCopy) { bool result = true; const PixelType* types; int typesCount; const PixelFormat* formats; int formatsCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { types = esTypes; typesCount = DE_LENGTH_OF_ARRAY(esTypes); formats = esFormats; formatsCount = DE_LENGTH_OF_ARRAY(esFormats); } else { types = coreTypes; typesCount = DE_LENGTH_OF_ARRAY(coreTypes); formats = coreFormats; formatsCount = DE_LENGTH_OF_ARRAY(coreFormats); } // for each output format for (int m = 0; m < formatsCount; ++m) { const PixelFormat& outputFormat = formats[m]; // for each output type for (int n = 0; n < typesCount; ++n) { const PixelType& outputType = types[n]; if (isCopy) { // continue when input format,type != canonical format,type and // output format,type != canonical format,type if ((outputFormat.format != m_copyInternalFormat.format || outputType.type != m_copyInternalFormat.type)) { // invalid output format and type - skipping case continue; } } else if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) && (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type)) { // invalid output format and type - skipping case continue; } result &= readPixelsInner(outputFormat, outputType, isCopy); } } return result; } bool RectangleTest::readPixelsInner(const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy) { const char* copyStage = "Copy stage: "; GLenum readerror = readOutputData(outputFormat, outputType, OUTPUT_READPIXELS); if (m_outputBuffer.empty()) { m_testCtx.getLog() << tcu::TestLog::Message << "No buffer allocated" << tcu::TestLog::EndMessage; return false; } m_countReadPixels++; // Check if output format is valid bool outputFormatValid = isFormatValid(outputFormat, outputType, isCopy ? m_copyInternalFormat : m_internalFormat, false, true, OUTPUT_READPIXELS); // Even if this is a valid glReadPixels format, we can't read non-existant components if (outputFormatValid && outputFormat.format == GL_DEPTH_STENCIL && m_inputFormat.format != GL_DEPTH_STENCIL) outputFormatValid = false; if (outputFormatValid) { if (readerror != GL_NO_ERROR) { m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "") << "Valid format used but glReadPixels failed for input = [" << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage; return false; } else { m_countReadPixelsOK++; m_countCompare++; // compare output gradient to input gradient if (!compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, isCopy)) { m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "") << "Gradient comparison failed during ReadPixels for input = [" << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage; return false; } m_countCompareOK++; } } else if (readerror == GL_NO_ERROR) { m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "") << "Invalid format used but glReadPixels succeeded for input = [" << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage; return false; } return true; } GLenum RectangleTest::readOutputData(const PixelFormat& outputFormat, const PixelType& outputType, int operation) { // If using PBOs buffer object for GL_PIXEL_PACK_BUFFER must // be bound and not allocated before calling when using PBOs glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); PackedPixelsBufferProperties& props = m_packProperties; props.elementSize = outputType.size; props.elementsInGroup = outputType.special ? 1 : outputFormat.components; props.rowLength = (props.rowLength == 0) ? (GRADIENT_WIDTH + props.skipPixels) : props.rowLength; props.elementsInRowNoAlign = props.elementsInGroup * props.rowLength; props.elementsInRow = props.elementsInRowNoAlign; if (glu::isContextTypeES(renderContext.getType())) { props.rowCount = 0; props.skipImages = 0; } else if ((operation == OUTPUT_READPIXELS) || (m_textureTarget == GL_TEXTURE_2D)) props.skipImages = 0; if (props.rowCount == 0) props.rowCount = GRADIENT_HEIGHT + props.skipRows; props.imagesCount = props.skipImages + 1; if (props.elementSize < props.alignment) { props.elementsInRow = (int)(props.alignment * deFloatCeil(props.elementSize * props.elementsInGroup * props.rowLength / ((float)props.alignment))) / props.elementSize; } int bufferSize = props.elementSize * props.elementsInRow * props.rowCount * props.imagesCount * (props.skipImages + 1); // The output buffer allocated should be initialized to a known value. After // a pack operation, any extra memory allocated for skipping should be // verified to be the original known value, untouched by the GL. const GLubyte defaultFillValue = 0xaa; m_outputBuffer.resize(static_cast(bufferSize)); std::fill(m_outputBuffer.begin(), m_outputBuffer.end(), defaultFillValue); GLuint packPBO; if (m_usePBO) { gl.genBuffers(1, &packPBO); gl.bindBuffer(GL_PIXEL_PACK_BUFFER, packPBO); gl.bufferData(GL_PIXEL_PACK_BUFFER, bufferSize, &m_outputBuffer[0], GL_STATIC_READ); } GLenum readError = GL_NO_ERROR; switch (operation) { case OUTPUT_GETTEXIMAGE: gl.getTexImage(m_textureTarget, 0, outputFormat.format, outputType.type, m_usePBO ? 0 : &m_outputBuffer[0]); break; case OUTPUT_READPIXELS: if (m_inputFormat.attachment != GL_DEPTH_ATTACHMENT && m_inputFormat.attachment != GL_DEPTH_STENCIL_ATTACHMENT && m_inputFormat.attachment != GL_STENCIL_ATTACHMENT) gl.readBuffer(m_inputFormat.attachment); readError = gl.getError(); if (readError == GL_NO_ERROR) gl.readPixels(0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, outputFormat.format, outputType.type, m_usePBO ? 0 : &m_outputBuffer[0]); break; } if (readError == GL_NO_ERROR) readError = gl.getError(); if (m_usePBO) { if (readError == GL_NO_ERROR) { GLvoid* mappedData = gl.mapBufferRange(GL_PIXEL_PACK_BUFFER, 0, bufferSize, GL_MAP_READ_BIT); if (!mappedData) return GL_INVALID_INDEX; std::memcpy(&m_outputBuffer[0], mappedData, bufferSize); gl.unmapBuffer(GL_PIXEL_PACK_BUFFER); } gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); gl.deleteBuffers(1, &packPBO); } if (m_packProperties.swapBytes && (readError == GL_NO_ERROR)) swapBytes(outputType.size, m_outputBuffer); return readError; } bool RectangleTest::doCopy() { bool result = true; const InternalFormat* copyInternalFormats; int internalFormatsCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { copyInternalFormats = esInternalformats; internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats); } else { copyInternalFormats = coreInternalformats; internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats); } if ((m_inputFormat.format == m_internalFormat.format) && (m_inputType.type == m_internalFormat.type)) { for (int i = 0; i < internalFormatsCount; ++i) { m_copyInternalFormat = copyInternalFormats[i]; result &= doCopyInner(); } } return result; } bool RectangleTest::doCopyInner() { glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); bool result = true; const EnumFormats* copyFormatEnum = getCanonicalFormat(m_copyInternalFormat, m_copyInternalFormat.format, m_copyInternalFormat.type); if (copyFormatEnum != 0) { GLuint texture2; GLenum status; bool validcopy = isCopyValid(m_copyInternalFormat, m_internalFormat); gl.genTextures(1, &texture2); // Target is always GL_TEXTURE_2D gl.bindTexture(GL_TEXTURE_2D, texture2); GLenum error = gl.getError(); // CopyTexImage to copy_internalformat (GL converts, but PixelStore is ignored) // Target is always GL_TEXTURE_2D gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_copyInternalFormat.sizedFormat, 0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0); error = gl.getError(); // if this combination of copy_internalformat,internalformat is invalid if (validcopy == false) { // expect error and continue if (error != GL_NO_ERROR) { // Invalid format used and glCopyTexImage2D failed result = true; } else { m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glCopyTexImage2D succeeded" << tcu::TestLog::EndMessage; result = false; } } else // validcopy == true { // expect no error and continue if (error != GL_NO_ERROR) { m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glCopyTexImage2D failed" << tcu::TestLog::EndMessage; result = false; } else { if (!glu::isContextTypeES(renderContext.getType())) { // if GetTexImage is supported we call the // inner function only as no loop needed const PixelFormat& outputFormat = getPixelFormat(copyFormatEnum->format); const PixelType& outputType = getPixelType(copyFormatEnum->type); result &= getTexImageInner(outputFormat, outputType); } GLint orginalFboId; gl.getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &orginalFboId); GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv"); GLuint fboId; gl.genFramebuffers(1, &fboId); gl.bindFramebuffer(GL_FRAMEBUFFER, fboId); bool validImageAttach = isFBOImageAttachValid(m_copyInternalFormat, copyFormatEnum->format, copyFormatEnum->type); // attach copy_internalformat texture to FBO // Target is always GL_TEXTURE_2D const PixelFormat& copyFormat = getPixelFormat(copyFormatEnum->format); gl.framebufferTexture2D(GL_FRAMEBUFFER, copyFormat.attachment, GL_TEXTURE_2D, texture2, 0); GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D"); status = gl.checkFramebufferStatus(GL_FRAMEBUFFER); GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus"); // if an unsized sizedFormat was given, then implementation chosen copy format // destination might be different than what's expected; // we cannot continue checking since ReadPixels might not choose a compatible // format, also the format may not be renderable as expected if (isUnsizedFormat(m_copyInternalFormat.sizedFormat)) { result &= true; } else if (status == GL_FRAMEBUFFER_COMPLETE) { if (validImageAttach) result &= readPixels(true); else { m_testCtx.getLog() << tcu::TestLog::Message << "Copy FBO is complete but expected incomplete with sizedFormat " << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement " << copyFormat.attachment << tcu::TestLog::EndMessage; result = false; } } else if (validImageAttach) { m_testCtx.getLog() << tcu::TestLog::Message << "Copy FBO is not complete but expected complete with sizedFormat " << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement " << copyFormat.attachment << tcu::TestLog::EndMessage; result = false; } // bind original FBO gl.bindFramebuffer(GL_FRAMEBUFFER, orginalFboId); gl.deleteFramebuffers(1, &fboId); } } gl.deleteTextures(1, &texture2); } return result; } bool RectangleTest::compare(GLvoid* gradient, GLvoid* data, const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy) const { // Compares the reference gradient data to the output data int iformatSampler = m_internalFormat.sampler; int outputSampler = getSampler(outputType, outputFormat); int inputSampler = getSampler(m_inputType, m_inputFormat); if (isCopy) iformatSampler = m_copyInternalFormat.sampler; int samplerIsIntUintFloat = 3; // 1: INT | 2: UINT | 3: FLOAT/UNORM/NORM if (m_internalFormat.sampler == SAMPLER_INT) samplerIsIntUintFloat = 1; else if (m_internalFormat.sampler == SAMPLER_UINT) samplerIsIntUintFloat = 2; std::vector gradientStrip; if (!stripBuffer(m_unpackProperties, static_cast(gradient), gradientStrip, false)) return false; std::vector dataStrip; if (!stripBuffer(m_packProperties, static_cast(data), dataStrip, true)) return false; if (gradientStrip.empty() || dataStrip.empty()) return false; std::vector inputBuffer; getFloatBuffer(&gradientStrip[0], samplerIsIntUintFloat, m_inputFormat, m_inputType, GRADIENT_WIDTH * GRADIENT_HEIGHT, inputBuffer); std::vector outputBuffer; getFloatBuffer(&dataStrip[0], samplerIsIntUintFloat, outputFormat, outputType, GRADIENT_WIDTH * GRADIENT_HEIGHT, outputBuffer); std::vector inputBitTable; getBits(m_inputType, m_inputFormat, inputBitTable); std::vector outputBitTable; getBits(outputType, outputFormat, outputBitTable); const int* internalformatBitTable = reinterpret_cast(&m_internalFormat.bits); const int* copyFormatBitTable = m_copyInternalFormat.bits.array; // make struct field iterable float* inputBufferFloat = reinterpret_cast(&inputBuffer[0]); float* outputBufferFloat = reinterpret_cast(&outputBuffer[0]); int* inputBufferInt = reinterpret_cast(&inputBuffer[0]); int* outputBufferInt = reinterpret_cast(&outputBuffer[0]); unsigned int* inputBufferUint = reinterpret_cast(&inputBuffer[0]); unsigned int* outputBufferUint = reinterpret_cast(&outputBuffer[0]); for (int i = 0; i < GRADIENT_WIDTH * GRADIENT_HEIGHT; ++i) { for (int j = 0; j < NUM_FLOAT_PIXEL_COUNT / 3; ++j) { int bit1 = getRealBitPrecision(inputBitTable[j], inputSampler == SAMPLER_FLOAT); int bit2 = getRealBitPrecision(outputBitTable[j], outputSampler == SAMPLER_FLOAT); int bit3 = getRealBitPrecision(internalformatBitTable[j], iformatSampler == SAMPLER_FLOAT); int bitdiff; if (bit1 >= bit3) { if ((inputSampler == SAMPLER_UNORM && m_internalFormat.sampler == SAMPLER_NORM)) bit3 -= 1; } if (bit2 <= bit3) { if (outputSampler == SAMPLER_NORM && m_internalFormat.sampler == SAMPLER_UNORM) bit2 -= 1; } if (!(m_internalFormat.flags & FLAG_REQ_RBO) && bit3 > 8 && m_internalFormat.sampler != SAMPLER_UINT && m_internalFormat.sampler != SAMPLER_INT) { // If this internalFormat is not a required format there is no requirement // that the implementation uses exactly the bit width requested. For example, // it may substitute RGB10 for RGB12. The implementation can't make subtitutions // for integer formats. bit3 = 8; } bitdiff = std::min(std::min(bit1, bit2), bit3); if (isCopy) { bitdiff = std::min(bitdiff, copyFormatBitTable[j]); } if (bitdiff > 0) { if (samplerIsIntUintFloat == 1) // 1: INT { int inputValue = inputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j]; int outputValue = outputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j]; if (inputSampler == SAMPLER_UINT) // If input data was unsigned, it should be clamped to fit into // internal format positive range (otherwise it may wrap and // yield negative internalformat values) inputValue = clampUnsignedValue(bit3 - 1, inputValue); ; inputValue = clampSignedValue(bit3, inputValue); if (isCopy) { inputValue = clampSignedValue(copyFormatBitTable[j], inputValue); } if (outputSampler == SAMPLER_UINT) inputValue = clampUnsignedValue(bit2, inputValue); else inputValue = clampSignedValue(bit2, inputValue); if (inputValue != outputValue) { m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", " << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage; return false; } } else if (samplerIsIntUintFloat == 2) // 2: UINT { unsigned int inputValue = inputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6]; unsigned int outputValue = outputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6]; inputValue = clampUnsignedValue(bit3, inputValue); if (isCopy) inputValue = clampUnsignedValue(copyFormatBitTable[j], inputValue); if (outputSampler == SAMPLER_UINT) inputValue = clampUnsignedValue(bit2, inputValue); else if (outputSampler == SAMPLER_INT) inputValue = clampUnsignedValue(bit2 - 1, inputValue); if (inputValue != outputValue) { m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", " << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage; return false; } } else if (samplerIsIntUintFloat == 3) // 3: FLOAT / UNORM / NORM { float inputValue = inputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12]; float outputValue = outputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12]; float epsilon; if ((outputSampler == SAMPLER_UNORM) || (outputSampler == SAMPLER_NORM)) { // Check if format is UNORM/NORM which needs different // precision since it implies a int->float conversion. epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1); } else if ((inputSampler == SAMPLER_FLOAT) != (outputSampler == SAMPLER_FLOAT)) { // Allow for rounding in either direction for float->int conversions. epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1); } else epsilon = 1.0f / ((float)((1 << bitdiff) - 1)); if (inputSampler == SAMPLER_FLOAT || outputSampler == SAMPLER_FLOAT) { // According to GL spec the precision requirement // of floating-point values is 1 part in 10^5. epsilon = deFloatMax(epsilon, 0.00001f); } if (m_internalFormat.flags & FLAG_COMPRESSED) epsilon = deFloatMax(epsilon, 0.1f); // Clamp input value to range of output if (iformatSampler == SAMPLER_UNORM || outputSampler == SAMPLER_UNORM) inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), 0.0f); else if (iformatSampler == SAMPLER_NORM || outputSampler == SAMPLER_NORM) inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), -1.0f); // Compare the input and output if (deFloatAbs(inputValue - outputValue) > epsilon) { m_testCtx.getLog() << tcu::TestLog::Message << "Non-integer comparison: " << i << ", " << j << ", " << NUM_FLOAT_PIXEL_COUNT * i + j << ", " << epsilon << ": " << inputValue << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage; return false; } } else { m_testCtx.getLog() << tcu::TestLog::Message << "Sampler type cannot be recognised, so no comparison" << tcu::TestLog::EndMessage; return false; } } } } return true; } void RectangleTest::getFloatBuffer(GLvoid* gradient, int samplerIsIntUintFloat, const PixelFormat& format, const PixelType& type, int elementCount, std::vector& result) const { int componentCount = format.components; switch (type.type) { case GL_UNSIGNED_BYTE: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_BYTE, result); break; case GL_BYTE: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_BYTE, result); break; case GL_UNSIGNED_SHORT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_SHORT, result); break; case GL_SHORT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_SHORT, result); break; case GL_UNSIGNED_INT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_INT, result); break; case GL_INT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_INT, result); break; case GL_HALF_FLOAT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_HALF_FLOAT, result); break; case GL_FLOAT: makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_FLOAT, result); break; case GL_UNSIGNED_SHORT_5_6_5: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5, result); break; case GL_UNSIGNED_SHORT_4_4_4_4: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4, result); break; case GL_UNSIGNED_SHORT_5_5_5_1: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1, result); break; case GL_UNSIGNED_INT_2_10_10_10_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV, result); break; case GL_UNSIGNED_INT_24_8: makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_24_8, result); break; case GL_UNSIGNED_INT_10F_11F_11F_REV: makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10F_11F_11F_REV, result); break; case GL_UNSIGNED_INT_5_9_9_9_REV: makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_5_9_9_9_REV, result); break; case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: makeBufferPackedFloat(gradient, format, elementCount, pack_FLOAT_32_UNSIGNED_INT_24_8_REV, result); break; case GL_UNSIGNED_BYTE_3_3_2: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2, result); break; case GL_UNSIGNED_BYTE_2_3_3_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV, result); break; case GL_UNSIGNED_SHORT_5_6_5_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV, result); break; case GL_UNSIGNED_SHORT_4_4_4_4_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV, result); break; case GL_UNSIGNED_SHORT_1_5_5_5_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV, result); break; case GL_UNSIGNED_INT_8_8_8_8: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8, result); break; case GL_UNSIGNED_INT_8_8_8_8_REV: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV, result); break; case GL_UNSIGNED_INT_10_10_10_2: if (samplerIsIntUintFloat == 1) makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_INT, result); else if (samplerIsIntUintFloat == 2) makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_UINT, result); else if (samplerIsIntUintFloat == 3) makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2, result); break; default: TCU_FAIL("Unsuported type"); } } template void RectangleTest::makeBuffer(const GLvoid* gradient, const PixelFormat& format, int samplerIsIntUintFloat, int elementCount, int componentCount, float (*pack)(Type), std::vector& result) const { const Type* sourceData = static_cast(gradient); result.resize(sizeof(FloatPixel) * elementCount); for (int i = 0; i < elementCount; ++i) { rawFloatPixel values; rawIntPixel valuesInt; rawUintPixel valuesUint; for (int j = 0; j < componentCount; j++) { if (samplerIsIntUintFloat == 1) valuesInt[j] = (int)static_cast(sourceData[componentCount * i + j]); else if (samplerIsIntUintFloat == 2) valuesUint[j] = (unsigned int)static_cast(sourceData[componentCount * i + j]); else if (samplerIsIntUintFloat == 3) values[j] = pack(sourceData[componentCount * i + j]); } if (samplerIsIntUintFloat == 1) result[i] = orderComponentsInt(valuesInt, format); else if (samplerIsIntUintFloat == 2) result[i] = orderComponentsUint(valuesUint, format); else if (samplerIsIntUintFloat == 3) result[i] = orderComponentsFloat(values, format); } } void RectangleTest::getBits(const PixelType& type, const PixelFormat& format, std::vector& resultTable) const { // return bit depth table based on type and format pair; // table is always NUM_FLOAT_PIXEL_COUNT digit long resultTable.resize(NUM_FLOAT_PIXEL_COUNT); std::fill(resultTable.begin(), resultTable.end(), 0); if (type.special == true) { std::memcpy(&resultTable[0], &type.bits, sizeof(int) * NUM_FLOAT_PIXEL_COUNT); if (type.type == GL_UNSIGNED_INT_5_9_9_9_REV) { //this type is another special case: it is always converted to 3-channel color (no A). //as results of this function are used for comparison of converted values we set A bits to 0. resultTable[3] = 0; } } else { int bits; if (type.type == GL_FLOAT) bits = 32; else if (type.type == GL_HALF_FLOAT) bits = 16; else bits = type.size << 3; if (format.format == GL_DEPTH_STENCIL || format.format == GL_DEPTH_COMPONENT) resultTable[4] = bits; if (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX || format.format == GL_STENCIL_INDEX8) { resultTable[5] = bits; } if (format.format == GL_RED || format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR || format.format == GL_BGRA || format.format == GL_RED_INTEGER || format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER || format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER) { resultTable[0] = bits; } if (format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR || format.format == GL_BGRA || format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER || format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER) { resultTable[1] = bits; } if (format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR || format.format == GL_BGRA || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER || format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER) { resultTable[2] = bits; } if (format.format == GL_RGBA || format.format == GL_BGRA || format.format == GL_RGBA_INTEGER || format.format == GL_BGRA_INTEGER) { resultTable[3] = bits; } } } template void RectangleTest::makeBufferPackedInt(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawIntPixel*, Type), std::vector& result) const { const Type* sourceData = static_cast(gradient); result.resize(sizeof(FloatPixel) * elementCount); for (int i = 0; i < elementCount; ++i) { rawIntPixel values; pack(&values, sourceData[i]); result[i] = orderComponentsInt(values, format); } } template void RectangleTest::makeBufferPackedUint(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawUintPixel*, Type), std::vector& result) const { const Type* sourceData = static_cast(gradient); result.resize(sizeof(FloatPixel) * elementCount); for (int i = 0; i < elementCount; ++i) { rawUintPixel values; pack(&values, sourceData[i]); result[i] = orderComponentsUint(values, format); } } template void RectangleTest::makeBufferPackedFloat(const GLvoid* gradient, const PixelFormat& format, int elementCount, void (*pack)(rawFloatPixel*, Type), std::vector& result) const { const Type* sourceData = static_cast(gradient); result.resize(sizeof(FloatPixel) * elementCount); for (int i = 0; i < elementCount; ++i) { rawFloatPixel values; pack(&values, sourceData[i]); result[i] = orderComponentsFloat(values, format); } } FloatPixel RectangleTest::orderComponentsInt(rawIntPixel values, const PixelFormat& format) const { FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF }; if (format.componentOrder.bits.red >= 0) fp.i_r = values[format.componentOrder.bits.red]; if (format.componentOrder.bits.green >= 0) fp.i_g = values[format.componentOrder.bits.green]; if (format.componentOrder.bits.blue >= 0) fp.i_b = values[format.componentOrder.bits.blue]; if (format.componentOrder.bits.alpha >= 0) fp.i_a = values[format.componentOrder.bits.alpha]; if (format.componentOrder.bits.depth >= 0) fp.i_d = values[format.componentOrder.bits.depth]; if (format.componentOrder.bits.stencil >= 0) fp.i_s = values[format.componentOrder.bits.stencil]; return fp; } FloatPixel RectangleTest::orderComponentsUint(rawUintPixel values, const PixelFormat& format) const { FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF }; if (format.componentOrder.bits.red >= 0) fp.ui_r = values[format.componentOrder.bits.red]; if (format.componentOrder.bits.green >= 0) fp.ui_g = values[format.componentOrder.bits.green]; if (format.componentOrder.bits.blue >= 0) fp.ui_b = values[format.componentOrder.bits.blue]; if (format.componentOrder.bits.alpha >= 0) fp.ui_a = values[format.componentOrder.bits.alpha]; if (format.componentOrder.bits.depth >= 0) fp.ui_d = values[format.componentOrder.bits.depth]; if (format.componentOrder.bits.stencil >= 0) fp.ui_s = values[format.componentOrder.bits.stencil]; return fp; } FloatPixel RectangleTest::orderComponentsFloat(rawFloatPixel values, const PixelFormat& format) const { FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF }; if (format.componentOrder.bits.red >= 0) fp.r = values[format.componentOrder.bits.red]; if (format.componentOrder.bits.green >= 0) fp.g = values[format.componentOrder.bits.green]; if (format.componentOrder.bits.blue >= 0) fp.b = values[format.componentOrder.bits.blue]; if (format.componentOrder.bits.alpha >= 0) fp.a = values[format.componentOrder.bits.alpha]; if (format.componentOrder.bits.depth >= 0) fp.d = values[format.componentOrder.bits.depth]; if (format.componentOrder.bits.stencil >= 0) fp.s = values[format.componentOrder.bits.stencil]; return fp; } unsigned int RectangleTest::getRealBitPrecision(int bits, bool isFloat) const { if (!isFloat) return bits; switch (bits) { case 32: return 23; case 16: return 10; case 11: return 6; case 10: return 5; } return bits; } bool RectangleTest::stripBuffer(const PackedPixelsBufferProperties& props, const GLubyte* orginalBuffer, std::vector& newBuffer, bool validate) const { // Extracts pixel data from a buffer with specific // pixel store configuration into a flat buffer int newBufferSize = props.elementSize * props.elementsInRowNoAlign * GRADIENT_HEIGHT; if (!newBufferSize) return false; newBuffer.resize(newBufferSize); int skipBottom = ((props.skipImages * props.rowCount + props.skipRows) * props.elementsInRow) * props.elementSize; int skipTop = (props.rowCount - GRADIENT_HEIGHT - props.skipRows) * props.elementsInRow * props.elementSize; int skipLeft = props.skipPixels * props.elementsInGroup * props.elementSize; int skipRight = (props.elementsInRow - GRADIENT_WIDTH * props.elementsInGroup) * props.elementSize - skipLeft; int copy = GRADIENT_WIDTH * props.elementsInGroup * props.elementSize; int skipAlign = (props.elementsInRow - props.elementsInRowNoAlign) * props.elementSize; if (validate) { for (int i = 0; i < skipBottom; i++) { if (orginalBuffer[i] != m_defaultFillValue) return false; } } int index_src = skipBottom; int index_dst = 0; for (int j = 0; j < GRADIENT_HEIGHT; j++) { if (validate) { for (int i = 0; i < skipLeft; i++) { if (orginalBuffer[index_src + i] != m_defaultFillValue) return false; } } index_src += skipLeft; std::memcpy(&newBuffer[0] + index_dst, &orginalBuffer[0] + index_src, copy); index_src += copy; index_dst += copy; if (validate) { for (int i = skipAlign; i < skipRight; i++) { if (orginalBuffer[index_src + i] != m_defaultFillValue) return false; } } index_src += skipRight; } if (validate) { for (int i = 0; i < skipTop; i++) { if (orginalBuffer[index_src + i] != m_defaultFillValue) return false; } } index_src += skipTop; return true; } int RectangleTest::clampSignedValue(int bits, int value) const { int max = 2147483647; int min = 0x80000000; if (bits < 32) { max = (1 << (bits - 1)) - 1; min = (1 << (bits - 1)) - (1 << bits); } if (value >= max) return max; else if (value <= min) return min; return value; } unsigned int RectangleTest::clampUnsignedValue(int bits, unsigned int value) const { unsigned int max = 4294967295u; unsigned int min = 0; if (bits < 32) { max = (1 << bits) - 1; } if (value >= max) return max; else if (value <= min) return min; return value; } float RectangleTest::pack_UNSIGNED_BYTE(GLubyte value) { return static_cast(value) / std::numeric_limits::max(); } float RectangleTest::pack_BYTE(GLbyte value) { return deFloatMax(static_cast(value) / std::numeric_limits::max(), -1.0f); } float RectangleTest::pack_UNSIGNED_SHORT(GLushort value) { return static_cast(value) / std::numeric_limits::max(); } float RectangleTest::pack_SHORT(GLshort value) { return deFloatMax(static_cast(value) / std::numeric_limits::max(), -1.0f); } float RectangleTest::pack_UNSIGNED_INT(GLuint value) { return static_cast(value) / std::numeric_limits::max(); } float RectangleTest::pack_INT(GLint value) { return deFloatMax(static_cast(value) / std::numeric_limits::max(), -1.0f); } float RectangleTest::pack_HALF_FLOAT(GLhalf value) { return halfFloatToFloat(value); } float RectangleTest::pack_FLOAT(GLfloat value) { return value; } void RectangleTest::pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel* values, GLubyte value) { (*values)[0] = ((value >> 5) & 7) / 7.0f; (*values)[1] = ((value >> 2) & 7) / 7.0f; (*values)[2] = ((value >> 0) & 3) / 3.0f; } void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel* values, GLubyte value) { (*values)[0] = (value >> 5) & 7; (*values)[1] = (value >> 2) & 7; (*values)[2] = (value >> 0) & 3; } void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel* values, GLubyte value) { (*values)[0] = (static_cast(value) >> 5) & 7; (*values)[1] = (static_cast(value) >> 2) & 7; (*values)[2] = (static_cast(value) >> 0) & 3; } void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel* values, GLubyte value) { (*values)[2] = ((value >> 6) & 3) / 3.0f; (*values)[1] = ((value >> 3) & 7) / 7.0f; (*values)[0] = ((value >> 0) & 7) / 7.0f; } void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel* values, GLubyte value) { (*values)[2] = (value >> 6) & 3; (*values)[1] = (value >> 3) & 7; (*values)[0] = (value >> 0) & 7; } void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel* values, GLubyte value) { (*values)[2] = (static_cast(value) >> 6) & 3; (*values)[1] = (static_cast(value) >> 3) & 7; (*values)[0] = (static_cast(value) >> 0) & 7; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel* values, GLushort value) { (*values)[0] = ((value >> 11) & 31) / 31.0f; (*values)[1] = ((value >> 5) & 63) / 63.0f; (*values)[2] = ((value >> 0) & 31) / 31.0f; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel* values, GLushort value) { (*values)[0] = (value >> 11) & 31; (*values)[1] = (value >> 5) & 63; (*values)[2] = (value >> 0) & 31; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel* values, GLushort value) { (*values)[0] = (static_cast(value) >> 11) & 31; (*values)[1] = (static_cast(value) >> 5) & 63; (*values)[2] = (static_cast(value) >> 0) & 31; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel* values, GLushort value) { (*values)[2] = ((value >> 11) & 31) / 31.0f; (*values)[1] = ((value >> 5) & 63) / 63.0f; (*values)[0] = ((value >> 0) & 31) / 31.0f; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel* values, GLushort value) { (*values)[2] = (value >> 11) & 31; (*values)[1] = (value >> 5) & 63; (*values)[0] = (value >> 0) & 31; } void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel* values, GLushort value) { (*values)[2] = (static_cast(value) >> 11) & 31; (*values)[1] = (static_cast(value) >> 5) & 63; (*values)[0] = (static_cast(value) >> 0) & 31; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel* values, GLushort value) { (*values)[0] = ((value >> 12) & 15) / 15.0f; (*values)[1] = ((value >> 8) & 15) / 15.0f; (*values)[2] = ((value >> 4) & 15) / 15.0f; (*values)[3] = ((value >> 0) & 15) / 15.0f; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel* values, GLushort value) { (*values)[0] = (value >> 12) & 15; (*values)[1] = (value >> 8) & 15; (*values)[2] = (value >> 4) & 15; (*values)[3] = (value >> 0) & 15; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel* values, GLushort value) { (*values)[0] = (static_cast(value) >> 12) & 15; (*values)[1] = (static_cast(value) >> 8) & 15; (*values)[2] = (static_cast(value) >> 4) & 15; (*values)[3] = (static_cast(value) >> 0) & 15; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel* values, GLushort value) { (*values)[3] = ((value >> 12) & 15) / 15.0f; (*values)[2] = ((value >> 8) & 15) / 15.0f; (*values)[1] = ((value >> 4) & 15) / 15.0f; (*values)[0] = ((value >> 0) & 15) / 15.0f; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel* values, GLushort value) { (*values)[3] = (value >> 12) & 15; (*values)[2] = (value >> 8) & 15; (*values)[1] = (value >> 4) & 15; (*values)[0] = (value >> 0) & 15; } void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel* values, GLushort value) { (*values)[3] = (static_cast(value) >> 12) & 15; (*values)[2] = (static_cast(value) >> 8) & 15; (*values)[1] = (static_cast(value) >> 4) & 15; (*values)[0] = (static_cast(value) >> 0) & 15; } void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel* values, GLushort value) { (*values)[0] = ((value >> 11) & 31) / 31.0f; (*values)[1] = ((value >> 6) & 31) / 31.0f; (*values)[2] = ((value >> 1) & 31) / 31.0f; (*values)[3] = ((value >> 0) & 1) / 1.0f; } void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel* values, GLushort value) { (*values)[0] = (value >> 11) & 31; (*values)[1] = (value >> 6) & 31; (*values)[2] = (value >> 1) & 31; (*values)[3] = (value >> 0) & 1; } void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel* values, GLushort value) { (*values)[0] = (static_cast(value) >> 11) & 31; (*values)[1] = (static_cast(value) >> 6) & 31; (*values)[2] = (static_cast(value) >> 1) & 31; (*values)[3] = (static_cast(value) >> 0) & 1; } void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel* values, GLushort value) { (*values)[3] = ((value >> 15) & 1) / 1.0f; (*values)[2] = ((value >> 10) & 31) / 31.0f; (*values)[1] = ((value >> 5) & 31) / 31.0f; (*values)[0] = ((value >> 0) & 31) / 31.0f; } void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel* values, GLushort value) { (*values)[3] = (value >> 15) & 1; (*values)[2] = (value >> 10) & 31; (*values)[1] = (value >> 5) & 31; (*values)[0] = (value >> 0) & 31; } void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel* values, GLushort value) { (*values)[3] = (static_cast(value) >> 15) & 1; (*values)[2] = (static_cast(value) >> 10) & 31; (*values)[1] = (static_cast(value) >> 5) & 31; (*values)[0] = (static_cast(value) >> 0) & 31; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel* values, GLuint value) { (*values)[0] = ((value >> 24) & 255) / 255.0f; (*values)[1] = ((value >> 16) & 255) / 255.0f; (*values)[2] = ((value >> 8) & 255) / 255.0f; (*values)[3] = ((value >> 0) & 255) / 255.0f; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel* values, GLuint value) { (*values)[0] = (value >> 24) & 255; (*values)[1] = (value >> 16) & 255; (*values)[2] = (value >> 8) & 255; (*values)[3] = (value >> 0) & 255; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel* values, GLuint value) { (*values)[0] = (static_cast(value) >> 24) & 255; (*values)[1] = (static_cast(value) >> 16) & 255; (*values)[2] = (static_cast(value) >> 8) & 255; (*values)[3] = (static_cast(value) >> 0) & 255; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel* values, GLuint value) { (*values)[3] = ((value >> 24) & 255) / 255.0f; (*values)[2] = ((value >> 16) & 255) / 255.0f; (*values)[1] = ((value >> 8) & 255) / 255.0f; (*values)[0] = ((value >> 0) & 255) / 255.0f; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel* values, GLuint value) { (*values)[3] = (value >> 24) & 255; (*values)[2] = (value >> 16) & 255; (*values)[1] = (value >> 8) & 255; (*values)[0] = (value >> 0) & 255; } void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel* values, GLuint value) { (*values)[3] = (static_cast(value) >> 24) & 255; (*values)[2] = (static_cast(value) >> 16) & 255; (*values)[1] = (static_cast(value) >> 8) & 255; (*values)[0] = (static_cast(value) >> 0) & 255; } void RectangleTest::pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel* values, GLuint value) { (*values)[0] = ((value >> 22) & 1023) / 1023.0f; (*values)[1] = ((value >> 12) & 1023) / 1023.0f; (*values)[2] = ((value >> 2) & 1023) / 1023.0f; (*values)[3] = ((value >> 0) & 3) / 3.0f; } void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel* values, GLuint value) { (*values)[0] = ((value >> 22) & 1023); (*values)[1] = ((value >> 12) & 1023); (*values)[2] = ((value >> 2) & 1023); (*values)[3] = ((value >> 0) & 3); } void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel* values, GLuint value) { (*values)[0] = ((static_cast(value) >> 22) & 1023); (*values)[1] = ((static_cast(value) >> 12) & 1023); (*values)[2] = ((static_cast(value) >> 2) & 1023); (*values)[3] = ((static_cast(value) >> 0) & 3); } void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel* values, GLuint value) { (*values)[3] = ((value >> 30) & 3) / 3.0f; (*values)[2] = ((value >> 20) & 1023) / 1023.0f; (*values)[1] = ((value >> 10) & 1023) / 1023.0f; (*values)[0] = ((value >> 0) & 1023) / 1023.0f; } void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel* values, GLuint value) { (*values)[3] = (value >> 30) & 3; (*values)[2] = (value >> 20) & 1023; (*values)[1] = (value >> 10) & 1023; (*values)[0] = (value >> 0) & 1023; } void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel* values, GLuint value) { (*values)[3] = (static_cast(value) >> 30) & 3; (*values)[2] = (static_cast(value) >> 20) & 1023; (*values)[1] = (static_cast(value) >> 10) & 1023; (*values)[0] = (static_cast(value) >> 0) & 1023; } void RectangleTest::pack_UNSIGNED_INT_24_8(rawFloatPixel* values, GLuint value) { (*values)[0] = ((value >> 8) & 16777215) / 16777215.0f; (*values)[1] = ((value >> 0) & 255) / 255.0f; } void RectangleTest::pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel* values, GLuint value) { (*values)[2] = unsignedF10ToFloat((value >> 22) & 1023); (*values)[1] = unsignedF11ToFloat((value >> 11) & 2047); (*values)[0] = unsignedF11ToFloat((value >> 0) & 2047); } void RectangleTest::pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel* values, GLuint value) { const int B = 15; const int N = 9; GLint pExp = ((value >> 27) & 31); GLuint pBlue = ((value >> 18) & 511); GLuint pGreen = ((value >> 9) & 511); GLuint pRed = ((value >> 0) & 511); (*values)[2] = (float)(pBlue * pow(2.0, pExp - B - N)); (*values)[1] = (float)(pGreen * pow(2.0, pExp - B - N)); (*values)[0] = (float)(pRed * pow(2.0, pExp - B - N)); (*values)[3] = 1.0f; } void RectangleTest::pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel* values, F_32_UINT_24_8_REV value) { (*values)[0] = value.d; (*values)[1] = (value.s & 255) / 255.0f; } bool RectangleTest::getTexImage() { // for each output format for (int m = 0; m < DE_LENGTH_OF_ARRAY(coreFormats); ++m) { const PixelFormat& outputFormat = coreFormats[m]; // for each output type for (int n = 0; n < DE_LENGTH_OF_ARRAY(coreTypes); ++n) { const PixelType& outputType = coreTypes[n]; if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) && (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type)) { continue; } if (!getTexImageInner(outputFormat, outputType)) return false; } } return true; } bool RectangleTest::getTexImageInner(const PixelFormat& outputFormat, const PixelType& outputType) { bool outputFormatValid = isFormatValid(outputFormat, outputType, m_internalFormat, false, true, OUTPUT_GETTEXIMAGE); GLenum error = readOutputData(outputFormat, outputType, OUTPUT_GETTEXIMAGE); m_countGetTexImage++; if (!outputFormatValid) { if (error) { m_countGetTexImageOK++; return true; } m_testCtx.getLog() << tcu::TestLog::Message << "Expected error but got no GL error" << tcu::TestLog::EndMessage; return false; } else if (error) { m_testCtx.getLog() << tcu::TestLog::Message << "Error during glGetTexImage" << tcu::TestLog::EndMessage; return false; } m_countGetTexImageOK++; m_countCompare++; // compare output gradient to input gradient if (compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, false)) { m_countCompareOK++; return true; } m_testCtx.getLog() << tcu::TestLog::Message << "Gradient comparison failed during GetTexImage for input = [" << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage; return false; } void RectangleTest::testAllFormatsAndTypes() { DE_ASSERT((m_textureTarget == GL_TEXTURE_2D) || (m_textureTarget == GL_TEXTURE_3D)); glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); bool result = true; gl.clear(GL_COLOR_BUFFER_BIT); const PixelType* types; int typesCount; const PixelFormat* formats; int formatsCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { types = esTypes; typesCount = DE_LENGTH_OF_ARRAY(esTypes); formats = esFormats; formatsCount = DE_LENGTH_OF_ARRAY(esFormats); } else { types = coreTypes; typesCount = DE_LENGTH_OF_ARRAY(coreTypes); formats = coreFormats; formatsCount = DE_LENGTH_OF_ARRAY(coreFormats); } for (int inputFormatIndex = 0; inputFormatIndex < formatsCount; inputFormatIndex++) { m_inputFormat = formats[inputFormatIndex]; for (int inputTypeIndex = 0; inputTypeIndex < typesCount; inputTypeIndex++) { GLenum error = 0; m_inputType = types[inputTypeIndex]; applyInitialStorageModes(); // Create input gradient in format,type, with appropriate range createGradient(); if (m_gradient.empty()) TCU_FAIL("Could not create gradient."); if (m_unpackProperties.swapBytes) swapBytes(m_inputType.size, m_gradient); GLuint texture; gl.genTextures(1, &texture); gl.bindTexture(m_textureTarget, texture); GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture"); if (m_textureTarget == GL_TEXTURE_3D) { gl.texImage3D(GL_TEXTURE_3D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 1, 0, m_inputFormat.format, m_inputType.type, &m_gradient[0]); } else { gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0, m_inputFormat.format, m_inputType.type, &m_gradient[0]); } if (m_unpackProperties.swapBytes) swapBytes(m_inputType.size, m_gradient); error = gl.getError(); if (isFormatValid(m_inputFormat, m_inputType, m_internalFormat, true, false, INPUT_TEXIMAGE)) { if (error == GL_NO_ERROR) { if (!glu::isContextTypeES(renderContext.getType())) result &= getTexImage(); result &= doRead(texture); } else { m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glTexImage2D/3D failed" << tcu::TestLog::EndMessage; result = false; } } else if (error == GL_NO_ERROR) { m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glTexImage2D/3D succeeded" << tcu::TestLog::EndMessage; result = false; } gl.deleteTextures(1, &texture); } } if (result) m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); else m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); } tcu::TestNode::IterateResult RectangleTest::iterate(void) { resetInitialStorageModes(); testAllFormatsAndTypes(); return STOP; } class InitialValuesTest : public deqp::TestCase { public: InitialValuesTest(deqp::Context& context); virtual ~InitialValuesTest(); tcu::TestNode::IterateResult iterate(void); }; InitialValuesTest::InitialValuesTest(deqp::Context& context) : deqp::TestCase(context, "initial_values", "Verify if all UNPACK and PACK initial " "state matches the values in table 6.28 (6.23, in ES.)") { } InitialValuesTest::~InitialValuesTest() { } tcu::TestNode::IterateResult InitialValuesTest::iterate(void) { glu::RenderContext& renderContext = m_context.getRenderContext(); const Functions& gl = renderContext.getFunctions(); bool result = true; GLenum commonIntModes[] = { GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_PIXELS, GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_IMAGES, GL_PACK_ROW_LENGTH, GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS }; // check if following eight storage modes are 0 GLint i = 1; for (int mode = 0; mode < DE_LENGTH_OF_ARRAY(commonIntModes); mode++) { gl.getIntegerv(commonIntModes[mode], &i); result &= (i == 0); } // check if following two storage modes are 4 gl.getIntegerv(GL_UNPACK_ALIGNMENT, &i); result &= (i == 4); gl.getIntegerv(GL_PACK_ALIGNMENT, &i); result &= (i == 4); // check storage modes available only in core GL if (!glu::isContextTypeES(renderContext.getType())) { // check if following four boolean modes are false GLboolean b = true; gl.getBooleanv(GL_UNPACK_SWAP_BYTES, &b); result &= (b == false); gl.getBooleanv(GL_UNPACK_LSB_FIRST, &b); result &= (b == false); gl.getBooleanv(GL_PACK_SWAP_BYTES, &b); result &= (b == false); gl.getBooleanv(GL_PACK_LSB_FIRST, &b); result &= (b == false); // check if following two modes are 0 gl.getIntegerv(GL_PACK_IMAGE_HEIGHT, &i); result &= (i == 0); gl.getIntegerv(GL_PACK_SKIP_IMAGES, &i); result &= (i == 0); } // make sure that no pack/unpack buffers are bound gl.getIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &i); result &= (i == 0); gl.getIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &i); result &= (i == 0); if (result) m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); else m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); return STOP; } class PBORectangleTest : public RectangleTest { public: PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat); virtual ~PBORectangleTest(); }; PBORectangleTest::PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat) : RectangleTest(context, name, internalFormat) { m_usePBO = true; } PBORectangleTest::~PBORectangleTest() { } class VariedRectangleTest : public RectangleTest { public: VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat); virtual ~VariedRectangleTest(); tcu::TestNode::IterateResult iterate(void); protected: struct StoreMode { GLenum parameter; GLint* property; GLint value; }; }; VariedRectangleTest::VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat) : RectangleTest(context, name, internalFormat) { } VariedRectangleTest::~VariedRectangleTest() { } tcu::TestNode::IterateResult VariedRectangleTest::iterate(void) { const int IMAGE_WIDTH_1 = 10; const int IMAGE_WIDTH_2 = 15; const int IMAGE_HEIGHT_1 = 10; const int IMAGE_HEIGHT_2 = 15; PackedPixelsBufferProperties& up = m_initialUnpackProperties; PackedPixelsBufferProperties& pp = m_initialPackProperties; StoreMode commonCases[] = { { GL_UNPACK_ROW_LENGTH, &up.rowLength, 0 }, { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_1 }, { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_2 }, { GL_UNPACK_SKIP_ROWS, &up.skipRows, 0 }, { GL_UNPACK_SKIP_ROWS, &up.skipRows, 1 }, { GL_UNPACK_SKIP_ROWS, &up.skipRows, 2 }, { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 0 }, { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 1 }, { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 2 }, { GL_UNPACK_ALIGNMENT, &up.alignment, 1 }, { GL_UNPACK_ALIGNMENT, &up.alignment, 2 }, { GL_UNPACK_ALIGNMENT, &up.alignment, 4 }, { GL_UNPACK_ALIGNMENT, &up.alignment, 8 }, { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, 0 }, { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_1 }, { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_2 }, { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 0 }, { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 1 }, { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 2 }, { GL_PACK_ROW_LENGTH, &pp.rowLength, 0 }, { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_1 }, { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_2 }, { GL_PACK_SKIP_ROWS, &pp.skipRows, 0 }, { GL_PACK_SKIP_ROWS, &pp.skipRows, 1 }, { GL_PACK_SKIP_ROWS, &pp.skipRows, 2 }, { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 0 }, { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 1 }, { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 2 }, { GL_PACK_ALIGNMENT, &pp.alignment, 1 }, { GL_PACK_ALIGNMENT, &pp.alignment, 2 }, { GL_PACK_ALIGNMENT, &pp.alignment, 4 }, { GL_PACK_ALIGNMENT, &pp.alignment, 8 }, }; StoreMode coreCases[] = { { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_FALSE }, { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_TRUE }, { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_FALSE }, { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_TRUE }, { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_FALSE }, { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_TRUE }, { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_FALSE }, { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_TRUE }, { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, 0 }, { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_1 }, { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_2 }, { GL_PACK_SKIP_IMAGES, &pp.skipImages, 0 }, { GL_PACK_SKIP_IMAGES, &pp.skipImages, 1 }, { GL_PACK_SKIP_IMAGES, &pp.skipImages, 2 }, }; std::vector testModes(commonCases, commonCases + DE_LENGTH_OF_ARRAY(commonCases)); glu::RenderContext& renderContext = m_context.getRenderContext(); bool contextTypeIsCoreGL = !glu::isContextTypeES(renderContext.getType()); if (contextTypeIsCoreGL) testModes.insert(testModes.end(), coreCases, coreCases + DE_LENGTH_OF_ARRAY(coreCases)); std::vector::iterator currentCase = testModes.begin(); while (currentCase != testModes.end()) { resetInitialStorageModes(); GLenum parameter = currentCase->parameter; GLint value = currentCase->value; *(currentCase->property) = value; // for some parameters an additional parameter needs to be set if (parameter == GL_PACK_SKIP_ROWS) { if (contextTypeIsCoreGL) m_initialPackProperties.rowCount = GRADIENT_HEIGHT + value; } else if (parameter == GL_PACK_SKIP_PIXELS) m_initialPackProperties.rowLength = GRADIENT_WIDTH + value; else if (parameter == GL_UNPACK_SKIP_ROWS) m_initialUnpackProperties.rowCount = GRADIENT_HEIGHT + value; else if (parameter == GL_UNPACK_SKIP_PIXELS) m_initialUnpackProperties.rowLength = GRADIENT_WIDTH + value; m_textureTarget = GL_TEXTURE_2D; if ((parameter == GL_PACK_IMAGE_HEIGHT) || (parameter == GL_PACK_SKIP_IMAGES) || (parameter == GL_UNPACK_IMAGE_HEIGHT) || (parameter == GL_UNPACK_SKIP_IMAGES)) m_textureTarget = GL_TEXTURE_3D; testAllFormatsAndTypes(); if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS) { m_testCtx.getLog() << tcu::TestLog::Message << "Case for: " << glu::getGettableStateStr(parameter).toString() << " = " << value << " failed." << tcu::TestLog::EndMessage; return STOP; } ++currentCase; } return STOP; } PackedPixelsTests::PackedPixelsTests(deqp::Context& context) : TestCaseGroup(context, "packed_pixels", "") { } PackedPixelsTests::~PackedPixelsTests(void) { #ifdef LOG_PACKED_PIXELS_STATISTICS m_testCtx.getLog() << tcu::TestLog::Message << "PackedPixelsTests statistics:" << "\n countReadPixels: " << RectangleTest::m_countReadPixels << "\n countReadPixelsOK: " << RectangleTest::m_countReadPixelsOK << "\n countGetTexImage: " << RectangleTest::m_countGetTexImage << "\n countGetTexImageOK: " << RectangleTest::m_countGetTexImageOK << "\n countCompare: " << RectangleTest::m_countCompare << "\n countCompareOK: " << RectangleTest::m_countCompareOK << tcu::TestLog::EndMessage; #endif } void PackedPixelsTests::init(void) { const InternalFormat* internalFormats; unsigned int internalFormatsCount; if (glu::isContextTypeES(m_context.getRenderContext().getType())) { internalFormats = esInternalformats; internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats); } else { internalFormats = coreInternalformats; internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats); } TestCaseGroup* rectangleGroup = new deqp::TestCaseGroup(m_context, "rectangle", ""); rectangleGroup->addChild(new InitialValuesTest(m_context)); TestCaseGroup* pboRectangleGroup = new deqp::TestCaseGroup(m_context, "pbo_rectangle", ""); TestCaseGroup* variedRectangleGroup = new deqp::TestCaseGroup(m_context, "varied_rectangle", ""); for (unsigned int internalFormatIndex = 0; internalFormatIndex < internalFormatsCount; internalFormatIndex++) { const InternalFormat& internalFormat = internalFormats[internalFormatIndex]; std::string internalFormatString = getFormatStr(internalFormat.sizedFormat); std::string name = internalFormatString.substr(3); std::transform(name.begin(), name.end(), name.begin(), tolower); rectangleGroup->addChild(new RectangleTest(m_context, name, internalFormat)); pboRectangleGroup->addChild(new PBORectangleTest(m_context, name, internalFormat)); variedRectangleGroup->addChild(new VariedRectangleTest(m_context, name, internalFormat)); } addChild(rectangleGroup); addChild(pboRectangleGroup); addChild(variedRectangleGroup); } } /* glcts namespace */