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
getTypeStr(GLenum type)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
getFormatStr(GLenum format)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
getModeStr(GLenum type)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
RectangleTest(deqp::Context & context,std::string & name,InternalFormat internalFormat)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
~RectangleTest()888 RectangleTest::~RectangleTest()
889 {
890 }
891
resetInitialStorageModes()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
applyInitialStorageModes()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
swapBytes(int typeSize,std::vector<GLbyte> & dataBuffer)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
getPixelFormat(GLenum format) const982 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
getPixelType(GLenum type) const1008 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
getCanonicalFormat(const InternalFormat & internalformat,GLenum format,GLenum type) const1033 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
getSampler(const PixelType & type,const PixelFormat & format) const1092 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
createGradient()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>
makeGradient(Type (* unpack)(float))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 = m_unpackProperties.skipImages; k < depth; k++)
1251 {
1252 for (int j = 0; j < rowCount; j++)
1253 {
1254 for (int i = 0; i < elementsInRow; i++)
1255 {
1256 DE_ASSERT(index < bufferSize);
1257 int x = i / elementsInGroup;
1258 if ((k == depth - 1) && (m_unpackProperties.skipRows <= j) &&
1259 (j < m_unpackProperties.skipRows + GRADIENT_HEIGHT) && (m_unpackProperties.skipPixels <= x) &&
1260 (x < m_unpackProperties.skipPixels + GRADIENT_WIDTH))
1261 {
1262 float value = static_cast<float>(x - m_unpackProperties.skipPixels) / GRADIENT_WIDTH;
1263 int channel = i - elementsInGroup * x;
1264 value *= 1.0f - 0.25f * channel;
1265 data[index] = unpack(value);
1266 }
1267 else
1268 {
1269 data[index] = defaultValue;
1270 }
1271 index++;
1272 }
1273 }
1274 }
1275 }
1276
1277 template <typename Type>
unpackSizedComponents(float value,int s1,int s2,int s3,int s4)1278 Type RectangleTest::unpackSizedComponents(float value, int s1, int s2, int s3, int s4)
1279 {
1280 int typeBits = sizeof(Type) * 8;
1281 double v = static_cast<double>(value);
1282 Type c1 = static_cast<Type>(v * 1.00 * ((1 << s1) - 1));
1283 Type c2 = static_cast<Type>(v * 0.75 * ((1 << s2) - 1));
1284 Type c3 = static_cast<Type>(v * 0.50 * ((1 << s3) - 1));
1285 Type c4 = static_cast<Type>(v * 0.25 * ((1 << s4) - 1));
1286 return ((c1) << (typeBits - s1)) | ((c2) << (typeBits - s1 - s2)) | ((c3) << (typeBits - s1 - s2 - s3)) |
1287 ((c4) << (typeBits - s1 - s2 - s3 - s4));
1288 }
1289
1290 template <typename Type>
unpackSizedComponentsRev(float value,int s1,int s2,int s3,int s4)1291 Type RectangleTest::unpackSizedComponentsRev(float value, int s1, int s2, int s3, int s4)
1292 {
1293 int typeBits = sizeof(Type) * 8;
1294 double v = static_cast<double>(value);
1295 Type c1 = static_cast<Type>(v * 1.00 * ((1 << s4) - 1));
1296 Type c2 = static_cast<Type>(v * 0.75 * ((1 << s3) - 1));
1297 Type c3 = static_cast<Type>(v * 0.50 * ((1 << s2) - 1));
1298 Type c4 = static_cast<Type>(v * 0.25 * ((1 << s1) - 1));
1299 return ((c4) << (typeBits - s1)) | ((c3) << (typeBits - s1 - s2)) | ((c2) << (typeBits - s1 - s2 - s3)) |
1300 ((c1) << (typeBits - s1 - s2 - s3 - s4));
1301 }
1302
unpack_UNSIGNED_BYTE(float value)1303 GLubyte RectangleTest::unpack_UNSIGNED_BYTE(float value)
1304 {
1305 return static_cast<GLubyte>(value * std::numeric_limits<GLubyte>::max());
1306 }
1307
unpack_BYTE(float value)1308 GLbyte RectangleTest::unpack_BYTE(float value)
1309 {
1310 return static_cast<GLbyte>(value * std::numeric_limits<GLbyte>::max());
1311 }
1312
unpack_UNSIGNED_SHORT(float value)1313 GLushort RectangleTest::unpack_UNSIGNED_SHORT(float value)
1314 {
1315 return static_cast<GLushort>(value * std::numeric_limits<GLushort>::max());
1316 }
1317
unpack_SHORT(float value)1318 GLshort RectangleTest::unpack_SHORT(float value)
1319 {
1320 return static_cast<GLshort>(value * std::numeric_limits<GLshort>::max());
1321 }
1322
unpack_UNSIGNED_INT(float value)1323 GLuint RectangleTest::unpack_UNSIGNED_INT(float value)
1324 {
1325 return static_cast<GLuint>(value * std::numeric_limits<GLuint>::max());
1326 }
1327
unpack_INT(float value)1328 GLint RectangleTest::unpack_INT(float value)
1329 {
1330 return static_cast<GLint>(value * std::numeric_limits<GLint>::max());
1331 }
1332
unpack_HALF_FLOAT(float value)1333 GLhalf RectangleTest::unpack_HALF_FLOAT(float value)
1334 {
1335 return floatToHalfFloat(value);
1336 }
1337
unpack_FLOAT(float value)1338 GLfloat RectangleTest::unpack_FLOAT(float value)
1339 {
1340 return value;
1341 }
1342
unpack_UNSIGNED_BYTE_3_3_2(float value)1343 GLubyte RectangleTest::unpack_UNSIGNED_BYTE_3_3_2(float value)
1344 {
1345 return unpackSizedComponents<GLubyte>(value, 3, 3, 2, 0);
1346 }
1347
unpack_UNSIGNED_BYTE_2_3_3_REV(float value)1348 GLubyte RectangleTest::unpack_UNSIGNED_BYTE_2_3_3_REV(float value)
1349 {
1350 return unpackSizedComponentsRev<GLubyte>(value, 2, 3, 3, 0);
1351 }
1352
unpack_UNSIGNED_SHORT_5_6_5_REV(float value)1353 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5_REV(float value)
1354 {
1355 return unpackSizedComponentsRev<GLushort>(value, 5, 6, 5, 0);
1356 }
1357
unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value)1358 GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value)
1359 {
1360 return unpackSizedComponentsRev<GLushort>(value, 4, 4, 4, 4);
1361 }
1362
unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value)1363 GLushort RectangleTest::unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value)
1364 {
1365 return unpackSizedComponentsRev<GLushort>(value, 1, 5, 5, 5);
1366 }
1367
unpack_UNSIGNED_INT_8_8_8_8(float value)1368 GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8(float value)
1369 {
1370 return unpackSizedComponents<GLuint>(value, 8, 8, 8, 8);
1371 }
1372
unpack_UNSIGNED_INT_8_8_8_8_REV(float value)1373 GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8_REV(float value)
1374 {
1375 return unpackSizedComponentsRev<GLuint>(value, 8, 8, 8, 8);
1376 }
1377
unpack_UNSIGNED_INT_10_10_10_2(float value)1378 GLuint RectangleTest::unpack_UNSIGNED_INT_10_10_10_2(float value)
1379 {
1380 return unpackSizedComponents<GLuint>(value, 10, 10, 10, 2);
1381 }
1382
unpack_UNSIGNED_SHORT_5_6_5(float value)1383 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5(float value)
1384 {
1385 return unpackSizedComponents<GLushort>(value, 5, 6, 5, 0);
1386 }
1387
unpack_UNSIGNED_SHORT_4_4_4_4(float value)1388 GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4(float value)
1389 {
1390 return unpackSizedComponents<GLushort>(value, 4, 4, 4, 4);
1391 }
1392
unpack_UNSIGNED_SHORT_5_5_5_1(float value)1393 GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_5_5_1(float value)
1394 {
1395 return unpackSizedComponents<GLushort>(value, 5, 5, 5, 1);
1396 }
1397
unpack_UNSIGNED_INT_2_10_10_10_REV(float value)1398 GLuint RectangleTest::unpack_UNSIGNED_INT_2_10_10_10_REV(float value)
1399 {
1400 return unpackSizedComponentsRev<GLuint>(value, 2, 10, 10, 10);
1401 }
1402
unpack_UNSIGNED_INT_24_8(float value)1403 GLuint RectangleTest::unpack_UNSIGNED_INT_24_8(float value)
1404 {
1405 return unpackSizedComponents<GLuint>(value, 24, 8, 0, 0);
1406 }
1407
unpack_UNSIGNED_INT_5_9_9_9_REV(float value)1408 GLuint RectangleTest::unpack_UNSIGNED_INT_5_9_9_9_REV(float value)
1409 {
1410 const int N = 9;
1411 const int B = 15;
1412 const int E_max = 31;
1413
1414 GLfloat red = value * 1.00f;
1415 GLfloat green = value * 0.75f;
1416 GLfloat blue = value * 0.50f;
1417
1418 GLfloat sharedExpMax = (deFloatPow(2.0f, (float)N) - 1.0f) / deFloatPow(2.0f, (float)N) * deFloatPow(2.0f, (float)(E_max - B));
1419
1420 GLfloat red_c = deFloatMax(0, deFloatMin(sharedExpMax, red));
1421 GLfloat green_c = deFloatMax(0, deFloatMin(sharedExpMax, green));
1422 GLfloat blue_c = deFloatMax(0, deFloatMin(sharedExpMax, blue));
1423
1424 GLfloat max_c = deFloatMax(deFloatMax(red_c, green_c), blue_c);
1425
1426 GLfloat exp_p = deFloatMax(-B - 1, deFloatFloor(deFloatLog2(max_c))) + 1 + B;
1427
1428 GLfloat max_s = deFloatFloor(max_c / deFloatPow(2.0f, exp_p - (float)B - (float)N) + 0.5f);
1429
1430 GLfloat exp_s;
1431
1432 if (0 <= max_s && max_s < deFloatPow(2.0f, (float)N))
1433 exp_s = exp_p;
1434 else
1435 exp_s = exp_p + 1;
1436
1437 GLfloat red_s = deFloatFloor(red_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1438 GLfloat green_s = deFloatFloor(green_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1439 GLfloat blue_s = deFloatFloor(blue_c / deFloatPow(2.0f, exp_s - (float)B - (float)N) + 0.5f);
1440
1441 GLuint c1 = (static_cast<GLuint>(red_s)) & 511;
1442 GLuint c2 = (static_cast<GLuint>(green_s)) & 511;
1443 GLuint c3 = (static_cast<GLuint>(blue_s)) & 511;
1444 GLuint c4 = (static_cast<GLuint>(exp_s)) & 31;
1445
1446 return (c1) | (c2 << 9) | (c3 << 18) | (c4 << 27);
1447 }
1448
unpack_UNSIGNED_INT_10F_11F_11F_REV(float value)1449 GLuint RectangleTest::unpack_UNSIGNED_INT_10F_11F_11F_REV(float value)
1450 {
1451 GLuint c1 = floatToUnisgnedF11(value * 1.00f);
1452 GLuint c2 = floatToUnisgnedF11(value * 0.75f);
1453 GLuint c3 = floatToUnisgnedF10(value * 0.50f);
1454 return (c3 << 22) | (c2 << 11) | (c1);
1455 }
1456
unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value)1457 F_32_UINT_24_8_REV RectangleTest::unpack_FLOAT_32_UNSIGNED_INT_24_8_REV(float value)
1458 {
1459 F_32_UINT_24_8_REV ret;
1460 ret.d = value;
1461 ret.s = (GLuint)(value * 255.0 * 0.75);
1462 ret.s &= 0xff;
1463 return ret;
1464 }
1465
isFormatValid(const PixelFormat & format,const PixelType & type,const struct InternalFormat & internalformat,bool checkInput,bool checkOutput,int operation) const1466 bool RectangleTest::isFormatValid(const PixelFormat& format, const PixelType& type,
1467 const struct InternalFormat& internalformat, bool checkInput, bool checkOutput,
1468 int operation) const
1469 {
1470 glu::RenderContext& renderContext = m_context.getRenderContext();
1471 glu::ContextType contextType = renderContext.getType();
1472 const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1473 const Functions& gl = renderContext.getFunctions();
1474
1475 int i;
1476
1477 // Test the combination of input format, input type and internalFormat
1478 if (glu::isContextTypeES(contextType))
1479 {
1480 if (checkInput)
1481 {
1482 // GLES30 has more restricted requirement on combination than GL for input
1483 for (i = 0; i < DE_LENGTH_OF_ARRAY(esValidFormats); ++i)
1484 {
1485 if (internalformat.sizedFormat == esValidFormats[i].internalformat &&
1486 format.format == esValidFormats[i].format && type.type == esValidFormats[i].type)
1487 {
1488 break;
1489 }
1490 }
1491
1492 if (i == DE_LENGTH_OF_ARRAY(esValidFormats))
1493 {
1494 // Check for support of OES_texture_float extension
1495 if (((GL_LUMINANCE_ALPHA == format.format) && (GL_LUMINANCE_ALPHA == internalformat.sizedFormat)) ||
1496 ((GL_LUMINANCE == format.format) && (GL_LUMINANCE == internalformat.sizedFormat)) ||
1497 ((GL_ALPHA == format.format) && (GL_ALPHA == internalformat.sizedFormat)) ||
1498 ((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) ||
1499 ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat)))
1500 {
1501 if ((contextInfo.isExtensionSupported("GL_OES_texture_float") && (GL_FLOAT == type.type)) ||
1502 (contextInfo.isExtensionSupported("GL_OES_texture_half_float") &&
1503 (GL_HALF_FLOAT_OES == type.type)))
1504 {
1505 return true;
1506 }
1507 }
1508
1509 // Check for support of EXT_texture_type_2_10_10_10_REV extension
1510 if (((GL_RGBA == format.format) && (GL_RGBA == internalformat.sizedFormat)) ||
1511 ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat)))
1512 {
1513 if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") &&
1514 ((GL_UNSIGNED_INT_2_10_10_10_REV_EXT == type.type)))
1515 return true;
1516 }
1517
1518 // Check for support of NV_packed_float extension
1519 if ((GL_RGB == format.format) && (GL_RGB == internalformat.sizedFormat))
1520 {
1521 if (contextInfo.isExtensionSupported("GL_NV_packed_float") &&
1522 ((GL_UNSIGNED_INT_10F_11F_11F_REV == type.type)))
1523 return true;
1524 }
1525
1526 // Check for support of EXT_texture_type_2_10_10_10_REV and GL_OES_required_internalformat extensions
1527 if (contextInfo.isExtensionSupported("GL_EXT_texture_type_2_10_10_10_REV") &&
1528 contextInfo.isExtensionSupported("GL_OES_required_internalformat"))
1529 {
1530 for (i = 0; i < DE_LENGTH_OF_ARRAY(validformats_OES_required_internalformat); ++i)
1531 {
1532 if (internalformat.sizedFormat == validformats_OES_required_internalformat[i].internalformat &&
1533 format.format == validformats_OES_required_internalformat[i].format &&
1534 type.type == validformats_OES_required_internalformat[i].type)
1535 {
1536 return true;
1537 }
1538 }
1539 }
1540
1541 return false;
1542 }
1543
1544 if ((m_textureTarget == GL_TEXTURE_3D) &&
1545 ((format.format == GL_DEPTH_COMPONENT) || (format.format == GL_DEPTH_STENCIL)))
1546 return false;
1547 }
1548 else if (checkOutput)
1549 {
1550 // GLES30 has more restricted requirement on combination than GL for output
1551 // As stated in Section Reading Pixels
1552 InternalFormatSamplerType sampler = internalformat.sampler;
1553
1554 const PixelFormat& inputFormat = getPixelFormat(internalformat.format);
1555
1556 if (inputFormat.attachment == GL_DEPTH_ATTACHMENT && contextInfo.isExtensionSupported("GL_NV_read_depth") &&
1557 format.format == GL_DEPTH_COMPONENT &&
1558 ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) ||
1559 (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT ||
1560 type.type == GL_UNSIGNED_INT_24_8))))
1561 {
1562 return true;
1563 }
1564
1565 if (inputFormat.attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
1566 contextInfo.isExtensionSupported("GL_NV_read_depth_stencil") &&
1567 ((format.format == GL_DEPTH_STENCIL &&
1568 ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV) ||
1569 (sampler != SAMPLER_FLOAT && type.type == GL_UNSIGNED_INT_24_8))) ||
1570 (format.format == GL_DEPTH_COMPONENT &&
1571 ((sampler == SAMPLER_FLOAT && type.type == GL_FLOAT) ||
1572 (sampler != SAMPLER_FLOAT && (type.type == GL_UNSIGNED_SHORT || type.type == GL_UNSIGNED_INT ||
1573 type.type == GL_UNSIGNED_INT_24_8))))))
1574 {
1575 return true;
1576 }
1577
1578 if (inputFormat.attachment != GL_COLOR_ATTACHMENT0)
1579 {
1580 return false;
1581 }
1582
1583 if ((sampler == SAMPLER_UNORM) && (((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGB) &&
1584 (internalformat.sizedFormat == GL_SRGB8)) ||
1585 ((type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA) &&
1586 (internalformat.sizedFormat == GL_SRGB8_ALPHA8))) &&
1587 contextInfo.isExtensionSupported("GL_NV_sRGB_formats"))
1588 {
1589 return true;
1590 }
1591
1592 if ((sampler == SAMPLER_UNORM) && (type.type == GL_UNSIGNED_SHORT) && (format.format == GL_RGBA) &&
1593 ((internalformat.sizedFormat == GL_R16) || (internalformat.sizedFormat == GL_RG16) ||
1594 (internalformat.sizedFormat == GL_RGBA16)) &&
1595 contextInfo.isExtensionSupported("GL_EXT_texture_norm16"))
1596 {
1597 return true;
1598 }
1599
1600 if ((sampler == SAMPLER_NORM) && (type.type == GL_SHORT) && (format.format == GL_RGBA) &&
1601 ((internalformat.sizedFormat == GL_R16_SNORM) || (internalformat.sizedFormat == GL_RG16_SNORM) ||
1602 (internalformat.sizedFormat == GL_RGBA16_SNORM)) &&
1603 (contextInfo.isExtensionSupported("GL_EXT_texture_norm16") && contextInfo.isExtensionSupported("GL_EXT_render_snorm")))
1604 {
1605 return true;
1606 }
1607
1608 if ((sampler == SAMPLER_NORM) && (type.type == GL_BYTE) && (format.format == GL_RGBA) &&
1609 ((internalformat.sizedFormat == GL_R8_SNORM) || (internalformat.sizedFormat == GL_RG8_SNORM) ||
1610 (internalformat.sizedFormat == GL_RGBA8_SNORM)) &&
1611 contextInfo.isExtensionSupported("GL_EXT_render_snorm"))
1612 {
1613 return true;
1614 }
1615
1616 GLint implementType;
1617 GLint implementFormat;
1618 gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &implementType);
1619 gl.getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implementFormat);
1620 GLenum err = gl.getError();
1621 GLenum implementTypeEnum = static_cast<GLenum>(implementType);
1622 GLenum implementFormatEnum = static_cast<GLenum>(implementFormat);
1623
1624 if (((sampler == SAMPLER_UNORM) && (type.type == GL_UNSIGNED_BYTE) && (format.format == GL_RGBA)) ||
1625 ((sampler == SAMPLER_UINT) && (type.type == GL_UNSIGNED_INT) && (format.format == GL_RGBA_INTEGER)) ||
1626 ((sampler == SAMPLER_INT) && (type.type == GL_INT) && (format.format == GL_RGBA_INTEGER)) ||
1627 ((sampler == SAMPLER_FLOAT) && (type.type == GL_FLOAT) && (format.format == GL_RGBA)) ||
1628 ((err == GL_NO_ERROR) && (type.type == implementTypeEnum) && (format.format == implementFormatEnum)) ||
1629 ((internalformat.sizedFormat == GL_RGB10_A2) && (type.type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
1630 (format.format == GL_RGBA)))
1631 {
1632 return true;
1633 }
1634 else
1635 {
1636 return false;
1637 }
1638 }
1639 }
1640 else
1641 {
1642 if (format.format == GL_DEPTH_STENCIL)
1643 {
1644 if (type.type != GL_UNSIGNED_INT_24_8 && type.type != GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
1645 {
1646 return false;
1647 }
1648 }
1649
1650 if ((format.componentFormat == FORMAT_COLOR_INTEGER) && (type.type == GL_FLOAT || type.type == GL_HALF_FLOAT))
1651 {
1652 return false;
1653 }
1654
1655 if ((internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_STENCIL_INDEX ||
1656 internalformat.baseFormat == GL_DEPTH_COMPONENT) !=
1657 (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX ||
1658 format.format == GL_DEPTH_COMPONENT))
1659 {
1660 return false;
1661 }
1662
1663 if (operation == INPUT_TEXIMAGE)
1664 {
1665 if (format.format == GL_STENCIL_INDEX || internalformat.baseFormat == GL_STENCIL_INDEX)
1666 {
1667 return false;
1668 }
1669
1670 if ((format.format == GL_DEPTH_COMPONENT || format.format == GL_DEPTH_STENCIL) &&
1671 !(internalformat.baseFormat == GL_DEPTH_STENCIL || internalformat.baseFormat == GL_DEPTH_COMPONENT))
1672 {
1673 return false;
1674 }
1675 }
1676 else if (operation == OUTPUT_GETTEXIMAGE)
1677 {
1678 if ((format.format == GL_STENCIL_INDEX &&
1679 ((internalformat.baseFormat != GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL) ||
1680 !contextInfo.isExtensionSupported("GL_ARB_texture_stencil8"))))
1681 {
1682 return false;
1683 }
1684
1685 if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL)
1686 {
1687 return false;
1688 }
1689 }
1690 else if (operation == OUTPUT_READPIXELS)
1691 {
1692 if (format.format == GL_DEPTH_STENCIL && internalformat.baseFormat != GL_DEPTH_STENCIL)
1693 {
1694 return false;
1695 }
1696
1697 if (format.format == GL_DEPTH_COMPONENT && internalformat.baseFormat != GL_DEPTH_STENCIL &&
1698 internalformat.baseFormat != GL_DEPTH_COMPONENT)
1699 {
1700 return false;
1701 }
1702
1703 if (format.format == GL_STENCIL_INDEX && internalformat.baseFormat != GL_DEPTH_STENCIL &&
1704 internalformat.baseFormat != GL_STENCIL_INDEX)
1705 {
1706 return false;
1707 }
1708 }
1709
1710 if (type.special == true)
1711 {
1712 bool valid = false;
1713
1714 for (i = 0; i < DE_LENGTH_OF_ARRAY(coreValidFormats); ++i)
1715 {
1716 if (coreValidFormats[i].format == format.format && coreValidFormats[i].type == type.type)
1717 {
1718 valid = true;
1719 break;
1720 }
1721 }
1722
1723 if (!valid)
1724 return false;
1725 }
1726
1727 if ((format.componentFormat == FORMAT_COLOR_INTEGER) &&
1728 !(internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT))
1729 {
1730 return false;
1731 }
1732
1733 if (!(format.componentFormat == FORMAT_COLOR_INTEGER) &&
1734 (internalformat.sampler == SAMPLER_INT || internalformat.sampler == SAMPLER_UINT))
1735 {
1736 return false;
1737 }
1738
1739 if ((m_textureTarget == GL_TEXTURE_3D) &&
1740 ((internalformat.baseFormat == GL_DEPTH_COMPONENT) || (internalformat.baseFormat == GL_DEPTH_STENCIL) ||
1741 (internalformat.sizedFormat == GL_COMPRESSED_RED_RGTC1) ||
1742 (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RED_RGTC1) ||
1743 (internalformat.sizedFormat == GL_COMPRESSED_RG_RGTC2) ||
1744 (internalformat.sizedFormat == GL_COMPRESSED_SIGNED_RG_RGTC2)))
1745 {
1746 return false;
1747 }
1748 }
1749
1750 return true;
1751 }
1752
isUnsizedFormat(GLenum format) const1753 bool RectangleTest::isUnsizedFormat(GLenum format) const
1754 {
1755 GLenum formats[] = { GL_RGBA, GL_RGB, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA };
1756 GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats);
1757 return (std::find(formats, formatsEnd, format) < formatsEnd);
1758 }
1759
isSRGBFormat(const InternalFormat & internalFormat) const1760 bool RectangleTest::isSRGBFormat(const InternalFormat& internalFormat) const
1761 {
1762 return (internalFormat.sizedFormat == GL_SRGB8) || (internalFormat.sizedFormat == GL_SRGB8_ALPHA8);
1763 }
1764
isSNORMFormat(const InternalFormat & internalFormat) const1765 bool RectangleTest::isSNORMFormat(const InternalFormat& internalFormat) const
1766 {
1767 GLenum formats[] = { GL_R8_SNORM, GL_RG8_SNORM, GL_RGB8_SNORM, GL_RGBA8_SNORM,
1768 GL_R16_SNORM, GL_RG16_SNORM, GL_RGB16_SNORM, GL_RGBA16_SNORM };
1769 GLenum* formatsEnd = formats + DE_LENGTH_OF_ARRAY(formats);
1770 return (std::find(formats, formatsEnd, internalFormat.sizedFormat) < formatsEnd);
1771 }
1772
isCopyValid(const InternalFormat & copyInternalFormat,const InternalFormat & internalFormat) const1773 bool RectangleTest::isCopyValid(const InternalFormat& copyInternalFormat, const InternalFormat& internalFormat) const
1774 {
1775 // check if copy between two internal formats is allowed
1776
1777 int b1 = getPixelFormat(internalFormat.format).components;
1778 int b2 = getPixelFormat(copyInternalFormat.format).components;
1779
1780 if (b2 > b1)
1781 return false;
1782
1783 //Check that the types can be converted in CopyTexImage.
1784 if (((copyInternalFormat.sampler == SAMPLER_UINT) && (internalFormat.sampler != SAMPLER_UINT)) ||
1785 ((copyInternalFormat.sampler == SAMPLER_INT) && (internalFormat.sampler != SAMPLER_INT)) ||
1786 (((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) ||
1787 (copyInternalFormat.sampler == SAMPLER_NORM)) &&
1788 (!((copyInternalFormat.sampler == SAMPLER_FLOAT) || (internalFormat.sampler == SAMPLER_UNORM) ||
1789 (internalFormat.sampler == SAMPLER_NORM)))))
1790 {
1791 return false;
1792 }
1793
1794 // Core GL is less restricted then ES - check it first
1795 if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
1796 {
1797 if ((copyInternalFormat.format == GL_DEPTH_COMPONENT && internalFormat.format != GL_DEPTH_COMPONENT) ||
1798 (copyInternalFormat.format == GL_DEPTH_STENCIL && internalFormat.format != GL_DEPTH_STENCIL) ||
1799 (copyInternalFormat.format == GL_ALPHA && internalFormat.format != GL_ALPHA) ||
1800 (copyInternalFormat.format == GL_LUMINANCE && internalFormat.format != GL_LUMINANCE) ||
1801 (copyInternalFormat.format == GL_LUMINANCE_ALPHA && internalFormat.format != GL_LUMINANCE_ALPHA))
1802 {
1803 return false;
1804 }
1805
1806 return true;
1807 }
1808
1809 const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1810
1811 // GLES30 has more restricted requirement on glCopyTexImage2D
1812 // As stated in Table 3.15 and comment to glCopyTexImage2D
1813 if ((internalFormat.baseFormat == GL_DEPTH_COMPONENT) || (internalFormat.baseFormat == GL_DEPTH_STENCIL) ||
1814 (copyInternalFormat.baseFormat == GL_DEPTH_COMPONENT) || (copyInternalFormat.baseFormat == GL_DEPTH_STENCIL) ||
1815 ((internalFormat.baseFormat != GL_RGBA && internalFormat.baseFormat != GL_ALPHA) &&
1816 ((copyInternalFormat.baseFormat == GL_ALPHA) || (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA))) ||
1817 ((internalFormat.baseFormat == GL_ALPHA) &&
1818 ((copyInternalFormat.baseFormat != GL_RGBA) && (copyInternalFormat.baseFormat != GL_ALPHA) &&
1819 (copyInternalFormat.baseFormat != GL_LUMINANCE_ALPHA))) ||
1820 (isSRGBFormat(internalFormat) != isSRGBFormat(copyInternalFormat)) ||
1821 // GLES30 does not define ReadPixels types for signed normalized fixed point formats in Table 3.14,
1822 // and conversions to SNORM internalformats are not allowed by Table 3.2
1823 (copyInternalFormat.sampler == SAMPLER_NORM) ||
1824 ((copyInternalFormat.sizedFormat == GL_RGB9_E5) &&
1825 (!contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float") &&
1826 !contextInfo.isExtensionSupported("GL_QCOM_render_shared_exponent"))))
1827 {
1828 /* Some formats are activated by extensions, check. */
1829 if (((internalFormat.baseFormat == GL_LUMINANCE && copyInternalFormat.baseFormat == GL_LUMINANCE) ||
1830 (internalFormat.baseFormat == GL_ALPHA && copyInternalFormat.baseFormat == GL_ALPHA) ||
1831 (internalFormat.baseFormat == GL_LUMINANCE_ALPHA &&
1832 (copyInternalFormat.baseFormat == GL_LUMINANCE_ALPHA || copyInternalFormat.baseFormat == GL_LUMINANCE ||
1833 copyInternalFormat.baseFormat == GL_ALPHA))) &&
1834 contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha"))
1835 {
1836 return true;
1837 }
1838 else if (contextInfo.isExtensionSupported("GL_EXT_render_snorm") && isSNORMFormat(copyInternalFormat) &&
1839 (internalFormat.sampler == copyInternalFormat.sampler) &&
1840 (((copyInternalFormat.baseFormat == GL_RED) &&
1841 (internalFormat.baseFormat == GL_RED || internalFormat.baseFormat == GL_RG ||
1842 internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA ||
1843 copyInternalFormat.baseFormat == GL_LUMINANCE)) ||
1844 ((copyInternalFormat.baseFormat == GL_RG) &&
1845 (internalFormat.baseFormat == GL_RG || internalFormat.baseFormat == GL_RGB ||
1846 internalFormat.baseFormat == GL_RGBA)) ||
1847 ((copyInternalFormat.baseFormat == GL_RGB) &&
1848 (internalFormat.baseFormat == GL_RGB || internalFormat.baseFormat == GL_RGBA)) ||
1849 ((copyInternalFormat.baseFormat == GL_RGBA) && (internalFormat.baseFormat == GL_RGBA))))
1850 {
1851 return true;
1852 }
1853
1854 return false;
1855 }
1856 else
1857 {
1858 if (internalFormat.sampler != copyInternalFormat.sampler)
1859 {
1860 // You can't convert between different base types, for example NORM<->FLOAT.
1861 return false;
1862 }
1863 if (!isUnsizedFormat(copyInternalFormat.sizedFormat))
1864 {
1865 if ((internalFormat.bits.bits.red && copyInternalFormat.bits.bits.red &&
1866 internalFormat.bits.bits.red != copyInternalFormat.bits.bits.red) ||
1867 (internalFormat.bits.bits.green && copyInternalFormat.bits.bits.green &&
1868 internalFormat.bits.bits.green != copyInternalFormat.bits.bits.green) ||
1869 (internalFormat.bits.bits.blue && copyInternalFormat.bits.bits.blue &&
1870 internalFormat.bits.bits.blue != copyInternalFormat.bits.bits.blue) ||
1871 (internalFormat.bits.bits.alpha && copyInternalFormat.bits.bits.alpha &&
1872 internalFormat.bits.bits.alpha != copyInternalFormat.bits.bits.alpha))
1873 {
1874 // If the destination internalFormat is sized we don't allow component size changes.
1875 return false;
1876 }
1877 }
1878 else
1879 {
1880 if (internalFormat.sizedFormat == GL_RGB10_A2)
1881 {
1882 // Not allowed to convert from a GL_RGB10_A2 surface.
1883 return false;
1884 }
1885 }
1886 }
1887
1888 return true;
1889 }
1890
isFBOImageAttachValid(const InternalFormat & internalformat,GLenum format,GLenum type) const1891 bool RectangleTest::isFBOImageAttachValid(const InternalFormat& internalformat, GLenum format, GLenum type) const
1892 {
1893 const glu::ContextInfo& contextInfo = m_context.getContextInfo();
1894
1895 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
1896 {
1897 const EnumFormats* validFormat = getCanonicalFormat(internalformat, format, type);
1898 if (validFormat != 0)
1899 {
1900 if (!validFormat->bRenderable)
1901 {
1902 /* Some formats are activated by extensions, check. */
1903 if ((GL_RGBA32F == validFormat->internalformat || GL_RGBA16F == validFormat->internalformat ||
1904 GL_RG32F == validFormat->internalformat || GL_RG16F == validFormat->internalformat ||
1905 GL_R32F == validFormat->internalformat || GL_R16F == validFormat->internalformat ||
1906 GL_R11F_G11F_B10F == validFormat->internalformat) &&
1907 contextInfo.isExtensionSupported("GL_EXT_color_buffer_float"))
1908 {
1909 return true;
1910 }
1911
1912 if ((GL_RGBA16F == validFormat->internalformat || GL_RGB16F == validFormat->internalformat ||
1913 GL_RG16F == validFormat->internalformat || GL_R16F == validFormat->internalformat) &&
1914 contextInfo.isExtensionSupported("GL_EXT_color_buffer_half_float"))
1915 {
1916 return true;
1917 }
1918
1919 if ((GL_R11F_G11F_B10F == validFormat->internalformat || GL_RGB9_E5 == validFormat->internalformat) &&
1920 contextInfo.isExtensionSupported("GL_APPLE_color_buffer_packed_float"))
1921 {
1922 return true;
1923 }
1924
1925 if ((GL_RGB9_E5 == validFormat->internalformat) &&
1926 contextInfo.isExtensionSupported("GL_QCOM_render_shared_exponent"))
1927 {
1928 return true;
1929 }
1930
1931 if ((GL_LUMINANCE == validFormat->internalformat || GL_ALPHA == validFormat->internalformat ||
1932 GL_LUMINANCE_ALPHA == validFormat->internalformat) &&
1933 contextInfo.isExtensionSupported("GL_NV_render_luminance_alpha"))
1934 {
1935 return true;
1936 }
1937
1938 if ((GL_SRGB8 == validFormat->internalformat) && contextInfo.isExtensionSupported("GL_NV_sRGB_formats"))
1939 {
1940 return true;
1941 }
1942
1943 if (((GL_R8_SNORM == validFormat->internalformat) || (GL_RG8_SNORM == validFormat->internalformat) ||
1944 (GL_RGBA8_SNORM == validFormat->internalformat) || (GL_R16_SNORM == validFormat->internalformat) ||
1945 (GL_RG16_SNORM == validFormat->internalformat) ||
1946 (GL_RGBA16_SNORM == validFormat->internalformat)) &&
1947 contextInfo.isExtensionSupported("GL_EXT_render_snorm"))
1948 {
1949 return true;
1950 }
1951 }
1952 return validFormat->bRenderable;
1953 }
1954 else
1955 {
1956 // Check for NV_packed_float
1957 if (GL_RGB == internalformat.sizedFormat && GL_RGB == format && GL_UNSIGNED_INT_10F_11F_11F_REV == type &&
1958 contextInfo.isExtensionSupported("GL_NV_packed_float"))
1959 {
1960 return true;
1961 }
1962 return false;
1963 }
1964 }
1965 else
1966 {
1967 if (format == GL_DEPTH_STENCIL && internalformat.sizedFormat != GL_DEPTH24_STENCIL8 &&
1968 internalformat.sizedFormat != GL_DEPTH32F_STENCIL8)
1969 {
1970 // We can't make a complete DEPTH_STENCIL attachment with a
1971 // texture that does not have both DEPTH and STENCIL components.
1972 return false;
1973 }
1974
1975 GLenum colorRenderableFrmats[] = { GL_RGBA32F, GL_RGBA32I, GL_RGBA32UI, GL_RGBA16,
1976 GL_RGBA16F, GL_RGBA16I, GL_RGBA16UI, GL_RGBA8,
1977 GL_RGBA8I, GL_RGBA8UI, GL_SRGB8_ALPHA8, GL_RGB10_A2,
1978 GL_RGB10_A2UI, GL_RGB5_A1, GL_RGBA4, GL_R11F_G11F_B10F,
1979 GL_RGB565, GL_RG32F, GL_RG32I, GL_RG32UI,
1980 GL_RG16, GL_RG16F, GL_RG16I, GL_RG16UI,
1981 GL_RG8, GL_RG8I, GL_RG8UI, GL_R32F,
1982 GL_R32I, GL_R32UI, GL_R16F, GL_R16I,
1983 GL_R16UI, GL_R16, GL_R8, GL_R8I,
1984 GL_R8UI };
1985 GLenum* formatsEnd = colorRenderableFrmats + DE_LENGTH_OF_ARRAY(colorRenderableFrmats);
1986 if (std::find(colorRenderableFrmats, formatsEnd, internalformat.sizedFormat) < formatsEnd)
1987 return true;
1988
1989 GLenum dsRenderableFormats[] = {
1990 GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
1991 GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8,
1992 };
1993
1994 formatsEnd = dsRenderableFormats + DE_LENGTH_OF_ARRAY(dsRenderableFormats);
1995 if (std::find(dsRenderableFormats, formatsEnd, internalformat.sizedFormat) < formatsEnd)
1996 return true;
1997
1998 return false;
1999 }
2000 }
2001
doRead(GLuint texture)2002 bool RectangleTest::doRead(GLuint texture)
2003 {
2004 glu::RenderContext& renderContext = m_context.getRenderContext();
2005 const Functions& gl = renderContext.getFunctions();
2006
2007 GLuint fboId;
2008 gl.genFramebuffers(1, &fboId);
2009 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
2010 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
2011
2012 bool validImageAttach = isFBOImageAttachValid(m_internalFormat, m_inputFormat.format, m_inputType.type);
2013 if (m_textureTarget == GL_TEXTURE_2D)
2014 gl.framebufferTexture2D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_2D, texture, 0);
2015 else if (glu::isContextTypeES(renderContext.getType()))
2016 gl.framebufferTextureLayer(GL_FRAMEBUFFER, m_inputFormat.attachment, texture, 0, 0);
2017 else
2018 gl.framebufferTexture3D(GL_FRAMEBUFFER, m_inputFormat.attachment, GL_TEXTURE_3D, texture, 0, 0);
2019 GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2020
2021 bool result = true;
2022 if (status == GL_FRAMEBUFFER_COMPLETE)
2023 {
2024 if (!validImageAttach && glu::isContextTypeES(renderContext.getType()))
2025 {
2026 m_testCtx.getLog() << tcu::TestLog::Message << "FBO is complete but expected incomplete with sizedFormat: "
2027 << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage;
2028 result = false;
2029 }
2030 else
2031 {
2032 result &= readPixels(false);
2033 result &= doCopy();
2034 }
2035 }
2036 else if (validImageAttach)
2037 {
2038 m_testCtx.getLog() << tcu::TestLog::Message << "FBO is not complete but expected complete with sizedFormat: "
2039 << getFormatStr(m_internalFormat.sizedFormat) << tcu::TestLog::EndMessage;
2040 result = false;
2041 }
2042
2043 gl.deleteFramebuffers(1, &fboId);
2044
2045 return result;
2046 }
2047
readPixels(bool isCopy)2048 bool RectangleTest::readPixels(bool isCopy)
2049 {
2050 bool result = true;
2051
2052 const PixelType* types;
2053 int typesCount;
2054 const PixelFormat* formats;
2055 int formatsCount;
2056
2057 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
2058 {
2059 types = esTypes;
2060 typesCount = DE_LENGTH_OF_ARRAY(esTypes);
2061 formats = esFormats;
2062 formatsCount = DE_LENGTH_OF_ARRAY(esFormats);
2063 }
2064 else
2065 {
2066 types = coreTypes;
2067 typesCount = DE_LENGTH_OF_ARRAY(coreTypes);
2068 formats = coreFormats;
2069 formatsCount = DE_LENGTH_OF_ARRAY(coreFormats);
2070 }
2071
2072 // for each output format
2073 for (int m = 0; m < formatsCount; ++m)
2074 {
2075 const PixelFormat& outputFormat = formats[m];
2076
2077 // for each output type
2078 for (int n = 0; n < typesCount; ++n)
2079 {
2080 const PixelType& outputType = types[n];
2081
2082 if (isCopy)
2083 {
2084 // continue when input format,type != canonical format,type and
2085 // output format,type != canonical format,type
2086 if ((outputFormat.format != m_copyInternalFormat.format ||
2087 outputType.type != m_copyInternalFormat.type))
2088 {
2089 // invalid output format and type - skipping case
2090 continue;
2091 }
2092 }
2093 else if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) &&
2094 (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type))
2095 {
2096 // invalid output format and type - skipping case
2097 continue;
2098 }
2099
2100 result &= readPixelsInner(outputFormat, outputType, isCopy);
2101 }
2102 }
2103
2104 return result;
2105 }
2106
readPixelsInner(const PixelFormat & outputFormat,const PixelType & outputType,bool isCopy)2107 bool RectangleTest::readPixelsInner(const PixelFormat& outputFormat, const PixelType& outputType, bool isCopy)
2108 {
2109 const char* copyStage = "Copy stage: ";
2110
2111 GLenum readerror = readOutputData(outputFormat, outputType, OUTPUT_READPIXELS);
2112 if (m_outputBuffer.empty())
2113 {
2114 m_testCtx.getLog() << tcu::TestLog::Message << "No buffer allocated" << tcu::TestLog::EndMessage;
2115 return false;
2116 }
2117
2118 m_countReadPixels++;
2119
2120 // Check if output format is valid
2121 bool outputFormatValid = isFormatValid(outputFormat, outputType, isCopy ? m_copyInternalFormat : m_internalFormat,
2122 false, true, OUTPUT_READPIXELS);
2123
2124 // Even if this is a valid glReadPixels format, we can't read non-existant components
2125 if (outputFormatValid && outputFormat.format == GL_DEPTH_STENCIL && m_inputFormat.format != GL_DEPTH_STENCIL)
2126 outputFormatValid = false;
2127
2128 if (outputFormatValid)
2129 {
2130 if (readerror != GL_NO_ERROR)
2131 {
2132 m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2133 << "Valid format used but glReadPixels failed 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 else
2140 {
2141 m_countReadPixelsOK++;
2142 m_countCompare++;
2143
2144 // compare output gradient to input gradient
2145 if (!compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, isCopy))
2146 {
2147 m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2148 << "Gradient comparison failed during ReadPixels for input = ["
2149 << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type)
2150 << "] output = [" << getFormatStr(outputFormat.format) << ", "
2151 << getTypeStr(outputType.type) << "]" << tcu::TestLog::EndMessage;
2152 return false;
2153 }
2154
2155 m_countCompareOK++;
2156 }
2157 }
2158 else if (readerror == GL_NO_ERROR)
2159 {
2160 m_testCtx.getLog() << tcu::TestLog::Message << (isCopy ? copyStage : "")
2161 << "Invalid format used but glReadPixels succeeded for input = ["
2162 << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type)
2163 << "] output = [" << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type)
2164 << "]" << tcu::TestLog::EndMessage;
2165 return false;
2166 }
2167
2168 return true;
2169 }
2170
readOutputData(const PixelFormat & outputFormat,const PixelType & outputType,int operation)2171 GLenum RectangleTest::readOutputData(const PixelFormat& outputFormat, const PixelType& outputType, int operation)
2172 {
2173 // If using PBOs buffer object for GL_PIXEL_PACK_BUFFER must
2174 // be bound and not allocated before calling when using PBOs
2175
2176 glu::RenderContext& renderContext = m_context.getRenderContext();
2177 const Functions& gl = renderContext.getFunctions();
2178
2179 PackedPixelsBufferProperties& props = m_packProperties;
2180 props.elementSize = outputType.size;
2181 props.elementsInGroup = outputType.special ? 1 : outputFormat.components;
2182 props.rowLength = (props.rowLength == 0) ? (GRADIENT_WIDTH + props.skipPixels) : props.rowLength;
2183 props.elementsInRowNoAlign = props.elementsInGroup * props.rowLength;
2184 props.elementsInRow = props.elementsInRowNoAlign;
2185
2186 if (glu::isContextTypeES(renderContext.getType()))
2187 {
2188 props.rowCount = 0;
2189 props.skipImages = 0;
2190 }
2191 else if ((operation == OUTPUT_READPIXELS) || (m_textureTarget == GL_TEXTURE_2D))
2192 props.skipImages = 0;
2193
2194 if (props.rowCount == 0)
2195 props.rowCount = GRADIENT_HEIGHT + props.skipRows;
2196 props.imagesCount = props.skipImages + 1;
2197 if (props.elementSize < props.alignment)
2198 {
2199 props.elementsInRow = (int)(props.alignment * deFloatCeil(props.elementSize * props.elementsInGroup *
2200 props.rowLength / ((float)props.alignment))) /
2201 props.elementSize;
2202 }
2203
2204 int bufferSize =
2205 props.elementSize * props.elementsInRow * props.rowCount * props.imagesCount * (props.skipImages + 1);
2206
2207 // The output buffer allocated should be initialized to a known value. After
2208 // a pack operation, any extra memory allocated for skipping should be
2209 // verified to be the original known value, untouched by the GL.
2210 const GLubyte defaultFillValue = 0xaa;
2211 m_outputBuffer.resize(static_cast<std::size_t>(bufferSize));
2212 std::fill(m_outputBuffer.begin(), m_outputBuffer.end(), defaultFillValue);
2213
2214 GLuint packPBO;
2215 if (m_usePBO)
2216 {
2217 gl.genBuffers(1, &packPBO);
2218 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, packPBO);
2219 gl.bufferData(GL_PIXEL_PACK_BUFFER, bufferSize, &m_outputBuffer[0], GL_STATIC_READ);
2220 }
2221
2222 GLenum readError = GL_NO_ERROR;
2223 switch (operation)
2224 {
2225 case OUTPUT_GETTEXIMAGE:
2226 gl.getTexImage(m_textureTarget, 0, outputFormat.format, outputType.type, m_usePBO ? 0 : &m_outputBuffer[0]);
2227 break;
2228
2229 case OUTPUT_READPIXELS:
2230 if (m_inputFormat.attachment != GL_DEPTH_ATTACHMENT &&
2231 m_inputFormat.attachment != GL_DEPTH_STENCIL_ATTACHMENT &&
2232 m_inputFormat.attachment != GL_STENCIL_ATTACHMENT)
2233 gl.readBuffer(m_inputFormat.attachment);
2234
2235 readError = gl.getError();
2236 if (readError == GL_NO_ERROR)
2237 gl.readPixels(0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, outputFormat.format, outputType.type,
2238 m_usePBO ? 0 : &m_outputBuffer[0]);
2239 break;
2240 }
2241
2242 if (readError == GL_NO_ERROR)
2243 readError = gl.getError();
2244
2245 if (m_usePBO)
2246 {
2247 if (readError == GL_NO_ERROR)
2248 {
2249 GLvoid* mappedData = gl.mapBufferRange(GL_PIXEL_PACK_BUFFER, 0, bufferSize, GL_MAP_READ_BIT);
2250 if (!mappedData)
2251 return GL_INVALID_INDEX;
2252
2253 std::memcpy(&m_outputBuffer[0], mappedData, bufferSize);
2254 gl.unmapBuffer(GL_PIXEL_PACK_BUFFER);
2255 }
2256
2257 gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2258 gl.deleteBuffers(1, &packPBO);
2259 }
2260
2261 if (m_packProperties.swapBytes && (readError == GL_NO_ERROR))
2262 swapBytes(outputType.size, m_outputBuffer);
2263
2264 return readError;
2265 }
2266
doCopy()2267 bool RectangleTest::doCopy()
2268 {
2269 bool result = true;
2270
2271 const InternalFormat* copyInternalFormats;
2272 int internalFormatsCount;
2273 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
2274 {
2275 copyInternalFormats = esInternalformats;
2276 internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats);
2277 }
2278 else
2279 {
2280 copyInternalFormats = coreInternalformats;
2281 internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats);
2282 }
2283
2284 if ((m_inputFormat.format == m_internalFormat.format) && (m_inputType.type == m_internalFormat.type))
2285 {
2286 for (int i = 0; i < internalFormatsCount; ++i)
2287 {
2288 m_copyInternalFormat = copyInternalFormats[i];
2289 result &= doCopyInner();
2290 }
2291 }
2292
2293 return result;
2294 }
2295
doCopyInner()2296 bool RectangleTest::doCopyInner()
2297 {
2298 glu::RenderContext& renderContext = m_context.getRenderContext();
2299 const Functions& gl = renderContext.getFunctions();
2300 bool result = true;
2301
2302 const EnumFormats* copyFormatEnum =
2303 getCanonicalFormat(m_copyInternalFormat, m_copyInternalFormat.format, m_copyInternalFormat.type);
2304
2305 if (copyFormatEnum != 0)
2306 {
2307 GLuint texture2;
2308 GLenum status;
2309
2310 bool validcopy = isCopyValid(m_copyInternalFormat, m_internalFormat);
2311
2312 gl.genTextures(1, &texture2);
2313 // Target is always GL_TEXTURE_2D
2314 gl.bindTexture(GL_TEXTURE_2D, texture2);
2315 GLenum error = gl.getError();
2316
2317 // CopyTexImage to copy_internalformat (GL converts, but PixelStore is ignored)
2318 // Target is always GL_TEXTURE_2D
2319 gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_copyInternalFormat.sizedFormat, 0, 0, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0);
2320 error = gl.getError();
2321
2322 // if this combination of copy_internalformat,internalformat is invalid
2323 if (validcopy == false)
2324 {
2325 // expect error and continue
2326 if (error != GL_NO_ERROR)
2327 {
2328 // Invalid format used and glCopyTexImage2D failed
2329 result = true;
2330 }
2331 else
2332 {
2333 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glCopyTexImage2D succeeded"
2334 << tcu::TestLog::EndMessage;
2335 result = false;
2336 }
2337 }
2338 else // validcopy == true
2339 {
2340 // expect no error and continue
2341 if (error != GL_NO_ERROR)
2342 {
2343 m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glCopyTexImage2D failed"
2344 << tcu::TestLog::EndMessage;
2345 result = false;
2346 }
2347 else
2348 {
2349 if (!glu::isContextTypeES(renderContext.getType()))
2350 {
2351 // if GetTexImage is supported we call the
2352 // inner function only as no loop needed
2353 const PixelFormat& outputFormat = getPixelFormat(copyFormatEnum->format);
2354 const PixelType& outputType = getPixelType(copyFormatEnum->type);
2355 result &= getTexImageInner(outputFormat, outputType);
2356 }
2357
2358 GLint orginalFboId;
2359 gl.getIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &orginalFboId);
2360 GLU_EXPECT_NO_ERROR(gl.getError(), "getIntegerv");
2361
2362 GLuint fboId;
2363 gl.genFramebuffers(1, &fboId);
2364 gl.bindFramebuffer(GL_FRAMEBUFFER, fboId);
2365
2366 bool validImageAttach =
2367 isFBOImageAttachValid(m_copyInternalFormat, copyFormatEnum->format, copyFormatEnum->type);
2368
2369 // attach copy_internalformat texture to FBO
2370 // Target is always GL_TEXTURE_2D
2371 const PixelFormat& copyFormat = getPixelFormat(copyFormatEnum->format);
2372 gl.framebufferTexture2D(GL_FRAMEBUFFER, copyFormat.attachment, GL_TEXTURE_2D, texture2, 0);
2373 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D");
2374
2375 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2376 GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus");
2377
2378 // if an unsized sizedFormat was given, then implementation chosen copy format
2379 // destination might be different than what's expected;
2380 // we cannot continue checking since ReadPixels might not choose a compatible
2381 // format, also the format may not be renderable as expected
2382 if (isUnsizedFormat(m_copyInternalFormat.sizedFormat))
2383 {
2384 result &= true;
2385 }
2386 else if (status == GL_FRAMEBUFFER_COMPLETE)
2387 {
2388 if (validImageAttach)
2389 result &= readPixels(true);
2390 else
2391 {
2392 m_testCtx.getLog()
2393 << tcu::TestLog::Message << "Copy FBO is complete but expected incomplete with sizedFormat "
2394 << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement "
2395 << copyFormat.attachment << tcu::TestLog::EndMessage;
2396 result = false;
2397 }
2398 }
2399 else if (validImageAttach)
2400 {
2401 m_testCtx.getLog() << tcu::TestLog::Message
2402 << "Copy FBO is not complete but expected complete with sizedFormat "
2403 << getFormatStr(m_copyInternalFormat.sizedFormat) << ", attachement "
2404 << copyFormat.attachment << tcu::TestLog::EndMessage;
2405 result = false;
2406 }
2407
2408 // bind original FBO
2409 gl.bindFramebuffer(GL_FRAMEBUFFER, orginalFboId);
2410 gl.deleteFramebuffers(1, &fboId);
2411 }
2412 }
2413
2414 gl.deleteTextures(1, &texture2);
2415 }
2416
2417 return result;
2418 }
2419
compare(GLvoid * gradient,GLvoid * data,const PixelFormat & outputFormat,const PixelType & outputType,bool isCopy) const2420 bool RectangleTest::compare(GLvoid* gradient, GLvoid* data, const PixelFormat& outputFormat,
2421 const PixelType& outputType, bool isCopy) const
2422 {
2423 // Compares the reference gradient data to the output data
2424
2425 int iformatSampler = m_internalFormat.sampler;
2426 int outputSampler = getSampler(outputType, outputFormat);
2427 int inputSampler = getSampler(m_inputType, m_inputFormat);
2428
2429 if (isCopy)
2430 iformatSampler = m_copyInternalFormat.sampler;
2431
2432 int samplerIsIntUintFloat = 3; // 1: INT | 2: UINT | 3: FLOAT/UNORM/NORM
2433 if (m_internalFormat.sampler == SAMPLER_INT)
2434 samplerIsIntUintFloat = 1;
2435 else if (m_internalFormat.sampler == SAMPLER_UINT)
2436 samplerIsIntUintFloat = 2;
2437
2438 std::vector<GLubyte> gradientStrip;
2439 if (!stripBuffer(m_unpackProperties, static_cast<const GLubyte*>(gradient), gradientStrip, false))
2440 return false;
2441 std::vector<GLubyte> dataStrip;
2442 if (!stripBuffer(m_packProperties, static_cast<const GLubyte*>(data), dataStrip, true))
2443 return false;
2444
2445 if (gradientStrip.empty() || dataStrip.empty())
2446 return false;
2447
2448 std::vector<FloatPixel> inputBuffer;
2449 getFloatBuffer(&gradientStrip[0], samplerIsIntUintFloat, m_inputFormat, m_inputType,
2450 GRADIENT_WIDTH * GRADIENT_HEIGHT, inputBuffer);
2451
2452 std::vector<FloatPixel> outputBuffer;
2453 getFloatBuffer(&dataStrip[0], samplerIsIntUintFloat, outputFormat, outputType, GRADIENT_WIDTH * GRADIENT_HEIGHT,
2454 outputBuffer);
2455
2456 std::vector<int> inputBitTable;
2457 getBits(m_inputType, m_inputFormat, inputBitTable);
2458 std::vector<int> outputBitTable;
2459 getBits(outputType, outputFormat, outputBitTable);
2460 const int* internalformatBitTable = reinterpret_cast<const int*>(&m_internalFormat.bits);
2461 const int* copyFormatBitTable = m_copyInternalFormat.bits.array;
2462
2463 // make struct field iterable
2464 float* inputBufferFloat = reinterpret_cast<float*>(&inputBuffer[0]);
2465 float* outputBufferFloat = reinterpret_cast<float*>(&outputBuffer[0]);
2466
2467 int* inputBufferInt = reinterpret_cast<int*>(&inputBuffer[0]);
2468 int* outputBufferInt = reinterpret_cast<int*>(&outputBuffer[0]);
2469
2470 unsigned int* inputBufferUint = reinterpret_cast<unsigned int*>(&inputBuffer[0]);
2471 unsigned int* outputBufferUint = reinterpret_cast<unsigned int*>(&outputBuffer[0]);
2472
2473 for (int i = 0; i < GRADIENT_WIDTH * GRADIENT_HEIGHT; ++i)
2474 {
2475 for (int j = 0; j < NUM_FLOAT_PIXEL_COUNT / 3; ++j)
2476 {
2477 int bit1 = getRealBitPrecision(inputBitTable[j], inputSampler == SAMPLER_FLOAT);
2478 int bit2 = getRealBitPrecision(outputBitTable[j], outputSampler == SAMPLER_FLOAT);
2479 int bit3 = getRealBitPrecision(internalformatBitTable[j], iformatSampler == SAMPLER_FLOAT);
2480 int bitdiff;
2481
2482 if (bit1 >= bit3)
2483 {
2484 if ((inputSampler == SAMPLER_UNORM && m_internalFormat.sampler == SAMPLER_NORM))
2485 bit3 -= 1;
2486 }
2487
2488 if (bit2 <= bit3)
2489 {
2490 if (outputSampler == SAMPLER_NORM && m_internalFormat.sampler == SAMPLER_UNORM)
2491 bit2 -= 1;
2492 }
2493
2494 if (!(m_internalFormat.flags & FLAG_REQ_RBO) && bit3 > 8 && m_internalFormat.sampler != SAMPLER_UINT &&
2495 m_internalFormat.sampler != SAMPLER_INT)
2496 {
2497 // If this internalFormat is not a required format there is no requirement
2498 // that the implementation uses exactly the bit width requested. For example,
2499 // it may substitute RGB10 for RGB12. The implementation can't make subtitutions
2500 // for integer formats.
2501 bit3 = 8;
2502 }
2503
2504 bitdiff = std::min(std::min(bit1, bit2), bit3);
2505 if (isCopy)
2506 {
2507 bitdiff = std::min(bitdiff, copyFormatBitTable[j]);
2508 }
2509
2510 if (bitdiff > 0)
2511 {
2512 if (samplerIsIntUintFloat == 1) // 1: INT
2513 {
2514 int inputValue = inputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j];
2515 int outputValue = outputBufferInt[NUM_FLOAT_PIXEL_COUNT * i + j];
2516
2517 if (inputSampler == SAMPLER_UINT)
2518 // If input data was unsigned, it should be clamped to fit into
2519 // internal format positive range (otherwise it may wrap and
2520 // yield negative internalformat values)
2521 inputValue = clampUnsignedValue(bit3 - 1, inputValue);
2522
2523 inputValue = clampSignedValue(bit3, inputValue);
2524 if (isCopy)
2525 {
2526 inputValue = clampSignedValue(copyFormatBitTable[j], inputValue);
2527 }
2528 if (outputSampler == SAMPLER_UINT)
2529 inputValue = clampUnsignedValue(bit2, inputValue);
2530 else
2531 inputValue = clampSignedValue(bit2, inputValue);
2532
2533 if (inputValue != outputValue)
2534 {
2535 m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", "
2536 << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue
2537 << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2538 return false;
2539 }
2540 }
2541 else if (samplerIsIntUintFloat == 2) // 2: UINT
2542 {
2543 unsigned int inputValue = inputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6];
2544 unsigned int outputValue = outputBufferUint[NUM_FLOAT_PIXEL_COUNT * i + j + 6];
2545
2546 inputValue = clampUnsignedValue(bit3, inputValue);
2547 if (isCopy)
2548 inputValue = clampUnsignedValue(copyFormatBitTable[j], inputValue);
2549
2550 if (outputSampler == SAMPLER_UINT)
2551 inputValue = clampUnsignedValue(bit2, inputValue);
2552 else if (outputSampler == SAMPLER_INT)
2553 inputValue = clampUnsignedValue(bit2 - 1, inputValue);
2554 if (inputValue != outputValue)
2555 {
2556 m_testCtx.getLog() << tcu::TestLog::Message << "Integer comparison: " << i << ", " << j << ", "
2557 << NUM_FLOAT_PIXEL_COUNT * i + j << ": " << inputValue
2558 << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2559 return false;
2560 }
2561 }
2562 else if (samplerIsIntUintFloat == 3) // 3: FLOAT / UNORM / NORM
2563 {
2564 float inputValue = inputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12];
2565 float outputValue = outputBufferFloat[NUM_FLOAT_PIXEL_COUNT * i + j + 12];
2566 float epsilon;
2567
2568 if ((outputSampler == SAMPLER_UNORM) || (outputSampler == SAMPLER_NORM))
2569 {
2570 // Check if format is UNORM/NORM which needs different
2571 // precision since it implies a int->float conversion.
2572 epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1);
2573 }
2574 else if ((inputSampler == SAMPLER_FLOAT) != (outputSampler == SAMPLER_FLOAT))
2575 {
2576 // Allow for rounding in either direction for float->int conversions.
2577 epsilon = 1.0f / ((float)((1 << (bitdiff - 1))) - 1);
2578 }
2579 else
2580 epsilon = 1.0f / ((float)((1 << bitdiff) - 1));
2581
2582 if (inputSampler == SAMPLER_FLOAT || outputSampler == SAMPLER_FLOAT)
2583 {
2584 // According to GL spec the precision requirement
2585 // of floating-point values is 1 part in 10^5.
2586 epsilon = deFloatMax(epsilon, 0.00001f);
2587 }
2588
2589 if (m_internalFormat.flags & FLAG_COMPRESSED)
2590 epsilon = deFloatMax(epsilon, 0.1f);
2591
2592 // Clamp input value to range of output
2593 if (iformatSampler == SAMPLER_UNORM || outputSampler == SAMPLER_UNORM)
2594 inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), 0.0f);
2595 else if (iformatSampler == SAMPLER_NORM || outputSampler == SAMPLER_NORM)
2596 inputValue = deFloatMax(deFloatMin(inputValue, 1.0f), -1.0f);
2597
2598 // Compare the input and output
2599 if (deFloatAbs(inputValue - outputValue) > epsilon)
2600 {
2601 m_testCtx.getLog()
2602 << tcu::TestLog::Message << "Non-integer comparison: " << i << ", " << j << ", "
2603 << NUM_FLOAT_PIXEL_COUNT * i + j << ", " << epsilon << ": " << inputValue
2604 << " == " << outputValue << ": not equal." << tcu::TestLog::EndMessage;
2605 return false;
2606 }
2607 }
2608 else
2609 {
2610 m_testCtx.getLog() << tcu::TestLog::Message << "Sampler type cannot be recognised, so no comparison"
2611 << tcu::TestLog::EndMessage;
2612 return false;
2613 }
2614 }
2615 }
2616 }
2617
2618 return true;
2619 }
2620
getFloatBuffer(GLvoid * gradient,int samplerIsIntUintFloat,const PixelFormat & format,const PixelType & type,int elementCount,std::vector<FloatPixel> & result) const2621 void RectangleTest::getFloatBuffer(GLvoid* gradient, int samplerIsIntUintFloat, const PixelFormat& format,
2622 const PixelType& type, int elementCount, std::vector<FloatPixel>& result) const
2623 {
2624 int componentCount = format.components;
2625 switch (type.type)
2626 {
2627 case GL_UNSIGNED_BYTE:
2628 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_BYTE, result);
2629 break;
2630 case GL_BYTE:
2631 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_BYTE, result);
2632 break;
2633 case GL_UNSIGNED_SHORT:
2634 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_SHORT, result);
2635 break;
2636 case GL_SHORT:
2637 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_SHORT, result);
2638 break;
2639 case GL_UNSIGNED_INT:
2640 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_UNSIGNED_INT, result);
2641 break;
2642 case GL_INT:
2643 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_INT, result);
2644 break;
2645 case GL_HALF_FLOAT:
2646 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_HALF_FLOAT, result);
2647 break;
2648 case GL_FLOAT:
2649 makeBuffer(gradient, format, samplerIsIntUintFloat, elementCount, componentCount, pack_FLOAT, result);
2650 break;
2651 case GL_UNSIGNED_SHORT_5_6_5:
2652 if (samplerIsIntUintFloat == 1)
2653 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_INT, result);
2654 else if (samplerIsIntUintFloat == 2)
2655 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_UINT, result);
2656 else if (samplerIsIntUintFloat == 3)
2657 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5, result);
2658 break;
2659 case GL_UNSIGNED_SHORT_4_4_4_4:
2660 if (samplerIsIntUintFloat == 1)
2661 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_INT, result);
2662 else if (samplerIsIntUintFloat == 2)
2663 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_UINT, result);
2664 else if (samplerIsIntUintFloat == 3)
2665 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4, result);
2666 break;
2667 case GL_UNSIGNED_SHORT_5_5_5_1:
2668 if (samplerIsIntUintFloat == 1)
2669 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_INT, result);
2670 else if (samplerIsIntUintFloat == 2)
2671 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1_UINT, result);
2672 else if (samplerIsIntUintFloat == 3)
2673 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_5_5_1, result);
2674 break;
2675 case GL_UNSIGNED_INT_2_10_10_10_REV:
2676 if (samplerIsIntUintFloat == 1)
2677 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_INT, result);
2678 else if (samplerIsIntUintFloat == 2)
2679 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV_UINT, result);
2680 else if (samplerIsIntUintFloat == 3)
2681 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_2_10_10_10_REV, result);
2682 break;
2683 case GL_UNSIGNED_INT_24_8:
2684 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_24_8, result);
2685 break;
2686 case GL_UNSIGNED_INT_10F_11F_11F_REV:
2687 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10F_11F_11F_REV, result);
2688 break;
2689 case GL_UNSIGNED_INT_5_9_9_9_REV:
2690 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_5_9_9_9_REV, result);
2691 break;
2692 case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
2693 makeBufferPackedFloat(gradient, format, elementCount, pack_FLOAT_32_UNSIGNED_INT_24_8_REV, result);
2694 break;
2695 case GL_UNSIGNED_BYTE_3_3_2:
2696 if (samplerIsIntUintFloat == 1)
2697 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_INT, result);
2698 else if (samplerIsIntUintFloat == 2)
2699 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2_UINT, result);
2700 else if (samplerIsIntUintFloat == 3)
2701 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_3_3_2, result);
2702 break;
2703 case GL_UNSIGNED_BYTE_2_3_3_REV:
2704 if (samplerIsIntUintFloat == 1)
2705 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_INT, result);
2706 else if (samplerIsIntUintFloat == 2)
2707 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV_UINT, result);
2708 else if (samplerIsIntUintFloat == 3)
2709 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_BYTE_2_3_3_REV, result);
2710 break;
2711 case GL_UNSIGNED_SHORT_5_6_5_REV:
2712 if (samplerIsIntUintFloat == 1)
2713 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_INT, result);
2714 else if (samplerIsIntUintFloat == 2)
2715 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV_UINT, result);
2716 else if (samplerIsIntUintFloat == 3)
2717 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_5_6_5_REV, result);
2718 break;
2719 case GL_UNSIGNED_SHORT_4_4_4_4_REV:
2720 if (samplerIsIntUintFloat == 1)
2721 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_INT, result);
2722 else if (samplerIsIntUintFloat == 2)
2723 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT, result);
2724 else if (samplerIsIntUintFloat == 3)
2725 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_4_4_4_4_REV, result);
2726 break;
2727 case GL_UNSIGNED_SHORT_1_5_5_5_REV:
2728 if (samplerIsIntUintFloat == 1)
2729 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_INT, result);
2730 else if (samplerIsIntUintFloat == 2)
2731 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT, result);
2732 else if (samplerIsIntUintFloat == 3)
2733 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_SHORT_1_5_5_5_REV, result);
2734 break;
2735 case GL_UNSIGNED_INT_8_8_8_8:
2736 if (samplerIsIntUintFloat == 1)
2737 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_INT, result);
2738 else if (samplerIsIntUintFloat == 2)
2739 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_UINT, result);
2740 else if (samplerIsIntUintFloat == 3)
2741 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8, result);
2742 break;
2743 case GL_UNSIGNED_INT_8_8_8_8_REV:
2744 if (samplerIsIntUintFloat == 1)
2745 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_INT, result);
2746 else if (samplerIsIntUintFloat == 2)
2747 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV_UINT, result);
2748 else if (samplerIsIntUintFloat == 3)
2749 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_8_8_8_8_REV, result);
2750 break;
2751 case GL_UNSIGNED_INT_10_10_10_2:
2752 if (samplerIsIntUintFloat == 1)
2753 makeBufferPackedInt(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_INT, result);
2754 else if (samplerIsIntUintFloat == 2)
2755 makeBufferPackedUint(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2_UINT, result);
2756 else if (samplerIsIntUintFloat == 3)
2757 makeBufferPackedFloat(gradient, format, elementCount, pack_UNSIGNED_INT_10_10_10_2, result);
2758 break;
2759 default:
2760 TCU_FAIL("Unsuported type");
2761 }
2762 }
2763
2764 template <typename Type>
makeBuffer(const GLvoid * gradient,const PixelFormat & format,int samplerIsIntUintFloat,int elementCount,int componentCount,float (* pack)(Type),std::vector<FloatPixel> & result) const2765 void RectangleTest::makeBuffer(const GLvoid* gradient, const PixelFormat& format, int samplerIsIntUintFloat,
2766 int elementCount, int componentCount, float (*pack)(Type),
2767 std::vector<FloatPixel>& result) const
2768 {
2769 const Type* sourceData = static_cast<const Type*>(gradient);
2770 result.resize(sizeof(FloatPixel) * elementCount);
2771 for (int i = 0; i < elementCount; ++i)
2772 {
2773 rawFloatPixel values;
2774 rawIntPixel valuesInt;
2775 rawUintPixel valuesUint;
2776 for (int j = 0; j < componentCount; j++)
2777 {
2778 if (samplerIsIntUintFloat == 1)
2779 valuesInt[j] = (int)static_cast<Type>(sourceData[componentCount * i + j]);
2780 else if (samplerIsIntUintFloat == 2)
2781 valuesUint[j] = (unsigned int)static_cast<Type>(sourceData[componentCount * i + j]);
2782 else if (samplerIsIntUintFloat == 3)
2783 values[j] = pack(sourceData[componentCount * i + j]);
2784 }
2785 if (samplerIsIntUintFloat == 1)
2786 result[i] = orderComponentsInt(valuesInt, format);
2787 else if (samplerIsIntUintFloat == 2)
2788 result[i] = orderComponentsUint(valuesUint, format);
2789 else if (samplerIsIntUintFloat == 3)
2790 result[i] = orderComponentsFloat(values, format);
2791 }
2792 }
2793
getBits(const PixelType & type,const PixelFormat & format,std::vector<int> & resultTable) const2794 void RectangleTest::getBits(const PixelType& type, const PixelFormat& format, std::vector<int>& resultTable) const
2795 {
2796 // return bit depth table based on type and format pair;
2797 // table is always NUM_FLOAT_PIXEL_COUNT digit long
2798
2799 resultTable.resize(NUM_FLOAT_PIXEL_COUNT);
2800 std::fill(resultTable.begin(), resultTable.end(), 0);
2801
2802 if (type.special == true)
2803 {
2804 std::memcpy(&resultTable[0], &type.bits, sizeof(type.bits));
2805 if (type.type == GL_UNSIGNED_INT_5_9_9_9_REV)
2806 {
2807 //this type is another special case: it is always converted to 3-channel color (no A).
2808 //as results of this function are used for comparison of converted values we set A bits to 0.
2809 resultTable[3] = 0;
2810 }
2811 }
2812 else
2813 {
2814 int bits;
2815
2816 if (type.type == GL_FLOAT)
2817 bits = 32;
2818 else if (type.type == GL_HALF_FLOAT)
2819 bits = 16;
2820 else
2821 bits = type.size << 3;
2822
2823 if (format.format == GL_DEPTH_STENCIL || format.format == GL_DEPTH_COMPONENT)
2824 resultTable[4] = bits;
2825
2826 if (format.format == GL_DEPTH_STENCIL || format.format == GL_STENCIL_INDEX ||
2827 format.format == GL_STENCIL_INDEX8)
2828 {
2829 resultTable[5] = bits;
2830 }
2831
2832 if (format.format == GL_RED || format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA ||
2833 format.format == GL_BGR || format.format == GL_BGRA || format.format == GL_RED_INTEGER ||
2834 format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER ||
2835 format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2836 {
2837 resultTable[0] = bits;
2838 }
2839
2840 if (format.format == GL_RG || format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR ||
2841 format.format == GL_BGRA || format.format == GL_RG_INTEGER || format.format == GL_RGB_INTEGER ||
2842 format.format == GL_RGBA_INTEGER || format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2843 {
2844 resultTable[1] = bits;
2845 }
2846
2847 if (format.format == GL_RGB || format.format == GL_RGBA || format.format == GL_BGR ||
2848 format.format == GL_BGRA || format.format == GL_RGB_INTEGER || format.format == GL_RGBA_INTEGER ||
2849 format.format == GL_BGR_INTEGER || format.format == GL_BGRA_INTEGER)
2850 {
2851 resultTable[2] = bits;
2852 }
2853
2854 if (format.format == GL_RGBA || format.format == GL_BGRA || format.format == GL_RGBA_INTEGER ||
2855 format.format == GL_BGRA_INTEGER)
2856 {
2857 resultTable[3] = bits;
2858 }
2859 }
2860 }
2861
2862 template <typename Type>
makeBufferPackedInt(const GLvoid * gradient,const PixelFormat & format,int elementCount,void (* pack)(rawIntPixel *,Type),std::vector<FloatPixel> & result) const2863 void RectangleTest::makeBufferPackedInt(const GLvoid* gradient, const PixelFormat& format, int elementCount,
2864 void (*pack)(rawIntPixel*, 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 rawIntPixel values;
2871 pack(&values, sourceData[i]);
2872 result[i] = orderComponentsInt(values, format);
2873 }
2874 }
2875
2876 template <typename Type>
makeBufferPackedUint(const GLvoid * gradient,const PixelFormat & format,int elementCount,void (* pack)(rawUintPixel *,Type),std::vector<FloatPixel> & result) const2877 void RectangleTest::makeBufferPackedUint(const GLvoid* gradient, const PixelFormat& format, int elementCount,
2878 void (*pack)(rawUintPixel*, 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 rawUintPixel values;
2885 pack(&values, sourceData[i]);
2886 result[i] = orderComponentsUint(values, format);
2887 }
2888 }
2889
2890 template <typename Type>
makeBufferPackedFloat(const GLvoid * gradient,const PixelFormat & format,int elementCount,void (* pack)(rawFloatPixel *,Type),std::vector<FloatPixel> & result) const2891 void RectangleTest::makeBufferPackedFloat(const GLvoid* gradient, const PixelFormat& format, int elementCount,
2892 void (*pack)(rawFloatPixel*, Type), std::vector<FloatPixel>& result) const
2893 {
2894 const Type* sourceData = static_cast<const Type*>(gradient);
2895 result.resize(sizeof(FloatPixel) * elementCount);
2896 for (int i = 0; i < elementCount; ++i)
2897 {
2898 rawFloatPixel values;
2899 pack(&values, sourceData[i]);
2900 result[i] = orderComponentsFloat(values, format);
2901 }
2902 }
2903
orderComponentsInt(rawIntPixel values,const PixelFormat & format) const2904 FloatPixel RectangleTest::orderComponentsInt(rawIntPixel values, const PixelFormat& format) const
2905 {
2906 FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI,
2907 PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2908 PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF };
2909
2910 if (format.componentOrder.bits.red >= 0)
2911 fp.i_r = values[format.componentOrder.bits.red];
2912 if (format.componentOrder.bits.green >= 0)
2913 fp.i_g = values[format.componentOrder.bits.green];
2914 if (format.componentOrder.bits.blue >= 0)
2915 fp.i_b = values[format.componentOrder.bits.blue];
2916 if (format.componentOrder.bits.alpha >= 0)
2917 fp.i_a = values[format.componentOrder.bits.alpha];
2918 if (format.componentOrder.bits.depth >= 0)
2919 fp.i_d = values[format.componentOrder.bits.depth];
2920 if (format.componentOrder.bits.stencil >= 0)
2921 fp.i_s = values[format.componentOrder.bits.stencil];
2922
2923 return fp;
2924 }
2925
orderComponentsUint(rawUintPixel values,const PixelFormat & format) const2926 FloatPixel RectangleTest::orderComponentsUint(rawUintPixel values, const PixelFormat& format) const
2927 {
2928 FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI,
2929 PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2930 PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF };
2931
2932 if (format.componentOrder.bits.red >= 0)
2933 fp.ui_r = values[format.componentOrder.bits.red];
2934 if (format.componentOrder.bits.green >= 0)
2935 fp.ui_g = values[format.componentOrder.bits.green];
2936 if (format.componentOrder.bits.blue >= 0)
2937 fp.ui_b = values[format.componentOrder.bits.blue];
2938 if (format.componentOrder.bits.alpha >= 0)
2939 fp.ui_a = values[format.componentOrder.bits.alpha];
2940 if (format.componentOrder.bits.depth >= 0)
2941 fp.ui_d = values[format.componentOrder.bits.depth];
2942 if (format.componentOrder.bits.stencil >= 0)
2943 fp.ui_s = values[format.componentOrder.bits.stencil];
2944
2945 return fp;
2946 }
2947
orderComponentsFloat(rawFloatPixel values,const PixelFormat & format) const2948 FloatPixel RectangleTest::orderComponentsFloat(rawFloatPixel values, const PixelFormat& format) const
2949 {
2950 FloatPixel fp = { PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI, PACK_DEFAULTI,
2951 PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI, PACK_DEFAULTUI,
2952 PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF, PACK_DEFAULTF };
2953
2954 if (format.componentOrder.bits.red >= 0)
2955 fp.r = values[format.componentOrder.bits.red];
2956 if (format.componentOrder.bits.green >= 0)
2957 fp.g = values[format.componentOrder.bits.green];
2958 if (format.componentOrder.bits.blue >= 0)
2959 fp.b = values[format.componentOrder.bits.blue];
2960 if (format.componentOrder.bits.alpha >= 0)
2961 fp.a = values[format.componentOrder.bits.alpha];
2962 if (format.componentOrder.bits.depth >= 0)
2963 fp.d = values[format.componentOrder.bits.depth];
2964 if (format.componentOrder.bits.stencil >= 0)
2965 fp.s = values[format.componentOrder.bits.stencil];
2966
2967 return fp;
2968 }
2969
getRealBitPrecision(int bits,bool isFloat) const2970 unsigned int RectangleTest::getRealBitPrecision(int bits, bool isFloat) const
2971 {
2972 if (!isFloat)
2973 return bits;
2974 switch (bits)
2975 {
2976 case 32:
2977 return 23;
2978 case 16:
2979 return 10;
2980 case 11:
2981 return 6;
2982 case 10:
2983 return 5;
2984 }
2985 return bits;
2986 }
2987
stripBuffer(const PackedPixelsBufferProperties & props,const GLubyte * orginalBuffer,std::vector<GLubyte> & newBuffer,bool validate) const2988 bool RectangleTest::stripBuffer(const PackedPixelsBufferProperties& props, const GLubyte* orginalBuffer,
2989 std::vector<GLubyte>& newBuffer, bool validate) const
2990 {
2991 // Extracts pixel data from a buffer with specific
2992 // pixel store configuration into a flat buffer
2993
2994 int newBufferSize = props.elementSize * props.elementsInRowNoAlign * GRADIENT_HEIGHT;
2995 if (!newBufferSize)
2996 return false;
2997 newBuffer.resize(newBufferSize);
2998
2999 int skipBottom = ((props.skipImages * props.rowCount + props.skipRows) * props.elementsInRow) * props.elementSize;
3000 int skipTop = (props.rowCount - GRADIENT_HEIGHT - props.skipRows) * props.elementsInRow * props.elementSize;
3001 int skipLeft = props.skipPixels * props.elementsInGroup * props.elementSize;
3002 int skipRight = (props.elementsInRow - GRADIENT_WIDTH * props.elementsInGroup) * props.elementSize - skipLeft;
3003 int copy = GRADIENT_WIDTH * props.elementsInGroup * props.elementSize;
3004 int skipAlign = (props.elementsInRow - props.elementsInRowNoAlign) * props.elementSize;
3005
3006 if (validate)
3007 {
3008 for (int i = 0; i < skipBottom; i++)
3009 {
3010 if (orginalBuffer[i] != m_defaultFillValue)
3011 return false;
3012 }
3013 }
3014
3015 int index_src = skipBottom;
3016 int index_dst = 0;
3017
3018 for (int j = 0; j < GRADIENT_HEIGHT; j++)
3019 {
3020 if (validate)
3021 {
3022 for (int i = 0; i < skipLeft; i++)
3023 {
3024 if (orginalBuffer[index_src + i] != m_defaultFillValue)
3025 return false;
3026 }
3027 }
3028 index_src += skipLeft;
3029
3030 std::memcpy(&newBuffer[0] + index_dst, &orginalBuffer[0] + index_src, copy);
3031 index_src += copy;
3032 index_dst += copy;
3033
3034 if (validate)
3035 {
3036 for (int i = skipAlign; i < skipRight; i++)
3037 {
3038 if (orginalBuffer[index_src + i] != m_defaultFillValue)
3039 return false;
3040 }
3041 }
3042 index_src += skipRight;
3043 }
3044
3045 if (validate)
3046 {
3047 for (int i = 0; i < skipTop; i++)
3048 {
3049 if (orginalBuffer[index_src + i] != m_defaultFillValue)
3050 return false;
3051 }
3052 }
3053 index_src += skipTop;
3054
3055 return true;
3056 }
3057
clampSignedValue(int bits,int value) const3058 int RectangleTest::clampSignedValue(int bits, int value) const
3059 {
3060 int max = 2147483647;
3061 int min = 0x80000000;
3062
3063 if (bits < 32)
3064 {
3065 max = (1 << (bits - 1)) - 1;
3066 min = (1 << (bits - 1)) - (1 << bits);
3067 }
3068
3069 if (value >= max)
3070 return max;
3071 else if (value <= min)
3072 return min;
3073
3074 return value;
3075 }
3076
clampUnsignedValue(int bits,unsigned int value) const3077 unsigned int RectangleTest::clampUnsignedValue(int bits, unsigned int value) const
3078 {
3079 unsigned int max = 4294967295u;
3080 unsigned int min = 0;
3081
3082 if (bits < 32)
3083 {
3084 max = (1 << bits) - 1;
3085 }
3086
3087 if (value >= max)
3088 return max;
3089 else if (value <= min)
3090 return min;
3091
3092 return value;
3093 }
3094
pack_UNSIGNED_BYTE(GLubyte value)3095 float RectangleTest::pack_UNSIGNED_BYTE(GLubyte value)
3096 {
3097 return static_cast<GLfloat>(value) / std::numeric_limits<GLubyte>::max();
3098 }
3099
pack_BYTE(GLbyte value)3100 float RectangleTest::pack_BYTE(GLbyte value)
3101 {
3102 return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLbyte>::max(), -1.0f);
3103 }
3104
pack_UNSIGNED_SHORT(GLushort value)3105 float RectangleTest::pack_UNSIGNED_SHORT(GLushort value)
3106 {
3107 return static_cast<GLfloat>(value) / std::numeric_limits<GLushort>::max();
3108 }
3109
pack_SHORT(GLshort value)3110 float RectangleTest::pack_SHORT(GLshort value)
3111 {
3112 return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLshort>::max(), -1.0f);
3113 }
3114
pack_UNSIGNED_INT(GLuint value)3115 float RectangleTest::pack_UNSIGNED_INT(GLuint value)
3116 {
3117 return static_cast<GLfloat>(value) / std::numeric_limits<GLuint>::max();
3118 }
3119
pack_INT(GLint value)3120 float RectangleTest::pack_INT(GLint value)
3121 {
3122 return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLint>::max(), -1.0f);
3123 }
3124
pack_HALF_FLOAT(GLhalf value)3125 float RectangleTest::pack_HALF_FLOAT(GLhalf value)
3126 {
3127 return halfFloatToFloat(value);
3128 }
3129
pack_FLOAT(GLfloat value)3130 float RectangleTest::pack_FLOAT(GLfloat value)
3131 {
3132 return value;
3133 }
3134
pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel * values,GLubyte value)3135 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2(rawFloatPixel* values, GLubyte value)
3136 {
3137 (*values)[0] = ((value >> 5) & 7) / 7.0f;
3138 (*values)[1] = ((value >> 2) & 7) / 7.0f;
3139 (*values)[2] = ((value >> 0) & 3) / 3.0f;
3140 }
3141
pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel * values,GLubyte value)3142 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_UINT(rawUintPixel* values, GLubyte value)
3143 {
3144 (*values)[0] = (value >> 5) & 7;
3145 (*values)[1] = (value >> 2) & 7;
3146 (*values)[2] = (value >> 0) & 3;
3147 }
3148
pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel * values,GLubyte value)3149 void RectangleTest::pack_UNSIGNED_BYTE_3_3_2_INT(rawIntPixel* values, GLubyte value)
3150 {
3151 (*values)[0] = (static_cast<GLbyte>(value) >> 5) & 7;
3152 (*values)[1] = (static_cast<GLbyte>(value) >> 2) & 7;
3153 (*values)[2] = (static_cast<GLbyte>(value) >> 0) & 3;
3154 }
3155
pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel * values,GLubyte value)3156 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV(rawFloatPixel* values, GLubyte value)
3157 {
3158 (*values)[2] = ((value >> 6) & 3) / 3.0f;
3159 (*values)[1] = ((value >> 3) & 7) / 7.0f;
3160 (*values)[0] = ((value >> 0) & 7) / 7.0f;
3161 }
3162
pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel * values,GLubyte value)3163 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_UINT(rawUintPixel* values, GLubyte value)
3164 {
3165 (*values)[2] = (value >> 6) & 3;
3166 (*values)[1] = (value >> 3) & 7;
3167 (*values)[0] = (value >> 0) & 7;
3168 }
3169
pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel * values,GLubyte value)3170 void RectangleTest::pack_UNSIGNED_BYTE_2_3_3_REV_INT(rawIntPixel* values, GLubyte value)
3171 {
3172 (*values)[2] = (static_cast<GLbyte>(value) >> 6) & 3;
3173 (*values)[1] = (static_cast<GLbyte>(value) >> 3) & 7;
3174 (*values)[0] = (static_cast<GLbyte>(value) >> 0) & 7;
3175 }
3176
pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel * values,GLushort value)3177 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5(rawFloatPixel* values, GLushort value)
3178 {
3179 (*values)[0] = ((value >> 11) & 31) / 31.0f;
3180 (*values)[1] = ((value >> 5) & 63) / 63.0f;
3181 (*values)[2] = ((value >> 0) & 31) / 31.0f;
3182 }
3183
pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel * values,GLushort value)3184 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_UINT(rawUintPixel* values, GLushort value)
3185 {
3186 (*values)[0] = (value >> 11) & 31;
3187 (*values)[1] = (value >> 5) & 63;
3188 (*values)[2] = (value >> 0) & 31;
3189 }
3190
pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel * values,GLushort value)3191 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_INT(rawIntPixel* values, GLushort value)
3192 {
3193 (*values)[0] = (static_cast<GLshort>(value) >> 11) & 31;
3194 (*values)[1] = (static_cast<GLshort>(value) >> 5) & 63;
3195 (*values)[2] = (static_cast<GLshort>(value) >> 0) & 31;
3196 }
3197
pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel * values,GLushort value)3198 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV(rawFloatPixel* values, GLushort value)
3199 {
3200 (*values)[2] = ((value >> 11) & 31) / 31.0f;
3201 (*values)[1] = ((value >> 5) & 63) / 63.0f;
3202 (*values)[0] = ((value >> 0) & 31) / 31.0f;
3203 }
3204
pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel * values,GLushort value)3205 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_UINT(rawUintPixel* values, GLushort value)
3206 {
3207 (*values)[2] = (value >> 11) & 31;
3208 (*values)[1] = (value >> 5) & 63;
3209 (*values)[0] = (value >> 0) & 31;
3210 }
3211
pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel * values,GLushort value)3212 void RectangleTest::pack_UNSIGNED_SHORT_5_6_5_REV_INT(rawIntPixel* values, GLushort value)
3213 {
3214 (*values)[2] = (static_cast<GLshort>(value) >> 11) & 31;
3215 (*values)[1] = (static_cast<GLshort>(value) >> 5) & 63;
3216 (*values)[0] = (static_cast<GLshort>(value) >> 0) & 31;
3217 }
3218
pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel * values,GLushort value)3219 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4(rawFloatPixel* values, GLushort value)
3220 {
3221 (*values)[0] = ((value >> 12) & 15) / 15.0f;
3222 (*values)[1] = ((value >> 8) & 15) / 15.0f;
3223 (*values)[2] = ((value >> 4) & 15) / 15.0f;
3224 (*values)[3] = ((value >> 0) & 15) / 15.0f;
3225 }
3226
pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel * values,GLushort value)3227 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_UINT(rawUintPixel* values, GLushort value)
3228 {
3229 (*values)[0] = (value >> 12) & 15;
3230 (*values)[1] = (value >> 8) & 15;
3231 (*values)[2] = (value >> 4) & 15;
3232 (*values)[3] = (value >> 0) & 15;
3233 }
3234
pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel * values,GLushort value)3235 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_INT(rawIntPixel* values, GLushort value)
3236 {
3237 (*values)[0] = (static_cast<GLshort>(value) >> 12) & 15;
3238 (*values)[1] = (static_cast<GLshort>(value) >> 8) & 15;
3239 (*values)[2] = (static_cast<GLshort>(value) >> 4) & 15;
3240 (*values)[3] = (static_cast<GLshort>(value) >> 0) & 15;
3241 }
3242
pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel * values,GLushort value)3243 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV(rawFloatPixel* values, GLushort value)
3244 {
3245 (*values)[3] = ((value >> 12) & 15) / 15.0f;
3246 (*values)[2] = ((value >> 8) & 15) / 15.0f;
3247 (*values)[1] = ((value >> 4) & 15) / 15.0f;
3248 (*values)[0] = ((value >> 0) & 15) / 15.0f;
3249 }
3250
pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel * values,GLushort value)3251 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_UINT(rawUintPixel* values, GLushort value)
3252 {
3253 (*values)[3] = (value >> 12) & 15;
3254 (*values)[2] = (value >> 8) & 15;
3255 (*values)[1] = (value >> 4) & 15;
3256 (*values)[0] = (value >> 0) & 15;
3257 }
3258
pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel * values,GLushort value)3259 void RectangleTest::pack_UNSIGNED_SHORT_4_4_4_4_REV_INT(rawIntPixel* values, GLushort value)
3260 {
3261 (*values)[3] = (static_cast<GLshort>(value) >> 12) & 15;
3262 (*values)[2] = (static_cast<GLshort>(value) >> 8) & 15;
3263 (*values)[1] = (static_cast<GLshort>(value) >> 4) & 15;
3264 (*values)[0] = (static_cast<GLshort>(value) >> 0) & 15;
3265 }
3266
pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel * values,GLushort value)3267 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1(rawFloatPixel* values, GLushort value)
3268 {
3269 (*values)[0] = ((value >> 11) & 31) / 31.0f;
3270 (*values)[1] = ((value >> 6) & 31) / 31.0f;
3271 (*values)[2] = ((value >> 1) & 31) / 31.0f;
3272 (*values)[3] = ((value >> 0) & 1) / 1.0f;
3273 }
3274
pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel * values,GLushort value)3275 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_UINT(rawUintPixel* values, GLushort value)
3276 {
3277 (*values)[0] = (value >> 11) & 31;
3278 (*values)[1] = (value >> 6) & 31;
3279 (*values)[2] = (value >> 1) & 31;
3280 (*values)[3] = (value >> 0) & 1;
3281 }
3282
pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel * values,GLushort value)3283 void RectangleTest::pack_UNSIGNED_SHORT_5_5_5_1_INT(rawIntPixel* values, GLushort value)
3284 {
3285 (*values)[0] = (static_cast<GLshort>(value) >> 11) & 31;
3286 (*values)[1] = (static_cast<GLshort>(value) >> 6) & 31;
3287 (*values)[2] = (static_cast<GLshort>(value) >> 1) & 31;
3288 (*values)[3] = (static_cast<GLshort>(value) >> 0) & 1;
3289 }
3290
pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel * values,GLushort value)3291 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV(rawFloatPixel* values, GLushort value)
3292 {
3293 (*values)[3] = ((value >> 15) & 1) / 1.0f;
3294 (*values)[2] = ((value >> 10) & 31) / 31.0f;
3295 (*values)[1] = ((value >> 5) & 31) / 31.0f;
3296 (*values)[0] = ((value >> 0) & 31) / 31.0f;
3297 }
3298
pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel * values,GLushort value)3299 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_UINT(rawUintPixel* values, GLushort value)
3300 {
3301 (*values)[3] = (value >> 15) & 1;
3302 (*values)[2] = (value >> 10) & 31;
3303 (*values)[1] = (value >> 5) & 31;
3304 (*values)[0] = (value >> 0) & 31;
3305 }
3306
pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel * values,GLushort value)3307 void RectangleTest::pack_UNSIGNED_SHORT_1_5_5_5_REV_INT(rawIntPixel* values, GLushort value)
3308 {
3309 (*values)[3] = (static_cast<GLshort>(value) >> 15) & 1;
3310 (*values)[2] = (static_cast<GLshort>(value) >> 10) & 31;
3311 (*values)[1] = (static_cast<GLshort>(value) >> 5) & 31;
3312 (*values)[0] = (static_cast<GLshort>(value) >> 0) & 31;
3313 }
3314
pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel * values,GLuint value)3315 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8(rawFloatPixel* values, GLuint value)
3316 {
3317 (*values)[0] = ((value >> 24) & 255) / 255.0f;
3318 (*values)[1] = ((value >> 16) & 255) / 255.0f;
3319 (*values)[2] = ((value >> 8) & 255) / 255.0f;
3320 (*values)[3] = ((value >> 0) & 255) / 255.0f;
3321 }
3322
pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel * values,GLuint value)3323 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_UINT(rawUintPixel* values, GLuint value)
3324 {
3325 (*values)[0] = (value >> 24) & 255;
3326 (*values)[1] = (value >> 16) & 255;
3327 (*values)[2] = (value >> 8) & 255;
3328 (*values)[3] = (value >> 0) & 255;
3329 }
3330
pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel * values,GLuint value)3331 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_INT(rawIntPixel* values, GLuint value)
3332 {
3333 (*values)[0] = (static_cast<GLint>(value) >> 24) & 255;
3334 (*values)[1] = (static_cast<GLint>(value) >> 16) & 255;
3335 (*values)[2] = (static_cast<GLint>(value) >> 8) & 255;
3336 (*values)[3] = (static_cast<GLint>(value) >> 0) & 255;
3337 }
3338
pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel * values,GLuint value)3339 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV(rawFloatPixel* values, GLuint value)
3340 {
3341 (*values)[3] = ((value >> 24) & 255) / 255.0f;
3342 (*values)[2] = ((value >> 16) & 255) / 255.0f;
3343 (*values)[1] = ((value >> 8) & 255) / 255.0f;
3344 (*values)[0] = ((value >> 0) & 255) / 255.0f;
3345 }
3346
pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel * values,GLuint value)3347 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_UINT(rawUintPixel* values, GLuint value)
3348 {
3349 (*values)[3] = (value >> 24) & 255;
3350 (*values)[2] = (value >> 16) & 255;
3351 (*values)[1] = (value >> 8) & 255;
3352 (*values)[0] = (value >> 0) & 255;
3353 }
3354
pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel * values,GLuint value)3355 void RectangleTest::pack_UNSIGNED_INT_8_8_8_8_REV_INT(rawIntPixel* values, GLuint value)
3356 {
3357 (*values)[3] = (static_cast<GLint>(value) >> 24) & 255;
3358 (*values)[2] = (static_cast<GLint>(value) >> 16) & 255;
3359 (*values)[1] = (static_cast<GLint>(value) >> 8) & 255;
3360 (*values)[0] = (static_cast<GLint>(value) >> 0) & 255;
3361 }
3362
pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel * values,GLuint value)3363 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2(rawFloatPixel* values, GLuint value)
3364 {
3365 (*values)[0] = ((value >> 22) & 1023) / 1023.0f;
3366 (*values)[1] = ((value >> 12) & 1023) / 1023.0f;
3367 (*values)[2] = ((value >> 2) & 1023) / 1023.0f;
3368 (*values)[3] = ((value >> 0) & 3) / 3.0f;
3369 }
3370
pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel * values,GLuint value)3371 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_UINT(rawUintPixel* values, GLuint value)
3372 {
3373 (*values)[0] = ((value >> 22) & 1023);
3374 (*values)[1] = ((value >> 12) & 1023);
3375 (*values)[2] = ((value >> 2) & 1023);
3376 (*values)[3] = ((value >> 0) & 3);
3377 }
3378
pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel * values,GLuint value)3379 void RectangleTest::pack_UNSIGNED_INT_10_10_10_2_INT(rawIntPixel* values, GLuint value)
3380 {
3381 (*values)[0] = ((static_cast<GLint>(value) >> 22) & 1023);
3382 (*values)[1] = ((static_cast<GLint>(value) >> 12) & 1023);
3383 (*values)[2] = ((static_cast<GLint>(value) >> 2) & 1023);
3384 (*values)[3] = ((static_cast<GLint>(value) >> 0) & 3);
3385 }
3386
pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel * values,GLuint value)3387 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV(rawFloatPixel* values, GLuint value)
3388 {
3389 (*values)[3] = ((value >> 30) & 3) / 3.0f;
3390 (*values)[2] = ((value >> 20) & 1023) / 1023.0f;
3391 (*values)[1] = ((value >> 10) & 1023) / 1023.0f;
3392 (*values)[0] = ((value >> 0) & 1023) / 1023.0f;
3393 }
3394
pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel * values,GLuint value)3395 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_UINT(rawUintPixel* values, GLuint value)
3396 {
3397 (*values)[3] = (value >> 30) & 3;
3398 (*values)[2] = (value >> 20) & 1023;
3399 (*values)[1] = (value >> 10) & 1023;
3400 (*values)[0] = (value >> 0) & 1023;
3401 }
3402
pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel * values,GLuint value)3403 void RectangleTest::pack_UNSIGNED_INT_2_10_10_10_REV_INT(rawIntPixel* values, GLuint value)
3404 {
3405 (*values)[3] = (static_cast<GLint>(value) >> 30) & 3;
3406 (*values)[2] = (static_cast<GLint>(value) >> 20) & 1023;
3407 (*values)[1] = (static_cast<GLint>(value) >> 10) & 1023;
3408 (*values)[0] = (static_cast<GLint>(value) >> 0) & 1023;
3409 }
3410
pack_UNSIGNED_INT_24_8(rawFloatPixel * values,GLuint value)3411 void RectangleTest::pack_UNSIGNED_INT_24_8(rawFloatPixel* values, GLuint value)
3412 {
3413 (*values)[0] = ((value >> 8) & 16777215) / 16777215.0f;
3414 (*values)[1] = ((value >> 0) & 255) / 255.0f;
3415 }
3416
pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel * values,GLuint value)3417 void RectangleTest::pack_UNSIGNED_INT_10F_11F_11F_REV(rawFloatPixel* values, GLuint value)
3418 {
3419 (*values)[2] = unsignedF10ToFloat((value >> 22) & 1023);
3420 (*values)[1] = unsignedF11ToFloat((value >> 11) & 2047);
3421 (*values)[0] = unsignedF11ToFloat((value >> 0) & 2047);
3422 }
3423
pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel * values,GLuint value)3424 void RectangleTest::pack_UNSIGNED_INT_5_9_9_9_REV(rawFloatPixel* values, GLuint value)
3425 {
3426 const int B = 15;
3427 const int N = 9;
3428 GLint pExp = ((value >> 27) & 31);
3429 GLuint pBlue = ((value >> 18) & 511);
3430 GLuint pGreen = ((value >> 9) & 511);
3431 GLuint pRed = ((value >> 0) & 511);
3432
3433 (*values)[2] = (float)(pBlue * pow(2.0, pExp - B - N));
3434 (*values)[1] = (float)(pGreen * pow(2.0, pExp - B - N));
3435 (*values)[0] = (float)(pRed * pow(2.0, pExp - B - N));
3436 (*values)[3] = 1.0f;
3437 }
3438
pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel * values,F_32_UINT_24_8_REV value)3439 void RectangleTest::pack_FLOAT_32_UNSIGNED_INT_24_8_REV(rawFloatPixel* values, F_32_UINT_24_8_REV value)
3440 {
3441 (*values)[0] = value.d;
3442 (*values)[1] = (value.s & 255) / 255.0f;
3443 }
3444
getTexImage()3445 bool RectangleTest::getTexImage()
3446 {
3447 // for each output format
3448 for (int m = 0; m < DE_LENGTH_OF_ARRAY(coreFormats); ++m)
3449 {
3450 const PixelFormat& outputFormat = coreFormats[m];
3451
3452 // for each output type
3453 for (int n = 0; n < DE_LENGTH_OF_ARRAY(coreTypes); ++n)
3454 {
3455 const PixelType& outputType = coreTypes[n];
3456
3457 if ((m_inputFormat.format != m_internalFormat.format || m_inputType.type != m_internalFormat.type) &&
3458 (outputFormat.format != m_internalFormat.format || outputType.type != m_internalFormat.type))
3459 {
3460 continue;
3461 }
3462
3463 if (!getTexImageInner(outputFormat, outputType))
3464 return false;
3465 }
3466 }
3467
3468 return true;
3469 }
3470
getTexImageInner(const PixelFormat & outputFormat,const PixelType & outputType)3471 bool RectangleTest::getTexImageInner(const PixelFormat& outputFormat, const PixelType& outputType)
3472 {
3473 bool outputFormatValid = isFormatValid(outputFormat, outputType, m_internalFormat, false, true, OUTPUT_GETTEXIMAGE);
3474
3475 GLenum error = readOutputData(outputFormat, outputType, OUTPUT_GETTEXIMAGE);
3476 m_countGetTexImage++;
3477
3478 if (!outputFormatValid)
3479 {
3480 if (error)
3481 {
3482 m_countGetTexImageOK++;
3483 return true;
3484 }
3485
3486 m_testCtx.getLog() << tcu::TestLog::Message << "Expected error but got no GL error" << tcu::TestLog::EndMessage;
3487 return false;
3488 }
3489 else if (error)
3490 {
3491 m_testCtx.getLog() << tcu::TestLog::Message << "Error during glGetTexImage" << tcu::TestLog::EndMessage;
3492 return false;
3493 }
3494
3495 m_countGetTexImageOK++;
3496 m_countCompare++;
3497
3498 // compare output gradient to input gradient
3499 if (compare(&m_gradient[0], &m_outputBuffer[0], outputFormat, outputType, false))
3500 {
3501 m_countCompareOK++;
3502 return true;
3503 }
3504
3505 m_testCtx.getLog() << tcu::TestLog::Message << "Gradient comparison failed during GetTexImage for input = ["
3506 << getFormatStr(m_inputFormat.format) << ", " << getTypeStr(m_inputType.type) << "] output = ["
3507 << getFormatStr(outputFormat.format) << ", " << getTypeStr(outputType.type) << "]"
3508 << tcu::TestLog::EndMessage;
3509 return false;
3510 }
3511
testAllFormatsAndTypes()3512 void RectangleTest::testAllFormatsAndTypes()
3513 {
3514 DE_ASSERT((m_textureTarget == GL_TEXTURE_2D) || (m_textureTarget == GL_TEXTURE_3D));
3515
3516 glu::RenderContext& renderContext = m_context.getRenderContext();
3517 const Functions& gl = renderContext.getFunctions();
3518 bool result = true;
3519
3520 gl.clear(GL_COLOR_BUFFER_BIT);
3521
3522 const PixelType* types;
3523 int typesCount;
3524 const PixelFormat* formats;
3525 int formatsCount;
3526 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
3527 {
3528 types = esTypes;
3529 typesCount = DE_LENGTH_OF_ARRAY(esTypes);
3530 formats = esFormats;
3531 formatsCount = DE_LENGTH_OF_ARRAY(esFormats);
3532 }
3533 else
3534 {
3535 types = coreTypes;
3536 typesCount = DE_LENGTH_OF_ARRAY(coreTypes);
3537 formats = coreFormats;
3538 formatsCount = DE_LENGTH_OF_ARRAY(coreFormats);
3539 }
3540
3541 for (int inputFormatIndex = 0; inputFormatIndex < formatsCount; inputFormatIndex++)
3542 {
3543 m_inputFormat = formats[inputFormatIndex];
3544
3545 for (int inputTypeIndex = 0; inputTypeIndex < typesCount; inputTypeIndex++)
3546 {
3547 GLenum error = 0;
3548 m_inputType = types[inputTypeIndex];
3549
3550 applyInitialStorageModes();
3551
3552 // Create input gradient in format,type, with appropriate range
3553 createGradient();
3554 if (m_gradient.empty())
3555 TCU_FAIL("Could not create gradient.");
3556
3557 if (m_unpackProperties.swapBytes)
3558 swapBytes(m_inputType.size, m_gradient);
3559
3560 GLuint texture;
3561 gl.genTextures(1, &texture);
3562 gl.bindTexture(m_textureTarget, texture);
3563 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture");
3564 if (m_textureTarget == GL_TEXTURE_3D)
3565 {
3566 gl.texImage3D(GL_TEXTURE_3D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 1, 0,
3567 m_inputFormat.format, m_inputType.type, &m_gradient[0]);
3568 }
3569 else
3570 {
3571 gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat.sizedFormat, GRADIENT_WIDTH, GRADIENT_HEIGHT, 0,
3572 m_inputFormat.format, m_inputType.type, &m_gradient[0]);
3573 }
3574
3575 if (m_unpackProperties.swapBytes)
3576 swapBytes(m_inputType.size, m_gradient);
3577
3578 error = gl.getError();
3579 if (isFormatValid(m_inputFormat, m_inputType, m_internalFormat, true, false, INPUT_TEXIMAGE))
3580 {
3581 if (error == GL_NO_ERROR)
3582 {
3583 if (!glu::isContextTypeES(renderContext.getType()))
3584 result &= getTexImage();
3585 result &= doRead(texture);
3586 }
3587 else
3588 {
3589 m_testCtx.getLog() << tcu::TestLog::Message << "Valid format used but glTexImage2D/3D failed"
3590 << tcu::TestLog::EndMessage;
3591 result = false;
3592 }
3593 }
3594 else if (error == GL_NO_ERROR)
3595 {
3596 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid format used but glTexImage2D/3D succeeded"
3597 << tcu::TestLog::EndMessage;
3598 result = false;
3599 }
3600
3601 gl.deleteTextures(1, &texture);
3602 }
3603 }
3604
3605 if (result)
3606 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3607 else
3608 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3609 }
3610
iterate(void)3611 tcu::TestNode::IterateResult RectangleTest::iterate(void)
3612 {
3613 resetInitialStorageModes();
3614 testAllFormatsAndTypes();
3615 return STOP;
3616 }
3617
3618 class InitialValuesTest : public deqp::TestCase
3619 {
3620 public:
3621 InitialValuesTest(deqp::Context& context);
3622 virtual ~InitialValuesTest();
3623
3624 tcu::TestNode::IterateResult iterate(void);
3625 };
3626
InitialValuesTest(deqp::Context & context)3627 InitialValuesTest::InitialValuesTest(deqp::Context& context)
3628 : deqp::TestCase(context, "initial_values", "Verify if all UNPACK and PACK initial "
3629 "state matches the values in table 6.28 (6.23, in ES.)")
3630 {
3631 }
3632
~InitialValuesTest()3633 InitialValuesTest::~InitialValuesTest()
3634 {
3635 }
3636
iterate(void)3637 tcu::TestNode::IterateResult InitialValuesTest::iterate(void)
3638 {
3639 glu::RenderContext& renderContext = m_context.getRenderContext();
3640 const Functions& gl = renderContext.getFunctions();
3641
3642 bool result = true;
3643
3644 GLenum commonIntModes[] = { GL_UNPACK_ROW_LENGTH, GL_UNPACK_SKIP_ROWS, GL_UNPACK_SKIP_PIXELS,
3645 GL_UNPACK_IMAGE_HEIGHT, GL_UNPACK_SKIP_IMAGES, GL_PACK_ROW_LENGTH,
3646 GL_PACK_SKIP_ROWS, GL_PACK_SKIP_PIXELS };
3647
3648 // check if following eight storage modes are 0
3649 GLint i = 1;
3650 for (int mode = 0; mode < DE_LENGTH_OF_ARRAY(commonIntModes); mode++)
3651 {
3652 gl.getIntegerv(commonIntModes[mode], &i);
3653 result &= (i == 0);
3654 }
3655
3656 // check if following two storage modes are 4
3657 gl.getIntegerv(GL_UNPACK_ALIGNMENT, &i);
3658 result &= (i == 4);
3659 gl.getIntegerv(GL_PACK_ALIGNMENT, &i);
3660 result &= (i == 4);
3661
3662 // check storage modes available only in core GL
3663 if (!glu::isContextTypeES(renderContext.getType()))
3664 {
3665 // check if following four boolean modes are false
3666 GLboolean b = true;
3667 gl.getBooleanv(GL_UNPACK_SWAP_BYTES, &b);
3668 result &= (b == false);
3669 gl.getBooleanv(GL_UNPACK_LSB_FIRST, &b);
3670 result &= (b == false);
3671 gl.getBooleanv(GL_PACK_SWAP_BYTES, &b);
3672 result &= (b == false);
3673 gl.getBooleanv(GL_PACK_LSB_FIRST, &b);
3674 result &= (b == false);
3675
3676 // check if following two modes are 0
3677 gl.getIntegerv(GL_PACK_IMAGE_HEIGHT, &i);
3678 result &= (i == 0);
3679 gl.getIntegerv(GL_PACK_SKIP_IMAGES, &i);
3680 result &= (i == 0);
3681 }
3682
3683 // make sure that no pack/unpack buffers are bound
3684 gl.getIntegerv(GL_PIXEL_PACK_BUFFER_BINDING, &i);
3685 result &= (i == 0);
3686 gl.getIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &i);
3687 result &= (i == 0);
3688
3689 if (result)
3690 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3691 else
3692 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3693 return STOP;
3694 }
3695
3696 class PBORectangleTest : public RectangleTest
3697 {
3698 public:
3699 PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3700 virtual ~PBORectangleTest();
3701 };
3702
PBORectangleTest(deqp::Context & context,std::string & name,InternalFormat internalFormat)3703 PBORectangleTest::PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3704 : RectangleTest(context, name, internalFormat)
3705 {
3706 m_usePBO = true;
3707 }
3708
~PBORectangleTest()3709 PBORectangleTest::~PBORectangleTest()
3710 {
3711 }
3712
3713 class VariedRectangleTest : public RectangleTest
3714 {
3715 public:
3716 VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3717 virtual ~VariedRectangleTest();
3718
3719 tcu::TestNode::IterateResult iterate(void);
3720
3721 protected:
3722 struct StoreMode
3723 {
3724 GLenum parameter;
3725 GLint* property;
3726 GLint value;
3727 };
3728 };
3729
VariedRectangleTest(deqp::Context & context,std::string & name,InternalFormat internalFormat)3730 VariedRectangleTest::VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3731 : RectangleTest(context, name, internalFormat)
3732 {
3733 }
3734
~VariedRectangleTest()3735 VariedRectangleTest::~VariedRectangleTest()
3736 {
3737 }
3738
iterate(void)3739 tcu::TestNode::IterateResult VariedRectangleTest::iterate(void)
3740 {
3741 const int IMAGE_WIDTH_1 = 10;
3742 const int IMAGE_WIDTH_2 = 15;
3743 const int IMAGE_HEIGHT_1 = 10;
3744 const int IMAGE_HEIGHT_2 = 15;
3745
3746 PackedPixelsBufferProperties& up = m_initialUnpackProperties;
3747 PackedPixelsBufferProperties& pp = m_initialPackProperties;
3748
3749 StoreMode commonCases[] = {
3750 { GL_UNPACK_ROW_LENGTH, &up.rowLength, 0 },
3751 { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_1 },
3752 { GL_UNPACK_ROW_LENGTH, &up.rowLength, IMAGE_WIDTH_2 },
3753 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 0 },
3754 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 1 },
3755 { GL_UNPACK_SKIP_ROWS, &up.skipRows, 2 },
3756 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 0 },
3757 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 1 },
3758 { GL_UNPACK_SKIP_PIXELS, &up.skipPixels, 2 },
3759 { GL_UNPACK_ALIGNMENT, &up.alignment, 1 },
3760 { GL_UNPACK_ALIGNMENT, &up.alignment, 2 },
3761 { GL_UNPACK_ALIGNMENT, &up.alignment, 4 },
3762 { GL_UNPACK_ALIGNMENT, &up.alignment, 8 },
3763 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, 0 },
3764 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_1 },
3765 { GL_UNPACK_IMAGE_HEIGHT, &up.rowCount, IMAGE_HEIGHT_2 },
3766 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 0 },
3767 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 1 },
3768 { GL_UNPACK_SKIP_IMAGES, &up.skipImages, 2 },
3769 { GL_PACK_ROW_LENGTH, &pp.rowLength, 0 },
3770 { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_1 },
3771 { GL_PACK_ROW_LENGTH, &pp.rowLength, IMAGE_WIDTH_2 },
3772 { GL_PACK_SKIP_ROWS, &pp.skipRows, 0 },
3773 { GL_PACK_SKIP_ROWS, &pp.skipRows, 1 },
3774 { GL_PACK_SKIP_ROWS, &pp.skipRows, 2 },
3775 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 0 },
3776 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 1 },
3777 { GL_PACK_SKIP_PIXELS, &pp.skipPixels, 2 },
3778 { GL_PACK_ALIGNMENT, &pp.alignment, 1 },
3779 { GL_PACK_ALIGNMENT, &pp.alignment, 2 },
3780 { GL_PACK_ALIGNMENT, &pp.alignment, 4 },
3781 { GL_PACK_ALIGNMENT, &pp.alignment, 8 },
3782 };
3783
3784 StoreMode coreCases[] = {
3785 { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_FALSE },
3786 { GL_UNPACK_SWAP_BYTES, &up.swapBytes, GL_TRUE },
3787 { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_FALSE },
3788 { GL_UNPACK_LSB_FIRST, &up.lsbFirst, GL_TRUE },
3789 { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_FALSE },
3790 { GL_PACK_SWAP_BYTES, &pp.swapBytes, GL_TRUE },
3791 { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_FALSE },
3792 { GL_PACK_LSB_FIRST, &pp.lsbFirst, GL_TRUE },
3793 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, 0 },
3794 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_1 },
3795 { GL_PACK_IMAGE_HEIGHT, &pp.rowCount, IMAGE_HEIGHT_2 },
3796 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 0 },
3797 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 1 },
3798 { GL_PACK_SKIP_IMAGES, &pp.skipImages, 2 },
3799 };
3800
3801 std::vector<StoreMode> testModes(commonCases, commonCases + DE_LENGTH_OF_ARRAY(commonCases));
3802 glu::RenderContext& renderContext = m_context.getRenderContext();
3803 bool contextTypeIsCoreGL = !glu::isContextTypeES(renderContext.getType());
3804 if (contextTypeIsCoreGL)
3805 testModes.insert(testModes.end(), coreCases, coreCases + DE_LENGTH_OF_ARRAY(coreCases));
3806
3807 std::vector<StoreMode>::iterator currentCase = testModes.begin();
3808 while (currentCase != testModes.end())
3809 {
3810 resetInitialStorageModes();
3811
3812 GLenum parameter = currentCase->parameter;
3813 GLint value = currentCase->value;
3814
3815 *(currentCase->property) = value;
3816
3817 // for some parameters an additional parameter needs to be set
3818 if (parameter == GL_PACK_SKIP_ROWS)
3819 {
3820 if (contextTypeIsCoreGL)
3821 m_initialPackProperties.rowCount = GRADIENT_HEIGHT + value;
3822 }
3823 else if (parameter == GL_PACK_SKIP_PIXELS)
3824 m_initialPackProperties.rowLength = GRADIENT_WIDTH + value;
3825 else if (parameter == GL_UNPACK_SKIP_ROWS)
3826 m_initialUnpackProperties.rowCount = GRADIENT_HEIGHT + value;
3827 else if (parameter == GL_UNPACK_SKIP_PIXELS)
3828 m_initialUnpackProperties.rowLength = GRADIENT_WIDTH + value;
3829
3830 m_textureTarget = GL_TEXTURE_2D;
3831 if ((parameter == GL_PACK_IMAGE_HEIGHT) || (parameter == GL_PACK_SKIP_IMAGES) ||
3832 (parameter == GL_UNPACK_IMAGE_HEIGHT) || (parameter == GL_UNPACK_SKIP_IMAGES))
3833 m_textureTarget = GL_TEXTURE_3D;
3834
3835 testAllFormatsAndTypes();
3836
3837 if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
3838 {
3839 m_testCtx.getLog() << tcu::TestLog::Message
3840 << "Case for: " << glu::getGettableStateStr(parameter).toString() << " = " << value
3841 << " failed." << tcu::TestLog::EndMessage;
3842 return STOP;
3843 }
3844
3845 ++currentCase;
3846 }
3847
3848 return STOP;
3849 }
3850
PackedPixelsTests(deqp::Context & context)3851 PackedPixelsTests::PackedPixelsTests(deqp::Context& context) : TestCaseGroup(context, "packed_pixels", "")
3852 {
3853 }
3854
~PackedPixelsTests(void)3855 PackedPixelsTests::~PackedPixelsTests(void)
3856 {
3857 #ifdef LOG_PACKED_PIXELS_STATISTICS
3858 m_testCtx.getLog() << tcu::TestLog::Message << "PackedPixelsTests statistics:"
3859 << "\n countReadPixels: " << RectangleTest::m_countReadPixels
3860 << "\n countReadPixelsOK: " << RectangleTest::m_countReadPixelsOK
3861 << "\n countGetTexImage: " << RectangleTest::m_countGetTexImage
3862 << "\n countGetTexImageOK: " << RectangleTest::m_countGetTexImageOK
3863 << "\n countCompare: " << RectangleTest::m_countCompare
3864 << "\n countCompareOK: " << RectangleTest::m_countCompareOK << tcu::TestLog::EndMessage;
3865 #endif
3866 }
3867
init(void)3868 void PackedPixelsTests::init(void)
3869 {
3870 const InternalFormat* internalFormats;
3871 unsigned int internalFormatsCount;
3872
3873 if (glu::isContextTypeES(m_context.getRenderContext().getType()))
3874 {
3875 internalFormats = esInternalformats;
3876 internalFormatsCount = DE_LENGTH_OF_ARRAY(esInternalformats);
3877 }
3878 else
3879 {
3880 internalFormats = coreInternalformats;
3881 internalFormatsCount = DE_LENGTH_OF_ARRAY(coreInternalformats);
3882 }
3883
3884 TestCaseGroup* rectangleGroup = new deqp::TestCaseGroup(m_context, "rectangle", "");
3885 rectangleGroup->addChild(new InitialValuesTest(m_context));
3886 TestCaseGroup* pboRectangleGroup = new deqp::TestCaseGroup(m_context, "pbo_rectangle", "");
3887 TestCaseGroup* variedRectangleGroup = new deqp::TestCaseGroup(m_context, "varied_rectangle", "");
3888
3889 for (unsigned int internalFormatIndex = 0; internalFormatIndex < internalFormatsCount; internalFormatIndex++)
3890 {
3891 const InternalFormat& internalFormat = internalFormats[internalFormatIndex];
3892 std::string internalFormatString = getFormatStr(internalFormat.sizedFormat);
3893
3894 std::string name = internalFormatString.substr(3);
3895 std::transform(name.begin(), name.end(), name.begin(), tolower);
3896
3897 rectangleGroup->addChild(new RectangleTest(m_context, name, internalFormat));
3898 pboRectangleGroup->addChild(new PBORectangleTest(m_context, name, internalFormat));
3899 variedRectangleGroup->addChild(new VariedRectangleTest(m_context, name, internalFormat));
3900 }
3901
3902 addChild(rectangleGroup);
3903 addChild(pboRectangleGroup);
3904 addChild(variedRectangleGroup);
3905 }
3906
3907 } /* glcts namespace */
3908