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
40using namespace glw;
41using namespace glu;
42
43namespace glcts
44{
45
46enum
47{
48	GRADIENT_WIDTH  = 7,
49	GRADIENT_HEIGHT = 3
50};
51
52enum InputOutputOperation
53{
54	OUTPUT_GETTEXIMAGE,
55	OUTPUT_READPIXELS,
56	INPUT_TEXIMAGE,
57};
58
59enum 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
68enum TypeStorage
69{
70	STORAGE_UNSIGNED, // unsigned fp/int
71	STORAGE_SIGNED,   // signed fp/int
72	STORAGE_FLOAT,	// signed/unsigned float
73};
74
75union 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
91struct 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
102struct 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
111enum 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
120enum 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
129struct 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
140struct 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
153static 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
240static 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
303static 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
325static 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
341static 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
368static 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
387static 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
465static 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
512static 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
519static 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.
526struct 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
534struct 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
558static const int NUM_FLOAT_PIXEL_COUNT = sizeof(FloatPixel) / sizeof(float);
559
560typedef int			 rawIntPixel[4];
561typedef unsigned int rawUintPixel[4];
562typedef float		 rawFloatPixel[4];
563
564struct 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
581std::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
608std::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
651std::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
681class RectangleTest : public deqp::TestCase
682{
683public:
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
693protected:
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
842protected:
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
853public:
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
862private:
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
872int RectangleTest::m_countReadPixels	= 0;
873int RectangleTest::m_countReadPixelsOK  = 0;
874int RectangleTest::m_countGetTexImage   = 0;
875int RectangleTest::m_countGetTexImageOK = 0;
876int RectangleTest::m_countCompare		= 0;
877int RectangleTest::m_countCompareOK		= 0;
878
879RectangleTest::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
888RectangleTest::~RectangleTest()
889{
890}
891
892void 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
913void 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
949void 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
982const 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
1008const 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
1033const 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
1092InternalFormatSamplerType 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
1114void 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
1195template <typename Type>
1196void 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
1277template <typename Type>
1278Type 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
1290template <typename Type>
1291Type 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
1303GLubyte RectangleTest::unpack_UNSIGNED_BYTE(float value)
1304{
1305	return static_cast<GLubyte>(value * std::numeric_limits<GLubyte>::max());
1306}
1307
1308GLbyte RectangleTest::unpack_BYTE(float value)
1309{
1310	return static_cast<GLbyte>(value * std::numeric_limits<GLbyte>::max());
1311}
1312
1313GLushort RectangleTest::unpack_UNSIGNED_SHORT(float value)
1314{
1315	return static_cast<GLushort>(value * std::numeric_limits<GLushort>::max());
1316}
1317
1318GLshort RectangleTest::unpack_SHORT(float value)
1319{
1320	return static_cast<GLshort>(value * std::numeric_limits<GLshort>::max());
1321}
1322
1323GLuint RectangleTest::unpack_UNSIGNED_INT(float value)
1324{
1325	return static_cast<GLuint>(value * std::numeric_limits<GLuint>::max());
1326}
1327
1328GLint RectangleTest::unpack_INT(float value)
1329{
1330	return static_cast<GLint>(value * std::numeric_limits<GLint>::max());
1331}
1332
1333GLhalf RectangleTest::unpack_HALF_FLOAT(float value)
1334{
1335	return floatToHalfFloat(value);
1336}
1337
1338GLfloat RectangleTest::unpack_FLOAT(float value)
1339{
1340	return value;
1341}
1342
1343GLubyte RectangleTest::unpack_UNSIGNED_BYTE_3_3_2(float value)
1344{
1345	return unpackSizedComponents<GLubyte>(value, 3, 3, 2, 0);
1346}
1347
1348GLubyte RectangleTest::unpack_UNSIGNED_BYTE_2_3_3_REV(float value)
1349{
1350	return unpackSizedComponentsRev<GLubyte>(value, 2, 3, 3, 0);
1351}
1352
1353GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5_REV(float value)
1354{
1355	return unpackSizedComponentsRev<GLushort>(value, 5, 6, 5, 0);
1356}
1357
1358GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4_REV(float value)
1359{
1360	return unpackSizedComponentsRev<GLushort>(value, 4, 4, 4, 4);
1361}
1362
1363GLushort RectangleTest::unpack_UNSIGNED_SHORT_1_5_5_5_REV(float value)
1364{
1365	return unpackSizedComponentsRev<GLushort>(value, 1, 5, 5, 5);
1366}
1367
1368GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8(float value)
1369{
1370	return unpackSizedComponents<GLuint>(value, 8, 8, 8, 8);
1371}
1372
1373GLuint RectangleTest::unpack_UNSIGNED_INT_8_8_8_8_REV(float value)
1374{
1375	return unpackSizedComponentsRev<GLuint>(value, 8, 8, 8, 8);
1376}
1377
1378GLuint RectangleTest::unpack_UNSIGNED_INT_10_10_10_2(float value)
1379{
1380	return unpackSizedComponents<GLuint>(value, 10, 10, 10, 2);
1381}
1382
1383GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_6_5(float value)
1384{
1385	return unpackSizedComponents<GLushort>(value, 5, 6, 5, 0);
1386}
1387
1388GLushort RectangleTest::unpack_UNSIGNED_SHORT_4_4_4_4(float value)
1389{
1390	return unpackSizedComponents<GLushort>(value, 4, 4, 4, 4);
1391}
1392
1393GLushort RectangleTest::unpack_UNSIGNED_SHORT_5_5_5_1(float value)
1394{
1395	return unpackSizedComponents<GLushort>(value, 5, 5, 5, 1);
1396}
1397
1398GLuint RectangleTest::unpack_UNSIGNED_INT_2_10_10_10_REV(float value)
1399{
1400	return unpackSizedComponentsRev<GLuint>(value, 2, 10, 10, 10);
1401}
1402
1403GLuint RectangleTest::unpack_UNSIGNED_INT_24_8(float value)
1404{
1405	return unpackSizedComponents<GLuint>(value, 24, 8, 0, 0);
1406}
1407
1408GLuint 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
1449GLuint 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
1457F_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
1466bool 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
1753bool 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
1760bool RectangleTest::isSRGBFormat(const InternalFormat& internalFormat) const
1761{
1762	return (internalFormat.sizedFormat == GL_SRGB8) || (internalFormat.sizedFormat == GL_SRGB8_ALPHA8);
1763}
1764
1765bool 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
1773bool 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
1891bool 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
2002bool 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
2048bool 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
2107bool 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
2171GLenum 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
2267bool 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
2296bool 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
2420bool 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
2621void 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
2764template <typename Type>
2765void 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
2794void 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
2862template <typename Type>
2863void 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
2876template <typename Type>
2877void 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
2890template <typename Type>
2891void 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
2904FloatPixel 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
2926FloatPixel 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
2948FloatPixel 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
2970unsigned 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
2988bool 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
3058int 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
3077unsigned 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
3095float RectangleTest::pack_UNSIGNED_BYTE(GLubyte value)
3096{
3097	return static_cast<GLfloat>(value) / std::numeric_limits<GLubyte>::max();
3098}
3099
3100float RectangleTest::pack_BYTE(GLbyte value)
3101{
3102	return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLbyte>::max(), -1.0f);
3103}
3104
3105float RectangleTest::pack_UNSIGNED_SHORT(GLushort value)
3106{
3107	return static_cast<GLfloat>(value) / std::numeric_limits<GLushort>::max();
3108}
3109
3110float RectangleTest::pack_SHORT(GLshort value)
3111{
3112	return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLshort>::max(), -1.0f);
3113}
3114
3115float RectangleTest::pack_UNSIGNED_INT(GLuint value)
3116{
3117	return static_cast<GLfloat>(value) / std::numeric_limits<GLuint>::max();
3118}
3119
3120float RectangleTest::pack_INT(GLint value)
3121{
3122	return deFloatMax(static_cast<GLfloat>(value) / std::numeric_limits<GLint>::max(), -1.0f);
3123}
3124
3125float RectangleTest::pack_HALF_FLOAT(GLhalf value)
3126{
3127	return halfFloatToFloat(value);
3128}
3129
3130float RectangleTest::pack_FLOAT(GLfloat value)
3131{
3132	return value;
3133}
3134
3135void 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
3142void 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
3149void 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
3156void 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
3163void 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
3170void 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
3177void 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
3184void 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
3191void 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
3198void 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
3205void 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
3212void 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
3219void 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
3227void 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
3235void 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
3243void 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
3251void 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
3259void 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
3267void 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
3275void 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
3283void 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
3291void 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
3299void 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
3307void 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
3315void 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
3323void 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
3331void 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
3339void 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
3347void 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
3355void 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
3363void 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
3371void 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
3379void 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
3387void 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
3395void 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
3403void 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
3411void 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
3417void 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
3424void 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
3439void 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
3445bool 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
3471bool 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
3512void 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
3611tcu::TestNode::IterateResult RectangleTest::iterate(void)
3612{
3613	resetInitialStorageModes();
3614	testAllFormatsAndTypes();
3615	return STOP;
3616}
3617
3618class InitialValuesTest : public deqp::TestCase
3619{
3620public:
3621	InitialValuesTest(deqp::Context& context);
3622	virtual ~InitialValuesTest();
3623
3624	tcu::TestNode::IterateResult iterate(void);
3625};
3626
3627InitialValuesTest::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
3633InitialValuesTest::~InitialValuesTest()
3634{
3635}
3636
3637tcu::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
3696class PBORectangleTest : public RectangleTest
3697{
3698public:
3699	PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3700	virtual ~PBORectangleTest();
3701};
3702
3703PBORectangleTest::PBORectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3704	: RectangleTest(context, name, internalFormat)
3705{
3706	m_usePBO = true;
3707}
3708
3709PBORectangleTest::~PBORectangleTest()
3710{
3711}
3712
3713class VariedRectangleTest : public RectangleTest
3714{
3715public:
3716	VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat);
3717	virtual ~VariedRectangleTest();
3718
3719	tcu::TestNode::IterateResult iterate(void);
3720
3721protected:
3722	struct StoreMode
3723	{
3724		GLenum parameter;
3725		GLint* property;
3726		GLint  value;
3727	};
3728};
3729
3730VariedRectangleTest::VariedRectangleTest(deqp::Context& context, std::string& name, InternalFormat internalFormat)
3731	: RectangleTest(context, name, internalFormat)
3732{
3733}
3734
3735VariedRectangleTest::~VariedRectangleTest()
3736{
3737}
3738
3739tcu::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
3851PackedPixelsTests::PackedPixelsTests(deqp::Context& context) : TestCaseGroup(context, "packed_pixels", "")
3852{
3853}
3854
3855PackedPixelsTests::~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
3868void 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