08119f95806d411ededf8aa2bc1e5d0b903fe51e
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / common / glcPackedPixelsTests.cpp
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 glcPackedPixelsTests.cpp
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23
24 #include "glcPackedPixelsTests.hpp"
25 #include "deMath.h"
26 #include "glcMisc.hpp"
27 #include "gluContextInfo.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 #include <algorithm>
35 #include <cstring>
36 #include <limits>
37 #include <map>
38 #include <stdio.h>
39
40 using namespace glw;
41 using namespace glu;
42
43 namespace glcts
44 {
45
46 enum
47 {
48         GRADIENT_WIDTH  = 7,
49         GRADIENT_HEIGHT = 3
50 };
51
52 enum InputOutputOperation
53 {
54         OUTPUT_GETTEXIMAGE,
55         OUTPUT_READPIXELS,
56         INPUT_TEXIMAGE,
57 };
58
59 enum ComponentFormat
60 {
61         FORMAT_STENCIL,           // stencil, unsigned int
62         FORMAT_DEPTH,             // depth, unsigned [fp|float]
63         FORMAT_DEPTH_STENCIL, // depth+stencil, unsigned [fp|float]
64         FORMAT_COLOR,             // color, [signed|unsigned] fp
65         FORMAT_COLOR_INTEGER, // color, [signed|unsigned] int
66 };
67
68 enum TypeStorage
69 {
70         STORAGE_UNSIGNED, // unsigned fp/int
71         STORAGE_SIGNED,   // signed fp/int
72         STORAGE_FLOAT,  // signed/unsigned float
73 };
74
75 union InternalFormatBits {
76         struct Bits
77         {
78                 int red;           // red bits
79                 int green;       // green bits
80                 int blue;         // blue bits
81                 int alpha;       // alpha bits
82                 int intensity; // intensity bits
83                 int luminance; // luminance bits
84                 int depth;       // depth bits
85                 int stencil;   // stencil bits
86                 int exponent;  // shared exponent bits
87         } bits;
88         int array[9]; // all the bits
89 };
90
91 struct PixelType
92 {
93         GLenum                     type;
94         int                                size;
95         int                                storage;
96         bool                       special;
97         bool                       reversed;
98         InternalFormatBits bits;
99         bool                       clamp;
100 };
101
102 struct PixelFormat
103 {
104         GLenum                     format;                      // format name
105         int                                components;          // number of components
106         int                                componentFormat; // element meaning
107         GLenum                     attachment;          // target buffer
108         InternalFormatBits componentOrder;  // zero based element order, -1 for N/A
109 };
110
111 enum InternalFormatSamplerType
112 {
113         SAMPLER_UNORM = 0, // unsigned normalized
114         SAMPLER_NORM,     // normalized
115         SAMPLER_UINT,     // unsigned integer
116         SAMPLER_INT,       // integer
117         SAMPLER_FLOAT     // floating-point
118 };
119
120 enum InternalFormatFlag
121 {
122         FLAG_PACKED               = 1,                                                                     // packed pixel format
123         FLAG_COMPRESSED   = 2,                                                                     // compressed format
124         FLAG_REQ_RBO_GL42 = 4,                                                                     // required RBO & tex format in OpenGL 4.2
125         FLAG_REQ_RBO_ES30 = 8,                                                                     // required RBO & tex format in OpenGL ES 3.0
126         FLAG_REQ_RBO      = FLAG_REQ_RBO_GL42 | FLAG_REQ_RBO_ES30, // Required RBO & tex format in both
127 };
128
129 struct InternalFormat
130 {
131         GLenum                                    sizedFormat;
132         GLenum                                    baseFormat;
133         GLenum                                    format;
134         GLenum                                    type;
135         InternalFormatSamplerType sampler;
136         InternalFormatBits                bits;
137         int                                               flags; // InternalFormatFlag
138 };
139
140 struct EnumFormats
141 {
142         GLenum internalformat;
143         GLenum format;
144         GLenum type;
145         int     size;
146         bool   bRenderable;
147 };
148
149 #define PACK_DEFAULTI (0)
150 #define PACK_DEFAULTUI (0)
151 #define PACK_DEFAULTF (-2.0f)
152
153 static const InternalFormat coreInternalformats[] =
154 {
155         { GL_DEPTH_COMPONENT,                     GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, 0 },
156         { GL_DEPTH_STENCIL,                               GL_DEPTH_STENCIL,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT,                                       SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, 0 },
157         { GL_RED,                                                 GL_RED,                         GL_RED,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
158         { GL_RG,                                                  GL_RG,                          GL_RG,                          GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
159         { GL_R8,                                                  GL_RED,                         GL_RED,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
160         { GL_R8_SNORM,                                    GL_RED,                         GL_RED,                         GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
161         { GL_R16,                                                 GL_RED,                         GL_RED,                         GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
162         { GL_R16_SNORM,                                   GL_RED,                         GL_RED,                         GL_SHORT,                                                      SAMPLER_NORM,   { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
163         { GL_RG8,                                                 GL_RG,                          GL_RG,                          GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
164         { GL_RG8_SNORM,                                   GL_RG,                          GL_RG,                          GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
165         { GL_RG16,                                                GL_RG,                          GL_RG,                          GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
166         { GL_RG16_SNORM,                                  GL_RG,                          GL_RG,                          GL_SHORT,                                                      SAMPLER_NORM,   { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
167         { GL_R3_G3_B2,                                    GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE_3_3_2,                        SAMPLER_UNORM,  { { 3, 3, 2, 0, 0, 0, 0, 0, 0 } }, FLAG_PACKED },
168         { GL_RGB4,                                                GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 4, 4, 4, 0, 0, 0, 0, 0, 0 } }, 0 },
169         { GL_RGB5,                                                GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 5, 5, 5, 0, 0, 0, 0, 0, 0 } }, 0 },
170         { GL_RGB8,                                                GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_ES30 },
171         { GL_RGB8_SNORM,                                  GL_RGB,                         GL_RGB,                         GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
172         { GL_RGB10,                                               GL_RGB,                         GL_RGB,                         GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {10,10,10, 0, 0, 0, 0, 0, 0 } }, 0 },
173         { GL_RGB12,                                               GL_RGB,                         GL_RGB,                         GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {12,12,12, 0, 0, 0, 0, 0, 0 } }, 0 },
174         { GL_RGB16,                                               GL_RGB,                         GL_RGB,                         GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
175         { GL_RGB16_SNORM,                                 GL_RGB,                         GL_RGB,                         GL_SHORT,                                                      SAMPLER_NORM,   { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
176         { GL_RGBA2,                                               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 2, 2, 2, 2, 0, 0, 0, 0, 0 } }, 0 },
177         { GL_RGBA4,                                               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4,             SAMPLER_UNORM,  { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
178         { GL_RGB5_A1,                                     GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1,             SAMPLER_UNORM,  { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
179         { GL_RGBA8,                                               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
180         { GL_RGBA8_SNORM,                                 GL_RGBA,                        GL_RGBA,                        GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 0 },
181         { GL_RGB10_A2,                                    GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_INT_10_10_10_2,            SAMPLER_UNORM,  { {10,10,10, 2, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 },
182         { GL_RGB10_A2UI,                                  GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_INT_10_10_10_2,            SAMPLER_UINT,   { {10,10,10, 2, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 },
183         { GL_RGBA12,                                      GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {12,12,12,12, 0, 0, 0, 0, 0 } }, 0 },
184         { GL_RGBA16,                                      GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
185         { GL_RGBA16_SNORM,                                GL_RGBA,                        GL_RGBA,                        GL_SHORT,                                                      SAMPLER_NORM,   { {16,16,16,16, 0, 0, 0, 0, 0 } }, 0 },
186         { GL_SRGB8,                                               GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
187         { GL_SRGB8_ALPHA8,                                GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
188         { GL_R16F,                                                GL_RED,                         GL_RED,                         GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
189         { GL_RG16F,                                               GL_RG,                          GL_RG,                          GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
190         { GL_RGB16F,                                      GL_RGB,                         GL_RGB,                         GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
191         { GL_RGBA16F,                                     GL_RGBA,                        GL_RGBA,                        GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
192         { GL_R32F,                                                GL_RED,                         GL_RED,                         GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
193         { GL_RG32F,                                               GL_RG,                          GL_RG,                          GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
194         { GL_RGB32F,                                      GL_RGB,                         GL_RGB,                         GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
195         { GL_RGBA32F,                                     GL_RGBA,                        GL_RGBA,                        GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
196         { GL_R11F_G11F_B10F,                      GL_RGB,                         GL_RGB,                         GL_UNSIGNED_INT_10F_11F_11F_REV,       SAMPLER_FLOAT,  { {11,11,10, 0, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 },
197         { 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 },
198         { GL_R8I,                                                 GL_RED,                         GL_RED_INTEGER,         GL_BYTE,                                                       SAMPLER_INT,    { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
199         { GL_R8UI,                                                GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
200         { GL_R16I,                                                GL_RED,                         GL_RED_INTEGER,         GL_SHORT,                                                      SAMPLER_INT,    { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
201         { GL_R16UI,                                               GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_SHORT,                             SAMPLER_UINT,   { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
202         { GL_R32I,                                                GL_RED,                         GL_RED_INTEGER,         GL_INT,                                                        SAMPLER_INT,    { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
203         { GL_R32UI,                                               GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
204         { GL_RG8I,                                                GL_RG,                          GL_RG_INTEGER,          GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
205         { GL_RG8UI,                                               GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
206         { GL_RG16I,                                               GL_RG,                          GL_RG_INTEGER,          GL_SHORT,                                                      SAMPLER_INT,    { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
207         { GL_RG16UI,                                      GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_SHORT,                             SAMPLER_UINT,   { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
208         { GL_RG32I,                                               GL_RG,                          GL_RG_INTEGER,          GL_INT,                                                        SAMPLER_INT,    { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
209         { GL_RG32UI,                                      GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
210         { GL_RGB8I,                                               GL_RGB,                         GL_RGB_INTEGER,         GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
211         { GL_RGB8UI,                                      GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
212         { GL_RGB16I,                                      GL_RGB,                         GL_RGB_INTEGER,         GL_SHORT,                                                      SAMPLER_INT,    { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
213         { GL_RGB16UI,                                     GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_SHORT,                             SAMPLER_UINT,   { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
214         { GL_RGB32I,                                      GL_RGB,                         GL_RGB_INTEGER,         GL_INT,                                                        SAMPLER_INT,    { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
215         { GL_RGB32UI,                                     GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
216         { GL_RGBA8I,                                      GL_RGBA,                        GL_RGBA_INTEGER,        GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
217         { GL_RGBA8UI,                                     GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
218         { GL_RGBA16I,                                     GL_RGBA,                        GL_RGBA_INTEGER,        GL_SHORT,                                                      SAMPLER_INT,    { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
219         { GL_RGBA16UI,                                    GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_SHORT,                             SAMPLER_UINT,   { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
220         { GL_RGBA32I,                                     GL_RGBA,                        GL_RGBA_INTEGER,        GL_INT,                                                        SAMPLER_INT,    { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
221         { GL_RGBA32UI,                                    GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
222         { GL_DEPTH_COMPONENT16,                   GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                             SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, FLAG_REQ_RBO },
223         { GL_DEPTH_COMPONENT24,                   GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                                       SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,24, 0, 0 } }, FLAG_REQ_RBO },
224         { GL_DEPTH_COMPONENT32,                   GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                                       SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,32, 0, 0 } }, 0 },
225         { GL_DEPTH_COMPONENT32F,                  GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT,                                                      SAMPLER_FLOAT,  { { 0, 0, 0, 0, 0, 0,32, 0, 0 } }, FLAG_REQ_RBO },
226         { GL_DEPTH24_STENCIL8,                    GL_DEPTH_STENCIL,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,                          SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, FLAG_REQ_RBO },
227         { GL_DEPTH32F_STENCIL8,                   GL_DEPTH_STENCIL,   GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, SAMPLER_FLOAT,  { { 0, 0, 0, 0, 0, 0,32, 8, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
228         { GL_COMPRESSED_RED,                      GL_RED,                         GL_RED,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
229         { GL_COMPRESSED_RG,                               GL_RG,                          GL_RG,                          GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
230         { GL_COMPRESSED_RGB,                      GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
231         { GL_COMPRESSED_RGBA,                     GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
232         { GL_COMPRESSED_SRGB,                     GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
233         { GL_COMPRESSED_SRGB_ALPHA,               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
234         { GL_COMPRESSED_RED_RGTC1,                GL_RED,                         GL_RED,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
235         { GL_COMPRESSED_SIGNED_RED_RGTC1, GL_RED,                         GL_RED,                         GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
236         { GL_COMPRESSED_RG_RGTC2,                 GL_RG,                          GL_RG,                          GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
237         { GL_COMPRESSED_SIGNED_RG_RGTC2,  GL_RG,                          GL_RG,                          GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_COMPRESSED },
238 };
239
240 static InternalFormat esInternalformats[] =
241 {
242         { GL_LUMINANCE,                  GL_LUMINANCE,           GL_LUMINANCE,           GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 8, 0, 0, 0 } }, 0 },
243         { GL_ALPHA,                              GL_ALPHA,                       GL_ALPHA,                       GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 0, 0, 0, 8, 0, 0, 0, 0, 0 } }, 0 },
244         { GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 0, 0, 0, 8, 0, 8, 0, 0, 0 } }, 0 },
245         { GL_RGB,                                GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
246         { GL_RGBA,                               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 0 },
247         { GL_R8,                                 GL_RED,                         GL_RED,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
248         { GL_R8_SNORM,                   GL_RED,                         GL_RED,                         GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
249         { GL_RG8,                                GL_RG,                          GL_RG,                          GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
250         { GL_RG8_SNORM,                  GL_RG,                          GL_RG,                          GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, 0 },
251         { GL_RGB8,                               GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_ES30 },
252         { GL_RGB8_SNORM,                 GL_RGB,                         GL_RGB,                         GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
253         { GL_RGB565,                     GL_RGB,                         GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5,                       SAMPLER_UNORM,  { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
254         { GL_RGBA4,                              GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4,                     SAMPLER_UNORM,  { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
255         { GL_RGB5_A1,                    GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1,                     SAMPLER_UNORM,  { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
256         { GL_RGBA8,                              GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
257         { GL_RGBA8_SNORM,                GL_RGBA,                        GL_RGBA,                        GL_BYTE,                                                       SAMPLER_NORM,   { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, 0 },
258         { GL_RGB10_A2,                   GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_INT_2_10_10_10_REV,        SAMPLER_UNORM,  { {10,10,10, 2, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_ES30 },
259         { GL_RGB10_A2UI,                 GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_INT_2_10_10_10_REV,        SAMPLER_UINT,   { {10,10,10, 2, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_ES30 },
260         { GL_SRGB8,                              GL_RGB,                         GL_RGB,                         GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
261         { GL_SRGB8_ALPHA8,               GL_RGBA,                        GL_RGBA,                        GL_UNSIGNED_BYTE,                                      SAMPLER_UNORM,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
262         { GL_R16F,                               GL_RED,                         GL_RED,                         GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
263         { GL_RG16F,                              GL_RG,                          GL_RG,                          GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
264         { GL_RGB16F,                     GL_RGB,                         GL_RGB,                         GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
265         { GL_RGBA16F,                    GL_RGBA,                        GL_RGBA,                        GL_HALF_FLOAT,                                         SAMPLER_FLOAT,  { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
266         { GL_R32F,                               GL_RED,                         GL_RED,                         GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
267         { GL_RG32F,                              GL_RG,                          GL_RG,                          GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
268         { GL_RGB32F,                     GL_RGB,                         GL_RGB,                         GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
269         { GL_RGBA32F,                    GL_RGBA,                        GL_RGBA,                        GL_FLOAT,                                                      SAMPLER_FLOAT,  { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO_GL42 },
270         { GL_R11F_G11F_B10F,     GL_RGB,                         GL_RGB,                         GL_UNSIGNED_INT_10F_11F_11F_REV,       SAMPLER_FLOAT,  { {11,11,10, 0, 0, 0, 0, 0, 0 } }, FLAG_PACKED|FLAG_REQ_RBO_GL42 },
271         { 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 },
272         { GL_R8I,                                GL_RED,                         GL_RED_INTEGER,         GL_BYTE,                                                       SAMPLER_INT,    { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
273         { GL_R8UI,                               GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
274         { GL_R16I,                               GL_RED,                         GL_RED_INTEGER,         GL_SHORT,                                                      SAMPLER_INT,    { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
275         { GL_R16UI,                              GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_SHORT,                                     SAMPLER_UINT,   { {16, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
276         { GL_R32I,                               GL_RED,                         GL_RED_INTEGER,         GL_INT,                                                        SAMPLER_INT,    { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
277         { GL_R32UI,                              GL_RED,                         GL_RED_INTEGER,         GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32, 0, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
278         { GL_RG8I,                               GL_RG,                          GL_RG_INTEGER,          GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
279         { GL_RG8UI,                              GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
280         { GL_RG16I,                              GL_RG,                          GL_RG_INTEGER,          GL_SHORT,                                                      SAMPLER_INT,    { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
281         { GL_RG16UI,                     GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_SHORT,                                     SAMPLER_UINT,   { {16,16, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
282         { GL_RG32I,                              GL_RG,                          GL_RG_INTEGER,          GL_INT,                                                        SAMPLER_INT,    { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
283         { GL_RG32UI,                     GL_RG,                          GL_RG_INTEGER,          GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32, 0, 0, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
284         { GL_RGB8I,                              GL_RGB,                         GL_RGB_INTEGER,         GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
285         { GL_RGB8UI,                     GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 8, 0, 0, 0, 0, 0, 0 } }, 0 },
286         { GL_RGB16I,                     GL_RGB,                         GL_RGB_INTEGER,         GL_SHORT,                                                      SAMPLER_INT,    { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
287         { GL_RGB16UI,                    GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_SHORT,                                     SAMPLER_UINT,   { {16,16,16, 0, 0, 0, 0, 0, 0 } }, 0 },
288         { GL_RGB32I,                     GL_RGB,                         GL_RGB_INTEGER,         GL_INT,                                                        SAMPLER_INT,    { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
289         { GL_RGB32UI,                    GL_RGB,                         GL_RGB_INTEGER,         GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32,32, 0, 0, 0, 0, 0, 0 } }, 0 },
290         { GL_RGBA8I,                     GL_RGBA,                        GL_RGBA_INTEGER,        GL_BYTE,                                                       SAMPLER_INT,    { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
291         { GL_RGBA8UI,                    GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_BYTE,                                      SAMPLER_UINT,   { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
292         { GL_RGBA16I,                    GL_RGBA,                        GL_RGBA_INTEGER,        GL_SHORT,                                                      SAMPLER_INT,    { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
293         { GL_RGBA16UI,                   GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_SHORT,                                     SAMPLER_UINT,   { {16,16,16,16, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
294         { GL_RGBA32I,                    GL_RGBA,                        GL_RGBA_INTEGER,        GL_INT,                                                        SAMPLER_INT,    { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
295         { GL_RGBA32UI,                   GL_RGBA,                        GL_RGBA_INTEGER,        GL_UNSIGNED_INT,                                       SAMPLER_UINT,   { {32,32,32,32, 0, 0, 0, 0, 0 } }, FLAG_REQ_RBO },
296         { GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                                     SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,16, 0, 0 } }, FLAG_REQ_RBO },
297         { GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                                       SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,24, 0, 0 } }, FLAG_REQ_RBO },
298         { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_FLOAT,                                                      SAMPLER_FLOAT,  { { 0, 0, 0, 0, 0, 0,32, 0, 0 } }, FLAG_REQ_RBO },
299         { GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,   GL_DEPTH_STENCIL,   GL_UNSIGNED_INT_24_8,                          SAMPLER_UNORM,  { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, FLAG_REQ_RBO },
300         { GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,   GL_DEPTH_STENCIL,   GL_FLOAT_32_UNSIGNED_INT_24_8_REV, SAMPLER_FLOAT,  { { 0, 0, 0, 0, 0, 0,32, 8, 0 } }, FLAG_PACKED|FLAG_REQ_RBO },
301 };
302
303 static const PixelFormat coreFormats[] = {
304         { GL_STENCIL_INDEX,   1, FORMAT_STENCIL,           GL_STENCIL_ATTACHMENT,               { {-1,-1,-1,-1,-1,-1,-1, 0,-1} } },
305         { GL_DEPTH_COMPONENT, 1, FORMAT_DEPTH,             GL_DEPTH_ATTACHMENT,                 { {-1,-1,-1,-1,-1,-1, 0,-1,-1} } },
306         { GL_DEPTH_STENCIL,   2, FORMAT_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0, 1,-1} } },
307         { GL_RED,                         1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } },
308         { GL_GREEN,                       1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { {-1, 0,-1,-1,-1,-1,-1,-1,-1} } },
309         { GL_BLUE,                        1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { {-1,-1, 0,-1,-1,-1,-1,-1,-1} } },
310         { GL_RG,                          2, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } },
311         { GL_RGB,                         3, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } },
312         { GL_RGBA,                        4, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } },
313         { GL_BGR,                         3, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 2, 1, 0,-1,-1,-1,-1,-1,-1} } },
314         { GL_BGRA,                        4, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 2, 1, 0, 3,-1,-1,-1,-1,-1} } },
315         { GL_RED_INTEGER,         1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } },
316         { GL_GREEN_INTEGER,   1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,            { {-1, 0,-1,-1,-1,-1,-1,-1,-1} } },
317         { GL_BLUE_INTEGER,        1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { {-1,-1, 0,-1,-1,-1,-1,-1,-1} } },
318         { GL_RG_INTEGER,          2, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } },
319         { GL_RGB_INTEGER,         3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } },
320         { GL_RGBA_INTEGER,        4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } },
321         { GL_BGR_INTEGER,         3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 2, 1, 0,-1,-1,-1,-1,-1,-1} } },
322         { GL_BGRA_INTEGER,        4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 2, 1, 0, 3,-1,-1,-1,-1,-1} } },
323 };
324
325 static const PixelFormat esFormats[] = {
326         { GL_DEPTH_COMPONENT, 1, FORMAT_DEPTH,             GL_DEPTH_ATTACHMENT,                 { {-1,-1,-1,-1,-1,-1, 0,-1,-1} } },
327         { GL_DEPTH_STENCIL,   2, FORMAT_DEPTH_STENCIL, GL_DEPTH_STENCIL_ATTACHMENT, { {-1,-1,-1,-1,-1,-1, 0, 1,-1} } },
328         { GL_RED,                         1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } },
329         { GL_RG,                          2, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } },
330         { GL_RGB,                         3, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } },
331         { GL_RGBA,                        4, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } },
332         { GL_LUMINANCE,           1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { {-1,-1,-1,-1,-1, 0,-1,-1,-1} } },
333         { GL_ALPHA,                       1, FORMAT_COLOR,                 GL_COLOR_ATTACHMENT0,                { {-1,-1,-1, 0,-1,-1,-1,-1,-1} } },
334         { GL_LUMINANCE_ALPHA, 2, FORMAT_COLOR,             GL_COLOR_ATTACHMENT0,                { {-1,-1,-1, 1,-1, 0,-1,-1,-1} } },
335         { GL_RED_INTEGER,         1, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0,-1,-1,-1,-1,-1,-1,-1,-1} } },
336         { GL_RG_INTEGER,          2, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1,-1,-1,-1,-1,-1,-1,-1} } },
337         { GL_RGB_INTEGER,         3, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1, 2,-1,-1,-1,-1,-1,-1} } },
338         { GL_RGBA_INTEGER,        4, FORMAT_COLOR_INTEGER, GL_COLOR_ATTACHMENT0,                { { 0, 1, 2, 3,-1,-1,-1,-1,-1} } },
339 };
340
341 static const PixelType coreTypes[] = {
342         { GL_UNSIGNED_BYTE,                                      sizeof(GLubyte),                                STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
343         { GL_BYTE,                                                       sizeof(GLbyte),                                 STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
344         { GL_UNSIGNED_SHORT,                             sizeof(GLushort),                               STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
345         { GL_SHORT,                                                      sizeof(GLshort),                                STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
346         { GL_UNSIGNED_INT,                                       sizeof(GLuint),                                 STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
347         { GL_INT,                                                        sizeof(GLint),                                  STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
348         { GL_HALF_FLOAT,                                         sizeof(GLhalf),                                 STORAGE_FLOAT,    false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
349         { GL_FLOAT,                                                      sizeof(GLfloat),                                STORAGE_FLOAT,    false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
350         { GL_UNSIGNED_SHORT_5_6_5,                       sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false },
351         { GL_UNSIGNED_SHORT_4_4_4_4,             sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false },
352         { GL_UNSIGNED_SHORT_5_5_5_1,             sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false },
353         { GL_UNSIGNED_INT_2_10_10_10_REV,        sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  true,  { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false },
354         { GL_UNSIGNED_INT_24_8,                          sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  false, { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, false },
355         { GL_UNSIGNED_INT_10F_11F_11F_REV,       sizeof(GLuint),                                 STORAGE_FLOAT,    true,  true,  { { 6, 7, 7, 0, 0, 0, 0, 0, 0 } }, false },
356         { GL_UNSIGNED_INT_5_9_9_9_REV,           sizeof(GLuint),                                 STORAGE_FLOAT,    true,  true,  { { 9, 9, 9, 5, 0, 0, 0, 0, 0 } }, false },
357         { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, sizeof(GLfloat)+sizeof(GLuint), STORAGE_FLOAT,        true,  true,  { { 0, 0, 0, 0, 0, 0,32, 8,24 } }, false },
358         { GL_UNSIGNED_BYTE_3_3_2,                        sizeof(GLubyte),                                STORAGE_UNSIGNED, true,  false, { { 3, 3, 2, 0, 0, 0, 0, 0, 0 } }, false },
359         { GL_UNSIGNED_BYTE_2_3_3_REV,            sizeof(GLubyte),                                STORAGE_UNSIGNED, true,  true,  { { 3, 3, 2, 0, 0, 0, 0, 0, 0 } }, false },
360         { GL_UNSIGNED_SHORT_5_6_5_REV,           sizeof(GLushort),                               STORAGE_UNSIGNED, true,  true,  { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false },
361         { GL_UNSIGNED_SHORT_4_4_4_4_REV,         sizeof(GLushort),                               STORAGE_UNSIGNED, true,  true,  { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false },
362         { GL_UNSIGNED_SHORT_1_5_5_5_REV,         sizeof(GLushort),                               STORAGE_UNSIGNED, true,  true,  { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false },
363         { GL_UNSIGNED_INT_8_8_8_8,                       sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  false, { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, false },
364         { GL_UNSIGNED_INT_8_8_8_8_REV,           sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  true,  { { 8, 8, 8, 8, 0, 0, 0, 0, 0 } }, false },
365         { GL_UNSIGNED_INT_10_10_10_2,            sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  true,  { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false },
366 };
367
368 static const PixelType esTypes[] = {
369         { GL_UNSIGNED_BYTE,                                      sizeof(GLubyte),                                STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
370         { GL_BYTE,                                                       sizeof(GLbyte),                                 STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
371         { GL_UNSIGNED_SHORT,                             sizeof(GLushort),                               STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
372         { GL_SHORT,                                                      sizeof(GLshort),                                STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, true },
373         { GL_UNSIGNED_INT,                                       sizeof(GLuint),                                 STORAGE_UNSIGNED, false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
374         { GL_INT,                                                        sizeof(GLint),                                  STORAGE_SIGNED,   false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
375         { GL_HALF_FLOAT,                                         sizeof(GLhalf),                                 STORAGE_FLOAT,    false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
376         { GL_FLOAT,                                                      sizeof(GLfloat),                                STORAGE_FLOAT,    false, false, { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, false },
377         { GL_UNSIGNED_SHORT_5_6_5,                       sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 5, 6, 5, 0, 0, 0, 0, 0, 0 } }, false },
378         { GL_UNSIGNED_SHORT_4_4_4_4,             sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 4, 4, 4, 4, 0, 0, 0, 0, 0 } }, false },
379         { GL_UNSIGNED_SHORT_5_5_5_1,             sizeof(GLushort),                               STORAGE_UNSIGNED, true,  false, { { 5, 5, 5, 1, 0, 0, 0, 0, 0 } }, false },
380         { GL_UNSIGNED_INT_2_10_10_10_REV,        sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  true,  { {10,10,10, 2, 0, 0, 0, 0, 0 } }, false },
381         { GL_UNSIGNED_INT_24_8,                          sizeof(GLuint),                                 STORAGE_UNSIGNED, true,  false, { { 0, 0, 0, 0, 0, 0,24, 8, 0 } }, false },
382         { GL_UNSIGNED_INT_10F_11F_11F_REV,       sizeof(GLuint),                                 STORAGE_FLOAT,    true,  true,  { { 6, 7, 7, 0, 0, 0, 0, 0, 0 } }, false },
383         { GL_UNSIGNED_INT_5_9_9_9_REV,           sizeof(GLuint),                                 STORAGE_FLOAT,    true,  true,  { { 9, 9, 9, 5, 0, 0, 0, 0, 0 } }, false },
384         { GL_FLOAT_32_UNSIGNED_INT_24_8_REV, sizeof(GLfloat)+sizeof(GLuint), STORAGE_FLOAT,        true,  true,  { { 0, 0, 0, 0, 0, 0,32, 8,24 } }, false },
385 };
386
387 static const EnumFormats esValidFormats[] = {
388         { GL_RGBA8,                              GL_RGBA,                        GL_UNSIGNED_BYTE,                                      4, true },
389         { GL_RGB5_A1,                    GL_RGBA,                        GL_UNSIGNED_BYTE,                                      4, true },
390         { GL_RGBA4,                              GL_RGBA,                        GL_UNSIGNED_BYTE,                                      4, true },
391         { GL_SRGB8_ALPHA8,               GL_RGBA,                        GL_UNSIGNED_BYTE,                                      4, true },
392         { GL_RGBA8_SNORM,                GL_RGBA,                        GL_BYTE,                                                       4, false },
393         { GL_RGBA4,                              GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4,                     2, true },
394         { GL_RGB5_A1,                    GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1,                     2, true },
395         { GL_RGB10_A2,                   GL_RGBA,                        GL_UNSIGNED_INT_2_10_10_10_REV,        4, true },
396         { GL_RGB5_A1,                    GL_RGBA,                        GL_UNSIGNED_INT_2_10_10_10_REV,        4, true },
397         { GL_RGBA16F,                    GL_RGBA,                        GL_HALF_FLOAT,                                         8, false },
398         { GL_RGBA32F,                    GL_RGBA,                        GL_FLOAT,                                                 16, false },
399         { GL_RGBA16F,                    GL_RGBA,                        GL_FLOAT,                                                 16, false },
400         { GL_RGBA8UI,                    GL_RGBA_INTEGER,        GL_UNSIGNED_BYTE,                                      4, true },
401         { GL_RGBA8I,                     GL_RGBA_INTEGER,        GL_BYTE,                                                       4, true },
402         { GL_RGBA16UI,                   GL_RGBA_INTEGER,        GL_UNSIGNED_SHORT,                                     8, true },
403         { GL_RGBA16I,                    GL_RGBA_INTEGER,        GL_SHORT,                                                      8, true },
404         { GL_RGBA32UI,                   GL_RGBA_INTEGER,        GL_UNSIGNED_INT,                                  16, true },
405         { GL_RGBA32I,                    GL_RGBA_INTEGER,        GL_INT,                                                   16, true },
406         { GL_RGB10_A2UI,                 GL_RGBA_INTEGER,        GL_UNSIGNED_INT_2_10_10_10_REV,        4, true },
407         { GL_RGB8,                               GL_RGB,                         GL_UNSIGNED_BYTE,                                      3, true },
408         { GL_RGB565,                     GL_RGB,                         GL_UNSIGNED_BYTE,                                      3, true },
409         { GL_SRGB8,                              GL_RGB,                         GL_UNSIGNED_BYTE,                                      3, false },
410         { GL_RGB8_SNORM,                 GL_RGB,                         GL_BYTE,                                                       3, false },
411         { GL_RGB565,                     GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5,                       2, true },
412         { GL_R11F_G11F_B10F,     GL_RGB,                         GL_UNSIGNED_INT_10F_11F_11F_REV,       4, false },
413         { GL_R11F_G11F_B10F,     GL_RGB,                         GL_HALF_FLOAT,                                         6, false },
414         { GL_R11F_G11F_B10F,     GL_RGB,                         GL_FLOAT,                                                 12, false },
415         { GL_RGB9_E5,                    GL_RGB,                         GL_UNSIGNED_INT_5_9_9_9_REV,           4, false },
416         { GL_RGB9_E5,                    GL_RGB,                         GL_HALF_FLOAT,                                         6, false },
417         { GL_RGB9_E5,                    GL_RGB,                         GL_FLOAT,                                                 12, false },
418         { GL_RGB16F,                     GL_RGB,                         GL_HALF_FLOAT,                                         6, false },
419         { GL_RGB32F,                     GL_RGB,                         GL_FLOAT,                                                 12, false },
420         { GL_RGB16F,                     GL_RGB,                         GL_FLOAT,                                                 12, false },
421         { GL_RGB8UI,                     GL_RGB_INTEGER,         GL_UNSIGNED_BYTE,                                      3, false },
422         { GL_RGB8I,                              GL_RGB_INTEGER,         GL_BYTE,                                                       3, false },
423         { GL_RGB16UI,                    GL_RGB_INTEGER,         GL_UNSIGNED_SHORT,                                     6, false },
424         { GL_RGB16I,                     GL_RGB_INTEGER,         GL_SHORT,                                                      6, false },
425         { GL_RGB32UI,                    GL_RGB_INTEGER,         GL_UNSIGNED_INT,                                  12, false },
426         { GL_RGB32I,                     GL_RGB_INTEGER,         GL_INT,                                                   12, false },
427         { GL_RG8,                                GL_RG,                          GL_UNSIGNED_BYTE,                                      2, true },
428         { GL_RG8_SNORM,                  GL_RG,                          GL_BYTE,                                                       2, false },
429         { GL_RG16F,                              GL_RG,                          GL_HALF_FLOAT,                                         4, false },
430         { GL_RG32F,                              GL_RG,                          GL_FLOAT,                                                      8, false },
431         { GL_RG16F,                              GL_RG,                          GL_FLOAT,                                                      8, false },
432         { GL_RG8UI,                              GL_RG_INTEGER,          GL_UNSIGNED_BYTE,                                      2, true },
433         { GL_RG8I,                               GL_RG_INTEGER,          GL_BYTE,                                                       2, true },
434         { GL_RG16UI,                     GL_RG_INTEGER,          GL_UNSIGNED_SHORT,                                     4, true },
435         { GL_RG16I,                              GL_RG_INTEGER,          GL_SHORT,                                                      4, true },
436         { GL_RG32UI,                     GL_RG_INTEGER,          GL_UNSIGNED_INT,                                       8, true },
437         { GL_RG32I,                              GL_RG_INTEGER,          GL_INT,                                                        8, true },
438         { GL_R8,                                 GL_RED,                         GL_UNSIGNED_BYTE,                                      1, true },
439         { GL_R8_SNORM,                   GL_RED,                         GL_BYTE,                                                       1, false },
440         { GL_R16F,                               GL_RED,                         GL_HALF_FLOAT,                                         2, false },
441         { GL_R32F,                               GL_RED,                         GL_FLOAT,                                                      4, false },
442         { GL_R16F,                               GL_RED,                         GL_FLOAT,                                                      4, false },
443         { GL_R8UI,                               GL_RED_INTEGER,         GL_UNSIGNED_BYTE,                                      1, true },
444         { GL_R8I,                                GL_RED_INTEGER,         GL_BYTE,                                                       1, true },
445         { GL_R16UI,                              GL_RED_INTEGER,         GL_UNSIGNED_SHORT,                                     2, true },
446         { GL_R16I,                               GL_RED_INTEGER,         GL_SHORT,                                                      2, true },
447         { GL_R32UI,                              GL_RED_INTEGER,         GL_UNSIGNED_INT,                                       4, true },
448         { GL_R32I,                               GL_RED_INTEGER,         GL_INT,                                                        4, true },
449         { GL_DEPTH_COMPONENT24,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                                   4, true },
450         { GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,                                   4, true },
451         { GL_DEPTH_COMPONENT16,  GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,                                 2, true },
452         { GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT,                                                  4, true },
453         { GL_DEPTH24_STENCIL8,   GL_DEPTH_STENCIL,       GL_UNSIGNED_INT_24_8,                          4, true },
454         { GL_DEPTH32F_STENCIL8,  GL_DEPTH_STENCIL,       GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8, true },
455         { GL_RGBA,                               GL_RGBA,                        GL_UNSIGNED_BYTE,                                      4, true },
456         { GL_RGBA,                               GL_RGBA,                        GL_UNSIGNED_SHORT_4_4_4_4,                     2, true },
457         { GL_RGBA,                               GL_RGBA,                        GL_UNSIGNED_SHORT_5_5_5_1,                     2, true },
458         { GL_RGB,                                GL_RGB,                         GL_UNSIGNED_BYTE,                                      3, true },
459         { GL_RGB,                                GL_RGB,                         GL_UNSIGNED_SHORT_5_6_5,                       2, true },
460         { GL_LUMINANCE_ALPHA,    GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,                                  2, false },
461         { GL_LUMINANCE,                  GL_LUMINANCE,           GL_UNSIGNED_BYTE,                                      1, false },
462         { GL_ALPHA,                              GL_ALPHA,                       GL_UNSIGNED_BYTE,                                      1, false },
463 };
464
465 static const EnumFormats coreValidFormats[] = {
466         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_BYTE_3_3_2,                        3, true },
467         { GL_RGB_INTEGER,       GL_RGB_INTEGER,   GL_UNSIGNED_BYTE_3_3_2,                        3, true },
468         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_BYTE_2_3_3_REV,            3, true },
469         { GL_RGB_INTEGER,       GL_RGB_INTEGER,   GL_UNSIGNED_BYTE_2_3_3_REV,            3, true },
470         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_SHORT_5_6_5,                       3, true },
471         { GL_RGB_INTEGER,       GL_RGB_INTEGER,   GL_UNSIGNED_SHORT_5_6_5,                       3, true },
472         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_SHORT_5_6_5_REV,           3, true },
473         { GL_RGB_INTEGER,       GL_RGB_INTEGER,   GL_UNSIGNED_SHORT_5_6_5_REV,           3, true },
474         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_SHORT_4_4_4_4,             4, true },
475         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_SHORT_4_4_4_4_REV,         4, true },
476         { GL_RGBA_INTEGER,      GL_RGBA_INTEGER,  GL_UNSIGNED_SHORT_4_4_4_4,             4, true },
477         { GL_RGBA_INTEGER,      GL_RGBA_INTEGER,  GL_UNSIGNED_SHORT_4_4_4_4_REV,         4, true },
478         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_SHORT_4_4_4_4_REV,         4, true },
479         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_SHORT_4_4_4_4,             4, true },
480         { GL_BGRA_INTEGER,      GL_BGRA_INTEGER,  GL_UNSIGNED_SHORT_4_4_4_4_REV,         4, true },
481         { GL_BGRA_INTEGER,      GL_BGRA_INTEGER,  GL_UNSIGNED_SHORT_4_4_4_4,             4, true },
482         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_SHORT_5_5_5_1,             4, true },
483         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_SHORT_5_5_5_1,             4, true },
484         { GL_RGBA_INTEGER,  GL_RGBA_INTEGER,  GL_UNSIGNED_SHORT_5_5_5_1,                 4, true },
485         { GL_BGRA_INTEGER,  GL_BGRA_INTEGER,  GL_UNSIGNED_SHORT_5_5_5_1,                 4, true },
486         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_SHORT_1_5_5_5_REV,         4, true },
487         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_SHORT_1_5_5_5_REV,         4, true },
488         { GL_RGBA_INTEGER,  GL_RGBA_INTEGER,  GL_UNSIGNED_SHORT_1_5_5_5_REV,     4, true },
489         { GL_BGRA_INTEGER,  GL_BGRA_INTEGER,  GL_UNSIGNED_SHORT_1_5_5_5_REV,     4, true },
490         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_INT_8_8_8_8,                       4, true },
491         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_INT_8_8_8_8,                       4, true },
492         { GL_RGBA_INTEGER,  GL_RGBA_INTEGER,  GL_UNSIGNED_INT_8_8_8_8,                   4, true },
493         { GL_BGRA_INTEGER,  GL_BGRA_INTEGER,  GL_UNSIGNED_INT_8_8_8_8,                   4, true },
494         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_INT_8_8_8_8_REV,           4, true },
495         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_INT_8_8_8_8_REV,           4, true },
496         { GL_RGBA_INTEGER,  GL_RGBA_INTEGER,  GL_UNSIGNED_INT_8_8_8_8_REV,               4, true },
497         { GL_BGRA_INTEGER,  GL_BGRA_INTEGER,  GL_UNSIGNED_INT_8_8_8_8_REV,               4, true },
498         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_INT_10_10_10_2,            4, true },
499         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_INT_10_10_10_2,            4, true },
500         { GL_RGBA_INTEGER, GL_RGBA_INTEGER,   GL_UNSIGNED_INT_10_10_10_2,                4, true },
501         { GL_BGRA_INTEGER, GL_BGRA_INTEGER,   GL_UNSIGNED_INT_10_10_10_2,                4, true },
502         { GL_RGBA,                      GL_RGBA,                  GL_UNSIGNED_INT_2_10_10_10_REV,        4, true },
503         { GL_BGRA,                      GL_BGRA,                  GL_UNSIGNED_INT_2_10_10_10_REV,        4, true },
504         { GL_RGBA_INTEGER, GL_RGBA_INTEGER,   GL_UNSIGNED_INT_2_10_10_10_REV,    4, true },
505         { GL_BGRA_INTEGER, GL_BGRA_INTEGER,   GL_UNSIGNED_INT_2_10_10_10_REV,    4, true },
506         { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,                              2, true },
507         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_INT_10F_11F_11F_REV,       3, true },
508         { GL_RGB,                       GL_RGB,                   GL_UNSIGNED_INT_5_9_9_9_REV,           4, true },
509         { GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 2, true },
510 };
511
512 static const EnumFormats validformats_EXT_texture_type_2_10_10_10_REV[] = {
513         { GL_RGBA, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 4, false },
514         { GL_RGB, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 3, false }
515 };
516
517 // Valid combinations given by GL_EXT_texture_type_2_10_10_10_REV and
518 // GL_OES_required_internalformat extensions
519 static const EnumFormats validformats_OES_required_internalformat[] = {
520         { GL_RGB8_OES, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 3, true },
521         { GL_RGB565, GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV_EXT, 4, true }
522 };
523
524 // Companion type for GL_FLOAT_32_UNSIGNED_INT_24_8_REV. Stencil part was
525 // not split into 24/8 to avoid any packing related issues from compiler.
526 struct F_32_UINT_24_8_REV
527 {
528         GLfloat d;
529         GLuint  s;
530 };
531
532 // custom pixel data type. holds both float and integer pixel data. memory consuming, but
533 // it is not that relavant in this case. makes comparing more reliable and flexible
534 struct FloatPixel
535 {
536         int i_r;
537         int i_g;
538         int i_b;
539         int i_a;
540         int i_d;
541         int i_s;
542
543         unsigned int ui_r;
544         unsigned int ui_g;
545         unsigned int ui_b;
546         unsigned int ui_a;
547         unsigned int ui_d;
548         unsigned int ui_s;
549
550         float r;
551         float g;
552         float b;
553         float a;
554         float d;
555         float s;
556 };
557
558 static const int NUM_FLOAT_PIXEL_COUNT = sizeof(FloatPixel) / sizeof(float);
559
560 typedef int                      rawIntPixel[4];
561 typedef unsigned int rawUintPixel[4];
562 typedef float            rawFloatPixel[4];
563
564 struct PackedPixelsBufferProperties
565 {
566         int elementsInGroup;      // number of elements in a group
567         int rowLength;                    // number of groups in the row
568         int alignment;                    // alignment (in bytes)
569         int elementSize;                  // size of an element (in bytes)
570         int elementsInRow;                // row size (in elements)
571         int elementsInRowNoAlign; // row size (in elements) without alignment
572         int rowCount;                     // number of rows in 2D image
573         int imagesCount;                  // number of 2D images in 3D image
574         int skipPixels;                   // (UN)PACK_SKIP_PIXELS
575         int skipRows;                     // (UN)PACK_SKIP_ROWS
576         int skipImages;                   // (UN)PACK_SKIP_IMAGES
577         int swapBytes;
578         int lsbFirst;
579 };
580
581 std::string getTypeStr(GLenum type)
582 {
583         // this function extends glu::getTypeStr by types used in this tests
584
585         typedef std::map<GLenum, std::string> TypeMap;
586         static TypeMap typeMap;
587         if (typeMap.empty())
588         {
589                 typeMap[GL_UNSIGNED_BYTE_3_3_2]            = "GL_UNSIGNED_BYTE_3_3_2";
590                 typeMap[GL_UNSIGNED_BYTE_2_3_3_REV]     = "GL_UNSIGNED_BYTE_2_3_3_REV";
591                 typeMap[GL_UNSIGNED_SHORT_5_6_5_REV]   = "GL_UNSIGNED_SHORT_5_6_5_REV";
592                 typeMap[GL_UNSIGNED_SHORT_4_4_4_4_REV] = "GL_UNSIGNED_SHORT_4_4_4_4_REV";
593                 typeMap[GL_UNSIGNED_SHORT_1_5_5_5_REV] = "GL_UNSIGNED_SHORT_1_5_5_5_REV";
594                 typeMap[GL_UNSIGNED_INT_8_8_8_8]           = "GL_UNSIGNED_INT_8_8_8_8";
595                 typeMap[GL_UNSIGNED_INT_8_8_8_8_REV]   = "GL_UNSIGNED_INT_8_8_8_8_REV";
596                 typeMap[GL_UNSIGNED_INT_10_10_10_2]     = "GL_UNSIGNED_INT_10_10_10_2";
597         }
598
599         TypeMap::iterator it = typeMap.find(type);
600         if (it == typeMap.end())
601         {
602                 // if type is not in map use glu function
603                 return glu::getTypeStr(type).toString();
604         }
605         return it->second;
606 }
607
608 std::string getFormatStr(GLenum format)
609 {
610         // this function extends glu::getTextureFormatStr by types used in this tests
611
612         typedef std::map<GLenum, std::string> FormatMap;
613         static FormatMap formatMap;
614         if (formatMap.empty())
615         {
616                 formatMap[GL_GREEN]                                               = "GL_GREEN";
617                 formatMap[GL_BLUE]                                                = "GL_BLUE";
618                 formatMap[GL_GREEN_INTEGER]                               = "GL_GREEN_INTEGER";
619                 formatMap[GL_BLUE_INTEGER]                                = "GL_BLUE_INTEGER";
620                 formatMap[GL_BGR]                                                 = "GL_BGR";
621                 formatMap[GL_BGR_INTEGER]                                 = "GL_BGR_INTEGER";
622                 formatMap[GL_BGRA_INTEGER]                                = "GL_BGRA_INTEGER";
623                 formatMap[GL_R3_G3_B2]                                    = "GL_R3_G3_B2";
624                 formatMap[GL_RGB4]                                                = "GL_RGB4";
625                 formatMap[GL_RGB5]                                                = "GL_RGB5";
626                 formatMap[GL_RGB12]                                               = "GL_RGB12";
627                 formatMap[GL_RGBA2]                                               = "GL_RGBA2";
628                 formatMap[GL_RGBA12]                                      = "GL_RGBA12";
629                 formatMap[GL_COMPRESSED_RED]                      = "GL_COMPRESSED_RED";
630                 formatMap[GL_COMPRESSED_RG]                               = "GL_COMPRESSED_RG";
631                 formatMap[GL_COMPRESSED_RGB]                      = "GL_COMPRESSED_RGB";
632                 formatMap[GL_COMPRESSED_RGBA]                     = "GL_COMPRESSED_RGBA";
633                 formatMap[GL_COMPRESSED_SRGB]                     = "GL_COMPRESSED_SRGB";
634                 formatMap[GL_COMPRESSED_SRGB_ALPHA]               = "GL_COMPRESSED_SRGB_ALPHA";
635                 formatMap[GL_COMPRESSED_RED_RGTC1]                = "GL_COMPRESSED_RED_RGTC1";
636                 formatMap[GL_COMPRESSED_SIGNED_RED_RGTC1] = "GL_COMPRESSED_SIGNED_RED_RGTC1";
637                 formatMap[GL_COMPRESSED_RG_RGTC2]                 = "GL_COMPRESSED_RG_RGTC2";
638                 formatMap[GL_COMPRESSED_SIGNED_RG_RGTC2]  = "GL_COMPRESSED_SIGNED_RG_RGTC2";
639                 formatMap[GL_STENCIL_INDEX]                               = "GL_STENCIL_INDEX";
640         }
641
642         FormatMap::iterator it = formatMap.find(format);
643         if (it == formatMap.end())
644         {
645                 // if format is not in map use glu function
646                 return glu::getTextureFormatStr(format).toString();
647         }
648         return it->second;
649 }
650
651 std::string getModeStr(GLenum type)
652 {
653         typedef std::map<GLenum, std::string> ModeMap;
654         static ModeMap modeMap;
655         if (modeMap.empty())
656         {
657                 modeMap[GL_UNPACK_ROW_LENGTH]   = "GL_UNPACK_ROW_LENGTH";
658                 modeMap[GL_UNPACK_SKIP_ROWS]    = "GL_UNPACK_SKIP_ROWS";
659                 modeMap[GL_UNPACK_SKIP_PIXELS]  = "GL_UNPACK_SKIP_PIXELS";
660                 modeMap[GL_UNPACK_ALIGNMENT]    = "GL_UNPACK_ALIGNMENT";
661                 modeMap[GL_UNPACK_IMAGE_HEIGHT] = "GL_UNPACK_IMAGE_HEIGHT";
662                 modeMap[GL_UNPACK_SKIP_IMAGES]  = "GL_UNPACK_SKIP_IMAGES";
663                 modeMap[GL_PACK_ROW_LENGTH]             = "GL_PACK_ROW_LENGTH";
664                 modeMap[GL_PACK_SKIP_ROWS]              = "GL_PACK_SKIP_ROWS";
665                 modeMap[GL_PACK_SKIP_PIXELS]    = "GL_PACK_SKIP_PIXELS";
666                 modeMap[GL_PACK_ALIGNMENT]              = "GL_PACK_ALIGNMENT";
667                 modeMap[GL_UNPACK_SWAP_BYTES]   = "GL_UNPACK_SWAP_BYTES";
668                 modeMap[GL_UNPACK_LSB_FIRST]    = "GL_UNPACK_LSB_FIRST";
669                 modeMap[GL_PACK_SWAP_BYTES]             = "GL_PACK_SWAP_BYTES";
670                 modeMap[GL_PACK_LSB_FIRST]              = "GL_PACK_LSB_FIRST";
671                 modeMap[GL_PACK_IMAGE_HEIGHT]   = "GL_PACK_IMAGE_HEIGHT";
672                 modeMap[GL_PACK_SKIP_IMAGES]    = "GL_PACK_SKIP_IMAGES";
673         }
674
675         ModeMap::iterator it = modeMap.find(type);
676         if (it == modeMap.end())
677                 TCU_FAIL("Unknown mode name");
678         return it->second;
679 }
680
681 class RectangleTest : public deqp::TestCase
682 {
683 public:
684         RectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
685         virtual ~RectangleTest();
686
687         void resetInitialStorageModes();
688         void applyInitialStorageModes();
689         void testAllFormatsAndTypes();
690
691         virtual tcu::TestNode::IterateResult iterate(void);
692
693 protected:
694         void createGradient();
695         void swapBytes(int typeSize, std::vector<GLbyte>& dataBuffer);
696
697         template <typename Type>
698         void makeGradient(Type (*unpack)(float));
699
700         template <typename Type>
701         static Type unpackSizedComponents(float value, int s1, int s2, int s3, int s4);
702
703         template <typename Type>
704         static Type unpackSizedComponentsRev(float value, int s1, int s2, int s3, int s4);
705
706         static GLubyte unpack_UNSIGNED_BYTE(float value);
707         static GLbyte unpack_BYTE(float value);
708         static GLushort unpack_UNSIGNED_SHORT(float value);
709         static GLshort unpack_SHORT(float value);
710         static GLuint unpack_UNSIGNED_INT(float value);
711         static GLint unpack_INT(float value);
712         static GLhalf unpack_HALF_FLOAT(float value);
713         static GLfloat unpack_FLOAT(float value);
714         static GLubyte unpack_UNSIGNED_BYTE_3_3_2(float value);
715         static GLubyte unpack_UNSIGNED_BYTE_2_3_3_REV(float value);
716         static GLushort unpack_UNSIGNED_SHORT_5_6_5_REV(float value);
717         static GLushort unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value);
718         static GLushort unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value);
719         static GLuint unpack_UNSIGNED_INT_8_8_8_8(float value);
720         static GLuint unpack_UNSIGNED_INT_8_8_8_8_REV(float value);
721         static GLuint unpack_UNSIGNED_INT_10_10_10_2(float value);
722         static GLushort unpack_UNSIGNED_SHORT_5_6_5(float value);
723         static GLushort unpack_UNSIGNED_SHORT_4_4_4_4(float value);
724         static GLushort unpack_UNSIGNED_SHORT_5_5_5_1(float value);
725         static GLuint unpack_UNSIGNED_INT_2_10_10_10_REV(float value);
726         static GLuint unpack_UNSIGNED_INT_24_8(float value);
727         static GLuint unpack_UNSIGNED_INT_5_9_9_9_REV(float value);
728         static GLuint unpack_UNSIGNED_INT_10F_11F_11F_REV(float value);
729         static F_32_UINT_24_8_REV unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value);
730
731         bool isFormatValid(const PixelFormat& format, const PixelType& type, const struct InternalFormat& internalformat,
732                                            bool checkInput, bool checkOutput, int operation) const;
733         bool isUnsizedFormat(GLenum format) const;
734         bool isSRGBFormat(const InternalFormat& internalFormat) const;
735         bool isSNORMFormat(const InternalFormat& internalFormat) const;
736         bool isCopyValid(const InternalFormat& copyInternalFormat, const InternalFormat& internalFormat) const;
737         bool isFBOImageAttachValid(const InternalFormat& internalformat, GLenum format, GLenum type) const;
738
739         const PixelFormat& getPixelFormat(GLenum format) const;
740         const PixelType& getPixelType(GLenum type) const;
741         const EnumFormats* getCanonicalFormat(const InternalFormat& internalformat, GLenum format, GLenum type) const;
742         InternalFormatSamplerType getSampler(const PixelType& type, const PixelFormat& format) const;
743
744         GLenum readOutputData(const PixelFormat& outputFormat, const PixelType& outputType, int operation);
745
746         bool doCopy();
747
748         bool doCopyInner();
749
750         bool compare(GLvoid* gradient, GLvoid* data, const PixelFormat& outputFormat, const PixelType& outputType,
751                                  bool isCopy) const;
752
753         void getFloatBuffer(GLvoid* gradient, int samplerIsIntUintFloat, const PixelFormat& format, const PixelType& type,
754                                                 int elementCount, std::vector<FloatPixel>& result) const;
755
756         void getBits(const PixelType& type, const PixelFormat& format, std::vector<int>& resultTable) const;
757
758         template <typename Type>
759         void makeBuffer(const GLvoid* gradient, const PixelFormat& format, int samplerIsIntUintFloat, int elementCount,
760                                         int componentCount, float (*pack)(Type), std::vector<FloatPixel>& result) const;
761
762         template <typename Type>
763         void makeBufferPackedInt(const GLvoid* gradient, const PixelFormat& format, int         elementCount,
764                                                          void (*pack)(rawIntPixel*, Type), std::vector<FloatPixel>& result) const;
765
766         template <typename Type>
767         void makeBufferPackedUint(const GLvoid* gradient, const PixelFormat& format, int          elementCount,
768                                                           void (*pack)(rawUintPixel*, Type), std::vector<FloatPixel>& result) const;
769
770         template <typename Type>
771         void makeBufferPackedFloat(const GLvoid* gradient, const PixelFormat& format, int               elementCount,
772                                                            void (*pack)(rawFloatPixel*, Type), std::vector<FloatPixel>& result) const;
773
774         FloatPixel orderComponentsInt(rawIntPixel values, const PixelFormat& format) const;
775         FloatPixel orderComponentsUint(rawUintPixel values, const PixelFormat& format) const;
776         FloatPixel orderComponentsFloat(rawFloatPixel values, const PixelFormat& format) const;
777
778         unsigned int getRealBitPrecision(int bits, bool isFloat) const;
779
780         bool stripBuffer(const PackedPixelsBufferProperties& props, const GLubyte* orginalBuffer,
781                                          std::vector<GLubyte>& newBuffer, bool validate) const;
782
783         int clampSignedValue(int bits, int value) const;
784         unsigned int clampUnsignedValue(int bits, unsigned int value) const;
785
786         static float pack_UNSIGNED_BYTE(GLubyte value);
787         static float pack_BYTE(GLbyte value);
788         static float pack_UNSIGNED_SHORT(GLushort value);
789         static float pack_SHORT(GLshort value);
790         static float pack_UNSIGNED_INT(GLuint value);
791         static float pack_INT(GLint value);
792         static float pack_HALF_FLOAT(GLhalf value);
793         static float pack_FLOAT(GLfloat value);
794         static void pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel* values, GLubyte value);
795         static void pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel* values, GLubyte value);
796         static void pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel* values, GLubyte value);
797         static void pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel* values, GLubyte value);
798         static void pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel* values, GLubyte value);
799         static void pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel* values, GLubyte value);
800         static void pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel* values, GLushort value);
801         static void pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel* values, GLushort value);
802         static void pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel* values, GLushort value);
803         static void pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel* values, GLushort value);
804         static void pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel* values, GLushort value);
805         static void pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel* values, GLushort value);
806         static void pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel* values, GLushort value);
807         static void pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel* values, GLushort value);
808         static void pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel* values, GLushort value);
809         static void pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel* values, GLushort value);
810         static void pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel* values, GLushort value);
811         static void pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel* values, GLushort value);
812         static void pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel* values, GLushort value);
813         static void pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel* values, GLushort value);
814         static void pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel* values, GLushort value);
815         static void pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel* values, GLushort value);
816         static void pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel* values, GLushort value);
817         static void pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel* values, GLushort value);
818         static void pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel* values, GLuint value);
819         static void pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel* values, GLuint value);
820         static void pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel* values, GLuint value);
821         static void pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel* values, GLuint value);
822         static void pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel* values, GLuint value);
823         static void pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel* values, GLuint value);
824         static void pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel* values, GLuint value);
825         static void pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel* values, GLuint value);
826         static void pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel* values, GLuint value);
827         static void pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel* values, GLuint value);
828         static void pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel* values, GLuint value);
829         static void pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel* values, GLuint value);
830         static void pack_UNSIGNED_INT_24_8(rawFloatPixel* values, GLuint value);
831         static void pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel* values, GLuint value);
832         static void pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel* values, GLuint value);
833         static void pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel* values, F_32_UINT_24_8_REV value);
834
835         bool getTexImage();
836         bool getTexImageInner(const PixelFormat& outputFormat, const PixelType& outputType);
837
838         bool doRead(GLuint texture);
839         bool readPixels(bool isCopy);
840         bool readPixelsInner(const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy);
841
842 protected:
843         const InternalFormat m_internalFormat;
844
845         bool                                             m_usePBO;
846         GLenum                                           m_textureTarget;
847         PackedPixelsBufferProperties m_initialPackProperties;
848         PackedPixelsBufferProperties m_initialUnpackProperties;
849
850         std::vector<GLbyte> m_gradient;
851         const GLubyte           m_defaultFillValue;
852
853 public:
854         // debuf counters
855         static int m_countReadPixels;
856         static int m_countReadPixelsOK;
857         static int m_countGetTexImage;
858         static int m_countGetTexImageOK;
859         static int m_countCompare;
860         static int m_countCompareOK;
861
862 private:
863         // those attribute change multiple times during test execution
864         PixelFormat                                      m_inputFormat;
865         PixelType                                        m_inputType;
866         InternalFormat                           m_copyInternalFormat;
867         PackedPixelsBufferProperties m_packProperties;
868         PackedPixelsBufferProperties m_unpackProperties;
869         std::vector<GLbyte>                      m_outputBuffer;
870 };
871
872 int RectangleTest::m_countReadPixels    = 0;
873 int RectangleTest::m_countReadPixelsOK  = 0;
874 int RectangleTest::m_countGetTexImage   = 0;
875 int RectangleTest::m_countGetTexImageOK = 0;
876 int RectangleTest::m_countCompare               = 0;
877 int RectangleTest::m_countCompareOK             = 0;
878
879 RectangleTest::RectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
880         : deqp::TestCase(context, name.c_str(), "")
881         , m_internalFormat(internalFormat)
882         , m_usePBO(false)
883         , m_textureTarget(GL_TEXTURE_2D)
884         , m_defaultFillValue(0xaa)
885 {
886 }
887
888 RectangleTest::~RectangleTest()
889 {
890 }
891
892 void RectangleTest::resetInitialStorageModes()
893 {
894         m_initialPackProperties.skipPixels = 0;
895         m_initialPackProperties.skipRows   = 0;
896         m_initialPackProperties.rowLength  = 0;
897         m_initialPackProperties.alignment  = 4;
898         m_initialPackProperties.rowCount   = 0;
899         m_initialPackProperties.skipImages = 0;
900         m_initialPackProperties.lsbFirst   = 0;
901         m_initialPackProperties.swapBytes  = 0;
902
903         m_initialUnpackProperties.skipPixels = 0;
904         m_initialUnpackProperties.skipRows   = 0;
905         m_initialUnpackProperties.rowLength  = 0;
906         m_initialUnpackProperties.alignment  = 4;
907         m_initialUnpackProperties.rowCount   = 0;
908         m_initialUnpackProperties.skipImages = 0;
909         m_initialUnpackProperties.lsbFirst   = 0;
910         m_initialUnpackProperties.swapBytes  = 0;
911 }
912
913 void RectangleTest::applyInitialStorageModes()
914 {
915         glu::RenderContext& renderContext = m_context.getRenderContext();
916         const Functions&        gl                        = renderContext.getFunctions();
917
918         PackedPixelsBufferProperties& up = m_initialUnpackProperties;
919         PackedPixelsBufferProperties& pp = m_initialPackProperties;
920
921         m_unpackProperties = up;
922         m_packProperties   = pp;
923
924         gl.pixelStorei(GL_PACK_ROW_LENGTH, pp.rowLength);
925         gl.pixelStorei(GL_PACK_SKIP_ROWS, pp.skipRows);
926         gl.pixelStorei(GL_PACK_SKIP_PIXELS, pp.skipPixels);
927         gl.pixelStorei(GL_PACK_ALIGNMENT, pp.alignment);
928
929         gl.pixelStorei(GL_UNPACK_ROW_LENGTH, up.rowLength);
930         gl.pixelStorei(GL_UNPACK_SKIP_ROWS, up.skipRows);
931         gl.pixelStorei(GL_UNPACK_SKIP_PIXELS, up.skipPixels);
932         gl.pixelStorei(GL_UNPACK_ALIGNMENT, up.alignment);
933         gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT, up.rowCount);
934         gl.pixelStorei(GL_UNPACK_SKIP_IMAGES, up.skipImages);
935
936         if (!isContextTypeES(renderContext.getType()))
937         {
938                 gl.pixelStorei(GL_PACK_IMAGE_HEIGHT, pp.rowCount);
939                 gl.pixelStorei(GL_PACK_SKIP_IMAGES, pp.skipImages);
940
941                 gl.pixelStorei(GL_PACK_SWAP_BYTES, pp.swapBytes);
942                 gl.pixelStorei(GL_PACK_LSB_FIRST, pp.lsbFirst);
943
944                 gl.pixelStorei(GL_UNPACK_SWAP_BYTES, up.swapBytes);
945                 gl.pixelStorei(GL_UNPACK_LSB_FIRST, up.lsbFirst);
946         }
947 }
948
949 void RectangleTest::swapBytes(int typeSize, std::vector<GLbyte>& dataBuffer)
950 {
951         int bufferSize = static_cast<int>(dataBuffer.size());
952         switch (typeSize)
953         {
954         case 1:
955                 break; // no swapping
956         case 2:
957         {
958                 GLushort* data = reinterpret_cast<GLushort*>(&dataBuffer[0]);
959                 for (int i = 0; i < bufferSize / 2; i++)
960                 {
961                         GLushort v = data[i];
962                         data[i] = ((v & 0xff) << 8) + ((v & 0xff00) >> 8);
963                 }
964                 break;
965         }
966         case 4:
967         case 8: // typeSize is 2 x 32bit, behaves the same this time
968         {
969                 GLuint* data = reinterpret_cast<GLuint*>(&dataBuffer[0]);
970                 for (int i = 0; i < bufferSize / 4; i++)
971                 {
972                         GLuint v = data[i];
973                         data[i]  = ((v & 0xff) << 24) + ((v & 0xff00) << 8) + ((v & 0xff0000) >> 8) + ((v & 0xff000000) >> 24);
974                 }
975                 break;
976         }
977         default:
978                 TCU_FAIL("Invalid size for swapBytes");
979         }
980 }
981
982 const PixelFormat& RectangleTest::getPixelFormat(GLenum format) const
983 {
984         const PixelFormat* formats;
985         int                                formatsCount;
986         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
987         {
988                 formats          = esFormats;
989                 formatsCount = DE_LENGTH_OF_ARRAY(esFormats);
990         }
991         else
992         {
993                 formats          = coreFormats;
994                 formatsCount = DE_LENGTH_OF_ARRAY(coreFormats);
995         }
996
997         // Look up pixel format from a GL enum
998         for (int i = 0; i < formatsCount; i++)
999         {
1000                 if (formats[i].format == format)
1001                         return formats[i];
1002         }
1003
1004         TCU_FAIL("Unsuported format.");
1005         return formats[0];
1006 }
1007
1008 const PixelType& RectangleTest::getPixelType(GLenum type) const
1009 {
1010         const PixelType* types;
1011         int                              typesCount;
1012         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
1013         {
1014                 types     = esTypes;
1015                 typesCount = DE_LENGTH_OF_ARRAY(esTypes);
1016         }
1017         else
1018         {
1019                 types     = coreTypes;
1020                 typesCount = DE_LENGTH_OF_ARRAY(coreTypes);
1021         }
1022
1023         for (int i = 0; i < typesCount; i++)
1024         {
1025                 if (types[i].type == type)
1026                         return types[i];
1027         }
1028
1029         TCU_FAIL("Unsuported type.");
1030         return types[0];
1031 }
1032
1033 const EnumFormats* RectangleTest::getCanonicalFormat(const InternalFormat& internalformat, GLenum format,
1034                                                                                                          GLenum type) const
1035 {
1036         // function returns a canonical format from internal format. for example
1037         // GL_RGBA16F => { GL_RGBA, GL_FLOAT }; used mostly for GLES tests
1038
1039         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
1040         {
1041                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(esValidFormats); ++i)
1042                 {
1043                         if ((esValidFormats[i].internalformat == internalformat.sizedFormat) &&
1044                                 (esValidFormats[i].format == format) && (esValidFormats[i].type == type))
1045                         {
1046                                 return &(esValidFormats[i]);
1047                         }
1048                 }
1049
1050                 const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1051                 if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV"))
1052                 {
1053                         for (int i = 0; i < DE_LENGTH_OF_ARRAY(validformats_EXT_texture_type_2_10_10_10_REV); ++i)
1054                         {
1055                                 if (validformats_EXT_texture_type_2_10_10_10_REV[i].internalformat == internalformat.sizedFormat &&
1056                                         validformats_EXT_texture_type_2_10_10_10_REV[i].format == format &&
1057                                         validformats_EXT_texture_type_2_10_10_10_REV[i].type == type)
1058                                 {
1059                                         return &(validformats_EXT_texture_type_2_10_10_10_REV[i]);
1060                                 }
1061                         }
1062
1063                         if (contextInfo.isExtensionSupported("GL_OES_required_internalformat"))
1064                         {
1065                                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(validformats_OES_required_internalformat); ++i)
1066                                 {
1067                                         if (validformats_OES_required_internalformat[i].internalformat == internalformat.sizedFormat &&
1068                                                 validformats_OES_required_internalformat[i].format == format &&
1069                                                 validformats_OES_required_internalformat[i].type == type)
1070                                         {
1071                                                 return &(validformats_OES_required_internalformat[i]);
1072                                         }
1073                                 }
1074                         }
1075                 }
1076         }
1077         else
1078         {
1079                 for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreValidFormats); ++i)
1080                 {
1081                         if ((coreValidFormats[i].internalformat == internalformat.sizedFormat) &&
1082                                 (coreValidFormats[i].format == format) && (coreValidFormats[i].type == type))
1083                         {
1084                                 return &(coreValidFormats[i]);
1085                         }
1086                 }
1087         }
1088
1089         return 0;
1090 }
1091
1092 InternalFormatSamplerType RectangleTest::getSampler(const PixelType& type, const PixelFormat& format) const
1093 {
1094         switch (type.storage)
1095         {
1096         case STORAGE_FLOAT:
1097                 return SAMPLER_FLOAT;
1098
1099         case STORAGE_UNSIGNED:
1100                 if ((format.componentFormat == FORMAT_COLOR_INTEGER) || (format.componentFormat == FORMAT_STENCIL))
1101                         return SAMPLER_UINT;
1102                 return SAMPLER_UNORM;
1103
1104         case STORAGE_SIGNED:
1105                 if (format.componentFormat == FORMAT_COLOR_INTEGER)
1106                         return SAMPLER_INT;
1107                 return SAMPLER_NORM;
1108
1109         default:
1110                 TCU_FAIL("Invalid storage specifier");
1111         }
1112 }
1113
1114 void RectangleTest::createGradient()
1115 {
1116         switch (m_inputType.type)
1117         {
1118         case GL_UNSIGNED_BYTE:
1119                 makeGradient(unpack_UNSIGNED_BYTE);
1120                 break;
1121         case GL_BYTE:
1122                 makeGradient<GLbyte>(unpack_BYTE);
1123                 break;
1124         case GL_UNSIGNED_SHORT:
1125                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT);
1126                 break;
1127         case GL_SHORT:
1128                 makeGradient<GLshort>(unpack_SHORT);
1129                 break;
1130         case GL_UNSIGNED_INT:
1131                 makeGradient<GLuint>(unpack_UNSIGNED_INT);
1132                 break;
1133         case GL_INT:
1134                 makeGradient<GLint>(unpack_INT);
1135                 break;
1136         case GL_HALF_FLOAT:
1137                 makeGradient<GLhalf>(unpack_HALF_FLOAT);
1138                 break;
1139         case GL_FLOAT:
1140                 makeGradient<GLfloat>(unpack_FLOAT);
1141                 break;
1142         case GL_UNSIGNED_SHORT_5_6_5:
1143                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_5_6_5);
1144                 break;
1145         case GL_UNSIGNED_SHORT_4_4_4_4:
1146                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_4_4_4_4);
1147                 break;
1148         case GL_UNSIGNED_SHORT_5_5_5_1:
1149                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_5_5_5_1);
1150                 break;
1151         case GL_UNSIGNED_INT_2_10_10_10_REV:
1152                 makeGradient<GLuint>(unpack_UNSIGNED_INT_2_10_10_10_REV);
1153                 break;
1154         case GL_UNSIGNED_INT_24_8:
1155                 makeGradient<GLuint>(unpack_UNSIGNED_INT_24_8);
1156                 break;
1157         case GL_UNSIGNED_INT_10F_11F_11F_REV:
1158                 makeGradient<GLuint>(unpack_UNSIGNED_INT_10F_11F_11F_REV);
1159                 break;
1160         case GL_UNSIGNED_INT_5_9_9_9_REV:
1161                 makeGradient<GLuint>(unpack_UNSIGNED_INT_5_9_9_9_REV);
1162                 break;
1163         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1164                 makeGradient<F_32_UINT_24_8_REV>(unpack_FLOAT_32_UNSIGNED_INT_24_8_REV);
1165                 break;
1166         case GL_UNSIGNED_BYTE_3_3_2:
1167                 makeGradient<GLubyte>(unpack_UNSIGNED_BYTE_3_3_2);
1168                 break;
1169         case GL_UNSIGNED_BYTE_2_3_3_REV:
1170                 makeGradient<GLubyte>(unpack_UNSIGNED_BYTE_2_3_3_REV);
1171                 break;
1172         case GL_UNSIGNED_SHORT_5_6_5_REV:
1173                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_5_6_5_REV);
1174                 break;
1175         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
1176                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_4_4_4_4_REV);
1177                 break;
1178         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
1179                 makeGradient<GLushort>(unpack_UNSIGNED_SHORT_1_5_5_5_REV);
1180                 break;
1181         case GL_UNSIGNED_INT_8_8_8_8:
1182                 makeGradient<GLuint>(unpack_UNSIGNED_INT_8_8_8_8);
1183                 break;
1184         case GL_UNSIGNED_INT_8_8_8_8_REV:
1185                 makeGradient<GLuint>(unpack_UNSIGNED_INT_8_8_8_8_REV);
1186                 break;
1187         case GL_UNSIGNED_INT_10_10_10_2:
1188                 makeGradient<GLuint>(unpack_UNSIGNED_INT_10_10_10_2);
1189                 break;
1190         default:
1191                 TCU_FAIL("Unsupported type");
1192         };
1193 }
1194
1195 template <typename Type>
1196 void RectangleTest::makeGradient(Type (*unpack)(float))
1197 {
1198         // number of elements in a group
1199         int elementsInGroup = m_inputFormat.components;
1200         if (m_inputType.special)
1201                 elementsInGroup = 1;
1202
1203         int rowCount = m_unpackProperties.rowCount;
1204         if (rowCount == 0)
1205                 rowCount = GRADIENT_HEIGHT + m_unpackProperties.skipRows;
1206
1207         // number of groups in the row
1208         int rowLength = m_unpackProperties.rowLength;
1209         if (rowLength == 0)
1210                 rowLength = GRADIENT_WIDTH + m_unpackProperties.skipPixels;
1211
1212         int elementSize = m_inputType.size;
1213
1214         // row size (in elements)
1215         int elementsInRowNoAlign = elementsInGroup * rowLength;
1216         int elementsInRow                = elementsInRowNoAlign;
1217         if (elementSize < m_unpackProperties.alignment)
1218         {
1219                 int alignment = m_unpackProperties.alignment;
1220                 elementsInRow = (int)(alignment * deFloatCeil(elementSize * elementsInGroup * rowLength / ((float)alignment))) /
1221                                                 elementSize;
1222         }
1223
1224         if (m_textureTarget == GL_TEXTURE_2D)
1225                 m_unpackProperties.skipImages = 0;
1226
1227         // "depth" will be 1 + skipped image layers.
1228         // We still want to work on a 2D-ish image later.
1229         int depth = 1 + m_unpackProperties.skipImages;
1230
1231         m_unpackProperties.elementsInGroup              = elementsInGroup;
1232         m_unpackProperties.rowCount                             = rowCount;
1233         m_unpackProperties.rowLength                    = rowLength;
1234         m_unpackProperties.elementSize                  = elementSize;
1235         m_unpackProperties.elementsInRowNoAlign = elementsInRowNoAlign;
1236         m_unpackProperties.elementsInRow                = elementsInRow;
1237         m_unpackProperties.imagesCount                  = depth;
1238
1239         // element size * elements in row * number of rows * number of 2d images
1240         std::size_t bufferSize = elementSize * elementsInRow * rowCount * depth;
1241
1242         m_gradient.resize(bufferSize);
1243         Type* data = reinterpret_cast<Type*>(&m_gradient[0]);
1244
1245         std::size_t dataToSkip   = m_unpackProperties.skipImages * rowCount * elementsInRow;
1246         std::size_t index                = dataToSkip;
1247         const Type  defaultValue = unpack(0.5f);
1248         std::fill(data, data + dataToSkip, defaultValue);
1249
1250         for (int k = 0; k < depth; k++)
1251         {
1252                 for (int j = 0; j < rowCount; j++)
1253                 {
1254                         for (int i = 0; i < elementsInRow; i++)
1255                         {
1256                                 int x = i / elementsInGroup;
1257                                 if ((k == depth - 1) && (m_unpackProperties.skipRows <= j) &&
1258                                         (j < m_unpackProperties.skipRows + GRADIENT_HEIGHT) && (m_unpackProperties.skipPixels <= x) &&
1259                                         (x < m_unpackProperties.skipPixels + GRADIENT_WIDTH))
1260                                 {
1261                                         float value   = static_cast<float>(x - m_unpackProperties.skipPixels) / GRADIENT_WIDTH;
1262                                         int   channel = i - elementsInGroup * x;
1263                                         value *= 1.0f - 0.25f * channel;
1264                                         data[index] = unpack(value);
1265                                 }
1266                                 else
1267                                 {
1268                                         data[index] = defaultValue;
1269                                 }
1270                                 index++;
1271                         }
1272                 }
1273         }
1274 }
1275
1276 template <typename Type>
1277 Type RectangleTest::unpackSizedComponents(float value, int s1, int s2, int s3, int s4)
1278 {
1279         int     typeBits = sizeof(Type) * 8;
1280         double v                = static_cast<double>(value);
1281         Type   c1               = static_cast<Type>(v * 1.00 * ((1 << s1) - 1));
1282         Type   c2               = static_cast<Type>(v * 0.75 * ((1 << s2) - 1));
1283         Type   c3               = static_cast<Type>(v * 0.50 * ((1 << s3) - 1));
1284         Type   c4               = static_cast<Type>(v * 0.25 * ((1 << s4) - 1));
1285         return ((c1) << (typeBits - s1)) | ((c2) << (typeBits - s1 - s2)) | ((c3) << (typeBits - s1 - s2 - s3)) |
1286                    ((c4) << (typeBits - s1 - s2 - s3 - s4));
1287 }
1288
1289 template <typename Type>
1290 Type RectangleTest::unpackSizedComponentsRev(float value, int s1, int s2, int s3, int s4)
1291 {
1292         int     typeBits = sizeof(Type) * 8;
1293         double v                = static_cast<double>(value);
1294         Type   c1               = static_cast<Type>(v * 1.00 * ((1 << s4) - 1));
1295         Type   c2               = static_cast<Type>(v * 0.75 * ((1 << s3) - 1));
1296         Type   c3               = static_cast<Type>(v * 0.50 * ((1 << s2) - 1));
1297         Type   c4               = static_cast<Type>(v * 0.25 * ((1 << s1) - 1));
1298         return ((c4) << (typeBits - s1)) | ((c3) << (typeBits - s1 - s2)) | ((c2) << (typeBits - s1 - s2 - s3)) |
1299                    ((c1) << (typeBits - s1 - s2 - s3 - s4));
1300 }
1301
1302 GLubyte RectangleTest::unpack_UNSIGNED_BYTE(float value)
1303 {
1304         return static_cast<GLubyte>(value * std::numeric_limits<GLubyte>::max());
1305 }
1306
1307 GLbyte RectangleTest::unpack_BYTE(float value)
1308 {
1309         return static_cast<GLbyte>(value * std::numeric_limits<GLbyte>::max());
1310 }
1311
1312 GLushort RectangleTest::unpack_UNSIGNED_SHORT(float value)
1313 {
1314         return static_cast<GLushort>(value * std::numeric_limits<GLushort>::max());
1315 }
1316
1317 GLshort RectangleTest::unpack_SHORT(float value)
1318 {
1319         return static_cast<GLshort>(value * std::numeric_limits<GLshort>::max());
1320 }
1321
1322 GLuint RectangleTest::unpack_UNSIGNED_INT(float value)
1323 {
1324         return static_cast<GLuint>(value * std::numeric_limits<GLuint>::max());
1325 }
1326
1327 GLint RectangleTest::unpack_INT(float value)
1328 {
1329         return static_cast<GLint>(value * std::numeric_limits<GLint>::max());
1330 }
1331
1332 GLhalf RectangleTest::unpack_HALF_FLOAT(float value)
1333 {
1334         return floatToHalfFloat(value);
1335 }
1336
1337 GLfloat RectangleTest::unpack_FLOAT(float value)
1338 {
1339         return value;
1340 }
1341
1342 GLubyte RectangleTest::unpack_UNSIGNED_BYTE_3_3_2(float value)
1343 {
1344         return unpackSizedComponents<GLubyte>(value, 3, 3, 2, 0);
1345 }
1346
1347 GLubyte RectangleTest::unpack_UNSIGNED_BYTE_2_3_3_REV(float value)
1348 {
1349         return unpackSizedComponentsRev<GLubyte>(value, 2, 3, 3, 0);
1350 }
1351
1352 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5_REV(float value)
1353 {
1354         return unpackSizedComponentsRev<GLushort>(value, 5, 6, 5, 0);
1355 }
1356
1357 GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value)
1358 {
1359         return unpackSizedComponentsRev<GLushort>(value, 4, 4, 4, 4);
1360 }
1361
1362 GLushort RectangleTest::unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value)
1363 {
1364         return unpackSizedComponentsRev<GLushort>(value, 1, 5, 5, 5);
1365 }
1366
1367 GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8(float value)
1368 {
1369         return unpackSizedComponents<GLuint>(value, 8, 8, 8, 8);
1370 }
1371
1372 GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8_REV(float value)
1373 {
1374         return unpackSizedComponentsRev<GLuint>(value, 8, 8, 8, 8);
1375 }
1376
1377 GLuint RectangleTest::unpack_UNSIGNED_INT_10_10_10_2(float value)
1378 {
1379         return unpackSizedComponents<GLuint>(value, 10, 10, 10, 2);
1380 }
1381
1382 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5(float value)
1383 {
1384         return unpackSizedComponents<GLushort>(value, 5, 6, 5, 0);
1385 }
1386
1387 GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4(float value)
1388 {
1389         return unpackSizedComponents<GLushort>(value, 4, 4, 4, 4);
1390 }
1391
1392 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_5_5_1(float value)
1393 {
1394         return unpackSizedComponents<GLushort>(value, 5, 5, 5, 1);
1395 }
1396
1397 GLuint RectangleTest::unpack_UNSIGNED_INT_2_10_10_10_REV(float value)
1398 {
1399         return unpackSizedComponentsRev<GLuint>(value, 2, 10, 10, 10);
1400 }
1401
1402 GLuint RectangleTest::unpack_UNSIGNED_INT_24_8(float value)
1403 {
1404         return unpackSizedComponents<GLuint>(value, 24, 8, 0, 0);
1405 }
1406
1407 GLuint RectangleTest::unpack_UNSIGNED_INT_5_9_9_9_REV(float value)
1408 {
1409         const int N             = 9;
1410         const int B             = 15;
1411         const int E_max = 31;
1412
1413         GLfloat red   = value * 1.00f;
1414         GLfloat green = value * 0.75f;
1415         GLfloat blue  = value * 0.50f;
1416
1417         GLfloat sharedExpMax = (deFloatPow(2.0f, (float)N) - 1.0f) / deFloatPow(2.0f, (float)N) * deFloatPow(2.0f, (float)(E_max - B));
1418
1419         GLfloat red_c   = deFloatMax(0, deFloatMin(sharedExpMax, red));
1420         GLfloat green_c = deFloatMax(0, deFloatMin(sharedExpMax, green));
1421         GLfloat blue_c  = deFloatMax(0, deFloatMin(sharedExpMax, blue));
1422
1423         GLfloat max_c = deFloatMax(deFloatMax(red_c, green_c), blue_c);
1424
1425         GLfloat exp_p = deFloatMax(-B - 1, deFloatFloor(deFloatLog2(max_c))) + 1 + B;
1426
1427         GLfloat max_s = deFloatFloor(max_c / deFloatPow(2.0f, exp_p - (float)B - (float)N) + 0.5f);
1428
1429         GLfloat exp_s;
1430
1431         if (0 <= max_s && max_s < deFloatPow(2.0f, (float)N))
1432                 exp_s = exp_p;
1433         else
1434                 exp_s = exp_p + 1;
1435
1436         GLfloat red_s   = deFloatFloor(red_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1437         GLfloat green_s = deFloatFloor(green_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1438         GLfloat blue_s  = deFloatFloor(blue_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1439
1440         GLuint c1 = (static_cast<GLuint>(red_s)) & 511;
1441         GLuint c2 = (static_cast<GLuint>(green_s)) & 511;
1442         GLuint c3 = (static_cast<GLuint>(blue_s)) & 511;
1443         GLuint c4 = (static_cast<GLuint>(exp_s)) & 31;
1444
1445         return (c1) | (c2 << 9) | (c3 << 18) | (c4 << 27);
1446 }
1447
1448 GLuint RectangleTest::unpack_UNSIGNED_INT_10F_11F_11F_REV(float value)
1449 {
1450         GLuint c1 = floatToUnisgnedF11(value * 1.00f);
1451         GLuint c2 = floatToUnisgnedF11(value * 0.75f);
1452         GLuint c3 = floatToUnisgnedF10(value * 0.50f);
1453         return (c3 << 22) | (c2 << 11) | (c1);
1454 }
1455
1456 F_32_UINT_24_8_REV RectangleTest::unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value)
1457 {
1458         F_32_UINT_24_8_REV ret;
1459         ret.d = value;
1460         ret.s = (GLuint)(value * 255.0 * 0.75);
1461         ret.s &= 0xff;
1462         return ret;
1463 }
1464
1465 bool RectangleTest::isFormatValid(const PixelFormat& format, const PixelType& type,
1466                                                                   const struct InternalFormat& internalformat, bool checkInput, bool checkOutput,
1467                                                                   int operation) const
1468 {
1469         glu::RenderContext&             renderContext = m_context.getRenderContext();
1470         glu::ContextType                contextType   = renderContext.getType();
1471         const glu::ContextInfo& contextInfo   = m_context.getContextInfo();
1472         const Functions&                gl                        = renderContext.getFunctions();
1473
1474         int i;
1475
1476         // Test the combination of input format, input type and internalFormat
1477         if (glu::isContextTypeES(contextType))
1478         {
1479                 if (checkInput)
1480                 {
1481                         // GLES30 has more restricted requirement on combination than GL for input
1482                         for (i = 0; i < DE_LENGTH_OF_ARRAY(esValidFormats); ++i)
1483                         {
1484                                 if (internalformat.sizedFormat == esValidFormats[i].internalformat &&
1485                                         format.format == esValidFormats[i].format && type.type == esValidFormats[i].type)
1486                                 {
1487                                         break;
1488                                 }
1489                         }
1490
1491                         if (i == DE_LENGTH_OF_ARRAY(esValidFormats))
1492                         {
1493                                 // Check for support of OES_texture_float extension
1494                                 if (((GL_LUMINANCE_ALPHA == format.format) && (GL_LUMINANCE_ALPHA == internalformat.sizedFormat)) ||
1495                                         ((GL_LUMINANCE == format.format) && (GL_LUMINANCE == internalformat.sizedFormat)) ||
1496                                         ((GL_ALPHA == format.format) && (GL_ALPHA == internalformat.sizedFormat)) ||
1497                                         ((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) ||
1498                                         ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat)))
1499                                 {
1500                                         if ((contextInfo.isExtensionSupported("GL_OES_texture_float") && (GL_FLOAT == type.type)) ||
1501                                                 (contextInfo.isExtensionSupported("GL_OES_texture_half_float") &&
1502                                                  (GL_HALF_FLOAT_OES == type.type)))
1503                                         {
1504                                                 return true;
1505                                         }
1506                                 }
1507
1508                                 // Check for support of EXT_texture_type_2_10_10_10_REV extension
1509                                 if (((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) ||
1510                                         ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat)))
1511                                 {
1512                                         if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") &&
1513                                                 ((GL_UNSIGNED_INT_2_10_10_10_REV_EXT == type.type)))
1514                                                 return true;
1515                                 }
1516
1517                                 // Check for support of NV_packed_float extension
1518                                 if ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat))
1519                                 {
1520                                         if (contextInfo.isExtensionSupported("GL_NV_packed_float") &&
1521                                                 ((GL_UNSIGNED_INT_10F_11F_11F_REV == type.type)))
1522                                                 return true;
1523                                 }
1524
1525                                 // Check for support of EXT_texture_type_2_10_10_10_REV and GL_OES_required_internalformat extensions
1526                                 if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") &&
1527                                         contextInfo.isExtensionSupported("GL_OES_required_internalformat"))
1528                                 {
1529                                         for (i = 0; i < DE_LENGTH_OF_ARRAY(validformats_OES_required_internalformat); ++i)
1530                                         {
1531                                                 if (internalformat.sizedFormat == validformats_OES_required_internalformat[i].internalformat &&
1532                                                         format.format == validformats_OES_required_internalformat[i].format &&
1533                                                         type.type == validformats_OES_required_internalformat[i].type)
1534                                                 {
1535                                                         return true;
1536                                                 }
1537                                         }
1538                                 }
1539
1540                                 return false;
1541                         }
1542
1543                         if ((m_textureTarget == GL_TEXTURE_3D) &&
1544                                 ((format.format == GL_DEPTH_COMPONENT) || (format.format == GL_DEPTH_STENCIL)))
1545                                 return false;
1546                 }
1547                 else if (checkOutput)
1548                 {
1549                         // GLES30 has more restricted requirement on combination than GL for output
1550                         // As stated in Section Reading Pixels
1551                         InternalFormatSamplerType sampler = internalformat.sampler;
1552
1553                         const PixelFormat& inputFormat = getPixelFormat(internalformat.format);
1554
1555                         if (inputFormat.attachment == GL_DEPTH_ATTACHMENT && contextInfo.isExtensionSupported("GL_NV_read_depth") &&
1556                                 format.format == GL_DEPTH_COMPONENT &&
1557                                 ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) ||
1558                                  (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT ||
1559                                                                                            type.type == GL_UNSIGNED_INT_24_8))))
1560                         {
1561                                 return true;
1562                         }
1563
1564                         if (inputFormat.attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
1565                                 contextInfo.isExtensionSupported("GL_NV_read_depth_stencil") &&
1566                                 ((format.format == GL_DEPTH_STENCIL &&
1567                                   ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) ||
1568                                    (sampler != SAMPLER_FLOAT && type.type == GL_UNSIGNED_INT_24_8))) ||
1569                                  (format.format == GL_DEPTH_COMPONENT &&
1570                                   ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) ||
1571                                    (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT ||
1572                                                                                                  type.type == GL_UNSIGNED_INT_24_8))))))
1573                         {
1574                                 return true;
1575                         }
1576
1577                         if (inputFormat.attachment != GL_COLOR_ATTACHMENT0)
1578                         {
1579                                 return false;
1580                         }
1581
1582                         if ((sampler == SAMPLER_UNORM) && (((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGB) &&
1583                                                                                                 (internalformat.sizedFormat == GL_SRGB8)) ||
1584                                                                                            ((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA) &&
1585                                                                                                 (internalformat.sizedFormat == GL_SRGB8_ALPHA8))) &&
1586                                 contextInfo.isExtensionSupported("GL_NV_sRGB_formats"))
1587                         {
1588                                 return true;
1589                         }
1590
1591                         if ((sampler == SAMPLER_NORM) && (type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA) &&
1592                                 ((internalformat.sizedFormat == GL_R8_SNORM) || (internalformat.sizedFormat == GL_RG8_SNORM) ||
1593                                  (internalformat.sizedFormat == GL_RGBA8_SNORM) || (internalformat.sizedFormat == GL_R16_SNORM) ||
1594                                  (internalformat.sizedFormat == GL_RG16_SNORM) || (internalformat.sizedFormat == GL_RGBA16_SNORM)) &&
1595                                 contextInfo.isExtensionSupported("GL_EXT_render_snorm"))
1596                         {
1597                                 return true;
1598                         }
1599
1600                         if ((sampler == SAMPLER_NORM) && (type.type == GL_BYTE) && (format.format == GL_RGBA) &&
1601                                 ((internalformat.sizedFormat == GL_R8_SNORM) || (internalformat.sizedFormat == GL_RG8_SNORM) ||
1602                                  (internalformat.sizedFormat == GL_RGBA8_SNORM)) &&
1603                                 contextInfo.isExtensionSupported("GL_EXT_render_snorm"))
1604                         {
1605                                 return true;
1606                         }
1607
1608                         GLint implementType;
1609                         GLint implementFormat;
1610                         gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &implementType);
1611                         gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implementFormat);
1612                         GLenum err                                 = gl.getError();
1613                         GLenum implementTypeEnum   = static_cast<GLenum>(implementType);
1614                         GLenum implementFormatEnum = static_cast<GLenum>(implementFormat);
1615
1616                         if (((sampler == SAMPLER_UNORM) && (type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA)) ||
1617                                 ((sampler == SAMPLER_UINT) && (type.type == GL_UNSIGNED_INT) && (format.format == GL_RGBA_INTEGER)) ||
1618                                 ((sampler == SAMPLER_INT) && (type.type == GL_INT) && (format.format == GL_RGBA_INTEGER)) ||
1619                                 ((sampler == SAMPLER_FLOAT) && (type.type == GL_FLOAT) && (format.format == GL_RGBA)) ||
1620                                 ((err == GL_NO_ERROR) && (type.type == implementTypeEnum) && (format.format == implementFormatEnum)) ||
1621                                 ((internalformat.sizedFormat == GL_RGB10_A2) && (type.type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
1622                                  (format.format == GL_RGBA)))
1623                         {
1624                                 return true;
1625                         }
1626                         else
1627                         {
1628                                 return false;
1629                         }
1630                 }
1631         }
1632         else
1633         {
1634                 if (format.format == GL_DEPTH_STENCIL)
1635                 {
1636                         if (type.type != GL_UNSIGNED_INT_24_8 && type.type != GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
1637                         {
1638                                 return false;
1639                         }
1640                 }
1641
1642                 if ((format.componentFormat == FORMAT_COLOR_INTEGER) && (type.type == GL_FLOAT || type.type == GL_HALF_FLOAT))
1643                 {
1644                         return false;
1645                 }
1646
1647                 if ((internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_STENCIL_INDEX ||
1648                          internalformat.baseFormat == GL_DEPTH_COMPONENT) !=
1649                         (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX ||
1650                          format.format == GL_DEPTH_COMPONENT))
1651                 {
1652                         return false;
1653                 }
1654
1655                 if (operation == INPUT_TEXIMAGE)
1656                 {
1657                         if (format.format == GL_STENCIL_INDEX || internalformat.baseFormat == GL_STENCIL_INDEX)
1658                         {
1659                                 return false;
1660                         }
1661
1662                         if ((format.format == GL_DEPTH_COMPONENT || format.format == GL_DEPTH_STENCIL) &&
1663                                 !(internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_DEPTH_COMPONENT))
1664                         {
1665                                 return false;
1666                         }
1667                 }
1668                 else if (operation == OUTPUT_GETTEXIMAGE)
1669                 {
1670                         if ((format.format == GL_STENCIL_INDEX &&
1671                                  ((internalformat.baseFormat != GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL) ||
1672                                   !contextInfo.isExtensionSupported("GL_ARB_texture_stencil8"))))
1673                         {
1674                                 return false;
1675                         }
1676
1677                         if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL)
1678                         {
1679                                 return false;
1680                         }
1681                 }
1682                 else if (operation == OUTPUT_READPIXELS)
1683                 {
1684                         if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL)
1685                         {
1686                                 return false;
1687                         }
1688
1689                         if (format.format == GL_DEPTH_COMPONENT && internalformat.baseFormat != GL_DEPTH_STENCIL &&
1690                                 internalformat.baseFormat != GL_DEPTH_COMPONENT)
1691                         {
1692                                 return false;
1693                         }
1694
1695                         if (format.format == GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL &&
1696                                 internalformat.baseFormat != GL_STENCIL_INDEX)
1697                         {
1698                                 return false;
1699                         }
1700                 }
1701
1702                 if (type.special == true)
1703                 {
1704                         bool valid = false;
1705
1706                         for (i = 0; i < DE_LENGTH_OF_ARRAY(coreValidFormats); ++i)
1707                         {
1708                                 if (coreValidFormats[i].format == format.format && coreValidFormats[i].type == type.type)
1709                                 {
1710                                         valid = true;
1711                                         break;
1712                                 }
1713                         }
1714
1715                         if (!valid)
1716                                 return false;
1717                 }
1718
1719                 if ((format.componentFormat == FORMAT_COLOR_INTEGER) &&
1720                         !(internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT))
1721                 {
1722                         return false;
1723                 }
1724
1725                 if (!(format.componentFormat == FORMAT_COLOR_INTEGER) &&
1726                         (internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT))
1727                 {
1728                         return false;
1729                 }
1730
1731                 if ((m_textureTarget == GL_TEXTURE_3D) &&
1732                         ((internalformat.baseFormat == GL_DEPTH_COMPONENT) || (internalformat.baseFormat == GL_DEPTH_STENCIL) ||
1733                          (internalformat.sizedFormat == GL_COMPRESSED_RED_RGTC1) ||
1734                          (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RED_RGTC1) ||
1735                          (internalformat.sizedFormat == GL_COMPRESSED_RG_RGTC2) ||
1736                          (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RG_RGTC2)))
1737                 {
1738                         return false;
1739                 }
1740         }
1741
1742         return true;
1743 }
1744
1745 bool RectangleTest::isUnsizedFormat(GLenum format) const
1746 {
1747         GLenum  formats[]  = { GL_RGBA, GL_RGB, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA };
1748         GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats);
1749         return (std::find(formats, formatsEnd, format) < formatsEnd);
1750 }
1751
1752 bool RectangleTest::isSRGBFormat(const InternalFormat& internalFormat) const
1753 {
1754         return (internalFormat.sizedFormat == GL_SRGB8) || (internalFormat.sizedFormat == GL_SRGB8_ALPHA8);
1755 }
1756
1757 bool RectangleTest::isSNORMFormat(const InternalFormat& internalFormat) const
1758 {
1759         GLenum formats[] = { GL_R8_SNORM,  GL_RG8_SNORM,  GL_RGB8_SNORM,  GL_RGBA8_SNORM,
1760                                                  GL_R16_SNORM, GL_RG16_SNORM, GL_RGB16_SNORM, GL_RGBA16_SNORM };
1761         GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats);
1762         return (std::find(formats, formatsEnd, internalFormat.sizedFormat) < formatsEnd);
1763 }
1764
1765 bool RectangleTest::isCopyValid(const InternalFormat& copyInternalFormat, const InternalFormat& internalFormat) const
1766 {
1767         // check if copy between two internal formats is allowed
1768
1769         int b1 = getPixelFormat(internalFormat.format).components;
1770         int b2 = getPixelFormat(copyInternalFormat.format).components;
1771
1772         if (b2 > b1)
1773                 return false;
1774
1775         //Check that the types can be converted in CopyTexImage.
1776         if (((copyInternalFormat.sampler == SAMPLER_UINT) && (internalFormat.sampler != SAMPLER_UINT)) ||
1777                 ((copyInternalFormat.sampler == SAMPLER_INT) && (internalFormat.sampler != SAMPLER_INT)) ||
1778                 (((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) ||
1779                   (copyInternalFormat.sampler == SAMPLER_NORM)) &&
1780                  (!((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) ||
1781                         (internalFormat.sampler == SAMPLER_NORM)))))
1782         {
1783                 return false;
1784         }
1785
1786         // Core GL is less restricted then ES - check it first
1787         if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1788         {
1789                 if ((copyInternalFormat.format == GL_DEPTH_COMPONENT && internalFormat.format != GL_DEPTH_COMPONENT) ||
1790                         (copyInternalFormat.format == GL_DEPTH_STENCIL && internalFormat.format != GL_DEPTH_STENCIL) ||
1791                         (copyInternalFormat.format == GL_ALPHA && internalFormat.format != GL_ALPHA) ||
1792                         (copyInternalFormat.format == GL_LUMINANCE && internalFormat.format != GL_LUMINANCE) ||
1793                         (copyInternalFormat.format == GL_LUMINANCE_ALPHA && internalFormat.format != GL_LUMINANCE_ALPHA))
1794                 {
1795                         return false;
1796                 }
1797
1798                 return true;
1799         }
1800
1801         const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1802
1803         // GLES30 has more restricted requirement on glCopyTexImage2D
1804         // As stated in Table 3.15 and comment to glCopyTexImage2D
1805         if ((internalFormat.baseFormat == GL_DEPTH_COMPONENT) || (internalFormat.baseFormat == GL_DEPTH_STENCIL) ||
1806                 (copyInternalFormat.baseFormat == GL_DEPTH_COMPONENT) || (copyInternalFormat.baseFormat == GL_DEPTH_STENCIL) ||
1807                 ((internalFormat.baseFormat != GL_RGBA && internalFormat.baseFormat != GL_ALPHA) &&
1808                  ((copyInternalFormat.baseFormat == GL_ALPHA) || (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA))) ||
1809                 ((internalFormat.baseFormat == GL_ALPHA) &&
1810                  ((copyInternalFormat.baseFormat != GL_RGBA) && (copyInternalFormat.baseFormat != GL_ALPHA) &&
1811                   (copyInternalFormat.baseFormat != GL_LUMINANCE_ALPHA))) ||
1812                 (isSRGBFormat(internalFormat) != isSRGBFormat(copyInternalFormat)) ||
1813                 // GLES30 does not define ReadPixels types for signed normalized fixed point formats in Table 3.14,
1814                 // and conversions to SNORM internalformats are not allowed by Table 3.2
1815                 (copyInternalFormat.sampler == SAMPLER_NORM) ||
1816                 ((copyInternalFormat.sizedFormat == GL_RGB9_E5) &&
1817                  !contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float")))
1818         {
1819                 /* Some formats are activated by extensions, check. */
1820                 if (((internalFormat.baseFormat == GL_LUMINANCE && copyInternalFormat.baseFormat == GL_LUMINANCE) ||
1821                          (internalFormat.baseFormat == GL_ALPHA && copyInternalFormat.baseFormat == GL_ALPHA) ||
1822                          (internalFormat.baseFormat == GL_LUMINANCE_ALPHA &&
1823                           (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA || copyInternalFormat.baseFormat == GL_LUMINANCE ||
1824                            copyInternalFormat.baseFormat == GL_ALPHA))) &&
1825                         contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha"))
1826                 {
1827                         return true;
1828                 }
1829                 else if (contextInfo.isExtensionSupported("GL_EXT_render_snorm") && isSNORMFormat(copyInternalFormat) &&
1830                                  (internalFormat.sampler == copyInternalFormat.sampler) &&
1831                                  (((copyInternalFormat.baseFormat == GL_RED) &&
1832                                    (internalFormat.baseFormat == GL_RED || internalFormat.baseFormat == GL_RG ||
1833                                         internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA ||
1834                                         copyInternalFormat.baseFormat == GL_LUMINANCE)) ||
1835                                   ((copyInternalFormat.baseFormat == GL_RG) &&
1836                                    (internalFormat.baseFormat == GL_RG || internalFormat.baseFormat == GL_RGB ||
1837                                         internalFormat.baseFormat == GL_RGBA)) ||
1838                                   ((copyInternalFormat.baseFormat == GL_RGB) &&
1839                                    (internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA)) ||
1840                                   ((copyInternalFormat.baseFormat == GL_RGBA) && (internalFormat.baseFormat == GL_RGBA))))
1841                 {
1842                         return true;
1843                 }
1844
1845                 return false;
1846         }
1847         else
1848         {
1849                 if (internalFormat.sampler != copyInternalFormat.sampler)
1850                 {
1851                         // You can't convert between different base types, for example NORM<->FLOAT.
1852                         return false;
1853                 }
1854                 if (!isUnsizedFormat(copyInternalFormat.sizedFormat))
1855                 {
1856                         if ((internalFormat.bits.bits.red && copyInternalFormat.bits.bits.red &&
1857                                  internalFormat.bits.bits.red != copyInternalFormat.bits.bits.red) ||
1858                                 (internalFormat.bits.bits.green && copyInternalFormat.bits.bits.green &&
1859                                  internalFormat.bits.bits.green != copyInternalFormat.bits.bits.green) ||
1860                                 (internalFormat.bits.bits.blue && copyInternalFormat.bits.bits.blue &&
1861                                  internalFormat.bits.bits.blue != copyInternalFormat.bits.bits.blue) ||
1862                                 (internalFormat.bits.bits.alpha && copyInternalFormat.bits.bits.alpha &&
1863                                  internalFormat.bits.bits.alpha != copyInternalFormat.bits.bits.alpha))
1864                         {
1865                                 // If the destination internalFormat is sized we don't allow component size changes.
1866                                 return false;
1867                         }
1868                 }
1869                 else
1870                 {
1871                         if (internalFormat.sizedFormat == GL_RGB10_A2)
1872                         {
1873                                 // Not allowed to convert from a GL_RGB10_A2 surface.
1874                                 return false;
1875                         }
1876                 }
1877         }
1878
1879         return true;
1880 }
1881
1882 bool RectangleTest::isFBOImageAttachValid(const InternalFormat& internalformat, GLenum format, GLenum type) const
1883 {
1884         const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1885
1886         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
1887         {
1888                 const EnumFormats* validFormat = getCanonicalFormat(internalformat, format, type);
1889                 if (validFormat != 0)
1890                 {
1891                         if (!validFormat->bRenderable)
1892                         {
1893                                 /* Some formats are activated by extensions, check. */
1894                                 if ((GL_RGBA32F == validFormat->internalformat || GL_RGBA16F == validFormat->internalformat ||
1895                                          GL_RG32F == validFormat->internalformat || GL_RG16F == validFormat->internalformat ||
1896                                          GL_R32F == validFormat->internalformat || GL_R16F == validFormat->internalformat ||
1897                                          GL_R11F_G11F_B10F == validFormat->internalformat) &&
1898                                         contextInfo.isExtensionSupported("GL_EXT_color_buffer_float"))
1899                                 {
1900                                         return true;
1901                                 }
1902
1903                                 if ((GL_RGBA16F == validFormat->internalformat || GL_RGB16F == validFormat->internalformat ||
1904                                          GL_RG16F == validFormat->internalformat || GL_R16F == validFormat->internalformat) &&
1905                                         contextInfo.isExtensionSupported("GL_EXT_color_buffer_half_float"))
1906                                 {
1907                                         return true;
1908                                 }
1909
1910                                 if ((GL_R11F_G11F_B10F == validFormat->internalformat || GL_RGB9_E5 == validFormat->internalformat) &&
1911                                         contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float"))
1912                                 {
1913                                         return true;
1914                                 }
1915
1916                                 if ((GL_LUMINANCE == validFormat->internalformat || GL_ALPHA == validFormat->internalformat ||
1917                                          GL_LUMINANCE_ALPHA == validFormat->internalformat) &&
1918                                         contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha"))
1919                                 {
1920                                         return true;
1921                                 }
1922
1923                                 if ((GL_SRGB8 == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_NV_sRGB_formats"))
1924                                 {
1925                                         return true;
1926                                 }
1927
1928                                 if (((GL_R8_SNORM == validFormat->internalformat) || (GL_RG8_SNORM == validFormat->internalformat) ||
1929                                          (GL_RGBA8_SNORM == validFormat->internalformat) || (GL_R16_SNORM == validFormat->internalformat) ||
1930                                          (GL_RG16_SNORM == validFormat->internalformat) ||
1931                                          (GL_RGBA16_SNORM == validFormat->internalformat)) &&
1932                                         contextInfo.isExtensionSupported("GL_EXT_render_snorm"))
1933                                 {
1934                                         return true;
1935                                 }
1936                         }
1937                         return validFormat->bRenderable;
1938                 }
1939                 else
1940                 {
1941                         // Check for NV_packed_float
1942                         if (GL_RGB == internalformat.sizedFormat && GL_RGB == format && GL_UNSIGNED_INT_10F_11F_11F_REV == type &&
1943                                 contextInfo.isExtensionSupported("GL_NV_packed_float"))
1944                         {
1945                                 return true;
1946                         }
1947                         return false;
1948                 }
1949         }
1950         else
1951         {
1952                 if (format == GL_DEPTH_STENCIL && internalformat.sizedFormat != GL_DEPTH24_STENCIL8 &&
1953                         internalformat.sizedFormat != GL_DEPTH32F_STENCIL8)
1954                 {
1955                         // We can't make a complete DEPTH_STENCIL attachment with a
1956                         // texture that does not have both DEPTH and STENCIL components.
1957                         return false;
1958                 }
1959
1960                 GLenum colorRenderableFrmats[] = { GL_RGBA32F,  GL_RGBA32I, GL_RGBA32UI,         GL_RGBA16,
1961                                                                                    GL_RGBA16F,  GL_RGBA16I, GL_RGBA16UI,         GL_RGBA8,
1962                                                                                    GL_RGBA8I,    GL_RGBA8UI, GL_SRGB8_ALPHA8, GL_RGB10_A2,
1963                                                                                    GL_RGB10_A2UI, GL_RGB5_A1, GL_RGBA4,            GL_R11F_G11F_B10F,
1964                                                                                    GL_RGB565,    GL_RG32F,   GL_RG32I,             GL_RG32UI,
1965                                                                                    GL_RG16,               GL_RG16F,   GL_RG16I,            GL_RG16UI,
1966                                                                                    GL_RG8,                GL_RG8I,      GL_RG8UI,                  GL_R32F,
1967                                                                                    GL_R32I,               GL_R32UI,   GL_R16F,             GL_R16I,
1968                                                                                    GL_R16UI,      GL_R16,        GL_R8,            GL_R8I,
1969                                                                                    GL_R8UI };
1970                 GLenum* formatsEnd = colorRenderableFrmats + DE_LENGTH_OF_ARRAY(colorRenderableFrmats);
1971                 if (std::find(colorRenderableFrmats, formatsEnd, internalformat.sizedFormat) < formatsEnd)
1972                         return true;
1973
1974                 GLenum dsRenderableFormats[] = {
1975                         GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
1976                         GL_DEPTH32F_STENCIL8,  GL_DEPTH24_STENCIL8,
1977                 };
1978
1979                 formatsEnd = dsRenderableFormats + DE_LENGTH_OF_ARRAY(dsRenderableFormats);
1980                 if (std::find(dsRenderableFormats, formatsEnd, internalformat.sizedFormat) < formatsEnd)
1981                         return true;
1982
1983                 return false;
1984         }
1985 }
1986
1987 bool RectangleTest::doRead(GLuint texture)
1988 {
1989         glu::RenderContext& renderContext = m_context.getRenderContext();
1990         const Functions&        gl                        = renderContext.getFunctions();
1991
1992         GLuint fboId;
1993         gl.genFramebuffers(1, &fboId);
1994         gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
1995         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
1996
1997         bool validImageAttach = isFBOImageAttachValid(m_internalFormat, m_inputFormat.format, m_inputType.type);
1998         if (m_textureTarget == GL_TEXTURE_2D)
1999                 gl.framebufferTexture2D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_2D, texture, 0);
2000         else if (glu::isContextTypeES(renderContext.getType()))
2001                 gl.framebufferTextureLayer(GL_FRAMEBUFFER, m_inputFormat.attachment, texture, 0, 0);
2002         else
2003                 gl.framebufferTexture3D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_3D, texture, 0, 0);
2004         GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2005
2006         bool result = true;
2007         if (status == GL_FRAMEBUFFER_COMPLETE)
2008         {
2009                 if (!validImageAttach && glu::isContextTypeES(renderContext.getType()))
2010                 {
2011                         m_testCtx.getLog() << tcu::TestLog::Message << "FBO is complete but expected incomplete with sizedFormat: "
2012                                                            << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage;
2013                         result = false;
2014                 }
2015                 else
2016                 {
2017                         result &= readPixels(false);
2018                         result &= doCopy();
2019                 }
2020         }
2021         else if (validImageAttach)
2022         {
2023                 m_testCtx.getLog() << tcu::TestLog::Message << "FBO is not complete but expected complete with sizedFormat: "
2024                                                    << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage;
2025                 result = false;
2026         }
2027
2028         gl.deleteFramebuffers(1, &fboId);
2029
2030         return result;
2031 }
2032
2033 bool RectangleTest::readPixels(bool isCopy)
2034 {
2035         bool result = true;
2036
2037         const PixelType*   types;
2038         int                                typesCount;
2039         const PixelFormat* formats;
2040         int                                formatsCount;
2041
2042         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
2043         {
2044                 types            = esTypes;
2045                 typesCount   = DE_LENGTH_OF_ARRAY(esTypes);
2046                 formats          = esFormats;
2047                 formatsCount = DE_LENGTH_OF_ARRAY(esFormats);
2048         }
2049         else
2050         {
2051                 types            = coreTypes;
2052                 typesCount   = DE_LENGTH_OF_ARRAY(coreTypes);
2053                 formats          = coreFormats;
2054                 formatsCount = DE_LENGTH_OF_ARRAY(coreFormats);
2055         }
2056
2057         // for each output format
2058         for (int m = 0; m < formatsCount; ++m)
2059         {
2060                 const PixelFormat& outputFormat = formats[m];
2061
2062                 // for each output type
2063                 for (int n = 0; n < typesCount; ++n)
2064                 {
2065                         const PixelType& outputType = types[n];
2066
2067                         if (isCopy)
2068                         {
2069                                 // continue when input format,type != canonical format,type and
2070                                 // output format,type != canonical format,type
2071                                 if ((outputFormat.format != m_copyInternalFormat.format ||
2072                                          outputType.type != m_copyInternalFormat.type))
2073                                 {
2074                                         // invalid output format and type - skipping case
2075                                         continue;
2076                                 }
2077                         }
2078                         else if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) &&
2079                                          (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type))
2080                         {
2081                                 // invalid output format and type - skipping case
2082                                 continue;
2083                         }
2084
2085                         result &= readPixelsInner(outputFormat, outputType, isCopy);
2086                 }
2087         }
2088
2089         return result;
2090 }
2091
2092 bool RectangleTest::readPixelsInner(const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy)
2093 {
2094         const char* copyStage = "Copy stage: ";
2095
2096         GLenum readerror = readOutputData(outputFormat, outputType, OUTPUT_READPIXELS);
2097         if (m_outputBuffer.empty())
2098         {
2099                 m_testCtx.getLog() << tcu::TestLog::Message << "No buffer allocated" << tcu::TestLog::EndMessage;
2100                 return false;
2101         }
2102
2103         m_countReadPixels++;
2104
2105         // Check if output format is valid
2106         bool outputFormatValid = isFormatValid(outputFormat, outputType, isCopy ? m_copyInternalFormat : m_internalFormat,
2107                                                                                    false, true, OUTPUT_READPIXELS);
2108
2109         // Even if this is a valid glReadPixels format, we can't read non-existant components
2110         if (outputFormatValid && outputFormat.format == GL_DEPTH_STENCIL && m_inputFormat.format != GL_DEPTH_STENCIL)
2111                 outputFormatValid = false;
2112
2113         if (outputFormatValid)
2114         {
2115                 if (readerror != GL_NO_ERROR)
2116                 {
2117                         m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2118                                                            << "Valid format used but glReadPixels failed for input = ["
2119                                                            << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type)
2120                                                            << "] output = [" << getFormatStr(outputFormat.format) << ", "
2121                                                            << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage;
2122                         return false;
2123                 }
2124                 else
2125                 {
2126                         m_countReadPixelsOK++;
2127                         m_countCompare++;
2128
2129                         // compare output gradient to input gradient
2130                         if (!compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, isCopy))
2131                         {
2132                                 m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2133                                                                    << "Gradient comparison failed during ReadPixels for input = ["
2134                                                                    << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type)
2135                                                                    << "] output = [" << getFormatStr(outputFormat.format) << ", "
2136                                                                    << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage;
2137                                 return false;
2138                         }
2139
2140                         m_countCompareOK++;
2141                 }
2142         }
2143         else if (readerror == GL_NO_ERROR)
2144         {
2145                 m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2146                                                    << "Invalid format used but glReadPixels succeeded for input = ["
2147                                                    << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type)
2148                                                    << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type)
2149                                                    << "]" << tcu::TestLog::EndMessage;
2150                 return false;
2151         }
2152
2153         return true;
2154 }
2155
2156 GLenum RectangleTest::readOutputData(const PixelFormat& outputFormat, const PixelType& outputType, int operation)
2157 {
2158         // If using PBOs buffer object for GL_PIXEL_PACK_BUFFER must
2159         // be bound and not allocated before calling when using PBOs
2160
2161         glu::RenderContext& renderContext = m_context.getRenderContext();
2162         const Functions&        gl                        = renderContext.getFunctions();
2163
2164         PackedPixelsBufferProperties& props = m_packProperties;
2165         props.elementSize                                       = outputType.size;
2166         props.elementsInGroup                           = outputType.special ? 1 : outputFormat.components;
2167         props.rowLength                    = (props.rowLength == 0) ? (GRADIENT_WIDTH + props.skipPixels) : props.rowLength;
2168         props.elementsInRowNoAlign = props.elementsInGroup * props.rowLength;
2169         props.elementsInRow                = props.elementsInRowNoAlign;
2170
2171         if (glu::isContextTypeES(renderContext.getType()))
2172         {
2173                 props.rowCount   = 0;
2174                 props.skipImages = 0;
2175         }
2176         else if ((operation == OUTPUT_READPIXELS) || (m_textureTarget == GL_TEXTURE_2D))
2177                 props.skipImages = 0;
2178
2179         if (props.rowCount == 0)
2180                 props.rowCount = GRADIENT_HEIGHT + props.skipRows;
2181         props.imagesCount  = props.skipImages + 1;
2182         if (props.elementSize < props.alignment)
2183         {
2184                 props.elementsInRow = (int)(props.alignment * deFloatCeil(props.elementSize * props.elementsInGroup *
2185                                                                                                                                   props.rowLength / ((float)props.alignment))) /
2186                                                           props.elementSize;
2187         }
2188
2189         int bufferSize =
2190                 props.elementSize * props.elementsInRow * props.rowCount * props.imagesCount * (props.skipImages + 1);
2191
2192         // The output buffer allocated should be initialized to a known value. After
2193         // a pack operation, any extra memory allocated for skipping should be
2194         // verified to be the original known value, untouched by the GL.
2195         const GLubyte defaultFillValue = 0xaa;
2196         m_outputBuffer.resize(static_cast<std::size_t>(bufferSize));
2197         std::fill(m_outputBuffer.begin(), m_outputBuffer.end(), defaultFillValue);
2198
2199         GLuint packPBO;
2200         if (m_usePBO)
2201         {
2202                 gl.genBuffers(1, &packPBO);
2203                 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, packPBO);
2204                 gl.bufferData(GL_PIXEL_PACK_BUFFER, bufferSize, &m_outputBuffer[0], GL_STATIC_READ);
2205         }
2206
2207         GLenum readError = GL_NO_ERROR;
2208         switch (operation)
2209         {
2210         case OUTPUT_GETTEXIMAGE:
2211                 gl.getTexImage(m_textureTarget, 0, outputFormat.format, outputType.type, m_usePBO ? 0 : &m_outputBuffer[0]);
2212                 break;
2213
2214         case OUTPUT_READPIXELS:
2215                 if (m_inputFormat.attachment != GL_DEPTH_ATTACHMENT &&
2216                         m_inputFormat.attachment != GL_DEPTH_STENCIL_ATTACHMENT &&
2217                         m_inputFormat.attachment != GL_STENCIL_ATTACHMENT)
2218                         gl.readBuffer(m_inputFormat.attachment);
2219
2220                 readError = gl.getError();
2221                 if (readError == GL_NO_ERROR)
2222                         gl.readPixels(0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, outputFormat.format, outputType.type,
2223                                                   m_usePBO ? 0 : &m_outputBuffer[0]);
2224                 break;
2225         }
2226
2227         if (readError == GL_NO_ERROR)
2228                 readError = gl.getError();
2229
2230         if (m_usePBO)
2231         {
2232                 if (readError == GL_NO_ERROR)
2233                 {
2234                         GLvoid* mappedData = gl.mapBufferRange(GL_PIXEL_PACK_BUFFER, 0, bufferSize, GL_MAP_READ_BIT);
2235                         if (!mappedData)
2236                                 return GL_INVALID_INDEX;
2237
2238                         std::memcpy(&m_outputBuffer[0], mappedData, bufferSize);
2239                         gl.unmapBuffer(GL_PIXEL_PACK_BUFFER);
2240                 }
2241
2242                 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2243                 gl.deleteBuffers(1, &packPBO);
2244         }
2245
2246         if (m_packProperties.swapBytes && (readError == GL_NO_ERROR))
2247                 swapBytes(outputType.size, m_outputBuffer);
2248
2249         return readError;
2250 }
2251
2252 bool RectangleTest::doCopy()
2253 {
2254         bool result = true;
2255
2256         const InternalFormat* copyInternalFormats;
2257         int                                       internalFormatsCount;
2258         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
2259         {
2260                 copyInternalFormats  = esInternalformats;
2261                 internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats);
2262         }
2263         else
2264         {
2265                 copyInternalFormats  = coreInternalformats;
2266                 internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats);
2267         }
2268
2269         if ((m_inputFormat.format == m_internalFormat.format) && (m_inputType.type == m_internalFormat.type))
2270         {
2271                 for (int i = 0; i < internalFormatsCount; ++i)
2272                 {
2273                         m_copyInternalFormat = copyInternalFormats[i];
2274                         result &= doCopyInner();
2275                 }
2276         }
2277
2278         return result;
2279 }
2280
2281 bool RectangleTest::doCopyInner()
2282 {
2283         glu::RenderContext& renderContext = m_context.getRenderContext();
2284         const Functions&        gl                        = renderContext.getFunctions();
2285         bool                            result            = true;
2286
2287         const EnumFormats* copyFormatEnum =
2288                 getCanonicalFormat(m_copyInternalFormat, m_copyInternalFormat.format, m_copyInternalFormat.type);
2289
2290         if (copyFormatEnum != 0)
2291         {
2292                 GLuint texture2;
2293                 GLenum status;
2294
2295                 bool validcopy = isCopyValid(m_copyInternalFormat, m_internalFormat);
2296
2297                 gl.genTextures(1, &texture2);
2298                 // Target is always GL_TEXTURE_2D
2299                 gl.bindTexture(GL_TEXTURE_2D, texture2);
2300                 GLenum error = gl.getError();
2301
2302                 // CopyTexImage to copy_internalformat (GL converts, but PixelStore is ignored)
2303                 // Target is always GL_TEXTURE_2D
2304                 gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_copyInternalFormat.sizedFormat, 0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0);
2305                 error = gl.getError();
2306
2307                 // if this combination of copy_internalformat,internalformat is invalid
2308                 if (validcopy == false)
2309                 {
2310                         // expect error and continue
2311                         if (error != GL_NO_ERROR)
2312                         {
2313                                 // Invalid format used and glCopyTexImage2D failed
2314                                 result = true;
2315                         }
2316                         else
2317                         {
2318                                 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glCopyTexImage2D succeeded"
2319                                                                    << tcu::TestLog::EndMessage;
2320                                 result = false;
2321                         }
2322                 }
2323                 else // validcopy == true
2324                 {
2325                         // expect no error and continue
2326                         if (error != GL_NO_ERROR)
2327                         {
2328                                 m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glCopyTexImage2D failed"
2329                                                                    << tcu::TestLog::EndMessage;
2330                                 result = false;
2331                         }
2332                         else
2333                         {
2334                                 if (!glu::isContextTypeES(renderContext.getType()))
2335                                 {
2336                                         // if GetTexImage is supported we call the
2337                                         // inner function only as no loop needed
2338                                         const PixelFormat& outputFormat = getPixelFormat(copyFormatEnum->format);
2339                                         const PixelType&   outputType   = getPixelType(copyFormatEnum->type);
2340                                         result &= getTexImageInner(outputFormat, outputType);
2341                                 }
2342
2343                                 GLint orginalFboId;
2344                                 gl.getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &orginalFboId);
2345                                 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2346
2347                                 GLuint fboId;
2348                                 gl.genFramebuffers(1, &fboId);
2349                                 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
2350
2351                                 bool validImageAttach =
2352                                         isFBOImageAttachValid(m_copyInternalFormat, copyFormatEnum->format, copyFormatEnum->type);
2353
2354                                 // attach copy_internalformat texture to FBO
2355                                 // Target is always GL_TEXTURE_2D
2356                                 const PixelFormat& copyFormat = getPixelFormat(copyFormatEnum->format);
2357                                 gl.framebufferTexture2D(GL_FRAMEBUFFER, copyFormat.attachment, GL_TEXTURE_2D, texture2, 0);
2358                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
2359
2360                                 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2361                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus");
2362
2363                                 // if an unsized sizedFormat was given, then implementation chosen copy format
2364                                 // destination might be different than what's expected;
2365                                 // we cannot continue checking since ReadPixels might not choose a compatible
2366                                 // format, also the format may not be renderable as expected
2367                                 if (isUnsizedFormat(m_copyInternalFormat.sizedFormat))
2368                                 {
2369                                         result &= true;
2370                                 }
2371                                 else if (status == GL_FRAMEBUFFER_COMPLETE)
2372                                 {
2373                                         if (validImageAttach)
2374                                                 result &= readPixels(true);
2375                                         else
2376                                         {
2377                                                 m_testCtx.getLog()
2378                                                         << tcu::TestLog::Message << "Copy FBO is complete but expected incomplete with sizedFormat "
2379                                                         << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement "
2380                                                         << copyFormat.attachment << tcu::TestLog::EndMessage;
2381                                                 result = false;
2382                                         }
2383                                 }
2384                                 else if (validImageAttach)
2385                                 {
2386                                         m_testCtx.getLog() << tcu::TestLog::Message
2387                                                                            << "Copy FBO is not complete but expected complete with sizedFormat "
2388                                                                            << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement "
2389                                                                            << copyFormat.attachment << tcu::TestLog::EndMessage;
2390                                         result = false;
2391                                 }
2392
2393                                 // bind original FBO
2394                                 gl.bindFramebuffer(GL_FRAMEBUFFER, orginalFboId);
2395                                 gl.deleteFramebuffers(1, &fboId);
2396                         }
2397                 }
2398
2399                 gl.deleteTextures(1, &texture2);
2400         }
2401
2402         return result;
2403 }
2404
2405 bool RectangleTest::compare(GLvoid* gradient, GLvoid* data, const PixelFormat& outputFormat,
2406                                                         const PixelType& outputType, bool isCopy) const
2407 {
2408         // Compares the reference gradient data to the output data
2409
2410         int iformatSampler = m_internalFormat.sampler;
2411         int outputSampler  = getSampler(outputType, outputFormat);
2412         int inputSampler   = getSampler(m_inputType, m_inputFormat);
2413
2414         if (isCopy)
2415                 iformatSampler = m_copyInternalFormat.sampler;
2416
2417         int samplerIsIntUintFloat = 3; // 1: INT | 2: UINT | 3: FLOAT/UNORM/NORM
2418         if (m_internalFormat.sampler == SAMPLER_INT)
2419                 samplerIsIntUintFloat = 1;
2420         else if (m_internalFormat.sampler == SAMPLER_UINT)
2421                 samplerIsIntUintFloat = 2;
2422
2423         std::vector<GLubyte> gradientStrip;
2424         if (!stripBuffer(m_unpackProperties, static_cast<const GLubyte*>(gradient), gradientStrip, false))
2425                 return false;
2426         std::vector<GLubyte> dataStrip;
2427         if (!stripBuffer(m_packProperties, static_cast<const GLubyte*>(data), dataStrip, true))
2428                 return false;
2429
2430         if (gradientStrip.empty() || dataStrip.empty())
2431                 return false;
2432
2433         std::vector<FloatPixel> inputBuffer;
2434         getFloatBuffer(&gradientStrip[0], samplerIsIntUintFloat, m_inputFormat, m_inputType,
2435                                    GRADIENT_WIDTH * GRADIENT_HEIGHT, inputBuffer);
2436
2437         std::vector<FloatPixel> outputBuffer;
2438         getFloatBuffer(&dataStrip[0], samplerIsIntUintFloat, outputFormat, outputType, GRADIENT_WIDTH * GRADIENT_HEIGHT,
2439                                    outputBuffer);
2440
2441         std::vector<int> inputBitTable;
2442         getBits(m_inputType, m_inputFormat, inputBitTable);
2443         std::vector<int> outputBitTable;
2444         getBits(outputType, outputFormat, outputBitTable);
2445         const int* internalformatBitTable = reinterpret_cast<const int*>(&m_internalFormat.bits);
2446         const int* copyFormatBitTable    = m_copyInternalFormat.bits.array;
2447
2448         // make struct field iterable
2449         float* inputBufferFloat  = reinterpret_cast<float*>(&inputBuffer[0]);
2450         float* outputBufferFloat = reinterpret_cast<float*>(&outputBuffer[0]);
2451
2452         int* inputBufferInt  = reinterpret_cast<int*>(&inputBuffer[0]);
2453         int* outputBufferInt = reinterpret_cast<int*>(&outputBuffer[0]);
2454
2455         unsigned int* inputBufferUint  = reinterpret_cast<unsigned int*>(&inputBuffer[0]);
2456         unsigned int* outputBufferUint = reinterpret_cast<unsigned int*>(&outputBuffer[0]);
2457
2458         for (int i = 0; i < GRADIENT_WIDTH * GRADIENT_HEIGHT; ++i)
2459         {
2460                 for (int j = 0; j < NUM_FLOAT_PIXEL_COUNT / 3; ++j)
2461                 {
2462                         int bit1 = getRealBitPrecision(inputBitTable[j], inputSampler == SAMPLER_FLOAT);
2463                         int bit2 = getRealBitPrecision(outputBitTable[j], outputSampler == SAMPLER_FLOAT);
2464                         int bit3 = getRealBitPrecision(internalformatBitTable[j], iformatSampler == SAMPLER_FLOAT);
2465                         int bitdiff;
2466
2467                         if (bit1 >= bit3)
2468                         {
2469                                 if ((inputSampler == SAMPLER_UNORM && m_internalFormat.sampler == SAMPLER_NORM))
2470                                         bit3 -= 1;
2471                         }
2472
2473                         if (bit2 <= bit3)
2474                         {
2475                                 if (outputSampler == SAMPLER_NORM && m_internalFormat.sampler == SAMPLER_UNORM)
2476                                         bit2 -= 1;
2477                         }
2478
2479                         if (!(m_internalFormat.flags & FLAG_REQ_RBO) && bit3 > 8 && m_internalFormat.sampler != SAMPLER_UINT &&
2480                                 m_internalFormat.sampler != SAMPLER_INT)
2481                         {
2482                                 // If this internalFormat is not a required format there is no requirement
2483                                 // that the implementation uses exactly the bit width requested. For example,
2484                                 // it may substitute RGB10 for RGB12. The implementation can't make subtitutions
2485                                 // for integer formats.
2486                                 bit3 = 8;
2487                         }
2488
2489                         bitdiff = std::min(std::min(bit1, bit2), bit3);
2490                         if (isCopy)
2491                         {
2492                                 bitdiff = std::min(bitdiff, copyFormatBitTable[j]);
2493                         }
2494
2495                         if (bitdiff > 0)
2496                         {
2497                                 if (samplerIsIntUintFloat == 1) // 1: INT
2498                                 {
2499                                         int inputValue  = inputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j];
2500                                         int outputValue = outputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j];
2501
2502                                         if (inputSampler == SAMPLER_UINT)
2503                                                 // If input data was unsigned, it should be clamped to fit into
2504                                                 // internal format positive range (otherwise it may wrap and
2505                                                 // yield negative internalformat values)
2506                                                 inputValue = clampUnsignedValue(bit3 - 1, inputValue);
2507                                         ;
2508
2509                                         inputValue = clampSignedValue(bit3, inputValue);
2510                                         if (isCopy)
2511                                         {
2512                                                 inputValue = clampSignedValue(copyFormatBitTable[j], inputValue);
2513                                         }
2514                                         if (outputSampler == SAMPLER_UINT)
2515                                                 inputValue = clampUnsignedValue(bit2, inputValue);
2516                                         else
2517                                                 inputValue = clampSignedValue(bit2, inputValue);
2518
2519                                         if (inputValue != outputValue)
2520                                         {
2521                                                 m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", "
2522                                                                                    << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue
2523                                                                                    << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2524                                                 return false;
2525                                         }
2526                                 }
2527                                 else if (samplerIsIntUintFloat == 2) // 2: UINT
2528                                 {
2529                                         unsigned int inputValue  = inputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6];
2530                                         unsigned int outputValue = outputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6];
2531
2532                                         inputValue = clampUnsignedValue(bit3, inputValue);
2533                                         if (isCopy)
2534                                                 inputValue = clampUnsignedValue(copyFormatBitTable[j], inputValue);
2535
2536                                         if (outputSampler == SAMPLER_UINT)
2537                                                 inputValue = clampUnsignedValue(bit2, inputValue);
2538                                         else if (outputSampler == SAMPLER_INT)
2539                                                 inputValue = clampUnsignedValue(bit2 - 1, inputValue);
2540                                         if (inputValue != outputValue)
2541                                         {
2542                                                 m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", "
2543                                                                                    << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue
2544                                                                                    << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2545                                                 return false;
2546                                         }
2547                                 }
2548                                 else if (samplerIsIntUintFloat == 3) // 3: FLOAT / UNORM / NORM
2549                                 {
2550                                         float inputValue  = inputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12];
2551                                         float outputValue = outputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12];
2552                                         float epsilon;
2553
2554                                         if ((outputSampler == SAMPLER_UNORM) || (outputSampler == SAMPLER_NORM))
2555                                         {
2556                                                 // Check if format is UNORM/NORM which needs different
2557                                                 // precision since it implies a int->float conversion.
2558                                                 epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1);
2559                                         }
2560                                         else if ((inputSampler == SAMPLER_FLOAT) != (outputSampler == SAMPLER_FLOAT))
2561                                         {
2562                                                 // Allow for rounding in either direction for float->int conversions.
2563                                                 epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1);
2564                                         }
2565                                         else
2566                                                 epsilon = 1.0f / ((float)((1 << bitdiff) - 1));
2567
2568                                         if (inputSampler == SAMPLER_FLOAT || outputSampler == SAMPLER_FLOAT)
2569                                         {
2570                                                 // According to GL spec the precision requirement
2571                                                 // of floating-point values is 1 part in 10^5.
2572                                                 epsilon = deFloatMax(epsilon, 0.00001f);
2573                                         }
2574
2575                                         if (m_internalFormat.flags & FLAG_COMPRESSED)
2576                                                 epsilon = deFloatMax(epsilon, 0.1f);
2577
2578                                         // Clamp input value to range of output
2579                                         if (iformatSampler == SAMPLER_UNORM || outputSampler == SAMPLER_UNORM)
2580                                                 inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), 0.0f);
2581                                         else if (iformatSampler == SAMPLER_NORM || outputSampler == SAMPLER_NORM)
2582                                                 inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), -1.0f);
2583
2584                                         // Compare the input and output
2585                                         if (deFloatAbs(inputValue - outputValue) > epsilon)
2586                                         {
2587                                                 m_testCtx.getLog()
2588                                                         << tcu::TestLog::Message << "Non-integer comparison: " << i << ", " << j << ", "
2589                                                         << NUM_FLOAT_PIXEL_COUNT * i + j << ", " << epsilon << ": " << inputValue
2590                                                         << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2591                                                 return false;
2592                                         }
2593                                 }
2594                                 else
2595                                 {
2596                                         m_testCtx.getLog() << tcu::TestLog::Message << "Sampler type cannot be recognised, so no comparison"
2597                                                                            << tcu::TestLog::EndMessage;
2598                                         return false;
2599                                 }
2600                         }
2601                 }
2602         }
2603
2604         return true;
2605 }
2606
2607 void RectangleTest::getFloatBuffer(GLvoid* gradient, int samplerIsIntUintFloat, const PixelFormat& format,
2608                                                                    const PixelType& type, int elementCount, std::vector<FloatPixel>& result) const
2609 {
2610         int componentCount = format.components;
2611         switch (type.type)
2612         {
2613         case GL_UNSIGNED_BYTE:
2614                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_BYTE, result);
2615                 break;
2616         case GL_BYTE:
2617                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_BYTE, result);
2618                 break;
2619         case GL_UNSIGNED_SHORT:
2620                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_SHORT, result);
2621                 break;
2622         case GL_SHORT:
2623                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_SHORT, result);
2624                 break;
2625         case GL_UNSIGNED_INT:
2626                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_INT, result);
2627                 break;
2628         case GL_INT:
2629                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_INT, result);
2630                 break;
2631         case GL_HALF_FLOAT:
2632                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_HALF_FLOAT, result);
2633                 break;
2634         case GL_FLOAT:
2635                 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_FLOAT, result);
2636                 break;
2637         case GL_UNSIGNED_SHORT_5_6_5:
2638                 if (samplerIsIntUintFloat == 1)
2639                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_INT, result);
2640                 else if (samplerIsIntUintFloat == 2)
2641                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_UINT, result);
2642                 else if (samplerIsIntUintFloat == 3)
2643                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5, result);
2644                 break;
2645         case GL_UNSIGNED_SHORT_4_4_4_4:
2646                 if (samplerIsIntUintFloat == 1)
2647                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_INT, result);
2648                 else if (samplerIsIntUintFloat == 2)
2649                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_UINT, result);
2650                 else if (samplerIsIntUintFloat == 3)
2651                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4, result);
2652                 break;
2653         case GL_UNSIGNED_SHORT_5_5_5_1:
2654                 if (samplerIsIntUintFloat == 1)
2655                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_INT, result);
2656                 else if (samplerIsIntUintFloat == 2)
2657                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_UINT, result);
2658                 else if (samplerIsIntUintFloat == 3)
2659                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1, result);
2660                 break;
2661         case GL_UNSIGNED_INT_2_10_10_10_REV:
2662                 if (samplerIsIntUintFloat == 1)
2663                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_INT, result);
2664                 else if (samplerIsIntUintFloat == 2)
2665                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_UINT, result);
2666                 else if (samplerIsIntUintFloat == 3)
2667                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV, result);
2668                 break;
2669         case GL_UNSIGNED_INT_24_8:
2670                 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_24_8, result);
2671                 break;
2672         case GL_UNSIGNED_INT_10F_11F_11F_REV:
2673                 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10F_11F_11F_REV, result);
2674                 break;
2675         case GL_UNSIGNED_INT_5_9_9_9_REV:
2676                 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_5_9_9_9_REV, result);
2677                 break;
2678         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
2679                 makeBufferPackedFloat(gradient, format, elementCount, pack_FLOAT_32_UNSIGNED_INT_24_8_REV, result);
2680                 break;
2681         case GL_UNSIGNED_BYTE_3_3_2:
2682                 if (samplerIsIntUintFloat == 1)
2683                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_INT, result);
2684                 else if (samplerIsIntUintFloat == 2)
2685                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_UINT, result);
2686                 else if (samplerIsIntUintFloat == 3)
2687                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2, result);
2688                 break;
2689         case GL_UNSIGNED_BYTE_2_3_3_REV:
2690                 if (samplerIsIntUintFloat == 1)
2691                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_INT, result);
2692                 else if (samplerIsIntUintFloat == 2)
2693                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_UINT, result);
2694                 else if (samplerIsIntUintFloat == 3)
2695                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV, result);
2696                 break;
2697         case GL_UNSIGNED_SHORT_5_6_5_REV:
2698                 if (samplerIsIntUintFloat == 1)
2699                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_INT, result);
2700                 else if (samplerIsIntUintFloat == 2)
2701                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_UINT, result);
2702                 else if (samplerIsIntUintFloat == 3)
2703                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV, result);
2704                 break;
2705         case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2706                 if (samplerIsIntUintFloat == 1)
2707                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_INT, result);
2708                 else if (samplerIsIntUintFloat == 2)
2709                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT, result);
2710                 else if (samplerIsIntUintFloat == 3)
2711                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV, result);
2712                 break;
2713         case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2714                 if (samplerIsIntUintFloat == 1)
2715                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_INT, result);
2716                 else if (samplerIsIntUintFloat == 2)
2717                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT, result);
2718                 else if (samplerIsIntUintFloat == 3)
2719                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV, result);
2720                 break;
2721         case GL_UNSIGNED_INT_8_8_8_8:
2722                 if (samplerIsIntUintFloat == 1)
2723                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_INT, result);
2724                 else if (samplerIsIntUintFloat == 2)
2725                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_UINT, result);
2726                 else if (samplerIsIntUintFloat == 3)
2727                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8, result);
2728                 break;
2729         case GL_UNSIGNED_INT_8_8_8_8_REV:
2730                 if (samplerIsIntUintFloat == 1)
2731                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_INT, result);
2732                 else if (samplerIsIntUintFloat == 2)
2733                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_UINT, result);
2734                 else if (samplerIsIntUintFloat == 3)
2735                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV, result);
2736                 break;
2737         case GL_UNSIGNED_INT_10_10_10_2:
2738                 if (samplerIsIntUintFloat == 1)
2739                         makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_INT, result);
2740                 else if (samplerIsIntUintFloat == 2)
2741                         makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_UINT, result);
2742                 else if (samplerIsIntUintFloat == 3)
2743                         makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2, result);
2744                 break;
2745         default:
2746                 TCU_FAIL("Unsuported type");
2747         }
2748 }
2749
2750 template <typename Type>
2751 void RectangleTest::makeBuffer(const GLvoid* gradient, const PixelFormat& format, int samplerIsIntUintFloat,
2752                                                            int elementCount, int componentCount, float (*pack)(Type),
2753                                                            std::vector<FloatPixel>& result) const
2754 {
2755         const Type* sourceData = static_cast<const Type*>(gradient);
2756         result.resize(sizeof(FloatPixel) * elementCount);
2757         for (int i = 0; i < elementCount; ++i)
2758         {
2759                 rawFloatPixel values;
2760                 rawIntPixel   valuesInt;
2761                 rawUintPixel  valuesUint;
2762                 for (int j = 0; j < componentCount; j++)
2763                 {
2764                         if (samplerIsIntUintFloat == 1)
2765                                 valuesInt[j] = (int)static_cast<Type>(sourceData[componentCount * i + j]);
2766                         else if (samplerIsIntUintFloat == 2)
2767                                 valuesUint[j] = (unsigned int)static_cast<Type>(sourceData[componentCount * i + j]);
2768                         else if (samplerIsIntUintFloat == 3)
2769                                 values[j] = pack(sourceData[componentCount * i + j]);
2770                 }
2771                 if (samplerIsIntUintFloat == 1)
2772                         result[i] = orderComponentsInt(valuesInt, format);
2773                 else if (samplerIsIntUintFloat == 2)
2774                         result[i] = orderComponentsUint(valuesUint, format);
2775                 else if (samplerIsIntUintFloat == 3)
2776                         result[i] = orderComponentsFloat(values, format);
2777         }
2778 }
2779
2780 void RectangleTest::getBits(const PixelType& type, const PixelFormat& format, std::vector<int>& resultTable) const
2781 {
2782         // return bit depth table based on type and format pair;
2783         // table is always NUM_FLOAT_PIXEL_COUNT digit long
2784
2785         resultTable.resize(NUM_FLOAT_PIXEL_COUNT);
2786         std::fill(resultTable.begin(), resultTable.end(), 0);
2787
2788         if (type.special == true)
2789         {
2790                 std::memcpy(&resultTable[0], &type.bits, sizeof(int) * NUM_FLOAT_PIXEL_COUNT);
2791                 if (type.type == GL_UNSIGNED_INT_5_9_9_9_REV)
2792                 {
2793                         //this type is another special case: it is always converted to 3-channel color (no A).
2794                         //as results of this function are used for comparison of converted values we set A bits to 0.
2795                         resultTable[3] = 0;
2796                 }
2797         }
2798         else
2799         {
2800                 int bits;
2801
2802                 if (type.type == GL_FLOAT)
2803                         bits = 32;
2804                 else if (type.type == GL_HALF_FLOAT)
2805                         bits = 16;
2806                 else
2807                         bits = type.size << 3;
2808
2809                 if (format.format == GL_DEPTH_STENCIL || format.format == GL_DEPTH_COMPONENT)
2810                         resultTable[4] = bits;
2811
2812                 if (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX ||
2813                         format.format == GL_STENCIL_INDEX8)
2814                 {
2815                         resultTable[5] = bits;
2816                 }
2817
2818                 if (format.format == GL_RED || format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA ||
2819                         format.format == GL_BGR || format.format == GL_BGRA || format.format == GL_RED_INTEGER ||
2820                         format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER ||
2821                         format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2822                 {
2823                         resultTable[0] = bits;
2824                 }
2825
2826                 if (format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR ||
2827                         format.format == GL_BGRA || format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER ||
2828                         format.format == GL_RGBA_INTEGER || format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2829                 {
2830                         resultTable[1] = bits;
2831                 }
2832
2833                 if (format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR ||
2834                         format.format == GL_BGRA || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER ||
2835                         format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2836                 {
2837                         resultTable[2] = bits;
2838                 }
2839
2840                 if (format.format == GL_RGBA || format.format == GL_BGRA || format.format == GL_RGBA_INTEGER ||
2841                         format.format == GL_BGRA_INTEGER)
2842                 {
2843                         resultTable[3] = bits;
2844                 }
2845         }
2846 }
2847
2848 template <typename Type>
2849 void RectangleTest::makeBufferPackedInt(const GLvoid* gradient, const PixelFormat& format, int   elementCount,
2850                                                                                 void (*pack)(rawIntPixel*, Type), std::vector<FloatPixel>& result) const
2851 {
2852         const Type* sourceData = static_cast<const Type*>(gradient);
2853         result.resize(sizeof(FloatPixel) * elementCount);
2854         for (int i = 0; i < elementCount; ++i)
2855         {
2856                 rawIntPixel values;
2857                 pack(&values, sourceData[i]);
2858                 result[i] = orderComponentsInt(values, format);
2859         }
2860 }
2861
2862 template <typename Type>
2863 void RectangleTest::makeBufferPackedUint(const GLvoid* gradient, const PixelFormat& format, int          elementCount,
2864                                                                                  void (*pack)(rawUintPixel*, Type), std::vector<FloatPixel>& result) const
2865 {
2866         const Type* sourceData = static_cast<const Type*>(gradient);
2867         result.resize(sizeof(FloatPixel) * elementCount);
2868         for (int i = 0; i < elementCount; ++i)
2869         {
2870                 rawUintPixel values;
2871                 pack(&values, sourceData[i]);
2872                 result[i] = orderComponentsUint(values, format);
2873         }
2874 }
2875
2876 template <typename Type>
2877 void RectangleTest::makeBufferPackedFloat(const GLvoid* gradient, const PixelFormat& format, int           elementCount,
2878                                                                                   void (*pack)(rawFloatPixel*, Type), std::vector<FloatPixel>& result) const
2879 {
2880         const Type* sourceData = static_cast<const Type*>(gradient);
2881         result.resize(sizeof(FloatPixel) * elementCount);
2882         for (int i = 0; i < elementCount; ++i)
2883         {
2884                 rawFloatPixel values;
2885                 pack(&values, sourceData[i]);
2886                 result[i] = orderComponentsFloat(values, format);
2887         }
2888 }
2889
2890 FloatPixel RectangleTest::orderComponentsInt(rawIntPixel values, const PixelFormat& format) const
2891 {
2892         FloatPixel fp = { PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,
2893                                           PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2894                                           PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF };
2895
2896         if (format.componentOrder.bits.red >= 0)
2897                 fp.i_r = values[format.componentOrder.bits.red];
2898         if (format.componentOrder.bits.green >= 0)
2899                 fp.i_g = values[format.componentOrder.bits.green];
2900         if (format.componentOrder.bits.blue >= 0)
2901                 fp.i_b = values[format.componentOrder.bits.blue];
2902         if (format.componentOrder.bits.alpha >= 0)
2903                 fp.i_a = values[format.componentOrder.bits.alpha];
2904         if (format.componentOrder.bits.depth >= 0)
2905                 fp.i_d = values[format.componentOrder.bits.depth];
2906         if (format.componentOrder.bits.stencil >= 0)
2907                 fp.i_s = values[format.componentOrder.bits.stencil];
2908
2909         return fp;
2910 }
2911
2912 FloatPixel RectangleTest::orderComponentsUint(rawUintPixel values, const PixelFormat& format) const
2913 {
2914         FloatPixel fp = { PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,
2915                                           PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2916                                           PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF };
2917
2918         if (format.componentOrder.bits.red >= 0)
2919                 fp.ui_r = values[format.componentOrder.bits.red];
2920         if (format.componentOrder.bits.green >= 0)
2921                 fp.ui_g = values[format.componentOrder.bits.green];
2922         if (format.componentOrder.bits.blue >= 0)
2923                 fp.ui_b = values[format.componentOrder.bits.blue];
2924         if (format.componentOrder.bits.alpha >= 0)
2925                 fp.ui_a = values[format.componentOrder.bits.alpha];
2926         if (format.componentOrder.bits.depth >= 0)
2927                 fp.ui_d = values[format.componentOrder.bits.depth];
2928         if (format.componentOrder.bits.stencil >= 0)
2929                 fp.ui_s = values[format.componentOrder.bits.stencil];
2930
2931         return fp;
2932 }
2933
2934 FloatPixel RectangleTest::orderComponentsFloat(rawFloatPixel values, const PixelFormat& format) const
2935 {
2936         FloatPixel fp = { PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,  PACK_DEFAULTI,
2937                                           PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2938                                           PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF,  PACK_DEFAULTF };
2939
2940         if (format.componentOrder.bits.red >= 0)
2941                 fp.r = values[format.componentOrder.bits.red];
2942         if (format.componentOrder.bits.green >= 0)
2943                 fp.g = values[format.componentOrder.bits.green];
2944         if (format.componentOrder.bits.blue >= 0)
2945                 fp.b = values[format.componentOrder.bits.blue];
2946         if (format.componentOrder.bits.alpha >= 0)
2947                 fp.a = values[format.componentOrder.bits.alpha];
2948         if (format.componentOrder.bits.depth >= 0)
2949                 fp.d = values[format.componentOrder.bits.depth];
2950         if (format.componentOrder.bits.stencil >= 0)
2951                 fp.s = values[format.componentOrder.bits.stencil];
2952
2953         return fp;
2954 }
2955
2956 unsigned int RectangleTest::getRealBitPrecision(int bits, bool isFloat) const
2957 {
2958         if (!isFloat)
2959                 return bits;
2960         switch (bits)
2961         {
2962         case 32:
2963                 return 23;
2964         case 16:
2965                 return 10;
2966         case 11:
2967                 return 6;
2968         case 10:
2969                 return 5;
2970         }
2971         return bits;
2972 }
2973
2974 bool RectangleTest::stripBuffer(const PackedPixelsBufferProperties& props, const GLubyte* orginalBuffer,
2975                                                                 std::vector<GLubyte>& newBuffer, bool validate) const
2976 {
2977         // Extracts pixel data from a buffer with specific
2978         // pixel store configuration into a flat buffer
2979
2980         int newBufferSize = props.elementSize * props.elementsInRowNoAlign * GRADIENT_HEIGHT;
2981         if (!newBufferSize)
2982                 return false;
2983         newBuffer.resize(newBufferSize);
2984
2985         int skipBottom = ((props.skipImages * props.rowCount + props.skipRows) * props.elementsInRow) * props.elementSize;
2986         int skipTop     = (props.rowCount - GRADIENT_HEIGHT - props.skipRows) * props.elementsInRow * props.elementSize;
2987         int skipLeft   = props.skipPixels * props.elementsInGroup * props.elementSize;
2988         int skipRight  = (props.elementsInRow - GRADIENT_WIDTH * props.elementsInGroup) * props.elementSize - skipLeft;
2989         int copy           = GRADIENT_WIDTH * props.elementsInGroup * props.elementSize;
2990         int skipAlign  = (props.elementsInRow - props.elementsInRowNoAlign) * props.elementSize;
2991
2992         if (validate)
2993         {
2994                 for (int i = 0; i < skipBottom; i++)
2995                 {
2996                         if (orginalBuffer[i] != m_defaultFillValue)
2997                                 return false;
2998                 }
2999         }
3000
3001         int index_src = skipBottom;
3002         int index_dst = 0;
3003
3004         for (int j = 0; j < GRADIENT_HEIGHT; j++)
3005         {
3006                 if (validate)
3007                 {
3008                         for (int i = 0; i < skipLeft; i++)
3009                         {
3010                                 if (orginalBuffer[index_src + i] != m_defaultFillValue)
3011                                         return false;
3012                         }
3013                 }
3014                 index_src += skipLeft;
3015
3016                 std::memcpy(&newBuffer[0] + index_dst, &orginalBuffer[0] + index_src, copy);
3017                 index_src += copy;
3018                 index_dst += copy;
3019
3020                 if (validate)
3021                 {
3022                         for (int i = skipAlign; i < skipRight; i++)
3023                         {
3024                                 if (orginalBuffer[index_src + i] != m_defaultFillValue)
3025                                         return false;
3026                         }
3027                 }
3028                 index_src += skipRight;
3029         }
3030
3031         if (validate)
3032         {
3033                 for (int i = 0; i < skipTop; i++)
3034                 {
3035                         if (orginalBuffer[index_src + i] != m_defaultFillValue)
3036                                 return false;
3037                 }
3038         }
3039         index_src += skipTop;
3040
3041         return true;
3042 }
3043
3044 int RectangleTest::clampSignedValue(int bits, int value) const
3045 {
3046         int max = 2147483647;
3047         int min = 0x80000000;
3048
3049         if (bits < 32)
3050         {
3051                 max = (1 << (bits - 1)) - 1;
3052                 min = (1 << (bits - 1)) - (1 << bits);
3053         }
3054
3055         if (value >= max)
3056                 return max;
3057         else if (value <= min)
3058                 return min;
3059
3060         return value;
3061 }
3062
3063 unsigned int RectangleTest::clampUnsignedValue(int bits, unsigned int value) const
3064 {
3065         unsigned int max = 4294967295u;
3066         unsigned int min = 0;
3067
3068         if (bits < 32)
3069         {
3070                 max = (1 << bits) - 1;
3071         }
3072
3073         if (value >= max)
3074                 return max;
3075         else if (value <= min)
3076                 return min;
3077
3078         return value;
3079 }
3080
3081 float RectangleTest::pack_UNSIGNED_BYTE(GLubyte value)
3082 {
3083         return static_cast<GLfloat>(value) / std::numeric_limits<GLubyte>::max();
3084 }
3085
3086 float RectangleTest::pack_BYTE(GLbyte value)
3087 {
3088         return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLbyte>::max(), -1.0f);
3089 }
3090
3091 float RectangleTest::pack_UNSIGNED_SHORT(GLushort value)
3092 {
3093         return static_cast<GLfloat>(value) / std::numeric_limits<GLushort>::max();
3094 }
3095
3096 float RectangleTest::pack_SHORT(GLshort value)
3097 {
3098         return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLshort>::max(), -1.0f);
3099 }
3100
3101 float RectangleTest::pack_UNSIGNED_INT(GLuint value)
3102 {
3103         return static_cast<GLfloat>(value) / std::numeric_limits<GLuint>::max();
3104 }
3105
3106 float RectangleTest::pack_INT(GLint value)
3107 {
3108         return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLint>::max(), -1.0f);
3109 }
3110
3111 float RectangleTest::pack_HALF_FLOAT(GLhalf value)
3112 {
3113         return halfFloatToFloat(value);
3114 }
3115
3116 float RectangleTest::pack_FLOAT(GLfloat value)
3117 {
3118         return value;
3119 }
3120
3121 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel* values, GLubyte value)
3122 {
3123         (*values)[0] = ((value >> 5) & 7) / 7.0f;
3124         (*values)[1] = ((value >> 2) & 7) / 7.0f;
3125         (*values)[2] = ((value >> 0) & 3) / 3.0f;
3126 }
3127
3128 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel* values, GLubyte value)
3129 {
3130         (*values)[0] = (value >> 5) & 7;
3131         (*values)[1] = (value >> 2) & 7;
3132         (*values)[2] = (value >> 0) & 3;
3133 }
3134
3135 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel* values, GLubyte value)
3136 {
3137         (*values)[0] = (static_cast<GLbyte>(value) >> 5) & 7;
3138         (*values)[1] = (static_cast<GLbyte>(value) >> 2) & 7;
3139         (*values)[2] = (static_cast<GLbyte>(value) >> 0) & 3;
3140 }
3141
3142 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel* values, GLubyte value)
3143 {
3144         (*values)[2] = ((value >> 6) & 3) / 3.0f;
3145         (*values)[1] = ((value >> 3) & 7) / 7.0f;
3146         (*values)[0] = ((value >> 0) & 7) / 7.0f;
3147 }
3148
3149 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel* values, GLubyte value)
3150 {
3151         (*values)[2] = (value >> 6) & 3;
3152         (*values)[1] = (value >> 3) & 7;
3153         (*values)[0] = (value >> 0) & 7;
3154 }
3155
3156 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel* values, GLubyte value)
3157 {
3158         (*values)[2] = (static_cast<GLbyte>(value) >> 6) & 3;
3159         (*values)[1] = (static_cast<GLbyte>(value) >> 3) & 7;
3160         (*values)[0] = (static_cast<GLbyte>(value) >> 0) & 7;
3161 }
3162
3163 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel* values, GLushort value)
3164 {
3165         (*values)[0] = ((value >> 11) & 31) / 31.0f;
3166         (*values)[1] = ((value >> 5) & 63) / 63.0f;
3167         (*values)[2] = ((value >> 0) & 31) / 31.0f;
3168 }
3169
3170 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel* values, GLushort value)
3171 {
3172         (*values)[0] = (value >> 11) & 31;
3173         (*values)[1] = (value >> 5) & 63;
3174         (*values)[2] = (value >> 0) & 31;
3175 }
3176
3177 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel* values, GLushort value)
3178 {
3179         (*values)[0] = (static_cast<GLshort>(value) >> 11) & 31;
3180         (*values)[1] = (static_cast<GLshort>(value) >> 5) & 63;
3181         (*values)[2] = (static_cast<GLshort>(value) >> 0) & 31;
3182 }
3183
3184 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel* values, GLushort value)
3185 {
3186         (*values)[2] = ((value >> 11) & 31) / 31.0f;
3187         (*values)[1] = ((value >> 5) & 63) / 63.0f;
3188         (*values)[0] = ((value >> 0) & 31) / 31.0f;
3189 }
3190
3191 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel* values, GLushort value)
3192 {
3193         (*values)[2] = (value >> 11) & 31;
3194         (*values)[1] = (value >> 5) & 63;
3195         (*values)[0] = (value >> 0) & 31;
3196 }
3197
3198 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel* values, GLushort value)
3199 {
3200         (*values)[2] = (static_cast<GLshort>(value) >> 11) & 31;
3201         (*values)[1] = (static_cast<GLshort>(value) >> 5) & 63;
3202         (*values)[0] = (static_cast<GLshort>(value) >> 0) & 31;
3203 }
3204
3205 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel* values, GLushort value)
3206 {
3207         (*values)[0] = ((value >> 12) & 15) / 15.0f;
3208         (*values)[1] = ((value >> 8) & 15) / 15.0f;
3209         (*values)[2] = ((value >> 4) & 15) / 15.0f;
3210         (*values)[3] = ((value >> 0) & 15) / 15.0f;
3211 }
3212
3213 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel* values, GLushort value)
3214 {
3215         (*values)[0] = (value >> 12) & 15;
3216         (*values)[1] = (value >> 8) & 15;
3217         (*values)[2] = (value >> 4) & 15;
3218         (*values)[3] = (value >> 0) & 15;
3219 }
3220
3221 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel* values, GLushort value)
3222 {
3223         (*values)[0] = (static_cast<GLshort>(value) >> 12) & 15;
3224         (*values)[1] = (static_cast<GLshort>(value) >> 8) & 15;
3225         (*values)[2] = (static_cast<GLshort>(value) >> 4) & 15;
3226         (*values)[3] = (static_cast<GLshort>(value) >> 0) & 15;
3227 }
3228
3229 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel* values, GLushort value)
3230 {
3231         (*values)[3] = ((value >> 12) & 15) / 15.0f;
3232         (*values)[2] = ((value >> 8) & 15) / 15.0f;
3233         (*values)[1] = ((value >> 4) & 15) / 15.0f;
3234         (*values)[0] = ((value >> 0) & 15) / 15.0f;
3235 }
3236
3237 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel* values, GLushort value)
3238 {
3239         (*values)[3] = (value >> 12) & 15;
3240         (*values)[2] = (value >> 8) & 15;
3241         (*values)[1] = (value >> 4) & 15;
3242         (*values)[0] = (value >> 0) & 15;
3243 }
3244
3245 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel* values, GLushort value)
3246 {
3247         (*values)[3] = (static_cast<GLshort>(value) >> 12) & 15;
3248         (*values)[2] = (static_cast<GLshort>(value) >> 8) & 15;
3249         (*values)[1] = (static_cast<GLshort>(value) >> 4) & 15;
3250         (*values)[0] = (static_cast<GLshort>(value) >> 0) & 15;
3251 }
3252
3253 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel* values, GLushort value)
3254 {
3255         (*values)[0] = ((value >> 11) & 31) / 31.0f;
3256         (*values)[1] = ((value >> 6) & 31) / 31.0f;
3257         (*values)[2] = ((value >> 1) & 31) / 31.0f;
3258         (*values)[3] = ((value >> 0) & 1) / 1.0f;
3259 }
3260
3261 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel* values, GLushort value)
3262 {
3263         (*values)[0] = (value >> 11) & 31;
3264         (*values)[1] = (value >> 6) & 31;
3265         (*values)[2] = (value >> 1) & 31;
3266         (*values)[3] = (value >> 0) & 1;
3267 }
3268
3269 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel* values, GLushort value)
3270 {
3271         (*values)[0] = (static_cast<GLshort>(value) >> 11) & 31;
3272         (*values)[1] = (static_cast<GLshort>(value) >> 6) & 31;
3273         (*values)[2] = (static_cast<GLshort>(value) >> 1) & 31;
3274         (*values)[3] = (static_cast<GLshort>(value) >> 0) & 1;
3275 }
3276
3277 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel* values, GLushort value)
3278 {
3279         (*values)[3] = ((value >> 15) & 1) / 1.0f;
3280         (*values)[2] = ((value >> 10) & 31) / 31.0f;
3281         (*values)[1] = ((value >> 5) & 31) / 31.0f;
3282         (*values)[0] = ((value >> 0) & 31) / 31.0f;
3283 }
3284
3285 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel* values, GLushort value)
3286 {
3287         (*values)[3] = (value >> 15) & 1;
3288         (*values)[2] = (value >> 10) & 31;
3289         (*values)[1] = (value >> 5) & 31;
3290         (*values)[0] = (value >> 0) & 31;
3291 }
3292
3293 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel* values, GLushort value)
3294 {
3295         (*values)[3] = (static_cast<GLshort>(value) >> 15) & 1;
3296         (*values)[2] = (static_cast<GLshort>(value) >> 10) & 31;
3297         (*values)[1] = (static_cast<GLshort>(value) >> 5) & 31;
3298         (*values)[0] = (static_cast<GLshort>(value) >> 0) & 31;
3299 }
3300
3301 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel* values, GLuint value)
3302 {
3303         (*values)[0] = ((value >> 24) & 255) / 255.0f;
3304         (*values)[1] = ((value >> 16) & 255) / 255.0f;
3305         (*values)[2] = ((value >> 8) & 255) / 255.0f;
3306         (*values)[3] = ((value >> 0) & 255) / 255.0f;
3307 }
3308
3309 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel* values, GLuint value)
3310 {
3311         (*values)[0] = (value >> 24) & 255;
3312         (*values)[1] = (value >> 16) & 255;
3313         (*values)[2] = (value >> 8) & 255;
3314         (*values)[3] = (value >> 0) & 255;
3315 }
3316
3317 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel* values, GLuint value)
3318 {
3319         (*values)[0] = (static_cast<GLint>(value) >> 24) & 255;
3320         (*values)[1] = (static_cast<GLint>(value) >> 16) & 255;
3321         (*values)[2] = (static_cast<GLint>(value) >> 8) & 255;
3322         (*values)[3] = (static_cast<GLint>(value) >> 0) & 255;
3323 }
3324
3325 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel* values, GLuint value)
3326 {
3327         (*values)[3] = ((value >> 24) & 255) / 255.0f;
3328         (*values)[2] = ((value >> 16) & 255) / 255.0f;
3329         (*values)[1] = ((value >> 8) & 255) / 255.0f;
3330         (*values)[0] = ((value >> 0) & 255) / 255.0f;
3331 }
3332
3333 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel* values, GLuint value)
3334 {
3335         (*values)[3] = (value >> 24) & 255;
3336         (*values)[2] = (value >> 16) & 255;
3337         (*values)[1] = (value >> 8) & 255;
3338         (*values)[0] = (value >> 0) & 255;
3339 }
3340
3341 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel* values, GLuint value)
3342 {
3343         (*values)[3] = (static_cast<GLint>(value) >> 24) & 255;
3344         (*values)[2] = (static_cast<GLint>(value) >> 16) & 255;
3345         (*values)[1] = (static_cast<GLint>(value) >> 8) & 255;
3346         (*values)[0] = (static_cast<GLint>(value) >> 0) & 255;
3347 }
3348
3349 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel* values, GLuint value)
3350 {
3351         (*values)[0] = ((value >> 22) & 1023) / 1023.0f;
3352         (*values)[1] = ((value >> 12) & 1023) / 1023.0f;
3353         (*values)[2] = ((value >> 2) & 1023) / 1023.0f;
3354         (*values)[3] = ((value >> 0) & 3) / 3.0f;
3355 }
3356
3357 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel* values, GLuint value)
3358 {
3359         (*values)[0] = ((value >> 22) & 1023);
3360         (*values)[1] = ((value >> 12) & 1023);
3361         (*values)[2] = ((value >> 2) & 1023);
3362         (*values)[3] = ((value >> 0) & 3);
3363 }
3364
3365 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel* values, GLuint value)
3366 {
3367         (*values)[0] = ((static_cast<GLint>(value) >> 22) & 1023);
3368         (*values)[1] = ((static_cast<GLint>(value) >> 12) & 1023);
3369         (*values)[2] = ((static_cast<GLint>(value) >> 2) & 1023);
3370         (*values)[3] = ((static_cast<GLint>(value) >> 0) & 3);
3371 }
3372
3373 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel* values, GLuint value)
3374 {
3375         (*values)[3] = ((value >> 30) & 3) / 3.0f;
3376         (*values)[2] = ((value >> 20) & 1023) / 1023.0f;
3377         (*values)[1] = ((value >> 10) & 1023) / 1023.0f;
3378         (*values)[0] = ((value >> 0) & 1023) / 1023.0f;
3379 }
3380
3381 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel* values, GLuint value)
3382 {
3383         (*values)[3] = (value >> 30) & 3;
3384         (*values)[2] = (value >> 20) & 1023;
3385         (*values)[1] = (value >> 10) & 1023;
3386         (*values)[0] = (value >> 0) & 1023;
3387 }
3388
3389 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel* values, GLuint value)
3390 {
3391         (*values)[3] = (static_cast<GLint>(value) >> 30) & 3;
3392         (*values)[2] = (static_cast<GLint>(value) >> 20) & 1023;
3393         (*values)[1] = (static_cast<GLint>(value) >> 10) & 1023;
3394         (*values)[0] = (static_cast<GLint>(value) >> 0) & 1023;
3395 }
3396
3397 void RectangleTest::pack_UNSIGNED_INT_24_8(rawFloatPixel* values, GLuint value)
3398 {
3399         (*values)[0] = ((value >> 8) & 16777215) / 16777215.0f;
3400         (*values)[1] = ((value >> 0) & 255) / 255.0f;
3401 }
3402
3403 void RectangleTest::pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel* values, GLuint value)
3404 {
3405         (*values)[2] = unsignedF10ToFloat((value >> 22) & 1023);
3406         (*values)[1] = unsignedF11ToFloat((value >> 11) & 2047);
3407         (*values)[0] = unsignedF11ToFloat((value >> 0) & 2047);
3408 }
3409
3410 void RectangleTest::pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel* values, GLuint value)
3411 {
3412         const int B              = 15;
3413         const int N              = 9;
3414         GLint    pExp   = ((value >> 27) & 31);
3415         GLuint  pBlue  = ((value >> 18) & 511);
3416         GLuint  pGreen = ((value >> 9) & 511);
3417         GLuint  pRed   = ((value >> 0) & 511);
3418
3419         (*values)[2] = (float)(pBlue * pow(2.0, pExp - B - N));
3420         (*values)[1] = (float)(pGreen * pow(2.0, pExp - B - N));
3421         (*values)[0] = (float)(pRed * pow(2.0, pExp - B - N));
3422         (*values)[3] = 1.0f;
3423 }
3424
3425 void RectangleTest::pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel* values, F_32_UINT_24_8_REV value)
3426 {
3427         (*values)[0] = value.d;
3428         (*values)[1] = (value.s & 255) / 255.0f;
3429 }
3430
3431 bool RectangleTest::getTexImage()
3432 {
3433         // for each output format
3434         for (int m = 0; m < DE_LENGTH_OF_ARRAY(coreFormats); ++m)
3435         {
3436                 const PixelFormat& outputFormat = coreFormats[m];
3437
3438                 // for each output type
3439                 for (int n = 0; n < DE_LENGTH_OF_ARRAY(coreTypes); ++n)
3440                 {
3441                         const PixelType& outputType = coreTypes[n];
3442
3443                         if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) &&
3444                                 (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type))
3445                         {
3446                                 continue;
3447                         }
3448
3449                         if (!getTexImageInner(outputFormat, outputType))
3450                                 return false;
3451                 }
3452         }
3453
3454         return true;
3455 }
3456
3457 bool RectangleTest::getTexImageInner(const PixelFormat& outputFormat, const PixelType& outputType)
3458 {
3459         bool outputFormatValid = isFormatValid(outputFormat, outputType, m_internalFormat, false, true, OUTPUT_GETTEXIMAGE);
3460
3461         GLenum error = readOutputData(outputFormat, outputType, OUTPUT_GETTEXIMAGE);
3462         m_countGetTexImage++;
3463
3464         if (!outputFormatValid)
3465         {
3466                 if (error)
3467                 {
3468                         m_countGetTexImageOK++;
3469                         return true;
3470                 }
3471
3472                 m_testCtx.getLog() << tcu::TestLog::Message << "Expected error but got no GL error" << tcu::TestLog::EndMessage;
3473                 return false;
3474         }
3475         else if (error)
3476         {
3477                 m_testCtx.getLog() << tcu::TestLog::Message << "Error during glGetTexImage" << tcu::TestLog::EndMessage;
3478                 return false;
3479         }
3480
3481         m_countGetTexImageOK++;
3482         m_countCompare++;
3483
3484         // compare output gradient to input gradient
3485         if (compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, false))
3486         {
3487                 m_countCompareOK++;
3488                 return true;
3489         }
3490
3491         m_testCtx.getLog() << tcu::TestLog::Message << "Gradient comparison failed during GetTexImage for input = ["
3492                                            << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = ["
3493                                            << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]"
3494                                            << tcu::TestLog::EndMessage;
3495         return false;
3496 }
3497
3498 void RectangleTest::testAllFormatsAndTypes()
3499 {
3500         DE_ASSERT((m_textureTarget == GL_TEXTURE_2D) || (m_textureTarget == GL_TEXTURE_3D));
3501
3502         glu::RenderContext& renderContext = m_context.getRenderContext();
3503         const Functions&        gl                        = renderContext.getFunctions();
3504         bool                            result            = true;
3505
3506         gl.clear(GL_COLOR_BUFFER_BIT);
3507
3508         const PixelType*   types;
3509         int                                typesCount;
3510         const PixelFormat* formats;
3511         int                                formatsCount;
3512         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
3513         {
3514                 types            = esTypes;
3515                 typesCount   = DE_LENGTH_OF_ARRAY(esTypes);
3516                 formats          = esFormats;
3517                 formatsCount = DE_LENGTH_OF_ARRAY(esFormats);
3518         }
3519         else
3520         {
3521                 types            = coreTypes;
3522                 typesCount   = DE_LENGTH_OF_ARRAY(coreTypes);
3523                 formats          = coreFormats;
3524                 formatsCount = DE_LENGTH_OF_ARRAY(coreFormats);
3525         }
3526
3527         for (int inputFormatIndex = 0; inputFormatIndex < formatsCount; inputFormatIndex++)
3528         {
3529                 m_inputFormat = formats[inputFormatIndex];
3530
3531                 for (int inputTypeIndex = 0; inputTypeIndex < typesCount; inputTypeIndex++)
3532                 {
3533                         GLenum error = 0;
3534                         m_inputType  = types[inputTypeIndex];
3535
3536                         applyInitialStorageModes();
3537
3538                         // Create input gradient in format,type, with appropriate range
3539                         createGradient();
3540                         if (m_gradient.empty())
3541                                 TCU_FAIL("Could not create gradient.");
3542
3543                         if (m_unpackProperties.swapBytes)
3544                                 swapBytes(m_inputType.size, m_gradient);
3545
3546                         GLuint texture;
3547                         gl.genTextures(1, &texture);
3548                         gl.bindTexture(m_textureTarget, texture);
3549                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
3550                         if (m_textureTarget == GL_TEXTURE_3D)
3551                         {
3552                                 gl.texImage3D(GL_TEXTURE_3D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 1, 0,
3553                                                           m_inputFormat.format, m_inputType.type, &m_gradient[0]);
3554                         }
3555                         else
3556                         {
3557                                 gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0,
3558                                                           m_inputFormat.format, m_inputType.type, &m_gradient[0]);
3559                         }
3560
3561                         if (m_unpackProperties.swapBytes)
3562                                 swapBytes(m_inputType.size, m_gradient);
3563
3564                         error = gl.getError();
3565                         if (isFormatValid(m_inputFormat, m_inputType, m_internalFormat, true, false, INPUT_TEXIMAGE))
3566                         {
3567                                 if (error == GL_NO_ERROR)
3568                                 {
3569                                         if (!glu::isContextTypeES(renderContext.getType()))
3570                                                 result &= getTexImage();
3571                                         result &= doRead(texture);
3572                                 }
3573                                 else
3574                                 {
3575                                         m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glTexImage2D/3D failed"
3576                                                                            << tcu::TestLog::EndMessage;
3577                                         result = false;
3578                                 }
3579                         }
3580                         else if (error == GL_NO_ERROR)
3581                         {
3582                                 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glTexImage2D/3D succeeded"
3583                                                                    << tcu::TestLog::EndMessage;
3584                                 result = false;
3585                         }
3586
3587                         gl.deleteTextures(1, &texture);
3588                 }
3589         }
3590
3591         if (result)
3592                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3593         else
3594                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3595 }
3596
3597 tcu::TestNode::IterateResult RectangleTest::iterate(void)
3598 {
3599         resetInitialStorageModes();
3600         testAllFormatsAndTypes();
3601         return STOP;
3602 }
3603
3604 class InitialValuesTest : public deqp::TestCase
3605 {
3606 public:
3607         InitialValuesTest(deqp::Context& context);
3608         virtual ~InitialValuesTest();
3609
3610         tcu::TestNode::IterateResult iterate(void);
3611 };
3612
3613 InitialValuesTest::InitialValuesTest(deqp::Context& context)
3614         : deqp::TestCase(context, "initial_values", "Verify if all UNPACK and PACK initial "
3615                                                                                                 "state matches the values in table 6.28 (6.23, in ES.)")
3616 {
3617 }
3618
3619 InitialValuesTest::~InitialValuesTest()
3620 {
3621 }
3622
3623 tcu::TestNode::IterateResult InitialValuesTest::iterate(void)
3624 {
3625         glu::RenderContext& renderContext = m_context.getRenderContext();
3626         const Functions&        gl                        = renderContext.getFunctions();
3627
3628         bool result = true;
3629
3630         GLenum commonIntModes[] = { GL_UNPACK_ROW_LENGTH,   GL_UNPACK_SKIP_ROWS,   GL_UNPACK_SKIP_PIXELS,
3631                                                                 GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_IMAGES, GL_PACK_ROW_LENGTH,
3632                                                                 GL_PACK_SKIP_ROWS,              GL_PACK_SKIP_PIXELS };
3633
3634         // check if following eight storage modes are 0
3635         GLint i = 1;
3636         for (int mode = 0; mode < DE_LENGTH_OF_ARRAY(commonIntModes); mode++)
3637         {
3638                 gl.getIntegerv(commonIntModes[mode], &i);
3639                 result &= (i == 0);
3640         }
3641
3642         // check if following two storage modes are 4
3643         gl.getIntegerv(GL_UNPACK_ALIGNMENT, &i);
3644         result &= (i == 4);
3645         gl.getIntegerv(GL_PACK_ALIGNMENT, &i);
3646         result &= (i == 4);
3647
3648         // check storage modes available only in core GL
3649         if (!glu::isContextTypeES(renderContext.getType()))
3650         {
3651                 // check if following four boolean modes are false
3652                 GLboolean b = true;
3653                 gl.getBooleanv(GL_UNPACK_SWAP_BYTES, &b);
3654                 result &= (b == false);
3655                 gl.getBooleanv(GL_UNPACK_LSB_FIRST, &b);
3656                 result &= (b == false);
3657                 gl.getBooleanv(GL_PACK_SWAP_BYTES, &b);
3658                 result &= (b == false);
3659                 gl.getBooleanv(GL_PACK_LSB_FIRST, &b);
3660                 result &= (b == false);
3661
3662                 // check if following two modes are 0
3663                 gl.getIntegerv(GL_PACK_IMAGE_HEIGHT, &i);
3664                 result &= (i == 0);
3665                 gl.getIntegerv(GL_PACK_SKIP_IMAGES, &i);
3666                 result &= (i == 0);
3667         }
3668
3669         // make sure that no pack/unpack buffers are bound
3670         gl.getIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &i);
3671         result &= (i == 0);
3672         gl.getIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &i);
3673         result &= (i == 0);
3674
3675         if (result)
3676                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3677         else
3678                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3679         return STOP;
3680 }
3681
3682 class PBORectangleTest : public RectangleTest
3683 {
3684 public:
3685         PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3686         virtual ~PBORectangleTest();
3687 };
3688
3689 PBORectangleTest::PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3690         : RectangleTest(context, name, internalFormat)
3691 {
3692         m_usePBO = true;
3693 }
3694
3695 PBORectangleTest::~PBORectangleTest()
3696 {
3697 }
3698
3699 class VariedRectangleTest : public RectangleTest
3700 {
3701 public:
3702         VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3703         virtual ~VariedRectangleTest();
3704
3705         tcu::TestNode::IterateResult iterate(void);
3706
3707 protected:
3708         struct StoreMode
3709         {
3710                 GLenum parameter;
3711                 GLint* property;
3712                 GLint  value;
3713         };
3714 };
3715
3716 VariedRectangleTest::VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3717         : RectangleTest(context, name, internalFormat)
3718 {
3719 }
3720
3721 VariedRectangleTest::~VariedRectangleTest()
3722 {
3723 }
3724
3725 tcu::TestNode::IterateResult VariedRectangleTest::iterate(void)
3726 {
3727         const int IMAGE_WIDTH_1  = 10;
3728         const int IMAGE_WIDTH_2  = 15;
3729         const int IMAGE_HEIGHT_1 = 10;
3730         const int IMAGE_HEIGHT_2 = 15;
3731
3732         PackedPixelsBufferProperties& up = m_initialUnpackProperties;
3733         PackedPixelsBufferProperties& pp = m_initialPackProperties;
3734
3735         StoreMode commonCases[] = {
3736                 { GL_UNPACK_ROW_LENGTH, &up.rowLength, 0 },
3737                 { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_1 },
3738                 { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_2 },
3739                 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 0 },
3740                 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 1 },
3741                 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 2 },
3742                 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 0 },
3743                 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 1 },
3744                 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 2 },
3745                 { GL_UNPACK_ALIGNMENT, &up.alignment, 1 },
3746                 { GL_UNPACK_ALIGNMENT, &up.alignment, 2 },
3747                 { GL_UNPACK_ALIGNMENT, &up.alignment, 4 },
3748                 { GL_UNPACK_ALIGNMENT, &up.alignment, 8 },
3749                 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, 0 },
3750                 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_1 },
3751                 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_2 },
3752                 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 0 },
3753                 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 1 },
3754                 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 2 },
3755                 { GL_PACK_ROW_LENGTH, &pp.rowLength, 0 },
3756                 { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_1 },
3757                 { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_2 },
3758                 { GL_PACK_SKIP_ROWS, &pp.skipRows, 0 },
3759                 { GL_PACK_SKIP_ROWS, &pp.skipRows, 1 },
3760                 { GL_PACK_SKIP_ROWS, &pp.skipRows, 2 },
3761                 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 0 },
3762                 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 1 },
3763                 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 2 },
3764                 { GL_PACK_ALIGNMENT, &pp.alignment, 1 },
3765                 { GL_PACK_ALIGNMENT, &pp.alignment, 2 },
3766                 { GL_PACK_ALIGNMENT, &pp.alignment, 4 },
3767                 { GL_PACK_ALIGNMENT, &pp.alignment, 8 },
3768         };
3769
3770         StoreMode coreCases[] = {
3771                 { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_FALSE },
3772                 { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_TRUE },
3773                 { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_FALSE },
3774                 { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_TRUE },
3775                 { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_FALSE },
3776                 { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_TRUE },
3777                 { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_FALSE },
3778                 { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_TRUE },
3779                 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, 0 },
3780                 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_1 },
3781                 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_2 },
3782                 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 0 },
3783                 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 1 },
3784                 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 2 },
3785         };
3786
3787         std::vector<StoreMode> testModes(commonCases, commonCases + DE_LENGTH_OF_ARRAY(commonCases));
3788         glu::RenderContext&     renderContext      = m_context.getRenderContext();
3789         bool                               contextTypeIsCoreGL = !glu::isContextTypeES(renderContext.getType());
3790         if (contextTypeIsCoreGL)
3791                 testModes.insert(testModes.end(), coreCases, coreCases + DE_LENGTH_OF_ARRAY(coreCases));
3792
3793         std::vector<StoreMode>::iterator currentCase = testModes.begin();
3794         while (currentCase != testModes.end())
3795         {
3796                 resetInitialStorageModes();
3797
3798                 GLenum parameter = currentCase->parameter;
3799                 GLint  value     = currentCase->value;
3800
3801                 *(currentCase->property) = value;
3802
3803                 // for some parameters an additional parameter needs to be set
3804                 if (parameter == GL_PACK_SKIP_ROWS)
3805                 {
3806                         if (contextTypeIsCoreGL)
3807                                 m_initialPackProperties.rowCount = GRADIENT_HEIGHT + value;
3808                 }
3809                 else if (parameter == GL_PACK_SKIP_PIXELS)
3810                         m_initialPackProperties.rowLength = GRADIENT_WIDTH + value;
3811                 else if (parameter == GL_UNPACK_SKIP_ROWS)
3812                         m_initialUnpackProperties.rowCount = GRADIENT_HEIGHT + value;
3813                 else if (parameter == GL_UNPACK_SKIP_PIXELS)
3814                         m_initialUnpackProperties.rowLength = GRADIENT_WIDTH + value;
3815
3816                 m_textureTarget = GL_TEXTURE_2D;
3817                 if ((parameter == GL_PACK_IMAGE_HEIGHT) || (parameter == GL_PACK_SKIP_IMAGES) ||
3818                         (parameter == GL_UNPACK_IMAGE_HEIGHT) || (parameter == GL_UNPACK_SKIP_IMAGES))
3819                         m_textureTarget = GL_TEXTURE_3D;
3820
3821                 testAllFormatsAndTypes();
3822
3823                 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
3824                 {
3825                         m_testCtx.getLog() << tcu::TestLog::Message
3826                                                            << "Case for: " << glu::getGettableStateStr(parameter).toString() << " = " << value
3827                                                            << " failed." << tcu::TestLog::EndMessage;
3828                         return STOP;
3829                 }
3830
3831                 ++currentCase;
3832         }
3833
3834         return STOP;
3835 }
3836
3837 PackedPixelsTests::PackedPixelsTests(deqp::Context& context) : TestCaseGroup(context, "packed_pixels", "")
3838 {
3839 }
3840
3841 PackedPixelsTests::~PackedPixelsTests(void)
3842 {
3843 #ifdef LOG_PACKED_PIXELS_STATISTICS
3844         m_testCtx.getLog() << tcu::TestLog::Message << "PackedPixelsTests statistics:"
3845                                            << "\n  countReadPixels: " << RectangleTest::m_countReadPixels
3846                                            << "\n  countReadPixelsOK: " << RectangleTest::m_countReadPixelsOK
3847                                            << "\n  countGetTexImage: " << RectangleTest::m_countGetTexImage
3848                                            << "\n  countGetTexImageOK: " << RectangleTest::m_countGetTexImageOK
3849                                            << "\n  countCompare: " << RectangleTest::m_countCompare
3850                                            << "\n  countCompareOK: " << RectangleTest::m_countCompareOK << tcu::TestLog::EndMessage;
3851 #endif
3852 }
3853
3854 void PackedPixelsTests::init(void)
3855 {
3856         const InternalFormat* internalFormats;
3857         unsigned int              internalFormatsCount;
3858
3859         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
3860         {
3861                 internalFormats          = esInternalformats;
3862                 internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats);
3863         }
3864         else
3865         {
3866                 internalFormats          = coreInternalformats;
3867                 internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats);
3868         }
3869
3870         TestCaseGroup* rectangleGroup = new deqp::TestCaseGroup(m_context, "rectangle", "");
3871         rectangleGroup->addChild(new InitialValuesTest(m_context));
3872         TestCaseGroup* pboRectangleGroup        = new deqp::TestCaseGroup(m_context, "pbo_rectangle", "");
3873         TestCaseGroup* variedRectangleGroup = new deqp::TestCaseGroup(m_context, "varied_rectangle", "");
3874
3875         for (unsigned int internalFormatIndex = 0; internalFormatIndex < internalFormatsCount; internalFormatIndex++)
3876         {
3877                 const InternalFormat& internalFormat       = internalFormats[internalFormatIndex];
3878                 std::string                       internalFormatString = getFormatStr(internalFormat.sizedFormat);
3879
3880                 std::string name = internalFormatString.substr(3);
3881                 std::transform(name.begin(), name.end(), name.begin(), tolower);
3882
3883                 rectangleGroup->addChild(new RectangleTest(m_context, name, internalFormat));
3884                 pboRectangleGroup->addChild(new PBORectangleTest(m_context, name, internalFormat));
3885                 variedRectangleGroup->addChild(new VariedRectangleTest(m_context, name, internalFormat));
3886         }
3887
3888         addChild(rectangleGroup);
3889         addChild(pboRectangleGroup);
3890         addChild(variedRectangleGroup);
3891 }
3892
3893 } /* glcts namespace */