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