xref: /aosp_15_r20/external/deqp/external/openglcts/modules/common/glcTextureRepeatModeTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 {
42     struct Bits
43     {
44         int red;       /* red bits */
45         int green;     /* green bits */
46         int blue;      /* blue bits */
47         int alpha;     /* alpha bits */
48         int intensity; /* intensity bits */
49         int luminance; /* luminance bits */
50         int depth;     /* depth bits */
51         int stencil;   /* stencil bits */
52         int exponent;  /* shared exponent bits */
53     } bits;
54     int array[9]; /* all the bits */
55 };
56 
57 enum InternalFormatSamplerType
58 {
59     SAMPLER_UNORM = 0, /* unsigned normalized */
60     SAMPLER_NORM,      /* normalized */
61     SAMPLER_UINT,      /* unsigned integer */
62     SAMPLER_INT,       /* integer */
63     SAMPLER_FLOAT      /* floating-point */
64 };
65 
66 enum InternalFormatFlag
67 {
68     NO_FLAG           = 0,
69     FLAG_PACKED       = 1,                                     /* Packed pixel format. */
70     FLAG_COMPRESSED   = 2,                                     /* Compressed format. */
71     FLAG_REQ_RBO_GL42 = 4,                                     /* Required RBO & tex format in OpenGL 4.2. */
72     FLAG_REQ_RBO_ES30 = 8,                                     /* Required RBO & tex format in OpenGL ES 3.0. */
73     FLAG_REQ_RBO      = FLAG_REQ_RBO_GL42 | FLAG_REQ_RBO_ES30, /* Required RBO & tex format in both. */
74 };
75 
76 #define MAX_PIXEL_SIZE 16
77 
78 /* Note that internal representation is in little endian - tests will fail on big endian, in particular RGB565 will fail */
79 struct FormatInfo
80 {
81     /* internal format, indicating tested format */
82     GLenum internalformat;
83 
84     const char *name;
85 
86     /* number of bytes per pixel */
87     GLsizei pixelSize;
88 
89     /* RGBW colors' representation, specific for each internalformat */
90     GLubyte internalred[MAX_PIXEL_SIZE];
91     GLubyte internalgreen[MAX_PIXEL_SIZE];
92     GLubyte internalblue[MAX_PIXEL_SIZE];
93     GLubyte internalwhite[MAX_PIXEL_SIZE];
94 
95     /* RGBW colors' mapped to RGBA, that are read from framebuffer */
96     GLubyte RGBAred[4];
97     GLubyte RGBAgreen[4];
98     GLubyte RGBAblue[4];
99     GLubyte RGBAwhite[4];
100 };
101 
102 static const FormatInfo testedFormats[] = {
103     {
104         GL_R8,
105         "r8",
106         1,
107         {0xFF},
108         {0xC7},
109         {0x30},
110         {0x00},
111         /* expected values */
112         {0xFF, 0x00, 0x00, 0xFF},
113         {0xC7, 0x00, 0x00, 0xFF},
114         {0x30, 0x00, 0x00, 0xFF},
115         {0x00, 0x00, 0x00, 0xFF},
116     },
117     {
118         GL_RGB565,
119         "rgb565",
120         2,
121         {0x00, 0xF8},
122         {0xE0, 0x07},
123         {0x1F, 0x00},
124         {0xFF, 0xFF},
125         /* expected values */
126         {0xFF, 0x00, 0x00, 0xFF},
127         {0x00, 0xFF, 0x00, 0xFF},
128         {0x00, 0x00, 0xFF, 0xFF},
129         {0xFF, 0xFF, 0xFF, 0xFF},
130     },
131     {
132         GL_RGB8,
133         "rgb8",
134         3,
135         {0xFF, 0x00, 0x00},
136         {0x00, 0xFF, 0x00},
137         {0x00, 0x00, 0xFF},
138         {0xFF, 0xFF, 0xFF},
139         /* expected values */
140         {0xFF, 0x00, 0x00, 0xFF},
141         {0x00, 0xFF, 0x00, 0xFF},
142         {0x00, 0x00, 0xFF, 0xFF},
143         {0xFF, 0xFF, 0xFF, 0xFF},
144     },
145     {
146         GL_RGB10_A2,
147         "rgb10_a2",
148         4,
149         {0xFF, 0x03, 0x00, 0xC0},
150         {0x00, 0xFC, 0x0F, 0xC0},
151         {0x00, 0x00, 0xF0, 0xFF},
152         {0xFF, 0xFF, 0xFF, 0xFF},
153         /* expected values */
154         {0xFF, 0x00, 0x00, 0xFF},
155         {0x00, 0xFF, 0x00, 0xFF},
156         {0x00, 0x00, 0xFF, 0xFF},
157         {0xFF, 0xFF, 0xFF, 0xFF},
158     },
159     {
160         /* unsigned integer texture formats : require an unsigned texture sampler in the fragment shader */
161         GL_R32UI,
162         "r32ui",
163         4,
164         {0xFF, 0x00, 0x00, 0x00},
165         {0x51, 0x00, 0x00, 0x00},
166         {0xF3, 0x00, 0x00, 0x00},
167         {0x00, 0x00, 0x00, 0x00},
168         /* expected values */
169         {0xFF, 0x00, 0x00, 0xFF},
170         {0x51, 0x00, 0x00, 0xFF},
171         {0xF3, 0x00, 0x00, 0xFF},
172         {0x00, 0x00, 0x00, 0xFF},
173     },
174     {
175         GL_RG32UI,
176         "rg32ui",
177         8,
178         {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00},
179         {0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
180         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
181         {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
182         /* expected values */
183         {0xFF, 0x00, 0x00, 0xFF},
184         {0x00, 0xFF, 0x00, 0xFF},
185         {0x00, 0x00, 0x00, 0xFF},
186         {0xFF, 0xFF, 0x00, 0xFF},
187     },
188     {
189         GL_RGBA32UI,
190         "rgba32ui",
191         16,
192         {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
193         {0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
194         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
195         {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
196         /* expected values */
197         {0xFF, 0x00, 0x00, 0xFF},
198         {0x00, 0xFF, 0x00, 0xFF},
199         {0x00, 0x00, 0xFF, 0xFF},
200         {0xFF, 0xFF, 0xFF, 0xFF},
201     },
202     {
203         /* DEPTH formats are tested by comparing with reference values hard-coded in shaders */
204         GL_DEPTH_COMPONENT16,
205         "depth_component16",
206         2,
207         {0xFF, 0xE8}, /* ~ 0.91 */
208         {0xFF, 0xAB}, /* ~ 0.67 */
209         {0x00, 0x78}, /* ~ 0.46 */
210         {0x00, 0x3C}, /* ~ 0.23 */
211         /* expected values */
212         {0x00, 0x00, 0x00, 0xff},
213         {0x00, 0x00, 0xff, 0xff},
214         {0x00, 0xff, 0xff, 0xff},
215         {0xff, 0xff, 0xff, 0xff},
216     },
217     {
218         /* little-endian order, so the bytes are in reverse order: stencil first, then depth */
219         GL_DEPTH24_STENCIL8,
220         "depth24_stencil8",
221         4,
222         {0x00, 0x00, 0xE8, 0xFF}, /* ~ 0.99 */
223         {0x88, 0x00, 0xAB, 0xAF}, /* ~ 0.68 */
224         {0xBB, 0x28, 0x55, 0x7F}, /* ~ 0.49 */
225         {0xFF, 0x78, 0x80, 0x02}, /* ~ 0.01 */
226         /* expected values */
227         {0x00, 0x00, 0x00, 0xff},
228         {0x00, 0x00, 0xff, 0xff},
229         {0x00, 0xff, 0xff, 0xff},
230         {0xff, 0xff, 0xff, 0xff},
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     {GL_DEPTH_COMPONENT,
246      GL_DEPTH_COMPONENT,
247      GL_DEPTH_COMPONENT,
248      GL_UNSIGNED_SHORT,
249      SAMPLER_UNORM,
250      {{0, 0, 0, 0, 0, 0, 16, 0, NO_FLAG}},
251      NO_FLAG},
252     {GL_DEPTH_STENCIL,
253      GL_DEPTH_STENCIL,
254      GL_DEPTH_STENCIL,
255      GL_UNSIGNED_INT,
256      SAMPLER_UNORM,
257      {{0, 0, 0, 0, 0, 0, 24, 8, NO_FLAG}},
258      NO_FLAG},
259 
260     {GL_RED, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
261     {GL_RG, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
262 
263     // Table 3.12
264     {GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
265     {GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
266     {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},
267     {GL_R16_SNORM, GL_RED, GL_RED, GL_SHORT, SAMPLER_NORM, {{16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
268     {GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
269     {GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
270     {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},
271     {GL_RG16_SNORM, GL_RG, GL_RG, GL_SHORT, SAMPLER_NORM, {{16, 16, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
272     {GL_R3_G3_B2,
273      GL_RGB,
274      GL_RGB,
275      GL_UNSIGNED_BYTE_3_3_2,
276      SAMPLER_UNORM,
277      {{3, 3, 2, 0, 0, 0, 0, 0, NO_FLAG}},
278      FLAG_PACKED},
279     {GL_RGB4, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{4, 4, 4, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
280     {GL_RGB5, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{5, 5, 5, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
281     {GL_RGB565,
282      GL_RGB,
283      GL_RGB,
284      GL_UNSIGNED_SHORT_5_6_5,
285      SAMPLER_UNORM,
286      {{5, 6, 5, 0, 0, 0, 0, 0, NO_FLAG}},
287      FLAG_PACKED | FLAG_REQ_RBO},
288     {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},
289     {GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
290     {GL_RGB10, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, {{10, 10, 10, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
291     {GL_RGB12, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, {{12, 12, 12, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
292     {GL_RGB16, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT, SAMPLER_UNORM, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
293     {GL_RGB16_SNORM, GL_RGB, GL_RGB, GL_SHORT, SAMPLER_NORM, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
294     {GL_RGBA2, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{2, 2, 2, 2, 0, 0, 0, 0, NO_FLAG}}, 0},
295 
296     {GL_RGBA4,
297      GL_RGBA,
298      GL_RGBA,
299      GL_UNSIGNED_SHORT_4_4_4_4,
300      SAMPLER_UNORM,
301      {{4, 4, 4, 4, 0, 0, 0, 0, NO_FLAG}},
302      FLAG_PACKED | FLAG_REQ_RBO},
303     {GL_RGB5_A1,
304      GL_RGBA,
305      GL_RGBA,
306      GL_UNSIGNED_SHORT_5_5_5_1,
307      SAMPLER_UNORM,
308      {{5, 5, 5, 1, 0, 0, 0, 0, NO_FLAG}},
309      FLAG_PACKED | FLAG_REQ_RBO},
310 
311     {GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
312     {GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, 0},
313 
314     {GL_RGB10_A2,
315      GL_RGBA,
316      GL_RGBA,
317      GL_UNSIGNED_INT_2_10_10_10_REV,
318      SAMPLER_UNORM,
319      {{10, 10, 10, 2, 0, 0, 0, 0, NO_FLAG}},
320      FLAG_PACKED | FLAG_REQ_RBO_GL42},
321     {GL_RGB10_A2UI,
322      GL_RGBA,
323      GL_RGBA_INTEGER,
324      GL_UNSIGNED_INT_2_10_10_10_REV,
325      SAMPLER_UINT,
326      {{10, 10, 10, 2, 0, 0, 0, 0, NO_FLAG}},
327      FLAG_PACKED | FLAG_REQ_RBO_GL42},
328 
329     {GL_RGBA12, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, SAMPLER_UNORM, {{12, 12, 12, 12, 0, 0, 0, 0, NO_FLAG}}, 0},
330     {GL_RGBA16,
331      GL_RGBA,
332      GL_RGBA,
333      GL_UNSIGNED_SHORT,
334      SAMPLER_UNORM,
335      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
336      FLAG_REQ_RBO_GL42},
337     {GL_RGBA16_SNORM, GL_RGBA, GL_RGBA, GL_SHORT, SAMPLER_NORM, {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}}, 0},
338 
339     {GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
340     {GL_SRGB8_ALPHA8,
341      GL_RGBA,
342      GL_RGBA,
343      GL_UNSIGNED_BYTE,
344      SAMPLER_UNORM,
345      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
346      FLAG_REQ_RBO},
347 
348     {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},
349     {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},
350     {GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
351     {GL_RGBA16F,
352      GL_RGBA,
353      GL_RGBA,
354      GL_HALF_FLOAT,
355      SAMPLER_FLOAT,
356      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
357      FLAG_REQ_RBO_GL42},
358     {GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, {{32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
359     {GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
360     {GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
361     {GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
362     {GL_R11F_G11F_B10F,
363      GL_RGB,
364      GL_RGB,
365      GL_UNSIGNED_INT_10F_11F_11F_REV,
366      SAMPLER_FLOAT,
367      {{11, 11, 10, 0, 0, 0, 0, 0, NO_FLAG}},
368      FLAG_PACKED | FLAG_REQ_RBO_GL42},
369 
370     {GL_RGB9_E5,
371      GL_RGB,
372      GL_RGB,
373      GL_UNSIGNED_INT_5_9_9_9_REV,
374      SAMPLER_FLOAT,
375      {{9, 9, 9, 0, 0, 0, 0, 0, 5}},
376      FLAG_PACKED},
377 
378     {GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
379     {GL_R8UI,
380      GL_RED,
381      GL_RED_INTEGER,
382      GL_UNSIGNED_BYTE,
383      SAMPLER_UINT,
384      {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
385      FLAG_REQ_RBO},
386     {GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
387     {GL_R16UI,
388      GL_RED,
389      GL_RED_INTEGER,
390      GL_UNSIGNED_SHORT,
391      SAMPLER_UINT,
392      {{16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
393      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,
396      GL_RED,
397      GL_RED_INTEGER,
398      GL_UNSIGNED_INT,
399      SAMPLER_UINT,
400      {{32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
401      FLAG_REQ_RBO},
402     {GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
403     {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},
404     {GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 16, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
405     {GL_RG16UI,
406      GL_RG,
407      GL_RG_INTEGER,
408      GL_UNSIGNED_SHORT,
409      SAMPLER_UINT,
410      {{16, 16, 0, 0, 0, 0, 0, 0, NO_FLAG}},
411      FLAG_REQ_RBO},
412     {GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
413     {GL_RG32UI,
414      GL_RG,
415      GL_RG_INTEGER,
416      GL_UNSIGNED_INT,
417      SAMPLER_UINT,
418      {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}},
419      FLAG_REQ_RBO},
420     {GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
421     {GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
422     {GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
423     {GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
424     {GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
425     {GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
426     {GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
427     {GL_RGBA8UI,
428      GL_RGBA,
429      GL_RGBA_INTEGER,
430      GL_UNSIGNED_BYTE,
431      SAMPLER_UINT,
432      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
433      FLAG_REQ_RBO},
434     {GL_RGBA16I,
435      GL_RGBA,
436      GL_RGBA_INTEGER,
437      GL_SHORT,
438      SAMPLER_INT,
439      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
440      FLAG_REQ_RBO},
441     {GL_RGBA16UI,
442      GL_RGBA,
443      GL_RGBA_INTEGER,
444      GL_UNSIGNED_SHORT,
445      SAMPLER_UINT,
446      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
447      FLAG_REQ_RBO},
448     {GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
449     {GL_RGBA32UI,
450      GL_RGBA,
451      GL_RGBA_INTEGER,
452      GL_UNSIGNED_INT,
453      SAMPLER_UINT,
454      {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}},
455      FLAG_REQ_RBO},
456 
457     // Table 3.13
458     {GL_DEPTH_COMPONENT16,
459      GL_DEPTH_COMPONENT,
460      GL_DEPTH_COMPONENT,
461      GL_UNSIGNED_SHORT,
462      SAMPLER_UNORM,
463      {{0, 0, 0, 0, 0, 0, 16, 0, NO_FLAG}},
464      FLAG_REQ_RBO},
465     {GL_DEPTH_COMPONENT24,
466      GL_DEPTH_COMPONENT,
467      GL_DEPTH_COMPONENT,
468      GL_UNSIGNED_INT,
469      SAMPLER_UNORM,
470      {{0, 0, 0, 0, 0, 0, 24, 0, NO_FLAG}},
471      FLAG_REQ_RBO},
472     {GL_DEPTH_COMPONENT32,
473      GL_DEPTH_COMPONENT,
474      GL_DEPTH_COMPONENT,
475      GL_UNSIGNED_INT,
476      SAMPLER_UNORM,
477      {{0, 0, 0, 0, 0, 0, 32, 0, NO_FLAG}},
478      0},
479     {GL_DEPTH_COMPONENT32F,
480      GL_DEPTH_COMPONENT,
481      GL_DEPTH_COMPONENT,
482      GL_FLOAT,
483      SAMPLER_FLOAT,
484      {{0, 0, 0, 0, 0, 0, 32, 0, NO_FLAG}},
485      FLAG_REQ_RBO},
486     {GL_DEPTH24_STENCIL8,
487      GL_DEPTH_STENCIL,
488      GL_DEPTH_STENCIL,
489      GL_UNSIGNED_INT_24_8,
490      SAMPLER_UNORM,
491      {{0, 0, 0, 0, 0, 0, 24, 8, NO_FLAG}},
492      FLAG_REQ_RBO},
493     {GL_DEPTH32F_STENCIL8,
494      GL_DEPTH_STENCIL,
495      GL_DEPTH_STENCIL,
496      GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
497      SAMPLER_FLOAT,
498      {{0, 0, 0, 0, 0, 0, 32, 8, NO_FLAG}},
499      FLAG_PACKED | FLAG_REQ_RBO},
500 
501     // Table 3.14
502     {GL_COMPRESSED_RED,
503      GL_RED,
504      GL_RED,
505      GL_UNSIGNED_BYTE,
506      SAMPLER_UNORM,
507      {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
508      FLAG_COMPRESSED},
509     {GL_COMPRESSED_RG,
510      GL_RG,
511      GL_RG,
512      GL_UNSIGNED_BYTE,
513      SAMPLER_UNORM,
514      {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}},
515      FLAG_COMPRESSED},
516     {GL_COMPRESSED_RGB,
517      GL_RGB,
518      GL_RGB,
519      GL_UNSIGNED_BYTE,
520      SAMPLER_UNORM,
521      {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}},
522      FLAG_COMPRESSED},
523     {GL_COMPRESSED_RGBA,
524      GL_RGBA,
525      GL_RGBA,
526      GL_UNSIGNED_BYTE,
527      SAMPLER_UNORM,
528      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
529      FLAG_COMPRESSED},
530     {GL_COMPRESSED_SRGB,
531      GL_RGB,
532      GL_RGB,
533      GL_UNSIGNED_BYTE,
534      SAMPLER_UNORM,
535      {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}},
536      FLAG_COMPRESSED},
537     {GL_COMPRESSED_SRGB_ALPHA,
538      GL_RGBA,
539      GL_RGBA,
540      GL_UNSIGNED_BYTE,
541      SAMPLER_UNORM,
542      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
543      FLAG_COMPRESSED},
544     {GL_COMPRESSED_RED_RGTC1,
545      GL_RED,
546      GL_RED,
547      GL_UNSIGNED_BYTE,
548      SAMPLER_UNORM,
549      {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
550      FLAG_COMPRESSED},
551     {GL_COMPRESSED_SIGNED_RED_RGTC1,
552      GL_RED,
553      GL_RED,
554      GL_BYTE,
555      SAMPLER_NORM,
556      {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
557      FLAG_COMPRESSED},
558     {GL_COMPRESSED_RG_RGTC2,
559      GL_RG,
560      GL_RG,
561      GL_UNSIGNED_BYTE,
562      SAMPLER_UNORM,
563      {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}},
564      FLAG_COMPRESSED},
565     {GL_COMPRESSED_SIGNED_RG_RGTC2,
566      GL_RG,
567      GL_RG,
568      GL_BYTE,
569      SAMPLER_NORM,
570      {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}},
571      FLAG_COMPRESSED},
572 };
573 
574 static const InternalFormat esInternalFormats[] = {
575     // Table 3.3
576     {GL_LUMINANCE, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{0, 0, 0, 0, 0, 8, 0, 0, NO_FLAG}}, 0},
577     {GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{0, 0, 0, 8, 0, 0, 0, 0, NO_FLAG}}, 0},
578     {GL_LUMINANCE_ALPHA,
579      GL_LUMINANCE_ALPHA,
580      GL_LUMINANCE_ALPHA,
581      GL_UNSIGNED_BYTE,
582      SAMPLER_UNORM,
583      {{0, 0, 0, 8, 0, 8, 0, 0, NO_FLAG}},
584      0},
585 
586     {GL_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
587     {GL_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, 0},
588 
589     // Table 3.12
590     {GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
591     {GL_R8_SNORM, GL_RED, GL_RED, GL_BYTE, SAMPLER_NORM, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
592     {GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
593     {GL_RG8_SNORM, GL_RG, GL_RG, GL_BYTE, SAMPLER_NORM, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
594     {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},
595     {GL_RGB8_SNORM, GL_RGB, GL_RGB, GL_BYTE, SAMPLER_NORM, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
596     {GL_RGB565,
597      GL_RGB,
598      GL_RGB,
599      GL_UNSIGNED_SHORT_5_6_5,
600      SAMPLER_UNORM,
601      {{5, 6, 5, 0, 0, 0, 0, 0, NO_FLAG}},
602      FLAG_PACKED | FLAG_REQ_RBO},
603 
604     {GL_RGBA4,
605      GL_RGBA,
606      GL_RGBA,
607      GL_UNSIGNED_SHORT_4_4_4_4,
608      SAMPLER_UNORM,
609      {{4, 4, 4, 4, 0, 0, 0, 0, NO_FLAG}},
610      FLAG_PACKED | FLAG_REQ_RBO},
611     {GL_RGB5_A1,
612      GL_RGBA,
613      GL_RGBA,
614      GL_UNSIGNED_SHORT_5_5_5_1,
615      SAMPLER_UNORM,
616      {{5, 5, 5, 1, 0, 0, 0, 0, NO_FLAG}},
617      FLAG_PACKED | FLAG_REQ_RBO},
618 
619     {GL_RGBA8, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
620     {GL_RGBA8_SNORM, GL_RGBA, GL_RGBA, GL_BYTE, SAMPLER_NORM, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, 0},
621 
622     {GL_RGB10_A2,
623      GL_RGBA,
624      GL_RGBA,
625      GL_UNSIGNED_INT_2_10_10_10_REV,
626      SAMPLER_UNORM,
627      {{10, 10, 10, 2, 0, 0, 0, 0, NO_FLAG}},
628      FLAG_PACKED | FLAG_REQ_RBO_ES30},
629     {GL_RGB10_A2UI,
630      GL_RGBA,
631      GL_RGBA_INTEGER,
632      GL_UNSIGNED_INT_2_10_10_10_REV,
633      SAMPLER_UINT,
634      {{10, 10, 10, 2, 0, 0, 0, 0, NO_FLAG}},
635      FLAG_PACKED | FLAG_REQ_RBO_ES30},
636 
637     {GL_SRGB8, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, SAMPLER_UNORM, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
638     {GL_SRGB8_ALPHA8,
639      GL_RGBA,
640      GL_RGBA,
641      GL_UNSIGNED_BYTE,
642      SAMPLER_UNORM,
643      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
644      FLAG_REQ_RBO},
645 
646     {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},
647     {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},
648     {GL_RGB16F, GL_RGB, GL_RGB, GL_HALF_FLOAT, SAMPLER_FLOAT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
649     {GL_RGBA16F,
650      GL_RGBA,
651      GL_RGBA,
652      GL_HALF_FLOAT,
653      SAMPLER_FLOAT,
654      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
655      FLAG_REQ_RBO_GL42},
656     {GL_R32F, GL_RED, GL_RED, GL_FLOAT, SAMPLER_FLOAT, {{32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
657     {GL_RG32F, GL_RG, GL_RG, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
658     {GL_RGB32F, GL_RGB, GL_RGB, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
659     {GL_RGBA32F, GL_RGBA, GL_RGBA, GL_FLOAT, SAMPLER_FLOAT, {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO_GL42},
660     {GL_R11F_G11F_B10F,
661      GL_RGB,
662      GL_RGB,
663      GL_UNSIGNED_INT_10F_11F_11F_REV,
664      SAMPLER_FLOAT,
665      {{11, 11, 10, 0, 0, 0, 0, 0, NO_FLAG}},
666      FLAG_PACKED | FLAG_REQ_RBO_GL42},
667 
668     {GL_RGB9_E5,
669      GL_RGB,
670      GL_RGB,
671      GL_UNSIGNED_INT_5_9_9_9_REV,
672      SAMPLER_FLOAT,
673      {{9, 9, 9, 0, 0, 0, 0, 0, 5}},
674      FLAG_PACKED},
675 
676     {GL_R8I, GL_RED, GL_RED_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
677     {GL_R8UI,
678      GL_RED,
679      GL_RED_INTEGER,
680      GL_UNSIGNED_BYTE,
681      SAMPLER_UINT,
682      {{8, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
683      FLAG_REQ_RBO},
684     {GL_R16I, GL_RED, GL_RED_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
685     {GL_R16UI,
686      GL_RED,
687      GL_RED_INTEGER,
688      GL_UNSIGNED_SHORT,
689      SAMPLER_UINT,
690      {{16, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
691      FLAG_REQ_RBO},
692     {GL_R32I, GL_RED, GL_RED_INTEGER, GL_INT, SAMPLER_INT, {{32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
693     {GL_R32UI,
694      GL_RED,
695      GL_RED_INTEGER,
696      GL_UNSIGNED_INT,
697      SAMPLER_UINT,
698      {{32, 0, 0, 0, 0, 0, 0, 0, NO_FLAG}},
699      FLAG_REQ_RBO},
700     {GL_RG8I, GL_RG, GL_RG_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
701     {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},
702     {GL_RG16I, GL_RG, GL_RG_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 16, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
703     {GL_RG16UI,
704      GL_RG,
705      GL_RG_INTEGER,
706      GL_UNSIGNED_SHORT,
707      SAMPLER_UINT,
708      {{16, 16, 0, 0, 0, 0, 0, 0, NO_FLAG}},
709      FLAG_REQ_RBO},
710     {GL_RG32I, GL_RG, GL_RG_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
711     {GL_RG32UI,
712      GL_RG,
713      GL_RG_INTEGER,
714      GL_UNSIGNED_INT,
715      SAMPLER_UINT,
716      {{32, 32, 0, 0, 0, 0, 0, 0, NO_FLAG}},
717      FLAG_REQ_RBO},
718     {GL_RGB8I, GL_RGB, GL_RGB_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
719     {GL_RGB8UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, SAMPLER_UINT, {{8, 8, 8, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
720     {GL_RGB16I, GL_RGB, GL_RGB_INTEGER, GL_SHORT, SAMPLER_INT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
721     {GL_RGB16UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_SHORT, SAMPLER_UINT, {{16, 16, 16, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
722     {GL_RGB32I, GL_RGB, GL_RGB_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
723     {GL_RGB32UI, GL_RGB, GL_RGB_INTEGER, GL_UNSIGNED_INT, SAMPLER_UINT, {{32, 32, 32, 0, 0, 0, 0, 0, NO_FLAG}}, 0},
724     {GL_RGBA8I, GL_RGBA, GL_RGBA_INTEGER, GL_BYTE, SAMPLER_INT, {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
725     {GL_RGBA8UI,
726      GL_RGBA,
727      GL_RGBA_INTEGER,
728      GL_UNSIGNED_BYTE,
729      SAMPLER_UINT,
730      {{8, 8, 8, 8, 0, 0, 0, 0, NO_FLAG}},
731      FLAG_REQ_RBO},
732     {GL_RGBA16I,
733      GL_RGBA,
734      GL_RGBA_INTEGER,
735      GL_SHORT,
736      SAMPLER_INT,
737      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
738      FLAG_REQ_RBO},
739     {GL_RGBA16UI,
740      GL_RGBA,
741      GL_RGBA_INTEGER,
742      GL_UNSIGNED_SHORT,
743      SAMPLER_UINT,
744      {{16, 16, 16, 16, 0, 0, 0, 0, NO_FLAG}},
745      FLAG_REQ_RBO},
746     {GL_RGBA32I, GL_RGBA, GL_RGBA_INTEGER, GL_INT, SAMPLER_INT, {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}}, FLAG_REQ_RBO},
747     {GL_RGBA32UI,
748      GL_RGBA,
749      GL_RGBA_INTEGER,
750      GL_UNSIGNED_INT,
751      SAMPLER_UINT,
752      {{32, 32, 32, 32, 0, 0, 0, 0, NO_FLAG}},
753      FLAG_REQ_RBO},
754 
755     // Table 3.13
756     {GL_DEPTH_COMPONENT16,
757      GL_DEPTH_COMPONENT,
758      GL_DEPTH_COMPONENT,
759      GL_UNSIGNED_SHORT,
760      SAMPLER_UNORM,
761      {{0, 0, 0, 0, 0, 0, 16, 0, NO_FLAG}},
762      FLAG_REQ_RBO},
763     {GL_DEPTH_COMPONENT24,
764      GL_DEPTH_COMPONENT,
765      GL_DEPTH_COMPONENT,
766      GL_UNSIGNED_INT,
767      SAMPLER_UNORM,
768      {{0, 0, 0, 0, 0, 0, 24, 0, NO_FLAG}},
769      FLAG_REQ_RBO},
770     {GL_DEPTH_COMPONENT32F,
771      GL_DEPTH_COMPONENT,
772      GL_DEPTH_COMPONENT,
773      GL_FLOAT,
774      SAMPLER_FLOAT,
775      {{0, 0, 0, 0, 0, 0, 32, 0, NO_FLAG}},
776      FLAG_REQ_RBO},
777     {GL_DEPTH24_STENCIL8,
778      GL_DEPTH_STENCIL,
779      GL_DEPTH_STENCIL,
780      GL_UNSIGNED_INT_24_8,
781      SAMPLER_UNORM,
782      {{0, 0, 0, 0, 0, 0, 24, 8, NO_FLAG}},
783      FLAG_REQ_RBO},
784     {GL_DEPTH32F_STENCIL8,
785      GL_DEPTH_STENCIL,
786      GL_DEPTH_STENCIL,
787      GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
788      SAMPLER_FLOAT,
789      {{0, 0, 0, 0, 0, 0, 32, 8, NO_FLAG}},
790      FLAG_PACKED | FLAG_REQ_RBO},
791 };
792 
793 const char *basic_vs = "precision mediump float;\n"
794                        "out vec2 texCoord;\n"
795                        "void main(void)\n"
796                        "{\n"
797                        "    switch(gl_VertexID)\n"
798                        "    {\n"
799                        "        case 0:\n"
800                        "            gl_Position = vec4( 1.0,-1.0, 0.0, 1.0);\n"
801                        "            texCoord = vec2(2.0, -1.0);\n"
802                        "            break;\n"
803                        "        case 1:\n"
804                        "            gl_Position = vec4( 1.0, 1.0, 0.0, 1.0);\n"
805                        "            texCoord = vec2(2.0, 2.0);\n"
806                        "            break;\n"
807                        "        case 2:\n"
808                        "            gl_Position = vec4(-1.0,-1.0, 0.0, 1.0);\n"
809                        "            texCoord = vec2(-1.0, -1.0);\n"
810                        "            break;\n"
811                        "        case 3:\n"
812                        "            gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
813                        "            texCoord = vec2(-1.0, 2.0);\n"
814                        "            break;\n"
815                        "    }\n"
816                        "}";
817 
818 const char *basic_fs = "precision mediump float;\n"
819                        "uniform sampler2D texture0;\n"
820                        "in vec2 texCoord;\n"
821                        "out vec4 color;\n"
822                        "void main(void)\n"
823                        "{\n"
824                        "    color = texture(texture0, texCoord);\n"
825                        "}";
826 
827 const char *shadow_fs = "precision mediump float;\n"
828                         "uniform mediump sampler2DShadow texture0;\n"
829                         "in  vec2 texCoord;\n"
830                         "out vec4 color;\n"
831                         "void main(void)\n"
832                         "{\n"
833                         "    float r = texture(texture0, vec3(texCoord.xy, 0.3));\n"
834                         "    float g = texture(texture0, vec3(texCoord.xy, 0.5));\n"
835                         "    float b = texture(texture0, vec3(texCoord.xy, 0.8));\n"
836                         "    color = vec4(r, g, b, 1.0);\n"
837                         "}\n";
838 
839 const char *integer_fs =
840     "precision mediump float;\n"
841     "uniform mediump usampler2D texture0;\n"
842     "in vec2 texCoord;\n"
843     "out vec4 color;\n"
844     "void main(void)\n"
845     "{\n"
846     "    highp uvec4 ci = texture(texture0, texCoord);\n"
847     "    color = vec4(ci) / 255.0; // we are using an integer texture format - so convert to float\n"
848     "    if (ci.a > 0u)\n"
849     "        color.a = 1.0;\n"
850     "    else\n"
851     "        color.a = 0.0;\n"
852     "}";
853 
854 struct TestArea
855 {
856     GLsizei left;
857     GLsizei right;
858     GLsizei top;
859     GLsizei bottom;
860 };
861 
862 class TestClampModeForInternalFormat : public deqp::TestCase
863 {
864 public:
865     /* Public methods */
866     TestClampModeForInternalFormat(deqp::Context &context, const std::string &name, GLenum internalFormat,
867                                    GLenum clampMode, GLint lodLevel, GLsizei width, GLsizei height);
~TestClampModeForInternalFormat()868     virtual ~TestClampModeForInternalFormat()
869     {
870     }
871 
872     /* Public methods inherited from TestCase */
873     virtual tcu::TestNode::IterateResult iterate(void);
874 
875 private:
876     /* Private methods */
877     const FormatInfo *findFormat(GLenum internalformat) const;
878     const InternalFormat &findInternalFormat(GLenum internalformat) const;
879     void clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod, GLenum internalformat, GLenum type,
880                        GLenum format) const;
881     void fillTextureWithColor(GLubyte *texture_data, GLsizei tex_width, GLsizei tex_height,
882                               GLenum internalformat) const;
883     void calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const;
884     GLsizei proportion(GLsizei a, GLsizei b, GLsizei c) const;
885     bool isEqual(const GLubyte *color1, const GLubyte *color2, GLubyte tolerance) const;
886 
887     bool verifyClampMode(GLubyte *buf, GLsizei width, GLsizei height, GLenum clampMode, GLenum internalformat) const;
888     bool verifyClampToEdge(GLubyte *buf, GLsizei width_init, GLsizei height_init, GLsizei width, GLsizei height,
889                            GLenum internalformat) const;
890     bool verifyRepeat(GLubyte *buf, GLsizei width, GLsizei height, GLenum internalformat) const;
891     bool verifyMirroredRepeat(GLubyte *buf, GLsizei width, GLsizei height, GLenum internalformat) const;
892 
893 private:
894     /* Private attributes */
895     GLenum m_internalFormat;
896     GLenum m_clampMode;
897     GLint m_lodLevel;
898     GLsizei m_width;
899     GLsizei m_height;
900 };
901 
902 /** Constructor.
903  *
904  * @param context Rendering context.
905  **/
TestClampModeForInternalFormat(deqp::Context & context,const std::string & name,GLenum internalFormat,GLenum clampMode,GLint lodLevel,GLsizei width,GLsizei height)906 TestClampModeForInternalFormat::TestClampModeForInternalFormat(deqp::Context &context, const std::string &name,
907                                                                GLenum internalFormat, GLenum clampMode, GLint lodLevel,
908                                                                GLsizei width, GLsizei height)
909     : deqp::TestCase(context, name.c_str(), "")
910     , m_internalFormat(internalFormat)
911     , m_clampMode(clampMode)
912     , m_lodLevel(lodLevel)
913     , m_width(width)
914     , m_height(height)
915 {
916     /* Left blank intentionally */
917 }
918 
findInternalFormat(GLenum internalformat) const919 const InternalFormat &TestClampModeForInternalFormat::findInternalFormat(GLenum internalformat) const
920 {
921     const InternalFormat *internalFormats = glInternalFormats;
922     GLsizei internalFormatsCount          = DE_LENGTH_OF_ARRAY(glInternalFormats);
923 
924     if (glu::isContextTypeES(m_context.getRenderContext().getType()))
925     {
926         internalFormats      = esInternalFormats;
927         internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalFormats);
928     }
929 
930     for (GLsizei i = 0; i < internalFormatsCount; i++)
931     {
932         if (internalFormats[i].sizedFormat == internalformat)
933             return internalFormats[i];
934     }
935 
936     TCU_FAIL("Internal format not found");
937 }
938 
findFormat(GLenum internalformat) const939 const FormatInfo *TestClampModeForInternalFormat::findFormat(GLenum internalformat) const
940 {
941     for (GLsizei i = 0; i < DE_LENGTH_OF_ARRAY(testedFormats); i++)
942         if (testedFormats[i].internalformat == internalformat)
943             return &testedFormats[i];
944     return NULL;
945 }
946 
isEqual(const GLubyte * color1,const GLubyte * color2,GLubyte tolerance) const947 bool TestClampModeForInternalFormat::isEqual(const GLubyte *color1, const GLubyte *color2, GLubyte tolerance) const
948 {
949     for (int i = 0; i < 4; i++)
950     {
951         if (de::abs((int)color1[i] - (int)color2[i]) > tolerance)
952             return false;
953     }
954     return true;
955 }
956 
957 /** Fill texture with RGBW colors, according to the scheme:
958  *  R R R G G G
959  *  R R R G G G
960  *  R R R G G G
961  *  B B B W W W
962  *  B B B W W W
963  *  B B B W W W
964  *
965  *  NOTE: width of the red and blue rectangles would be less than green and white ones for odd texture's widths
966  *        height of the red and green rectangles would be less than blue and white ones for odd texture's heights
967  */
fillTextureWithColor(GLubyte * texture_data,GLsizei tex_width,GLsizei tex_height,GLenum internalformat) const968 void TestClampModeForInternalFormat::fillTextureWithColor(GLubyte *texture_data, GLsizei tex_width, GLsizei tex_height,
969                                                           GLenum internalformat) const
970 {
971     const FormatInfo *testedFormat = findFormat(internalformat);
972     const GLubyte *red             = testedFormat->internalred;
973     const GLubyte *green           = testedFormat->internalgreen;
974     const GLubyte *blue            = testedFormat->internalblue;
975     const GLubyte *white           = testedFormat->internalwhite;
976     const GLsizei size             = testedFormat->pixelSize;
977 
978     GLint i = 0;
979     GLint j = 0;
980     for (j = 0; j < tex_height / 2; j++)
981     {
982         for (i = 0; i < tex_width / 2; i++)
983         {
984             deMemcpy(texture_data, red, size);
985             texture_data += size;
986         }
987         for (; i < tex_width; i++)
988         {
989             deMemcpy(texture_data, green, size);
990             texture_data += size;
991         }
992     }
993     for (; j < tex_height; j++)
994     {
995         for (i = 0; i < tex_width / 2; i++)
996         {
997             deMemcpy(texture_data, blue, size);
998             texture_data += size;
999         }
1000         for (; i < tex_width; i++)
1001         {
1002             deMemcpy(texture_data, white, size);
1003             texture_data += size;
1004         }
1005     }
1006 }
1007 
clearTextures(GLenum target,GLsizei width,GLsizei height,GLint lod,GLenum internalformat,GLenum type,GLenum format) const1008 void TestClampModeForInternalFormat::clearTextures(GLenum target, GLsizei width, GLsizei height, GLint lod,
1009                                                    GLenum internalformat, GLenum type, GLenum format) const
1010 {
1011     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1012 
1013     GLint level;
1014     for (level = lod; level > 0; level--)
1015     {
1016         width *= 2;
1017         height *= 2;
1018     }
1019 
1020     bool continueLoop = true;
1021     std::vector<GLubyte> tex_buf(width * height * MAX_PIXEL_SIZE, 0);
1022     do
1023     {
1024         if (level != lod)
1025             gl.texImage2D(target, level, internalformat, width, height, 0, format, type, &tex_buf[0]);
1026         level++;
1027 
1028         continueLoop = !((height == 1) && (width == 1));
1029         if (width > 1)
1030             width /= 2;
1031         if (height > 1)
1032             height /= 2;
1033     } while (continueLoop);
1034 }
1035 
1036 /* Calculate error epsilons to the least accurate of either
1037 ** frame buffer or texture precision. RGBA epsilons are
1038 ** returned in textureEpsilon[]. target must be a valid
1039 ** texture target.
1040 */
calcTextureEpsilon(const GLsizei textureBits[4],GLfloat textureEpsilon[4]) const1041 void TestClampModeForInternalFormat::calcTextureEpsilon(const GLsizei textureBits[4], GLfloat textureEpsilon[4]) const
1042 {
1043     GLint i, bits;
1044     GLint bufferBits[4];
1045 
1046     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1047     gl.getIntegerv(GL_RED_BITS, &bufferBits[0]);
1048     gl.getIntegerv(GL_GREEN_BITS, &bufferBits[1]);
1049     gl.getIntegerv(GL_BLUE_BITS, &bufferBits[2]);
1050     gl.getIntegerv(GL_ALPHA_BITS, &bufferBits[3]);
1051 
1052     for (i = 0; i < 4; i++)
1053     {
1054 
1055         if (textureBits[i] == 0)
1056         {
1057             /* 'exact' */
1058             bits = 1000;
1059         }
1060         else
1061         {
1062             bits = textureBits[i];
1063         }
1064 
1065         /* Some tests fail on RGB10_A2 pixelformat, because framebuffer precision calculated here is 10-bit, but these tests use 8-bit data types
1066            for pixel transfers and 8-bit textures. Because of that, the required precision is limited to 8-bit only. */
1067         if (bits > 8)
1068         {
1069             bits = 8;
1070         }
1071 
1072         /* frame buffer bits */
1073         if (bits > bufferBits[i])
1074         {
1075             bits = bufferBits[i];
1076         }
1077 
1078         if (bits == 0)
1079         {
1080             /* infinity */
1081             textureEpsilon[i] = 2.0f;
1082         }
1083         else
1084         {
1085             const float zeroEpsilon = deFloatLdExp(1.0f, -13);
1086             textureEpsilon[i]       = (1.0f / (deFloatLdExp(1.0f, bits) - 1.0f)) + zeroEpsilon;
1087             textureEpsilon[i]       = (float)deMin(1.0f, textureEpsilon[i]);
1088         }
1089 
1090         /* If we have 8 bits framebuffer, we should hit the right value within one intensity level. */
1091         if (bits == 8 && bufferBits[i] != 0)
1092         {
1093             textureEpsilon[i] /= 2.0;
1094         }
1095     }
1096 }
1097 
1098 /* calculate (a * b) / c with rounding */
proportion(GLsizei a,GLsizei b,GLsizei c) const1099 GLsizei TestClampModeForInternalFormat::proportion(GLsizei a, GLsizei b, GLsizei c) const
1100 {
1101     float result = (float)a * b;
1102     return (GLsizei)(0.5f + result / c);
1103 }
1104 
1105 /* check out the read-back values for GL_CLAMP_TO_EDGE mode
1106  * r r r g g g
1107  * r r r g g g
1108  * r r R G g g
1109  * b b B W w w
1110  * b b b w w w
1111  * b b b w w w
1112 
1113    width_init, height_init arguments refer to the basic pattern texture, which describes proportions
1114    between colors in the rendered rectangle (tex_width, tex_height)
1115  */
verifyClampToEdge(GLubyte * buf,GLsizei width_init,GLsizei height_init,GLsizei width,GLsizei height,GLenum internalformat) const1116 bool TestClampModeForInternalFormat::verifyClampToEdge(GLubyte *buf, GLsizei width_init, GLsizei height_init,
1117                                                        GLsizei width, GLsizei height, GLenum internalformat) const
1118 {
1119     GLint i, h;
1120     const FormatInfo *testedFormat = findFormat(internalformat);
1121     const GLubyte *red             = testedFormat->RGBAred;
1122     const GLubyte *green           = testedFormat->RGBAgreen;
1123     const GLubyte *blue            = testedFormat->RGBAblue;
1124     const GLubyte *white           = testedFormat->RGBAwhite;
1125     const GLsizei size             = 4;
1126     const GLsizei skip             = 6;
1127 
1128     GLsizei red_w   = proportion(width, width_init / 2, width_init);
1129     GLsizei red_h   = proportion(height, height_init / 2, height_init);
1130     GLsizei bits[4] = {8, 8, 8, 8};
1131     GLfloat epsilonf[4];
1132     GLubyte epsilons[4];
1133 
1134     TestArea check_area = {0, width, 0, height};
1135 
1136     calcTextureEpsilon(bits, epsilonf);
1137     for (i = 0; i < 4; ++i)
1138     {
1139         epsilons[i] = (GLubyte)(epsilonf[i] * 255.0f);
1140     }
1141 
1142     for (h = 0; h < red_h - skip / 2; h++)
1143     {
1144         for (i = 0; i < red_w - skip / 2; i++)
1145         {
1146             /* skip over corner pixel to avoid issues with mipmap selection */
1147             if (i >= check_area.left || h >= check_area.top)
1148                 if (!isEqual(buf, red, epsilons[0]))
1149                     TCU_FAIL("verifyClampToEdge failed");
1150             buf += size;
1151         }
1152 
1153         /* skip over border pixels to avoid issues with rounding */
1154         i += skip;
1155         buf += skip * size;
1156 
1157         for (; i < width; i++)
1158         {
1159             /* skip over corner pixel to avoid issues with mipmap selection */
1160             if (i < check_area.right || h >= check_area.top)
1161                 if (!isEqual(buf, green, epsilons[1]))
1162                     TCU_FAIL("verifyClampToEdge failed");
1163             buf += size;
1164         }
1165     }
1166 
1167     /* skip over border pixels to avoid issues with rounding */
1168     h += skip;
1169     buf += skip * width * size;
1170 
1171     for (; h < height; h++)
1172     {
1173         for (i = 0; i < red_w - skip / 2; i++)
1174         {
1175             /* skip over corner pixel to avoid issues with mipmap selection */
1176             if (i >= check_area.left || h < check_area.bottom)
1177                 if (!isEqual(buf, blue, epsilons[2]))
1178                     TCU_FAIL("verifyClampToEdge failed");
1179             buf += size;
1180         }
1181 
1182         /* skip over border pixels to avoid issues with rounding */
1183         i += skip;
1184         buf += skip * size;
1185 
1186         for (; i < width; i++)
1187         {
1188             /* skip over corner pixel to avoid issues with mipmap selection */
1189             if (i < check_area.right || h < check_area.bottom)
1190                 if (!isEqual(buf, white, epsilons[0]))
1191                     TCU_FAIL("verifyClampToEdge failed");
1192             buf += size;
1193         }
1194     }
1195 
1196     m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyClampToEdge succeeded."
1197                                         << tcu::TestLog::EndMessage;
1198     return true;
1199 }
1200 
1201 /* check out the read-back values for GL_REPEAT mode
1202  * r g r g r g
1203  * b w b w b w
1204  * r g R G r g
1205  * b w B W b w
1206  * r g r g r g
1207  * b w b w b w
1208  */
verifyRepeat(GLubyte * buf,GLsizei width,GLsizei height,GLenum internalformat) const1209 bool TestClampModeForInternalFormat::verifyRepeat(GLubyte *buf, GLsizei width, GLsizei height,
1210                                                   GLenum internalformat) const
1211 {
1212     GLint i, j, g, h;
1213     const FormatInfo *testedFormat = findFormat(internalformat);
1214 
1215     const GLubyte *red      = testedFormat->RGBAred;
1216     const GLubyte *green    = testedFormat->RGBAgreen;
1217     const GLubyte *blue     = testedFormat->RGBAblue;
1218     const GLubyte *white    = testedFormat->RGBAwhite;
1219     const GLsizei size      = 4;
1220     const GLubyte tolerance = 0;
1221 
1222     GLsizei tex_w = width / 3;
1223     GLsizei tex_h = height / 3;
1224 
1225     GLsizei red_w = tex_w / 2;
1226     GLsizei red_h = tex_h / 2;
1227 
1228     GLsizei green_w = tex_w - red_w;
1229 
1230     GLsizei blue_w = red_w;
1231     GLsizei blue_h = tex_h - red_h;
1232 
1233     GLsizei white_w = green_w;
1234 
1235     for (g = 0; g < 3; g++)
1236     {
1237         for (h = 0; h < red_h; h++)
1238         {
1239             for (j = 0; j < 3; j++)
1240             {
1241                 for (i = 0; i < red_w; i++)
1242                 {
1243                     if (!isEqual(buf, red, tolerance))
1244                         TCU_FAIL("verifyRepeat failed");
1245 
1246                     buf += size;
1247                 }
1248                 for (i = 0; i < green_w; i++)
1249                 {
1250                     if (!isEqual(buf, green, tolerance))
1251                         TCU_FAIL("verifyRepeat failed");
1252 
1253                     buf += size;
1254                 }
1255             }
1256         }
1257         for (h = 0; h < blue_h; h++)
1258         {
1259             for (j = 0; j < 3; j++)
1260             {
1261                 for (i = 0; i < blue_w; i++)
1262                 {
1263                     if (!isEqual(buf, blue, tolerance))
1264                         TCU_FAIL("verifyRepeat failed");
1265 
1266                     buf += size;
1267                 }
1268                 for (i = 0; i < white_w; i++)
1269                 {
1270                     if (!isEqual(buf, white, tolerance))
1271                         TCU_FAIL("verifyRepeat failed");
1272 
1273                     buf += size;
1274                 }
1275             }
1276         }
1277     }
1278 
1279     m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyRepeat succeeded."
1280                                         << tcu::TestLog::EndMessage;
1281     return true;
1282 }
1283 
1284 /* check out the read-back values for GL_MIRRORED_REPEAT mode
1285  * w b b w w b
1286  * g r r g g r
1287  * r g R G r g
1288  * w b B W w b
1289  * w b b w w b
1290  * g r r g g r
1291  */
verifyMirroredRepeat(GLubyte * buf,GLsizei width,GLsizei height,GLenum internalformat) const1292 bool TestClampModeForInternalFormat::verifyMirroredRepeat(GLubyte *buf, GLsizei width, GLsizei height,
1293                                                           GLenum internalformat) const
1294 {
1295     GLint i, j, g, h;
1296     const FormatInfo *testedFormat = findFormat(internalformat);
1297 
1298     const GLubyte *red   = testedFormat->RGBAred;
1299     const GLubyte *green = testedFormat->RGBAgreen;
1300     const GLubyte *blue  = testedFormat->RGBAblue;
1301     const GLubyte *white = testedFormat->RGBAwhite;
1302 
1303     const GLsizei size      = 4;
1304     const GLubyte tolerance = 0;
1305 
1306     GLsizei tex_w = width / 3;
1307     GLsizei tex_h = height / 3;
1308 
1309     GLsizei red_w = tex_w / 2;
1310     GLsizei red_h = tex_h / 2;
1311 
1312     GLsizei green_w = tex_w - red_w;
1313     GLsizei green_h = red_h;
1314 
1315     GLsizei blue_w = red_w;
1316     GLsizei blue_h = tex_h - red_h;
1317 
1318     GLsizei white_w = green_w;
1319     GLsizei white_h = blue_h;
1320 
1321     for (g = 0; g < 3; g++)
1322     {
1323         if (g % 2 == 0)
1324         {
1325             for (h = 0; h < white_h; h++)
1326             {
1327                 for (j = 0; j < 3; j++)
1328                 {
1329                     if (j % 2 == 0)
1330                     {
1331                         for (i = 0; i < white_w; i++)
1332                         {
1333                             if (!isEqual(buf, white, tolerance))
1334                                 TCU_FAIL("verifyMirroredRepeat failed");
1335 
1336                             buf += size;
1337                         }
1338                         for (i = 0; i < blue_w; i++)
1339                         {
1340                             if (!isEqual(buf, blue, tolerance))
1341                                 TCU_FAIL("verifyMirroredRepeat failed");
1342 
1343                             buf += size;
1344                         }
1345                     }
1346                     else
1347                     {
1348                         for (i = 0; i < blue_w; i++)
1349                         {
1350                             if (!isEqual(buf, blue, tolerance))
1351                                 TCU_FAIL("verifyMirroredRepeat failed");
1352 
1353                             buf += size;
1354                         }
1355                         for (i = 0; i < white_w; i++)
1356                         {
1357                             if (!isEqual(buf, white, tolerance))
1358                                 TCU_FAIL("verifyMirroredRepeat failed");
1359 
1360                             buf += size;
1361                         }
1362                     }
1363                 }
1364             }
1365             for (h = 0; h < green_h; h++)
1366             {
1367                 for (j = 0; j < 3; j++)
1368                 {
1369                     if (j % 2 == 0)
1370                     {
1371                         for (i = 0; i < green_w; i++)
1372                         {
1373                             if (!isEqual(buf, green, tolerance))
1374                                 TCU_FAIL("verifyMirroredRepeat failed");
1375 
1376                             buf += size;
1377                         }
1378                         for (i = 0; i < red_w; i++)
1379                         {
1380                             if (!isEqual(buf, red, tolerance))
1381                                 TCU_FAIL("verifyMirroredRepeat failed");
1382 
1383                             buf += size;
1384                         }
1385                     }
1386                     else
1387                     {
1388                         for (i = 0; i < red_w; i++)
1389                         {
1390                             if (!isEqual(buf, red, tolerance))
1391                                 TCU_FAIL("verifyMirroredRepeat failed");
1392 
1393                             buf += size;
1394                         }
1395                         for (i = 0; i < green_w; i++)
1396                         {
1397                             if (!isEqual(buf, green, tolerance))
1398                                 TCU_FAIL("verifyMirroredRepeat failed");
1399 
1400                             buf += size;
1401                         }
1402                     }
1403                 }
1404             }
1405         }
1406         else
1407         {
1408             for (h = 0; h < green_h; h++)
1409             {
1410                 for (j = 0; j < 3; j++)
1411                 {
1412                     if (j % 2 == 0)
1413                     {
1414                         for (i = 0; i < green_w; i++)
1415                         {
1416                             if (!isEqual(buf, green, tolerance))
1417                                 TCU_FAIL("verifyMirroredRepeat failed");
1418 
1419                             buf += size;
1420                         }
1421                         for (i = 0; i < red_w; i++)
1422                         {
1423                             if (!isEqual(buf, red, tolerance))
1424                                 TCU_FAIL("verifyMirroredRepeat failed");
1425 
1426                             buf += size;
1427                         }
1428                     }
1429                     else
1430                     {
1431                         for (i = 0; i < red_w; i++)
1432                         {
1433                             if (!isEqual(buf, red, tolerance))
1434                                 TCU_FAIL("verifyMirroredRepeat failed");
1435 
1436                             buf += size;
1437                         }
1438                         for (i = 0; i < green_w; i++)
1439                         {
1440                             if (!isEqual(buf, green, tolerance))
1441                                 TCU_FAIL("verifyMirroredRepeat failed");
1442 
1443                             buf += size;
1444                         }
1445                     }
1446                 }
1447             }
1448             for (h = 0; h < white_h; h++)
1449             {
1450                 for (j = 0; j < 3; j++)
1451                 {
1452                     if (j % 2 == 0)
1453                     {
1454                         for (i = 0; i < white_w; i++)
1455                         {
1456                             if (!isEqual(buf, white, tolerance))
1457                                 TCU_FAIL("verifyMirroredRepeat failed");
1458 
1459                             buf += size;
1460                         }
1461                         for (i = 0; i < blue_w; i++)
1462                         {
1463                             if (!isEqual(buf, blue, tolerance))
1464                                 TCU_FAIL("verifyMirroredRepeat failed");
1465 
1466                             buf += size;
1467                         }
1468                     }
1469                     else
1470                     {
1471                         for (i = 0; i < blue_w; i++)
1472                         {
1473                             if (!isEqual(buf, blue, tolerance))
1474                                 TCU_FAIL("verifyMirroredRepeat failed");
1475 
1476                             buf += size;
1477                         }
1478                         for (i = 0; i < white_w; i++)
1479                         {
1480                             if (!isEqual(buf, white, tolerance))
1481                                 TCU_FAIL("verifyMirroredRepeat failed");
1482 
1483                             buf += size;
1484                         }
1485                     }
1486                 }
1487             }
1488         }
1489     }
1490 
1491     m_context.getTestContext().getLog() << tcu::TestLog::Message << " verifyMirroredRepeat succeeded."
1492                                         << tcu::TestLog::EndMessage;
1493     return true;
1494 }
1495 
verifyClampMode(GLubyte * buf,GLsizei width,GLsizei height,GLenum clampMode,GLenum internalformat) const1496 bool TestClampModeForInternalFormat::verifyClampMode(GLubyte *buf, GLsizei width, GLsizei height, GLenum clampMode,
1497                                                      GLenum internalformat) const
1498 {
1499     switch (clampMode)
1500     {
1501     case GL_CLAMP_TO_EDGE:
1502         return verifyClampToEdge(buf, width, height, width, height, internalformat);
1503     case GL_REPEAT:
1504         return verifyRepeat(buf, width, height, internalformat);
1505     case GL_MIRRORED_REPEAT:
1506         return verifyMirroredRepeat(buf, width, height, internalformat);
1507     }
1508     return false;
1509 }
1510 
1511 /** Execute test
1512  *
1513  * Upload the texture, set up a quad 3 times the size of the
1514  * texture. Coordinates should be integers to avoid spatial rounding
1515  * differences. Set texture coordinates as shown below.
1516  *
1517  * (-1,  2, 0) --- (2,  2, 0)
1518  * |                        |
1519  * |                        |
1520  * (-1, -1, 0) --- (2, -1, 0)
1521  *
1522  * Set TEXTURE_MIN_FILTER for the texture to NEAREST_MIPMAP_NEAREST.
1523  *
1524  * Repeat the test for each repeat mode, i.e., set the repeat mode to
1525  * one of CLAMP_TO_EDGE, REPEAT, and MIRRORED_REPEAT for both S and
1526  * T, depending on the iteration.
1527  *
1528  * For vertex shader, just pass on the vertices and texture
1529  * coordinates for interpolation. For fragment shader, look up the
1530  * fragment corresponding to given texture coordinates.
1531  *
1532  * Render the quad.
1533  *
1534  * Read back the pixels covering the quad.
1535  *
1536  * For CLAMP_TO_EDGE result should be (Each character has dimension
1537  * half the original texture, original texture in capitals):
1538  *
1539  * rrrggg
1540  * rrrggg
1541  * rrRGgg
1542  * bbBWww
1543  * bbbwww
1544  * bbbwww
1545  *
1546  * For REPEAT:
1547  *
1548  * rgrgrg
1549  * bwbwbw
1550  * rgRGrg
1551  * bwBWbw
1552  * rgrgrg
1553  * bwbwbw
1554  *
1555  * For MIRRORED_REPEAT
1556  *
1557  * wbbwwb
1558  * grrggr
1559  * grRGgr
1560  * wbBWwb
1561  * wbbwwb
1562  * grrggr
1563  *
1564  * If implementation under test is for OpenGL 3.2 Core specification,
1565  * the test includes repeat mode of CLAMP_TO_BORDER. For this case,
1566  * the TEXTURE_BORDER_COLOR is set to black (0, 0, 0, 1) (RGBA). Then
1567  * the result will be (0 meaning black):
1568  *
1569  * 000000
1570  * 000000
1571  * 00RG00
1572  * 00BW00
1573  * 000000
1574  * 000000
1575  *
1576  * Procedure:
1577  * - allocate large enough memory buffer for the texture data - tex_width * tex_height * tex_depth * MAX_PIXEL_SIZE
1578  * - fill the buffer with the pattern
1579  * - upload the texture with glTexImage2D() to the requested level
1580  * - upload black texture to other LOD levels
1581  * - render a quad with size matching the texture LOD level
1582  * - read back pixels
1583  * - verify the results
1584  * - free the buffer
1585  **/
iterate(void)1586 tcu::TestNode::IterateResult TestClampModeForInternalFormat::iterate(void)
1587 {
1588     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
1589     m_context.getTestContext().setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1590 
1591     /* Retrieve properties of the tested format */
1592     const InternalFormat &internalFormatStruct = findInternalFormat(m_internalFormat);
1593     GLenum format                              = internalFormatStruct.format;
1594     GLenum type                                = internalFormatStruct.type;
1595     GLenum internalformat                      = internalFormatStruct.sizedFormat;
1596     GLenum sampler                             = internalFormatStruct.sampler;
1597     GLsizei viewWidth                          = 3 * m_width;
1598     GLsizei viewHeight                         = 3 * m_height;
1599 
1600     /* Allocate buffers for texture data */
1601     GLsizei resultTextureSize = viewWidth * viewHeight;
1602     std::vector<GLubyte> textureData(resultTextureSize * MAX_PIXEL_SIZE, 0);
1603     std::fill(textureData.begin(), textureData.end(), 0);
1604 
1605     /* Set pixel storage modes */
1606     gl.pixelStorei(GL_UNPACK_ALIGNMENT, 1);
1607     gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
1608 
1609     /* Generate and bind the texture object that will store test result*/
1610     GLuint resultTextureId;
1611     gl.genTextures(1, &resultTextureId);
1612     gl.bindTexture(GL_TEXTURE_2D, resultTextureId);
1613     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1614     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1615     gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, viewWidth, viewHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, &textureData[0]);
1616 
1617     /* Reuse textureData buffer to initialize source texture.
1618      * Fill the buffer according to the color scheme */
1619     fillTextureWithColor(&textureData[0], m_width, m_height, internalformat);
1620 
1621     /* Generate and bind the texture object that will store color scheme*/
1622     GLuint sourceTextureId;
1623     gl.genTextures(1, &sourceTextureId);
1624     gl.bindTexture(GL_TEXTURE_2D, sourceTextureId);
1625     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1626     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1627     gl.texImage2D(GL_TEXTURE_2D, m_lodLevel, internalformat, m_width, m_height, 0, format, type, &textureData[0]);
1628 
1629     /* Set compare function used by shadow samplers */
1630     if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format))
1631     {
1632         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1633         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GEQUAL);
1634     }
1635 
1636     /* Clear the other source texture levels with black */
1637     clearTextures(GL_TEXTURE_2D, m_width, m_height, m_lodLevel, internalformat, type, format);
1638 
1639     /* Create and bind the FBO */
1640     GLuint fbId;
1641     gl.genFramebuffers(1, &fbId);
1642     gl.bindFramebuffer(GL_FRAMEBUFFER, fbId);
1643     gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resultTextureId, 0);
1644 
1645     /* Construct shaders */
1646     glu::ContextType contextType = m_context.getRenderContext().getType();
1647     glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(contextType);
1648     std::string version          = glu::getGLSLVersionDeclaration(glslVersion) + std::string("\n");
1649     std::string vs               = version + basic_vs;
1650     std::string fs               = version;
1651     if ((GL_DEPTH_COMPONENT == format) || (GL_DEPTH_STENCIL == format))
1652         fs += shadow_fs;
1653     else if ((SAMPLER_UINT == sampler) || (SAMPLER_INT == sampler))
1654         fs += integer_fs;
1655     else
1656         fs += basic_fs;
1657     glu::ProgramSources sources = glu::makeVtxFragSources(vs, fs);
1658 
1659     /* Create program object */
1660     glu::ShaderProgram program(m_context.getRenderContext(), sources);
1661     if (!program.isOk())
1662         TCU_FAIL("Compile failed");
1663     GLint programId       = program.getProgram();
1664     GLint samplerLocation = gl.getUniformLocation(programId, "texture0");
1665     if (-1 == samplerLocation)
1666         TCU_FAIL("Fragment shader does not have texture0 input.");
1667     gl.useProgram(programId);
1668     gl.uniform1i(samplerLocation, 0);
1669 
1670     m_context.getTestContext().getLog() << tcu::TestLog::Message << "NPOT [" << m_internalFormat << "] (" << viewWidth
1671                                         << " x " << viewHeight << "), Level: " << m_lodLevel
1672                                         << tcu::TestLog::EndMessage;
1673 
1674     /* Set the wrap parameters for texture coordinates s and t to the current clamp mode */
1675     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_clampMode);
1676     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_clampMode);
1677 
1678     /* Set viewport's width and height based on an overview */
1679     gl.viewport(0, 0, viewWidth, viewHeight);
1680 
1681     /* Draw rectangle */
1682     GLuint vaoId;
1683     gl.genVertexArrays(1, &vaoId);
1684     gl.bindVertexArray(vaoId);
1685     gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
1686     gl.bindVertexArray(0);
1687     gl.deleteVertexArrays(1, &vaoId);
1688 
1689     /* Read back pixels and verify that they have the proper values */
1690     std::vector<GLubyte> buffer(resultTextureSize * 4, 0);
1691     gl.readPixels(0, 0, viewWidth, viewHeight, GL_RGBA, GL_UNSIGNED_BYTE, (void *)&(buffer[0]));
1692     if (verifyClampMode(&buffer[0], viewWidth, viewHeight, m_clampMode, internalformat))
1693         m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1694 
1695     /* Cleanup */
1696     gl.bindTexture(GL_TEXTURE_2D, 0);
1697     gl.deleteTextures(1, &resultTextureId);
1698     gl.deleteTextures(1, &sourceTextureId);
1699     gl.bindFramebuffer(GL_FRAMEBUFFER, fbId);
1700     gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1701     gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1702     gl.deleteFramebuffers(1, &fbId);
1703 
1704     return STOP;
1705 }
1706 
1707 /** Constructor.
1708  *
1709  *  @param context Rendering context.
1710  */
TextureRepeatModeTests(deqp::Context & context)1711 TextureRepeatModeTests::TextureRepeatModeTests(deqp::Context &context)
1712     : TestCaseGroup(context, "texture_repeat_mode", "Texture repeat mode tests")
1713 {
1714 }
1715 
1716 /** Initializes the test group contents. */
init()1717 void TextureRepeatModeTests::init()
1718 {
1719     /* Texture sizes to test */
1720     const struct TexSize
1721     {
1722         GLsizei width;
1723         GLsizei height;
1724     } textureSizes[] = {
1725         {49, 23},
1726         {11, 131},
1727     };
1728 
1729     /* LOD levels to test */
1730     const GLint levelsOfDetail[] = {0, 1, 2};
1731 
1732     for (GLint sizeIndex = 0; sizeIndex < DE_LENGTH_OF_ARRAY(textureSizes); sizeIndex++)
1733     {
1734         const TexSize &ts = textureSizes[sizeIndex];
1735         for (GLint formatIndex = 0; formatIndex < DE_LENGTH_OF_ARRAY(testedFormats); formatIndex++)
1736         {
1737             const FormatInfo &formatInfo = testedFormats[formatIndex];
1738             GLenum internalFormat        = formatInfo.internalformat;
1739             for (GLsizei lodIndex = 0; lodIndex < DE_LENGTH_OF_ARRAY(levelsOfDetail); lodIndex++)
1740             {
1741                 GLint lod = levelsOfDetail[lodIndex];
1742                 std::stringstream testBaseName;
1743                 testBaseName << formatInfo.name << "_" << ts.width << "x" << ts.height << "_" << lod << "_";
1744                 std::string names[] = {testBaseName.str() + "clamp_to_edge", testBaseName.str() + "repeat",
1745                                        testBaseName.str() + "mirrored_repeat"};
1746                 addChild(new TestClampModeForInternalFormat(m_context, names[0], internalFormat, GL_CLAMP_TO_EDGE, lod,
1747                                                             ts.width, ts.height));
1748                 addChild(new TestClampModeForInternalFormat(m_context, names[1], internalFormat, GL_REPEAT, lod,
1749                                                             ts.width, ts.height));
1750                 addChild(new TestClampModeForInternalFormat(m_context, names[2], internalFormat, GL_MIRRORED_REPEAT,
1751                                                             lod, ts.width, ts.height));
1752             }
1753         }
1754     }
1755 }
1756 } // namespace glcts
1757