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
35 using namespace glw;
36
37 namespace glcts
38 {
39
40 union 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
56 enum 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
65 enum 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 */
78 struct 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
101 static 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
233 struct 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
244 static 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
347 static 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
423 const 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
448 const 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
457 const 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
469 const 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
483 struct TestArea
484 {
485 GLsizei left;
486 GLsizei right;
487 GLsizei top;
488 GLsizei bottom;
489 };
490
491 class TestClampModeForInternalFormat : public deqp::TestCase
492 {
493 public:
494 /* Public methods */
495 TestClampModeForInternalFormat(deqp::Context& context, const std::string& name, GLenum internalFormat,
496 GLenum clampMode, GLint lodLevel, GLsizei width, GLsizei height);
~TestClampModeForInternalFormat()497 virtual ~TestClampModeForInternalFormat()
498 {
499 }
500
501 /* Public methods inherited from TestCase */
502 virtual tcu::TestNode::IterateResult iterate(void);
503
504 private:
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
522 private:
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 **/
TestClampModeForInternalFormat(deqp::Context & context,const std::string & name,GLenum internalFormat,GLenum clampMode,GLint lodLevel,GLsizei width,GLsizei height)535 TestClampModeForInternalFormat::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
findInternalFormat(GLenum internalformat) const548 const 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
findFormat(GLenum internalformat) const568 const 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
isEqual(const GLubyte * color1,const GLubyte * color2,GLubyte tolerance) const576 bool 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 */
fillTextureWithColor(GLubyte * texture_data,GLsizei tex_width,GLsizei tex_height,GLenum internalformat) const597 void 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
clearTextures(GLenum target,GLsizei width,GLsizei height,GLint lod,GLenum internalformat,GLenum type,GLenum format) const637 void 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 */
calcTextureEpsilon(const GLsizei textureBits[4],GLfloat textureEpsilon[4]) const670 void 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 */
proportion(GLsizei a,GLsizei b,GLsizei c) const728 GLsizei 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 */
verifyClampToEdge(GLubyte * buf,GLsizei width_init,GLsizei height_init,GLsizei width,GLsizei height,GLenum internalformat) const745 bool 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 */
verifyRepeat(GLubyte * buf,GLsizei width,GLsizei height,GLenum internalformat) const838 bool 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 */
verifyMirroredRepeat(GLubyte * buf,GLsizei width,GLsizei height,GLenum internalformat) const921 bool 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
verifyClampMode(GLubyte * buf,GLsizei width,GLsizei height,GLenum clampMode,GLenum internalformat) const1125 bool 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 **/
iterate(void)1215 tcu::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 */
TextureRepeatModeTests(deqp::Context & context)1340 TextureRepeatModeTests::TextureRepeatModeTests(deqp::Context& context)
1341 : TestCaseGroup(context, "texture_repeat_mode", "Texture repeat mode tests")
1342 {
1343 }
1344
1345 /** Initializes the test group contents. */
init()1346 void 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