1/*------------------------------------------------------------------------- 2 * OpenGL Conformance Test Suite 3 * ----------------------------- 4 * 5 * Copyright (c) 2017 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 */ /*! 20 * \file glcTextureRepeatModeTests.cpp 21 * \brief 22 */ /*-------------------------------------------------------------------*/ 23 24#include "glcTextureRepeatModeTests.hpp" 25#include "deMath.h" 26#include "gluContextInfo.hpp" 27#include "gluDefs.hpp" 28#include "gluShaderProgram.hpp" 29#include "gluStrUtil.hpp" 30#include "glwEnums.hpp" 31#include "glwFunctions.hpp" 32#include "tcuRenderTarget.hpp" 33#include "tcuTestLog.hpp" 34 35using namespace glw; 36 37namespace glcts 38{ 39 40union InternalFormatBits { 41 struct Bits 42 { 43 int red; /* red bits */ 44 int green; /* green bits */ 45 int blue; /* blue bits */ 46 int alpha; /* alpha bits */ 47 int intensity; /* intensity bits */ 48 int luminance; /* luminance bits */ 49 int depth; /* depth bits */ 50 int stencil; /* stencil bits */ 51 int exponent; /* shared exponent bits */ 52 } bits; 53 int array[9]; /* all the bits */ 54}; 55 56enum InternalFormatSamplerType 57{ 58 SAMPLER_UNORM = 0, /* unsigned normalized */ 59 SAMPLER_NORM, /* normalized */ 60 SAMPLER_UINT, /* unsigned integer */ 61 SAMPLER_INT, /* integer */ 62 SAMPLER_FLOAT /* floating-point */ 63}; 64 65enum InternalFormatFlag 66{ 67 NO_FLAG = 0, 68 FLAG_PACKED = 1, /* Packed pixel format. */ 69 FLAG_COMPRESSED = 2, /* Compressed format. */ 70 FLAG_REQ_RBO_GL42 = 4, /* Required RBO & tex format in OpenGL 4.2. */ 71 FLAG_REQ_RBO_ES30 = 8, /* Required RBO & tex format in OpenGL ES 3.0. */ 72 FLAG_REQ_RBO = FLAG_REQ_RBO_GL42 | FLAG_REQ_RBO_ES30, /* Required RBO & tex format in both. */ 73}; 74 75#define MAX_PIXEL_SIZE 16 76 77/* Note that internal representation is in little endian - tests will fail on big endian, in particular RGB565 will fail */ 78struct FormatInfo 79{ 80 /* internal format, indicating tested format */ 81 GLenum internalformat; 82 83 const char* name; 84 85 /* number of bytes per pixel */ 86 GLsizei pixelSize; 87 88 /* RGBW colors' representation, specific for each internalformat */ 89 GLubyte internalred[MAX_PIXEL_SIZE]; 90 GLubyte internalgreen[MAX_PIXEL_SIZE]; 91 GLubyte internalblue[MAX_PIXEL_SIZE]; 92 GLubyte internalwhite[MAX_PIXEL_SIZE]; 93 94 /* RGBW colors' mapped to RGBA, that are read from framebuffer */ 95 GLubyte RGBAred[4]; 96 GLubyte RGBAgreen[4]; 97 GLubyte RGBAblue[4]; 98 GLubyte RGBAwhite[4]; 99}; 100 101static const FormatInfo testedFormats[] = { 102 { 103 GL_R8, 104 "r8", 105 1, 106 { 0xFF }, 107 { 0xC7 }, 108 { 0x30 }, 109 { 0x00 }, 110 /* expected values */ 111 { 0xFF, 0x00, 0x00, 0xFF }, 112 { 0xC7, 0x00, 0x00, 0xFF }, 113 { 0x30, 0x00, 0x00, 0xFF }, 114 { 0x00, 0x00, 0x00, 0xFF }, 115 }, 116 { 117 GL_RGB565, 118 "rgb565", 119 2, 120 { 0x00, 0xF8 }, 121 { 0xE0, 0x07 }, 122 { 0x1F, 0x00 }, 123 { 0xFF, 0xFF }, 124 /* expected values */ 125 { 0xFF, 0x00, 0x00, 0xFF }, 126 { 0x00, 0xFF, 0x00, 0xFF }, 127 { 0x00, 0x00, 0xFF, 0xFF }, 128 { 0xFF, 0xFF, 0xFF, 0xFF }, 129 }, 130 { 131 GL_RGB8, 132 "rgb8", 133 3, 134 { 0xFF, 0x00, 0x00 }, 135 { 0x00, 0xFF, 0x00 }, 136 { 0x00, 0x00, 0xFF }, 137 { 0xFF, 0xFF, 0xFF }, 138 /* expected values */ 139 { 0xFF, 0x00, 0x00, 0xFF }, 140 { 0x00, 0xFF, 0x00, 0xFF }, 141 { 0x00, 0x00, 0xFF, 0xFF }, 142 { 0xFF, 0xFF, 0xFF, 0xFF }, 143 }, 144 { 145 GL_RGB10_A2, 146 "rgb10_a2", 147 4, 148 { 0xFF, 0x03, 0x00, 0xC0 }, 149 { 0x00, 0xFC, 0x0F, 0xC0 }, 150 { 0x00, 0x00, 0xF0, 0xFF }, 151 { 0xFF, 0xFF, 0xFF, 0xFF }, 152 /* expected values */ 153 { 0xFF, 0x00, 0x00, 0xFF }, 154 { 0x00, 0xFF, 0x00, 0xFF }, 155 { 0x00, 0x00, 0xFF, 0xFF }, 156 { 0xFF, 0xFF, 0xFF, 0xFF }, 157 }, 158 { 159 /* unsigned integer texture formats : require an unsigned texture sampler in the fragment shader */ 160 GL_R32UI, 161 "r32ui", 162 4, 163 { 0xFF, 0x00, 0x00, 0x00 }, 164 { 0x51, 0x00, 0x00, 0x00 }, 165 { 0xF3, 0x00, 0x00, 0x00 }, 166 { 0x00, 0x00, 0x00, 0x00 }, 167 /* expected values */ 168 { 0xFF, 0x00, 0x00, 0xFF }, 169 { 0x51, 0x00, 0x00, 0xFF }, 170 { 0xF3, 0x00, 0x00, 0xFF }, 171 { 0x00, 0x00, 0x00, 0xFF }, 172 }, 173 { 174 GL_RG32UI, 175 "rg32ui", 176 8, 177 { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 }, 178 { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, 179 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 180 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 181 /* expected values */ 182 { 0xFF, 0x00, 0x00, 0xFF }, 183 { 0x00, 0xFF, 0x00, 0xFF }, 184 { 0x00, 0x00, 0x00, 0xFF }, 185 { 0xFF, 0xFF, 0x00, 0xFF }, 186 }, 187 { 188 GL_RGBA32UI, 189 "rgba32ui", 190 16, 191 { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, 192 { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }, 193 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 194 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, 195 /* expected values */ 196 { 0xFF, 0x00, 0x00, 0xFF }, 197 { 0x00, 0xFF, 0x00, 0xFF }, 198 { 0x00, 0x00, 0xFF, 0xFF }, 199 { 0xFF, 0xFF, 0xFF, 0xFF }, 200 }, 201 { 202 /* DEPTH formats are tested by comparing with reference values hard-coded in shaders */ 203 GL_DEPTH_COMPONENT16, 204 "depth_component16", 205 2, 206 { 0xFF, 0xE8 }, /* ~ 0.91 */ 207 { 0xFF, 0xAB }, /* ~ 0.67 */ 208 { 0x00, 0x78 }, /* ~ 0.46 */ 209 { 0x00, 0x3C }, /* ~ 0.23 */ 210 /* expected values */ 211 { 0x00, 0x00, 0x00, 0xff }, 212 { 0x00, 0x00, 0xff, 0xff }, 213 { 0x00, 0xff, 0xff, 0xff }, 214 { 0xff, 0xff, 0xff, 0xff }, 215 }, 216 { 217 /* little-endian order, so the bytes are in reverse order: stencil first, then depth */ 218 GL_DEPTH24_STENCIL8, 219 "depth24_stencil8", 220 4, 221 { 0x00, 0x00, 0xE8, 0xFF }, /* ~ 0.99 */ 222 { 0x88, 0x00, 0xAB, 0xAF }, /* ~ 0.68 */ 223 { 0xBB, 0x28, 0x55, 0x7F }, /* ~ 0.49 */ 224 { 0xFF, 0x78, 0x80, 0x02 }, /* ~ 0.01 */ 225 /* expected values */ 226 { 0x00, 0x00, 0x00, 0xff }, 227 { 0x00, 0x00, 0xff, 0xff }, 228 { 0x00, 0xff, 0xff, 0xff }, 229 { 0xff, 0xff, 0xff, 0xff }, 230 } 231}; 232 233struct InternalFormat 234{ 235 GLenum sizedFormat; 236 GLenum baseFormat; 237 GLenum format; 238 GLenum type; 239 InternalFormatSamplerType sampler; 240 InternalFormatBits bits; 241 GLuint flags; // InternalFormatFlag 242}; 243 244static const InternalFormat glInternalFormats[] = 245{ 246 { 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 }, 247 { 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 }, 248 249 { GL_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 250 { GL_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 251 252 // Table 3.12 253 { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 254 { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 255 { 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 }, 256 { GL_R16_SNORM, GL_RED, GL_RED, GL_SHORT, SAMPLER_NORM, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 257 { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 258 { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 259 { 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 }, 260 { GL_RG16_SNORM, GL_RG, GL_RG, GL_SHORT, SAMPLER_NORM, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 261 { 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 }, 262 { GL_RGB4, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 4, 4, 4, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 263 { GL_RGB5, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 5, 5, 5, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 264 { 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 }, 265 { 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 }, 266 { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 267 { GL_RGB10, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {10,10,10, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 268 { GL_RGB12, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {12,12,12, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 269 { GL_RGB16, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 270 { GL_RGB16_SNORM, GL_RGB, GL_RGB, GL_SHORT, SAMPLER_NORM, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 271 { GL_RGBA2, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 2, 2, 2, 2, 0, 0, 0, 0, NO_FLAG } }, 0 }, 272 273 { 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 }, 274 { 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 }, 275 276 { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 277 { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, 278 279 { 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 }, 280 { 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 }, 281 282 { GL_RGBA12, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, SAMPLER_UNORM, { {12,12,12,12, 0, 0, 0, 0, NO_FLAG } }, 0 }, 283 { 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 }, 284 { GL_RGBA16_SNORM, GL_RGBA, GL_RGBA, GL_SHORT, SAMPLER_NORM, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, 0 }, 285 286 { GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 287 { 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 }, 288 289 { 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 }, 290 { 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 }, 291 { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 292 { 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 }, 293 { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 294 { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 295 { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 296 { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 297 { 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 }, 298 299 { 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 }, 300 301 { GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 302 { 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 }, 303 { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 304 { 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 }, 305 { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 306 { 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 }, 307 { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 308 { 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 }, 309 { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 310 { 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 }, 311 { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 312 { 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 }, 313 { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 314 { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 315 { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 316 { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 317 { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 318 { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 319 { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 320 { 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 }, 321 { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 322 { 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 }, 323 { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 324 { 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 }, 325 326 // Table 3.13 327 { 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 }, 328 { 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 }, 329 { 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 }, 330 { 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 }, 331 { 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 }, 332 { 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 }, 333 334 // Table 3.14 335 { GL_COMPRESSED_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, 336 { GL_COMPRESSED_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, 337 { GL_COMPRESSED_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, 338 { GL_COMPRESSED_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, 339 { GL_COMPRESSED_SRGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_COMPRESSED }, 340 { 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 }, 341 { 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 }, 342 { 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 }, 343 { 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 }, 344 { 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 }, 345}; 346 347static const InternalFormat esInternalFormats[] = 348{ 349 // Table 3.3 350 { GL_LUMINANCE, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 0, 0, 8, 0, 0, NO_FLAG } }, 0 }, 351 { GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 0, 0, 0, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, 352 { 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 }, 353 354 { GL_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 355 { GL_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, 356 357 // Table 3.12 358 { GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 359 { GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 360 { GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 361 { GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 362 { 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 }, 363 { GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 364 { 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 }, 365 366 { 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 }, 367 { 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 }, 368 369 { GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 370 { GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, 0 }, 371 372 { 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 }, 373 { 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 }, 374 375 { GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 376 { 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 }, 377 378 { 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 }, 379 { 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 }, 380 { GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 381 { 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 }, 382 { GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 383 { GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 384 { GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 385 { GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO_GL42 }, 386 { 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 }, 387 388 { 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 }, 389 390 { GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 391 { 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 }, 392 { GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, { {16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 393 { 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 }, 394 { GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, { {32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 395 { 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 }, 396 { GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 397 { 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 }, 398 { GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 399 { 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 }, 400 { GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, { {32,32, 0, 0, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 401 { 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 }, 402 { GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 403 { GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, { { 8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 404 { GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 405 { GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, { {16,16,16, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 406 { GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 407 { GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, { {32,32,32, 0, 0, 0, 0, 0, NO_FLAG } }, 0 }, 408 { GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, { { 8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 409 { 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 }, 410 { GL_RGBA16I, GL_RGBA, GL_RGBA_INTEGER, GL_SHORT, SAMPLER_INT, { {16,16,16,16, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 411 { 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 }, 412 { GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, { {32,32,32,32, 0, 0, 0, 0, NO_FLAG } }, FLAG_REQ_RBO }, 413 { 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 }, 414 415 // Table 3.13 416 { 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 }, 417 { 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 }, 418 { 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 }, 419 { 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 }, 420 { 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 }, 421}; 422 423const char* basic_vs = "precision mediump float;\n" 424 "out vec2 texCoord;\n" 425 "void main(void)\n" 426 "{\n" 427 " switch(gl_VertexID)\n" 428 " {\n" 429 " case 0:\n" 430 " gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n" 431 " texCoord = vec2(2.0, -1.0);\n" 432 " break;\n" 433 " case 1:\n" 434 " gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n" 435 " texCoord = vec2(2.0, 2.0);\n" 436 " break;\n" 437 " case 2:\n" 438 " gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n" 439 " texCoord = vec2(-1.0, -1.0);\n" 440 " break;\n" 441 " case 3:\n" 442 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" 443 " texCoord = vec2(-1.0, 2.0);\n" 444 " break;\n" 445 " }\n" 446 "}"; 447 448const char* basic_fs = "precision mediump float;\n" 449 "uniform sampler2D texture0;\n" 450 "in vec2 texCoord;\n" 451 "out vec4 color;\n" 452 "void main(void)\n" 453 "{\n" 454 " color = texture(texture0, texCoord);\n" 455 "}"; 456 457const char* shadow_fs = "precision mediump float;\n" 458 "uniform mediump sampler2DShadow texture0;\n" 459 "in vec2 texCoord;\n" 460 "out vec4 color;\n" 461 "void main(void)\n" 462 "{\n" 463 " float r = texture(texture0, vec3(texCoord.xy, 0.3));\n" 464 " float g = texture(texture0, vec3(texCoord.xy, 0.5));\n" 465 " float b = texture(texture0, vec3(texCoord.xy, 0.8));\n" 466 " color = vec4(r, g, b, 1.0);\n" 467 "}\n"; 468 469const char* integer_fs = "precision mediump float;\n" 470 "uniform mediump usampler2D texture0;\n" 471 "in vec2 texCoord;\n" 472 "out vec4 color;\n" 473 "void main(void)\n" 474 "{\n" 475 " highp uvec4 ci = texture(texture0, texCoord);\n" 476 " color = vec4(ci) / 255.0; // we are using an integer texture format - so convert to float\n" 477 " if (ci.a > 0u)\n" 478 " color.a = 1.0;\n" 479 " else\n" 480 " color.a = 0.0;\n" 481 "}"; 482 483struct TestArea 484{ 485 GLsizei left; 486 GLsizei right; 487 GLsizei top; 488 GLsizei bottom; 489}; 490 491class TestClampModeForInternalFormat : public deqp::TestCase 492{ 493public: 494 /* Public methods */ 495 TestClampModeForInternalFormat(deqp::Context& context, const std::string& name, GLenum internalFormat, 496 GLenum clampMode, GLint lodLevel, GLsizei width, GLsizei height); 497 virtual ~TestClampModeForInternalFormat() 498 { 499 } 500 501 /* Public methods inherited from TestCase */ 502 virtual tcu::TestNode::IterateResult iterate(void); 503 504private: 505 /* Private methods */ 506 const FormatInfo* findFormat(GLenum internalformat) const; 507 const InternalFormat& findInternalFormat(GLenum internalformat) const; 508 void clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod, GLenum internalformat, GLenum type, 509 GLenum format) const; 510 void fillTextureWithColor(GLubyte* texture_data, GLsizei tex_width, GLsizei tex_height, 511 GLenum internalformat) const; 512 void calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const; 513 GLsizei proportion(GLsizei a, GLsizei b, GLsizei c) const; 514 bool isEqual(const GLubyte* color1, const GLubyte* color2, GLubyte tolerance) const; 515 516 bool verifyClampMode(GLubyte* buf, GLsizei width, GLsizei height, GLenum clampMode, GLenum internalformat) const; 517 bool verifyClampToEdge(GLubyte* buf, GLsizei width_init, GLsizei height_init, GLsizei width, GLsizei height, 518 GLenum internalformat) const; 519 bool verifyRepeat(GLubyte* buf, GLsizei width, GLsizei height, GLenum internalformat) const; 520 bool verifyMirroredRepeat(GLubyte* buf, GLsizei width, GLsizei height, GLenum internalformat) const; 521 522private: 523 /* Private attributes */ 524 GLenum m_internalFormat; 525 GLenum m_clampMode; 526 GLint m_lodLevel; 527 GLsizei m_width; 528 GLsizei m_height; 529}; 530 531/** Constructor. 532 * 533 * @param context Rendering context. 534 **/ 535TestClampModeForInternalFormat::TestClampModeForInternalFormat(deqp::Context& context, const std::string& name, 536 GLenum internalFormat, GLenum clampMode, GLint lodLevel, 537 GLsizei width, GLsizei height) 538 : deqp::TestCase(context, name.c_str(), "") 539 , m_internalFormat(internalFormat) 540 , m_clampMode(clampMode) 541 , m_lodLevel(lodLevel) 542 , m_width(width) 543 , m_height(height) 544{ 545 /* Left blank intentionally */ 546} 547 548const InternalFormat& TestClampModeForInternalFormat::findInternalFormat(GLenum internalformat) const 549{ 550 const InternalFormat* internalFormats = glInternalFormats; 551 GLsizei internalFormatsCount = DE_LENGTH_OF_ARRAY(glInternalFormats); 552 553 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 554 { 555 internalFormats = esInternalFormats; 556 internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalFormats); 557 } 558 559 for (GLsizei i = 0; i < internalFormatsCount; i++) 560 { 561 if (internalFormats[i].sizedFormat == internalformat) 562 return internalFormats[i]; 563 } 564 565 TCU_FAIL("Internal format not found"); 566} 567 568const FormatInfo* TestClampModeForInternalFormat::findFormat(GLenum internalformat) const 569{ 570 for (GLsizei i = 0; i < DE_LENGTH_OF_ARRAY(testedFormats); i++) 571 if (testedFormats[i].internalformat == internalformat) 572 return &testedFormats[i]; 573 return NULL; 574} 575 576bool TestClampModeForInternalFormat::isEqual(const GLubyte* color1, const GLubyte* color2, GLubyte tolerance) const 577{ 578 for (int i = 0; i < 4; i++) 579 { 580 if (de::abs((int)color1[i] - (int)color2[i]) > tolerance) 581 return false; 582 } 583 return true; 584} 585 586/** Fill texture with RGBW colors, according to the scheme: 587 * R R R G G G 588 * R R R G G G 589 * R R R G G G 590 * B B B W W W 591 * B B B W W W 592 * B B B W W W 593 * 594 * NOTE: width of the red and blue rectangles would be less than green and white ones for odd texture's widths 595 * height of the red and green rectangles would be less than blue and white ones for odd texture's heights 596 */ 597void TestClampModeForInternalFormat::fillTextureWithColor(GLubyte* texture_data, GLsizei tex_width, GLsizei tex_height, 598 GLenum internalformat) const 599{ 600 const FormatInfo* testedFormat = findFormat(internalformat); 601 const GLubyte* red = testedFormat->internalred; 602 const GLubyte* green = testedFormat->internalgreen; 603 const GLubyte* blue = testedFormat->internalblue; 604 const GLubyte* white = testedFormat->internalwhite; 605 const GLsizei size = testedFormat->pixelSize; 606 607 GLint i = 0; 608 GLint j = 0; 609 for (j = 0; j < tex_height / 2; j++) 610 { 611 for (i = 0; i < tex_width / 2; i++) 612 { 613 deMemcpy(texture_data, red, size); 614 texture_data += size; 615 } 616 for (; i < tex_width; i++) 617 { 618 deMemcpy(texture_data, green, size); 619 texture_data += size; 620 } 621 } 622 for (; j < tex_height; j++) 623 { 624 for (i = 0; i < tex_width / 2; i++) 625 { 626 deMemcpy(texture_data, blue, size); 627 texture_data += size; 628 } 629 for (; i < tex_width; i++) 630 { 631 deMemcpy(texture_data, white, size); 632 texture_data += size; 633 } 634 } 635} 636 637void TestClampModeForInternalFormat::clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod, 638 GLenum internalformat, GLenum type, GLenum format) const 639{ 640 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 641 642 GLint level; 643 for (level = lod; level > 0; level--) 644 { 645 width *= 2; 646 height *= 2; 647 } 648 649 bool continueLoop = true; 650 std::vector<GLubyte> tex_buf(width * height * MAX_PIXEL_SIZE, 0); 651 do 652 { 653 if (level != lod) 654 gl.texImage2D(target, level, internalformat, width, height, 0, format, type, &tex_buf[0]); 655 level++; 656 657 continueLoop = !((height == 1) && (width == 1)); 658 if (width > 1) 659 width /= 2; 660 if (height > 1) 661 height /= 2; 662 } while (continueLoop); 663} 664 665/* Calculate error epsilons to the least accurate of either 666** frame buffer or texture precision. RGBA epsilons are 667** returned in textureEpsilon[]. target must be a valid 668** texture target. 669*/ 670void TestClampModeForInternalFormat::calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const 671{ 672 GLint i, bits; 673 GLint bufferBits[4]; 674 675 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 676 gl.getIntegerv(GL_RED_BITS, &bufferBits[0]); 677 gl.getIntegerv(GL_GREEN_BITS, &bufferBits[1]); 678 gl.getIntegerv(GL_BLUE_BITS, &bufferBits[2]); 679 gl.getIntegerv(GL_ALPHA_BITS, &bufferBits[3]); 680 681 for (i = 0; i < 4; i++) 682 { 683 684 if (textureBits[i] == 0) 685 { 686 /* 'exact' */ 687 bits = 1000; 688 } 689 else 690 { 691 bits = textureBits[i]; 692 } 693 694 /* Some tests fail on RGB10_A2 pixelformat, because framebuffer precision calculated here is 10-bit, but these tests use 8-bit data types 695 for pixel transfers and 8-bit textures. Because of that, the required precision is limited to 8-bit only. */ 696 if (bits > 8) 697 { 698 bits = 8; 699 } 700 701 /* frame buffer bits */ 702 if (bits > bufferBits[i]) 703 { 704 bits = bufferBits[i]; 705 } 706 707 if (bits == 0) 708 { 709 /* infinity */ 710 textureEpsilon[i] = 2.0f; 711 } 712 else 713 { 714 const float zeroEpsilon = deFloatLdExp(1.0f, -13); 715 textureEpsilon[i] = (1.0f / (deFloatLdExp(1.0f, bits) - 1.0f)) + zeroEpsilon; 716 textureEpsilon[i] = (float)deMin(1.0f, textureEpsilon[i]); 717 } 718 719 /* If we have 8 bits framebuffer, we should hit the right value within one intensity level. */ 720 if (bits == 8 && bufferBits[i] != 0) 721 { 722 textureEpsilon[i] /= 2.0; 723 } 724 } 725} 726 727/* calculate (a * b) / c with rounding */ 728GLsizei TestClampModeForInternalFormat::proportion(GLsizei a, GLsizei b, GLsizei c) const 729{ 730 float result = (float)a * b; 731 return (GLsizei)(0.5f + result / c); 732} 733 734/* check out the read-back values for GL_CLAMP_TO_EDGE mode 735 * r r r g g g 736 * r r r g g g 737 * r r R G g g 738 * b b B W w w 739 * b b b w w w 740 * b b b w w w 741 742 width_init, height_init arguments refer to the basic pattern texture, which describes proportions 743 between colors in the rendered rectangle (tex_width, tex_height) 744 */ 745bool TestClampModeForInternalFormat::verifyClampToEdge(GLubyte* buf, GLsizei width_init, GLsizei height_init, 746 GLsizei width, GLsizei height, GLenum internalformat) const 747{ 748 GLint i, h; 749 const FormatInfo* testedFormat = findFormat(internalformat); 750 const GLubyte* red = testedFormat->RGBAred; 751 const GLubyte* green = testedFormat->RGBAgreen; 752 const GLubyte* blue = testedFormat->RGBAblue; 753 const GLubyte* white = testedFormat->RGBAwhite; 754 const GLsizei size = 4; 755 const GLsizei skip = 6; 756 757 GLsizei red_w = proportion(width, width_init / 2, width_init); 758 GLsizei red_h = proportion(height, height_init / 2, height_init); 759 GLsizei bits[4] = { 8, 8, 8, 8 }; 760 GLfloat epsilonf[4]; 761 GLubyte epsilons[4]; 762 763 TestArea check_area = { 0, width, 0, height }; 764 765 calcTextureEpsilon(bits, epsilonf); 766 for (i = 0; i < 4; ++i) 767 { 768 epsilons[i] = (GLubyte)(epsilonf[i] * 255.0f); 769 } 770 771 for (h = 0; h < red_h - skip / 2; h++) 772 { 773 for (i = 0; i < red_w - skip / 2; i++) 774 { 775 /* skip over corner pixel to avoid issues with mipmap selection */ 776 if (i >= check_area.left || h >= check_area.top) 777 if (!isEqual(buf, red, epsilons[0])) 778 TCU_FAIL("verifyClampToEdge failed"); 779 buf += size; 780 } 781 782 /* skip over border pixels to avoid issues with rounding */ 783 i += skip; 784 buf += skip * size; 785 786 for (; i < width; i++) 787 { 788 /* skip over corner pixel to avoid issues with mipmap selection */ 789 if (i < check_area.right || h >= check_area.top) 790 if (!isEqual(buf, green, epsilons[1])) 791 TCU_FAIL("verifyClampToEdge failed"); 792 buf += size; 793 } 794 } 795 796 /* skip over border pixels to avoid issues with rounding */ 797 h += skip; 798 buf += skip * width * size; 799 800 for (; h < height; h++) 801 { 802 for (i = 0; i < red_w - skip / 2; i++) 803 { 804 /* skip over corner pixel to avoid issues with mipmap selection */ 805 if (i >= check_area.left || h < check_area.bottom) 806 if (!isEqual(buf, blue, epsilons[2])) 807 TCU_FAIL("verifyClampToEdge failed"); 808 buf += size; 809 } 810 811 /* skip over border pixels to avoid issues with rounding */ 812 i += skip; 813 buf += skip * size; 814 815 for (; i < width; i++) 816 { 817 /* skip over corner pixel to avoid issues with mipmap selection */ 818 if (i < check_area.right || h < check_area.bottom) 819 if (!isEqual(buf, white, epsilons[0])) 820 TCU_FAIL("verifyClampToEdge failed"); 821 buf += size; 822 } 823 } 824 825 m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyClampToEdge succeeded." 826 << tcu::TestLog::EndMessage; 827 return true; 828} 829 830/* check out the read-back values for GL_REPEAT mode 831 * r g r g r g 832 * b w b w b w 833 * r g R G r g 834 * b w B W b w 835 * r g r g r g 836 * b w b w b w 837 */ 838bool TestClampModeForInternalFormat::verifyRepeat(GLubyte* buf, GLsizei width, GLsizei height, 839 GLenum internalformat) const 840{ 841 GLint i, j, g, h; 842 const FormatInfo* testedFormat = findFormat(internalformat); 843 844 const GLubyte* red = testedFormat->RGBAred; 845 const GLubyte* green = testedFormat->RGBAgreen; 846 const GLubyte* blue = testedFormat->RGBAblue; 847 const GLubyte* white = testedFormat->RGBAwhite; 848 const GLsizei size = 4; 849 const GLubyte tolerance = 0; 850 851 GLsizei tex_w = width / 3; 852 GLsizei tex_h = height / 3; 853 854 GLsizei red_w = tex_w / 2; 855 GLsizei red_h = tex_h / 2; 856 857 GLsizei green_w = tex_w - red_w; 858 859 GLsizei blue_w = red_w; 860 GLsizei blue_h = tex_h - red_h; 861 862 GLsizei white_w = green_w; 863 864 for (g = 0; g < 3; g++) 865 { 866 for (h = 0; h < red_h; h++) 867 { 868 for (j = 0; j < 3; j++) 869 { 870 for (i = 0; i < red_w; i++) 871 { 872 if (!isEqual(buf, red, tolerance)) 873 TCU_FAIL("verifyRepeat failed"); 874 875 buf += size; 876 } 877 for (i = 0; i < green_w; i++) 878 { 879 if (!isEqual(buf, green, tolerance)) 880 TCU_FAIL("verifyRepeat failed"); 881 882 buf += size; 883 } 884 } 885 } 886 for (h = 0; h < blue_h; h++) 887 { 888 for (j = 0; j < 3; j++) 889 { 890 for (i = 0; i < blue_w; i++) 891 { 892 if (!isEqual(buf, blue, tolerance)) 893 TCU_FAIL("verifyRepeat failed"); 894 895 buf += size; 896 } 897 for (i = 0; i < white_w; i++) 898 { 899 if (!isEqual(buf, white, tolerance)) 900 TCU_FAIL("verifyRepeat failed"); 901 902 buf += size; 903 } 904 } 905 } 906 } 907 908 m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyRepeat succeeded." 909 << tcu::TestLog::EndMessage; 910 return true; 911} 912 913/* check out the read-back values for GL_MIRRORED_REPEAT mode 914 * w b b w w b 915 * g r r g g r 916 * r g R G r g 917 * w b B W w b 918 * w b b w w b 919 * g r r g g r 920 */ 921bool TestClampModeForInternalFormat::verifyMirroredRepeat(GLubyte* buf, GLsizei width, GLsizei height, 922 GLenum internalformat) const 923{ 924 GLint i, j, g, h; 925 const FormatInfo* testedFormat = findFormat(internalformat); 926 927 const GLubyte* red = testedFormat->RGBAred; 928 const GLubyte* green = testedFormat->RGBAgreen; 929 const GLubyte* blue = testedFormat->RGBAblue; 930 const GLubyte* white = testedFormat->RGBAwhite; 931 932 const GLsizei size = 4; 933 const GLubyte tolerance = 0; 934 935 GLsizei tex_w = width / 3; 936 GLsizei tex_h = height / 3; 937 938 GLsizei red_w = tex_w / 2; 939 GLsizei red_h = tex_h / 2; 940 941 GLsizei green_w = tex_w - red_w; 942 GLsizei green_h = red_h; 943 944 GLsizei blue_w = red_w; 945 GLsizei blue_h = tex_h - red_h; 946 947 GLsizei white_w = green_w; 948 GLsizei white_h = blue_h; 949 950 for (g = 0; g < 3; g++) 951 { 952 if (g % 2 == 0) 953 { 954 for (h = 0; h < white_h; h++) 955 { 956 for (j = 0; j < 3; j++) 957 { 958 if (j % 2 == 0) 959 { 960 for (i = 0; i < white_w; i++) 961 { 962 if (!isEqual(buf, white, tolerance)) 963 TCU_FAIL("verifyMirroredRepeat failed"); 964 965 buf += size; 966 } 967 for (i = 0; i < blue_w; i++) 968 { 969 if (!isEqual(buf, blue, tolerance)) 970 TCU_FAIL("verifyMirroredRepeat failed"); 971 972 buf += size; 973 } 974 } 975 else 976 { 977 for (i = 0; i < blue_w; i++) 978 { 979 if (!isEqual(buf, blue, tolerance)) 980 TCU_FAIL("verifyMirroredRepeat failed"); 981 982 buf += size; 983 } 984 for (i = 0; i < white_w; i++) 985 { 986 if (!isEqual(buf, white, tolerance)) 987 TCU_FAIL("verifyMirroredRepeat failed"); 988 989 buf += size; 990 } 991 } 992 } 993 } 994 for (h = 0; h < green_h; h++) 995 { 996 for (j = 0; j < 3; j++) 997 { 998 if (j % 2 == 0) 999 { 1000 for (i = 0; i < green_w; i++) 1001 { 1002 if (!isEqual(buf, green, tolerance)) 1003 TCU_FAIL("verifyMirroredRepeat failed"); 1004 1005 buf += size; 1006 } 1007 for (i = 0; i < red_w; i++) 1008 { 1009 if (!isEqual(buf, red, tolerance)) 1010 TCU_FAIL("verifyMirroredRepeat failed"); 1011 1012 buf += size; 1013 } 1014 } 1015 else 1016 { 1017 for (i = 0; i < red_w; i++) 1018 { 1019 if (!isEqual(buf, red, tolerance)) 1020 TCU_FAIL("verifyMirroredRepeat failed"); 1021 1022 buf += size; 1023 } 1024 for (i = 0; i < green_w; i++) 1025 { 1026 if (!isEqual(buf, green, tolerance)) 1027 TCU_FAIL("verifyMirroredRepeat failed"); 1028 1029 buf += size; 1030 } 1031 } 1032 } 1033 } 1034 } 1035 else 1036 { 1037 for (h = 0; h < green_h; h++) 1038 { 1039 for (j = 0; j < 3; j++) 1040 { 1041 if (j % 2 == 0) 1042 { 1043 for (i = 0; i < green_w; i++) 1044 { 1045 if (!isEqual(buf, green, tolerance)) 1046 TCU_FAIL("verifyMirroredRepeat failed"); 1047 1048 buf += size; 1049 } 1050 for (i = 0; i < red_w; i++) 1051 { 1052 if (!isEqual(buf, red, tolerance)) 1053 TCU_FAIL("verifyMirroredRepeat failed"); 1054 1055 buf += size; 1056 } 1057 } 1058 else 1059 { 1060 for (i = 0; i < red_w; i++) 1061 { 1062 if (!isEqual(buf, red, tolerance)) 1063 TCU_FAIL("verifyMirroredRepeat failed"); 1064 1065 buf += size; 1066 } 1067 for (i = 0; i < green_w; i++) 1068 { 1069 if (!isEqual(buf, green, tolerance)) 1070 TCU_FAIL("verifyMirroredRepeat failed"); 1071 1072 buf += size; 1073 } 1074 } 1075 } 1076 } 1077 for (h = 0; h < white_h; h++) 1078 { 1079 for (j = 0; j < 3; j++) 1080 { 1081 if (j % 2 == 0) 1082 { 1083 for (i = 0; i < white_w; i++) 1084 { 1085 if (!isEqual(buf, white, tolerance)) 1086 TCU_FAIL("verifyMirroredRepeat failed"); 1087 1088 buf += size; 1089 } 1090 for (i = 0; i < blue_w; i++) 1091 { 1092 if (!isEqual(buf, blue, tolerance)) 1093 TCU_FAIL("verifyMirroredRepeat failed"); 1094 1095 buf += size; 1096 } 1097 } 1098 else 1099 { 1100 for (i = 0; i < blue_w; i++) 1101 { 1102 if (!isEqual(buf, blue, tolerance)) 1103 TCU_FAIL("verifyMirroredRepeat failed"); 1104 1105 buf += size; 1106 } 1107 for (i = 0; i < white_w; i++) 1108 { 1109 if (!isEqual(buf, white, tolerance)) 1110 TCU_FAIL("verifyMirroredRepeat failed"); 1111 1112 buf += size; 1113 } 1114 } 1115 } 1116 } 1117 } 1118 } 1119 1120 m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyMirroredRepeat succeeded." 1121 << tcu::TestLog::EndMessage; 1122 return true; 1123} 1124 1125bool TestClampModeForInternalFormat::verifyClampMode(GLubyte* buf, GLsizei width, GLsizei height, GLenum clampMode, 1126 GLenum internalformat) const 1127{ 1128 switch (clampMode) 1129 { 1130 case GL_CLAMP_TO_EDGE: 1131 return verifyClampToEdge(buf, width, height, width, height, internalformat); 1132 case GL_REPEAT: 1133 return verifyRepeat(buf, width, height, internalformat); 1134 case GL_MIRRORED_REPEAT: 1135 return verifyMirroredRepeat(buf, width, height, internalformat); 1136 } 1137 return false; 1138} 1139 1140/** Execute test 1141 * 1142 * Upload the texture, set up a quad 3 times the size of the 1143 * texture. Coordinates should be integers to avoid spatial rounding 1144 * differences. Set texture coordinates as shown below. 1145 * 1146 * (-1, 2, 0) --- (2, 2, 0) 1147 * | | 1148 * | | 1149 * (-1, -1, 0) --- (2, -1, 0) 1150 * 1151 * Set TEXTURE_MIN_FILTER for the texture to NEAREST_MIPMAP_NEAREST. 1152 * 1153 * Repeat the test for each repeat mode, i.e., set the repeat mode to 1154 * one of CLAMP_TO_EDGE, REPEAT, and MIRRORED_REPEAT for both S and 1155 * T, depending on the iteration. 1156 * 1157 * For vertex shader, just pass on the vertices and texture 1158 * coordinates for interpolation. For fragment shader, look up the 1159 * fragment corresponding to given texture coordinates. 1160 * 1161 * Render the quad. 1162 * 1163 * Read back the pixels covering the quad. 1164 * 1165 * For CLAMP_TO_EDGE result should be (Each character has dimension 1166 * half the original texture, original texture in capitals): 1167 * 1168 * rrrggg 1169 * rrrggg 1170 * rrRGgg 1171 * bbBWww 1172 * bbbwww 1173 * bbbwww 1174 * 1175 * For REPEAT: 1176 * 1177 * rgrgrg 1178 * bwbwbw 1179 * rgRGrg 1180 * bwBWbw 1181 * rgrgrg 1182 * bwbwbw 1183 * 1184 * For MIRRORED_REPEAT 1185 * 1186 * wbbwwb 1187 * grrggr 1188 * grRGgr 1189 * wbBWwb 1190 * wbbwwb 1191 * grrggr 1192 * 1193 * If implementation under test is for OpenGL 3.2 Core specification, 1194 * the test includes repeat mode of CLAMP_TO_BORDER. For this case, 1195 * the TEXTURE_BORDER_COLOR is set to black (0, 0, 0, 1) (RGBA). Then 1196 * the result will be (0 meaning black): 1197 * 1198 * 000000 1199 * 000000 1200 * 00RG00 1201 * 00BW00 1202 * 000000 1203 * 000000 1204 * 1205 * Procedure: 1206 * - allocate large enough memory buffer for the texture data - tex_width * tex_height * tex_depth * MAX_PIXEL_SIZE 1207 * - fill the buffer with the pattern 1208 * - upload the texture with glTexImage2D() to the requested level 1209 * - upload black texture to other LOD levels 1210 * - render a quad with size matching the texture LOD level 1211 * - read back pixels 1212 * - verify the results 1213 * - free the buffer 1214**/ 1215tcu::TestNode::IterateResult TestClampModeForInternalFormat::iterate(void) 1216{ 1217 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1218 m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 1219 1220 /* Retrieve properties of the tested format */ 1221 const InternalFormat& internalFormatStruct = findInternalFormat(m_internalFormat); 1222 GLenum format = internalFormatStruct.format; 1223 GLenum type = internalFormatStruct.type; 1224 GLenum internalformat = internalFormatStruct.sizedFormat; 1225 GLenum sampler = internalFormatStruct.sampler; 1226 GLsizei viewWidth = 3 * m_width; 1227 GLsizei viewHeight = 3 * m_height; 1228 1229 /* Allocate buffers for texture data */ 1230 GLsizei resultTextureSize = viewWidth * viewHeight; 1231 std::vector<GLubyte> textureData(resultTextureSize * MAX_PIXEL_SIZE, 0); 1232 std::fill(textureData.begin(), textureData.end(), 0); 1233 1234 /* Set pixel storage modes */ 1235 gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1); 1236 gl.pixelStorei(GL_PACK_ALIGNMENT, 1); 1237 1238 /* Generate and bind the texture object that will store test result*/ 1239 GLuint resultTextureId; 1240 gl.genTextures(1, &resultTextureId); 1241 gl.bindTexture(GL_TEXTURE_2D, resultTextureId); 1242 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1243 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1244 gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewWidth, viewHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]); 1245 1246 /* Reuse textureData buffer to initialize source texture. 1247 * Fill the buffer according to the color scheme */ 1248 fillTextureWithColor(&textureData[0], m_width, m_height, internalformat); 1249 1250 /* Generate and bind the texture object that will store color scheme*/ 1251 GLuint sourceTextureId; 1252 gl.genTextures(1, &sourceTextureId); 1253 gl.bindTexture(GL_TEXTURE_2D, sourceTextureId); 1254 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); 1255 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1256 gl.texImage2D(GL_TEXTURE_2D, m_lodLevel, internalformat, m_width, m_height, 0, format, type, &textureData[0]); 1257 1258 /* Set compare function used by shadow samplers */ 1259 if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format)) 1260 { 1261 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); 1262 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GEQUAL); 1263 } 1264 1265 /* Clear the other source texture levels with black */ 1266 clearTextures(GL_TEXTURE_2D, m_width, m_height, m_lodLevel, internalformat, type, format); 1267 1268 /* Create and bind the FBO */ 1269 GLuint fbId; 1270 gl.genFramebuffers(1, &fbId); 1271 gl.bindFramebuffer(GL_FRAMEBUFFER, fbId); 1272 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resultTextureId, 0); 1273 1274 /* Construct shaders */ 1275 glu::ContextType contextType = m_context.getRenderContext().getType(); 1276 glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType); 1277 std::string version = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n"); 1278 std::string vs = version + basic_vs; 1279 std::string fs = version; 1280 if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format)) 1281 fs += shadow_fs; 1282 else if ((SAMPLER_UINT == sampler) || (SAMPLER_INT == sampler)) 1283 fs += integer_fs; 1284 else 1285 fs += basic_fs; 1286 glu::ProgramSources sources = glu::makeVtxFragSources(vs, fs); 1287 1288 /* Create program object */ 1289 glu::ShaderProgram program(m_context.getRenderContext(), sources); 1290 if (!program.isOk()) 1291 TCU_FAIL("Compile failed"); 1292 GLint programId = program.getProgram(); 1293 GLint samplerLocation = gl.getUniformLocation(programId, "texture0"); 1294 if (-1 == samplerLocation) 1295 TCU_FAIL("Fragment shader does not have texture0 input."); 1296 gl.useProgram(programId); 1297 gl.uniform1i(samplerLocation, 0); 1298 1299 m_context.getTestContext().getLog() << tcu::TestLog::Message << "NPOT [" << m_internalFormat << "] (" << viewWidth 1300 << " x " << viewHeight << "), Level: " << m_lodLevel 1301 << tcu::TestLog::EndMessage; 1302 1303 /* Set the wrap parameters for texture coordinates s and t to the current clamp mode */ 1304 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_clampMode); 1305 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_clampMode); 1306 1307 /* Set viewport's width and height based on an overview */ 1308 gl.viewport(0, 0, viewWidth, viewHeight); 1309 1310 /* Draw rectangle */ 1311 GLuint vaoId; 1312 gl.genVertexArrays(1, &vaoId); 1313 gl.bindVertexArray(vaoId); 1314 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4); 1315 gl.bindVertexArray(0); 1316 gl.deleteVertexArrays(1, &vaoId); 1317 1318 /* Read back pixels and verify that they have the proper values */ 1319 std::vector<GLubyte> buffer(resultTextureSize * 4, 0); 1320 gl.readPixels(0, 0, viewWidth, viewHeight, GL_RGBA, GL_UNSIGNED_BYTE, (void*)&(buffer[0])); 1321 if (verifyClampMode(&buffer[0], viewWidth, viewHeight, m_clampMode, internalformat)) 1322 m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass"); 1323 1324 /* Cleanup */ 1325 gl.bindTexture(GL_TEXTURE_2D, 0); 1326 gl.deleteTextures(1, &resultTextureId); 1327 gl.deleteTextures(1, &sourceTextureId); 1328 gl.bindFramebuffer(GL_FRAMEBUFFER, fbId); 1329 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 1330 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 1331 gl.deleteFramebuffers(1, &fbId); 1332 1333 return STOP; 1334} 1335 1336/** Constructor. 1337 * 1338 * @param context Rendering context. 1339 */ 1340TextureRepeatModeTests::TextureRepeatModeTests(deqp::Context& context) 1341 : TestCaseGroup(context, "texture_repeat_mode", "Texture repeat mode tests") 1342{ 1343} 1344 1345/** Initializes the test group contents. */ 1346void TextureRepeatModeTests::init() 1347{ 1348 /* Texture sizes to test */ 1349 const struct TexSize 1350 { 1351 GLsizei width; 1352 GLsizei height; 1353 } textureSizes[] = { 1354 { 49, 23 }, { 11, 131 }, 1355 }; 1356 1357 /* LOD levels to test */ 1358 const GLint levelsOfDetail[] = { 0, 1, 2 }; 1359 1360 for (GLint sizeIndex = 0; sizeIndex < DE_LENGTH_OF_ARRAY(textureSizes); sizeIndex++) 1361 { 1362 const TexSize& ts = textureSizes[sizeIndex]; 1363 for (GLint formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(testedFormats); formatIndex++) 1364 { 1365 const FormatInfo& formatInfo = testedFormats[formatIndex]; 1366 GLenum internalFormat = formatInfo.internalformat; 1367 for (GLsizei lodIndex = 0; lodIndex < DE_LENGTH_OF_ARRAY(levelsOfDetail); lodIndex++) 1368 { 1369 GLint lod = levelsOfDetail[lodIndex]; 1370 std::stringstream testBaseName; 1371 testBaseName << formatInfo.name << "_" << ts.width << "x" << ts.height << "_" << lod << "_"; 1372 std::string names[] = { testBaseName.str() + "clamp_to_edge", testBaseName.str() + "repeat", 1373 testBaseName.str() + "mirrored_repeat" }; 1374 addChild(new TestClampModeForInternalFormat(m_context, names[0], internalFormat, GL_CLAMP_TO_EDGE, lod, 1375 ts.width, ts.height)); 1376 addChild(new TestClampModeForInternalFormat(m_context, names[1], internalFormat, GL_REPEAT, lod, 1377 ts.width, ts.height)); 1378 addChild(new TestClampModeForInternalFormat(m_context, names[2], internalFormat, GL_MIRRORED_REPEAT, 1379 lod, ts.width, ts.height)); 1380 } 1381 } 1382 } 1383} 1384} /* glcts namespace */ 1385