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