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