Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      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
     21  * \brief Texture specification tests.
     22  *
     23  * \todo [pyry] Following tests are missing:
     24  *  - Specify mipmap incomplete texture, use without mipmaps, re-specify
     25  *    as complete and render.
     26  *  - Randomly re-specify levels to eventually reach mipmap-complete texture.
     27  *//*--------------------------------------------------------------------*/
     28 
     29 #include "es3fTextureSpecificationTests.hpp"
     30 #include "tcuTestLog.hpp"
     31 #include "tcuImageCompare.hpp"
     32 #include "tcuTextureUtil.hpp"
     33 #include "tcuVectorUtil.hpp"
     34 #include "gluStrUtil.hpp"
     35 #include "gluTexture.hpp"
     36 #include "gluTextureUtil.hpp"
     37 #include "sglrContextUtil.hpp"
     38 #include "sglrContextWrapper.hpp"
     39 #include "sglrGLContext.hpp"
     40 #include "sglrReferenceContext.hpp"
     41 #include "glsTextureTestUtil.hpp"
     42 #include "deRandom.hpp"
     43 #include "deStringUtil.hpp"
     44 
     45 // \todo [2012-04-29 pyry] Should be named SglrUtil
     46 #include "es3fFboTestUtil.hpp"
     47 
     48 #include "glwEnums.hpp"
     49 
     50 namespace deqp
     51 {
     52 namespace gles3
     53 {
     54 namespace Functional
     55 {
     56 
     57 using std::string;
     58 using std::vector;
     59 using std::pair;
     60 using tcu::TestLog;
     61 using tcu::Vec4;
     62 using tcu::IVec4;
     63 using tcu::UVec4;
     64 using namespace FboTestUtil;
     65 
     66 tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat)
     67 {
     68 	using tcu::TextureFormat;
     69 	switch (internalFormat)
     70 	{
     71 		case GL_ALPHA:				return TextureFormat(TextureFormat::A,		TextureFormat::UNORM_INT8);
     72 		case GL_LUMINANCE:			return TextureFormat(TextureFormat::L,		TextureFormat::UNORM_INT8);
     73 		case GL_LUMINANCE_ALPHA:	return TextureFormat(TextureFormat::LA,		TextureFormat::UNORM_INT8);
     74 		case GL_RGB:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
     75 		case GL_RGBA:				return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
     76 		default:
     77 			throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format");
     78 	}
     79 }
     80 
     81 enum
     82 {
     83 	VIEWPORT_WIDTH	= 256,
     84 	VIEWPORT_HEIGHT	= 256
     85 };
     86 
     87 static inline int maxLevelCount (int width, int height)
     88 {
     89 	return (int)deLog2Floor32(de::max(width, height))+1;
     90 }
     91 
     92 static inline int maxLevelCount (int width, int height, int depth)
     93 {
     94 	return (int)deLog2Floor32(de::max(width, de::max(height, depth)))+1;
     95 }
     96 
     97 template <int Size>
     98 static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
     99 {
    100 	tcu::Vector<float, Size> res;
    101 	for (int ndx = 0; ndx < Size; ndx++)
    102 		res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
    103 	return res;
    104 }
    105 
    106 static const deUint32 s_cubeMapFaces[] =
    107 {
    108 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
    109 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    110 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
    111 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
    112 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
    113 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    114 };
    115 
    116 static tcu::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
    117 {
    118 	switch (textureFormat.order)
    119 	{
    120 		case tcu::TextureFormat::L:
    121 		case tcu::TextureFormat::LA:
    122 			return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits);
    123 		default:
    124 			return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
    125 	}
    126 }
    127 
    128 static IVec4 getEffectiveTextureFormatBitDepth (tcu::TextureFormat textureFormat)
    129 {
    130 	if (textureFormat.order == tcu::TextureFormat::DS)
    131 	{
    132 		// When sampling depth-stencil texture, we actually sample just
    133 		// the depth component.
    134 		return tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(textureFormat, tcu::Sampler::MODE_DEPTH));
    135 	}
    136 	else
    137 		return tcu::getTextureFormatBitDepth(textureFormat);
    138 }
    139 
    140 static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
    141 {
    142 	const IVec4		texFormatBits		= getEffectiveTextureFormatBitDepth(textureFormat);
    143 	const IVec4		pixelFormatBits		= getPixelFormatCompareDepth(pixelFormat, textureFormat);
    144 	const IVec4		accurateFmtBits		= min(pixelFormatBits, texFormatBits);
    145 	const IVec4		compareBits			= select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1;
    146 
    147 	return (IVec4(1) << (8-compareBits)).asUint();
    148 }
    149 
    150 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
    151 {
    152 public:
    153 							TextureSpecCase		(Context& context, const char* name, const char* desc);
    154 							~TextureSpecCase	(void);
    155 
    156 	IterateResult			iterate				(void);
    157 
    158 protected:
    159 	virtual void			createTexture		(void)																	= DE_NULL;
    160 	virtual void			verifyTexture		(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)	= DE_NULL;
    161 
    162 	// Utilities.
    163 	void					renderTex			(tcu::Surface& dst, deUint32 program, int width, int height);
    164 	void					readPixels			(tcu::Surface& dst, int x, int y, int width, int height);
    165 
    166 private:
    167 							TextureSpecCase		(const TextureSpecCase& other);
    168 	TextureSpecCase&		operator=			(const TextureSpecCase& other);
    169 };
    170 
    171 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
    172 	: TestCase(context, name, desc)
    173 {
    174 }
    175 
    176 TextureSpecCase::~TextureSpecCase (void)
    177 {
    178 }
    179 
    180 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
    181 {
    182 	glu::RenderContext&			renderCtx				= TestCase::m_context.getRenderContext();
    183 	const tcu::RenderTarget&	renderTarget			= renderCtx.getRenderTarget();
    184 	tcu::TestLog&				log						= m_testCtx.getLog();
    185 
    186 	if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
    187 		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
    188 
    189 	// Context size, and viewport for GLES3
    190 	de::Random		rnd			(deStringHash(getName()));
    191 	int				width		= deMin32(renderTarget.getWidth(),	VIEWPORT_WIDTH);
    192 	int				height		= deMin32(renderTarget.getHeight(),	VIEWPORT_HEIGHT);
    193 	int				x			= rnd.getInt(0, renderTarget.getWidth()		- width);
    194 	int				y			= rnd.getInt(0, renderTarget.getHeight()	- height);
    195 
    196 	// Contexts.
    197 	sglr::GLContext					gles3Context	(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
    198 	sglr::ReferenceContextBuffers	refBuffers		(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
    199 	sglr::ReferenceContext			refContext		(sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
    200 
    201 	// Clear color buffer.
    202 	for (int ndx = 0; ndx < 2; ndx++)
    203 	{
    204 		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles3Context);
    205 		glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
    206 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    207 	}
    208 
    209 	// Construct texture using both GLES3 and reference contexts.
    210 	for (int ndx = 0; ndx < 2; ndx++)
    211 	{
    212 		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles3Context);
    213 		createTexture();
    214 		TCU_CHECK(glGetError() == GL_NO_ERROR);
    215 	}
    216 
    217 	// Initialize case result to pass.
    218 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    219 
    220 	// Disable logging.
    221 	gles3Context.enableLogging(0);
    222 
    223 	// Verify results.
    224 	verifyTexture(gles3Context, refContext);
    225 
    226 	return STOP;
    227 }
    228 
    229 void TextureSpecCase::renderTex (tcu::Surface& dst, deUint32 program, int width, int height)
    230 {
    231 	int		targetW		= getWidth();
    232 	int		targetH		= getHeight();
    233 
    234 	float	w			= (float)width	/ (float)targetW;
    235 	float	h			= (float)height	/ (float)targetH;
    236 
    237 	sglr::drawQuad(*getCurrentContext(), program, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
    238 
    239 	// Read pixels back.
    240 	readPixels(dst, 0, 0, width, height);
    241 }
    242 
    243 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
    244 {
    245 	dst.setSize(width, height);
    246 	glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
    247 }
    248 
    249 class Texture2DSpecCase : public TextureSpecCase
    250 {
    251 public:
    252 							Texture2DSpecCase	(Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels);
    253 							~Texture2DSpecCase	(void);
    254 
    255 protected:
    256 	virtual void			verifyTexture		(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
    257 
    258 	tcu::TextureFormat		m_texFormat;
    259 	tcu::TextureFormatInfo	m_texFormatInfo;
    260 	int						m_width;
    261 	int						m_height;
    262 	int						m_numLevels;
    263 };
    264 
    265 Texture2DSpecCase::Texture2DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLevels)
    266 	: TextureSpecCase		(context, name, desc)
    267 	, m_texFormat			(format)
    268 	, m_texFormatInfo		(tcu::getTextureFormatInfo(format))
    269 	, m_width				(width)
    270 	, m_height				(height)
    271 	, m_numLevels			(numLevels)
    272 {
    273 }
    274 
    275 Texture2DSpecCase::~Texture2DSpecCase (void)
    276 {
    277 }
    278 
    279 void Texture2DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
    280 {
    281 	Texture2DShader shader			(DataTypes() << glu::getSampler2DType(m_texFormat), glu::TYPE_FLOAT_VEC4);
    282 	deUint32		shaderIDgles	= gles3Context.createProgram(&shader);
    283 	deUint32		shaderIDRef		= refContext.createProgram(&shader);
    284 
    285 	shader.setTexScaleBias(0, m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
    286 
    287 	// Set state.
    288 	for (int ndx = 0; ndx < 2; ndx++)
    289 	{
    290 		sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
    291 
    292 		setContext(ctx);
    293 
    294 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    295 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    296 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    297 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    298 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,	m_numLevels-1);
    299 	}
    300 
    301 	for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
    302 	{
    303 		int				levelW		= de::max(1, m_width >> levelNdx);
    304 		int				levelH		= de::max(1, m_height >> levelNdx);
    305 		tcu::Surface	reference;
    306 		tcu::Surface	result;
    307 
    308 		for (int ndx = 0; ndx < 2; ndx++)
    309 		{
    310 			tcu::Surface&	dst			= ndx ? reference									: result;
    311 			sglr::Context*	ctx			= ndx ? static_cast<sglr::Context*>(&refContext)	: static_cast<sglr::Context*>(&gles3Context);
    312 			deUint32		shaderID	= ndx ? shaderIDRef									: shaderIDgles;
    313 
    314 			setContext(ctx);
    315 			shader.setUniforms(*ctx, shaderID);
    316 			renderTex(dst, shaderID, levelW, levelH);
    317 		}
    318 
    319 		UVec4			threshold	= computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
    320 		string			levelStr	= de::toString(levelNdx);
    321 		string			name		= string("Level") + levelStr;
    322 		string			desc		= string("Level ") + levelStr;
    323 		bool			isOk		= tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
    324 															   levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
    325 
    326 		if (!isOk)
    327 		{
    328 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
    329 			break;
    330 		}
    331 	}
    332 }
    333 
    334 class TextureCubeSpecCase : public TextureSpecCase
    335 {
    336 public:
    337 							TextureCubeSpecCase		(Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels);
    338 							~TextureCubeSpecCase	(void);
    339 
    340 protected:
    341 	virtual void			verifyTexture			(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
    342 
    343 	tcu::TextureFormat		m_texFormat;
    344 	tcu::TextureFormatInfo	m_texFormatInfo;
    345 	int						m_size;
    346 	int						m_numLevels;
    347 };
    348 
    349 TextureCubeSpecCase::TextureCubeSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int numLevels)
    350 	: TextureSpecCase		(context, name, desc)
    351 	, m_texFormat			(format)
    352 	, m_texFormatInfo		(tcu::getTextureFormatInfo(format))
    353 	, m_size				(size)
    354 	, m_numLevels			(numLevels)
    355 {
    356 }
    357 
    358 TextureCubeSpecCase::~TextureCubeSpecCase (void)
    359 {
    360 }
    361 
    362 void TextureCubeSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
    363 {
    364 	TextureCubeShader	shader			(glu::getSamplerCubeType(m_texFormat), glu::TYPE_FLOAT_VEC4);
    365 	deUint32			shaderIDgles	= gles3Context.createProgram(&shader);
    366 	deUint32			shaderIDRef		= refContext.createProgram(&shader);
    367 
    368 	shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
    369 
    370 	// Set state.
    371 	for (int ndx = 0; ndx < 2; ndx++)
    372 	{
    373 		sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
    374 
    375 		setContext(ctx);
    376 
    377 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    378 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    379 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    380 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    381 		glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,	m_numLevels-1);
    382 	}
    383 
    384 	for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
    385 	{
    386 		int		levelSize	= de::max(1, m_size >> levelNdx);
    387 		bool	isOk		= true;
    388 
    389 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    390 		{
    391 			tcu::Surface	reference;
    392 			tcu::Surface	result;
    393 
    394 			if (levelSize <= 2)
    395 				continue; // Fuzzy compare doesn't work for images this small.
    396 
    397 			shader.setFace((tcu::CubeFace)face);
    398 
    399 			for (int ndx = 0; ndx < 2; ndx++)
    400 			{
    401 				tcu::Surface&	dst			= ndx ? reference									: result;
    402 				sglr::Context*	ctx			= ndx ? static_cast<sglr::Context*>(&refContext)	: static_cast<sglr::Context*>(&gles3Context);
    403 				deUint32		shaderID	= ndx ? shaderIDRef									: shaderIDgles;
    404 
    405 				setContext(ctx);
    406 				shader.setUniforms(*ctx, shaderID);
    407 				renderTex(dst, shaderID, levelSize, levelSize);
    408 			}
    409 
    410 			const float		threshold	= 0.02f;
    411 			string			faceStr		= de::toString((tcu::CubeFace)face);
    412 			string			levelStr	= de::toString(levelNdx);
    413 			string			name		= string("Level") + levelStr;
    414 			string			desc		= string("Level ") + levelStr + ", face " + faceStr;
    415 			bool			isFaceOk	= tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold,
    416 															levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
    417 
    418 			if (!isFaceOk)
    419 			{
    420 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
    421 				isOk = false;
    422 				break;
    423 			}
    424 		}
    425 
    426 		if (!isOk)
    427 			break;
    428 	}
    429 }
    430 
    431 class Texture2DArraySpecCase : public TextureSpecCase
    432 {
    433 public:
    434 							Texture2DArraySpecCase	(Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels);
    435 							~Texture2DArraySpecCase	(void);
    436 
    437 protected:
    438 	virtual void			verifyTexture			(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
    439 
    440 	tcu::TextureFormat		m_texFormat;
    441 	tcu::TextureFormatInfo	m_texFormatInfo;
    442 	int						m_width;
    443 	int						m_height;
    444 	int						m_numLayers;
    445 	int						m_numLevels;
    446 };
    447 
    448 Texture2DArraySpecCase::Texture2DArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int numLayers, int numLevels)
    449 	: TextureSpecCase		(context, name, desc)
    450 	, m_texFormat			(format)
    451 	, m_texFormatInfo		(tcu::getTextureFormatInfo(format))
    452 	, m_width				(width)
    453 	, m_height				(height)
    454 	, m_numLayers			(numLayers)
    455 	, m_numLevels			(numLevels)
    456 {
    457 }
    458 
    459 Texture2DArraySpecCase::~Texture2DArraySpecCase (void)
    460 {
    461 }
    462 
    463 void Texture2DArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
    464 {
    465 	Texture2DArrayShader	shader			(glu::getSampler2DArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4);
    466 	deUint32				shaderIDgles	= gles3Context.createProgram(&shader);
    467 	deUint32				shaderIDRef		= refContext.createProgram(&shader);
    468 
    469 	shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
    470 
    471 	// Set state.
    472 	for (int ndx = 0; ndx < 2; ndx++)
    473 	{
    474 		sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
    475 
    476 		setContext(ctx);
    477 
    478 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    479 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    480 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    481 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    482 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
    483 		glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,	m_numLevels-1);
    484 	}
    485 
    486 	for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
    487 	{
    488 		bool layerOk = true;
    489 
    490 		shader.setLayer(layerNdx);
    491 
    492 		for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
    493 		{
    494 			int				levelW		= de::max(1, m_width	>> levelNdx);
    495 			int				levelH		= de::max(1, m_height	>> levelNdx);
    496 			tcu::Surface	reference;
    497 			tcu::Surface	result;
    498 
    499 			for (int ndx = 0; ndx < 2; ndx++)
    500 			{
    501 				tcu::Surface&	dst			= ndx ? reference									: result;
    502 				sglr::Context*	ctx			= ndx ? static_cast<sglr::Context*>(&refContext)	: static_cast<sglr::Context*>(&gles3Context);
    503 				deUint32		shaderID	= ndx ? shaderIDRef									: shaderIDgles;
    504 
    505 				setContext(ctx);
    506 				shader.setUniforms(*ctx, shaderID);
    507 				renderTex(dst, shaderID, levelW, levelH);
    508 			}
    509 
    510 			UVec4			threshold	= computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
    511 			string			levelStr	= de::toString(levelNdx);
    512 			string			layerStr	= de::toString(layerNdx);
    513 			string			name		= string("Layer") + layerStr + "Level" + levelStr;
    514 			string			desc		= string("Layer ") + layerStr + ", Level " + levelStr;
    515 			bool			depthOk		= tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
    516 																   (levelNdx == 0 && layerNdx == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
    517 
    518 			if (!depthOk)
    519 			{
    520 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
    521 				layerOk = false;
    522 				break;
    523 			}
    524 		}
    525 
    526 		if (!layerOk)
    527 			break;
    528 	}
    529 }
    530 
    531 class Texture3DSpecCase : public TextureSpecCase
    532 {
    533 public:
    534 							Texture3DSpecCase	(Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels);
    535 							~Texture3DSpecCase	(void);
    536 
    537 protected:
    538 	virtual void			verifyTexture		(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);
    539 
    540 	tcu::TextureFormat		m_texFormat;
    541 	tcu::TextureFormatInfo	m_texFormatInfo;
    542 	int						m_width;
    543 	int						m_height;
    544 	int						m_depth;
    545 	int						m_numLevels;
    546 };
    547 
    548 Texture3DSpecCase::Texture3DSpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int width, int height, int depth, int numLevels)
    549 	: TextureSpecCase		(context, name, desc)
    550 	, m_texFormat			(format)
    551 	, m_texFormatInfo		(tcu::getTextureFormatInfo(format))
    552 	, m_width				(width)
    553 	, m_height				(height)
    554 	, m_depth				(depth)
    555 	, m_numLevels			(numLevels)
    556 {
    557 }
    558 
    559 Texture3DSpecCase::~Texture3DSpecCase (void)
    560 {
    561 }
    562 
    563 void Texture3DSpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
    564 {
    565 	Texture3DShader shader			(glu::getSampler3DType(m_texFormat), glu::TYPE_FLOAT_VEC4);
    566 	deUint32		shaderIDgles	= gles3Context.createProgram(&shader);
    567 	deUint32		shaderIDRef		= refContext.createProgram(&shader);
    568 
    569 	shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);
    570 
    571 	// Set state.
    572 	for (int ndx = 0; ndx < 2; ndx++)
    573 	{
    574 		sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);
    575 
    576 		setContext(ctx);
    577 
    578 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    579 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    580 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    581 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    582 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
    583 		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,	m_numLevels-1);
    584 	}
    585 
    586 	for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
    587 	{
    588 		int		levelW		= de::max(1, m_width	>> levelNdx);
    589 		int		levelH		= de::max(1, m_height	>> levelNdx);
    590 		int		levelD		= de::max(1, m_depth	>> levelNdx);
    591 		bool	levelOk		= true;
    592 
    593 		for (int depth = 0; depth < levelD; depth++)
    594 		{
    595 			tcu::Surface	reference;
    596 			tcu::Surface	result;
    597 
    598 			shader.setDepth(((float)depth + 0.5f) / (float)levelD);
    599 
    600 			for (int ndx = 0; ndx < 2; ndx++)
    601 			{
    602 				tcu::Surface&	dst			= ndx ? reference									: result;
    603 				sglr::Context*	ctx			= ndx ? static_cast<sglr::Context*>(&refContext)	: static_cast<sglr::Context*>(&gles3Context);
    604 				deUint32		shaderID	= ndx ? shaderIDRef									: shaderIDgles;
    605 
    606 				setContext(ctx);
    607 				shader.setUniforms(*ctx, shaderID);
    608 				renderTex(dst, shaderID, levelW, levelH);
    609 			}
    610 
    611 			UVec4			threshold	= computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
    612 			string			levelStr	= de::toString(levelNdx);
    613 			string			sliceStr	= de::toString(depth);
    614 			string			name		= string("Level") + levelStr + "Slice" + sliceStr;
    615 			string			desc		= string("Level ") + levelStr + ", Slice " + sliceStr;
    616 			bool			depthOk		= tcu::intThresholdCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference.getAccess(), result.getAccess(), threshold,
    617 																   (levelNdx == 0 && depth == 0) ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
    618 
    619 			if (!depthOk)
    620 			{
    621 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
    622 				levelOk = false;
    623 				break;
    624 			}
    625 		}
    626 
    627 		if (!levelOk)
    628 			break;
    629 	}
    630 }
    631 
    632 // Basic TexImage2D() with 2D texture usage
    633 class BasicTexImage2DCase : public Texture2DSpecCase
    634 {
    635 public:
    636 	// Unsized internal format.
    637 	BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
    638 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
    639 		, m_internalFormat	(format)
    640 		, m_format			(format)
    641 		, m_dataType		(dataType)
    642 	{
    643 	}
    644 
    645 	// Sized internal format.
    646 	BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
    647 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
    648 		, m_internalFormat	(internalFormat)
    649 		, m_format			(GL_NONE)
    650 		, m_dataType		(GL_NONE)
    651 	{
    652 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
    653 		m_format	= fmt.format;
    654 		m_dataType	= fmt.dataType;
    655 	}
    656 
    657 protected:
    658 	void createTexture (void)
    659 	{
    660 		deUint32			tex			= 0;
    661 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(m_format, m_dataType));
    662 		de::Random			rnd			(deStringHash(getName()));
    663 
    664 		glGenTextures(1, &tex);
    665 		glBindTexture(GL_TEXTURE_2D, tex);
    666 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    667 
    668 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    669 		{
    670 			int		levelW		= de::max(1, m_width >> ndx);
    671 			int		levelH		= de::max(1, m_height >> ndx);
    672 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    673 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    674 
    675 			levelData.setSize(levelW, levelH);
    676 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    677 
    678 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
    679 		}
    680 	}
    681 
    682 	deUint32	m_internalFormat;
    683 	deUint32	m_format;
    684 	deUint32	m_dataType;
    685 };
    686 
    687 // Basic TexImage2D() with cubemap usage
    688 class BasicTexImageCubeCase : public TextureCubeSpecCase
    689 {
    690 public:
    691 	// Unsized formats.
    692 	BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
    693 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
    694 		, m_internalFormat		(format)
    695 		, m_format				(format)
    696 		, m_dataType			(dataType)
    697 	{
    698 	}
    699 
    700 	// Sized internal formats.
    701 	BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
    702 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
    703 		, m_internalFormat		(internalFormat)
    704 		, m_format				(GL_NONE)
    705 		, m_dataType			(GL_NONE)
    706 	{
    707 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
    708 		m_format	= fmt.format;
    709 		m_dataType	= fmt.dataType;
    710 	}
    711 
    712 protected:
    713 	void createTexture (void)
    714 	{
    715 		deUint32			tex			= 0;
    716 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(m_format, m_dataType));
    717 		de::Random			rnd			(deStringHash(getName()));
    718 
    719 		glGenTextures(1, &tex);
    720 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
    721 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    722 
    723 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    724 		{
    725 			int levelSize = de::max(1, m_size >> ndx);
    726 
    727 			levelData.setSize(levelSize, levelSize);
    728 
    729 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
    730 			{
    731 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    732 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    733 
    734 				tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    735 
    736 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
    737 			}
    738 		}
    739 	}
    740 
    741 	deUint32	m_internalFormat;
    742 	deUint32	m_format;
    743 	deUint32	m_dataType;
    744 };
    745 
    746 // Basic TexImage3D() with 2D array texture usage
    747 class BasicTexImage2DArrayCase : public Texture2DArraySpecCase
    748 {
    749 public:
    750 	BasicTexImage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers)
    751 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, maxLevelCount(width, height))
    752 		, m_internalFormat			(internalFormat)
    753 	{
    754 	}
    755 
    756 protected:
    757 	void createTexture (void)
    758 	{
    759 		deUint32				tex			= 0;
    760 		de::Random				rnd			(deStringHash(getName()));
    761 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
    762 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
    763 
    764 		glGenTextures(1, &tex);
    765 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
    766 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    767 
    768 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    769 		{
    770 			int		levelW		= de::max(1, m_width	>> ndx);
    771 			int		levelH		= de::max(1, m_height	>> ndx);
    772 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    773 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    774 
    775 			levelData.setSize(levelW, levelH, m_numLayers);
    776 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    777 
    778 			glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
    779 		}
    780 	}
    781 
    782 	deUint32 m_internalFormat;
    783 };
    784 
    785 // Basic TexImage3D() with 3D texture usage
    786 class BasicTexImage3DCase : public Texture3DSpecCase
    787 {
    788 public:
    789 	BasicTexImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
    790 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
    791 		, m_internalFormat	(internalFormat)
    792 	{
    793 	}
    794 
    795 protected:
    796 	void createTexture (void)
    797 	{
    798 		deUint32				tex			= 0;
    799 		de::Random				rnd			(deStringHash(getName()));
    800 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
    801 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
    802 
    803 		glGenTextures(1, &tex);
    804 		glBindTexture(GL_TEXTURE_3D, tex);
    805 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    806 
    807 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    808 		{
    809 			int		levelW		= de::max(1, m_width	>> ndx);
    810 			int		levelH		= de::max(1, m_height	>> ndx);
    811 			int		levelD		= de::max(1, m_depth	>> ndx);
    812 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    813 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    814 
    815 			levelData.setSize(levelW, levelH, levelD);
    816 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    817 
    818 			glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
    819 		}
    820 	}
    821 
    822 	deUint32 m_internalFormat;
    823 };
    824 
    825 // Randomized 2D texture specification using TexImage2D
    826 class RandomOrderTexImage2DCase : public Texture2DSpecCase
    827 {
    828 public:
    829 	RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
    830 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
    831 		, m_internalFormat	(format)
    832 		, m_format			(format)
    833 		, m_dataType		(dataType)
    834 	{
    835 	}
    836 
    837 	RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
    838 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
    839 		, m_internalFormat	(internalFormat)
    840 		, m_format			(GL_NONE)
    841 		, m_dataType		(GL_NONE)
    842 	{
    843 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
    844 		m_format	= fmt.format;
    845 		m_dataType	= fmt.dataType;
    846 	}
    847 
    848 protected:
    849 	void createTexture (void)
    850 	{
    851 		deUint32			tex			= 0;
    852 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(m_format, m_dataType));
    853 		de::Random			rnd			(deStringHash(getName()));
    854 
    855 		glGenTextures(1, &tex);
    856 		glBindTexture(GL_TEXTURE_2D, tex);
    857 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    858 
    859 		vector<int>			levels		(m_numLevels);
    860 
    861 		for (int i = 0; i < m_numLevels; i++)
    862 			levels[i] = i;
    863 		rnd.shuffle(levels.begin(), levels.end());
    864 
    865 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    866 		{
    867 			int		levelNdx	= levels[ndx];
    868 			int		levelW		= de::max(1, m_width	>> levelNdx);
    869 			int		levelH		= de::max(1, m_height	>> levelNdx);
    870 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    871 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    872 
    873 			levelData.setSize(levelW, levelH);
    874 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    875 
    876 			glTexImage2D(GL_TEXTURE_2D, levelNdx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
    877 		}
    878 	}
    879 
    880 	deUint32	m_internalFormat;
    881 	deUint32	m_format;
    882 	deUint32	m_dataType;
    883 };
    884 
    885 // Randomized cubemap texture specification using TexImage2D
    886 class RandomOrderTexImageCubeCase : public TextureCubeSpecCase
    887 {
    888 public:
    889 	RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
    890 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
    891 		, m_internalFormat		(GL_NONE)
    892 		, m_format				(format)
    893 		, m_dataType			(dataType)
    894 	{
    895 	}
    896 
    897 	RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
    898 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
    899 		, m_internalFormat		(internalFormat)
    900 		, m_format				(GL_NONE)
    901 		, m_dataType			(GL_NONE)
    902 	{
    903 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
    904 		m_format	= fmt.format;
    905 		m_dataType	= fmt.dataType;
    906 	}
    907 
    908 protected:
    909 	void createTexture (void)
    910 	{
    911 		deUint32			tex			= 0;
    912 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(m_format, m_dataType));
    913 		de::Random			rnd			(deStringHash(getName()));
    914 
    915 		glGenTextures(1, &tex);
    916 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
    917 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    918 
    919 		// Level-face pairs.
    920 		vector<pair<int, tcu::CubeFace> >	images	(m_numLevels*6);
    921 
    922 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    923 			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    924 				images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face);
    925 
    926 		rnd.shuffle(images.begin(), images.end());
    927 
    928 		for (int ndx = 0; ndx < (int)images.size(); ndx++)
    929 		{
    930 			int				levelNdx	= images[ndx].first;
    931 			tcu::CubeFace	face		= images[ndx].second;
    932 			int				levelSize	= de::max(1, m_size >> levelNdx);
    933 			Vec4			gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    934 			Vec4			gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
    935 
    936 			levelData.setSize(levelSize, levelSize);
    937 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
    938 
    939 			glTexImage2D(s_cubeMapFaces[face], levelNdx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
    940 		}
    941 	}
    942 
    943 	deUint32	m_internalFormat;
    944 	deUint32	m_format;
    945 	deUint32	m_dataType;
    946 };
    947 
    948 // TexImage2D() unpack alignment case.
    949 class TexImage2DAlignCase : public Texture2DSpecCase
    950 {
    951 public:
    952 	TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int numLevels, int alignment)
    953 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, numLevels)
    954 		, m_internalFormat	(format)
    955 		, m_format			(format)
    956 		, m_dataType		(dataType)
    957 		, m_alignment		(alignment)
    958 	{
    959 	}
    960 
    961 	TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels, int alignment)
    962 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
    963 		, m_internalFormat	(internalFormat)
    964 		, m_format			(GL_NONE)
    965 		, m_dataType		(GL_NONE)
    966 		, m_alignment		(alignment)
    967 	{
    968 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
    969 		m_format	= fmt.format;
    970 		m_dataType	= fmt.dataType;
    971 	}
    972 
    973 protected:
    974 	void createTexture (void)
    975 	{
    976 		deUint32			tex			= 0;
    977 		vector<deUint8>		data;
    978 
    979 		glGenTextures(1, &tex);
    980 		glBindTexture(GL_TEXTURE_2D, tex);
    981 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
    982 
    983 		for (int ndx = 0; ndx < m_numLevels; ndx++)
    984 		{
    985 			int		levelW		= de::max(1, m_width >> ndx);
    986 			int		levelH		= de::max(1, m_height >> ndx);
    987 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
    988 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
    989 			int		rowPitch	= deAlign32(levelW*m_texFormat.getPixelSize(), m_alignment);
    990 			int		cellSize	= de::max(1, de::min(levelW >> 2, levelH >> 2));
    991 
    992 			data.resize(rowPitch*levelH);
    993 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
    994 
    995 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, &data[0]);
    996 		}
    997 	}
    998 
    999 	deUint32	m_internalFormat;
   1000 	deUint32	m_format;
   1001 	deUint32	m_dataType;
   1002 	int			m_alignment;
   1003 };
   1004 
   1005 // TexImage2D() unpack alignment case.
   1006 class TexImageCubeAlignCase : public TextureCubeSpecCase
   1007 {
   1008 public:
   1009 	TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int numLevels, int alignment)
   1010 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, numLevels)
   1011 		, m_internalFormat		(format)
   1012 		, m_format				(format)
   1013 		, m_dataType			(dataType)
   1014 		, m_alignment			(alignment)
   1015 	{
   1016 	}
   1017 
   1018 	TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels, int alignment)
   1019 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
   1020 		, m_internalFormat		(internalFormat)
   1021 		, m_format				(GL_NONE)
   1022 		, m_dataType			(GL_NONE)
   1023 		, m_alignment			(alignment)
   1024 	{
   1025 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1026 		m_format	= fmt.format;
   1027 		m_dataType	= fmt.dataType;
   1028 	}
   1029 
   1030 protected:
   1031 	void createTexture (void)
   1032 	{
   1033 		deUint32			tex			= 0;
   1034 		vector<deUint8>		data;
   1035 
   1036 		glGenTextures(1, &tex);
   1037 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1038 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
   1039 
   1040 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1041 		{
   1042 			int		levelSize	= de::max(1, m_size >> ndx);
   1043 			int		rowPitch	= deAlign32(m_texFormat.getPixelSize()*levelSize, m_alignment);
   1044 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
   1045 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*(m_texFormatInfo.valueMax-m_texFormatInfo.valueMin) + m_texFormatInfo.valueMin;
   1046 			int		cellSize	= de::max(1, levelSize >> 2);
   1047 
   1048 			data.resize(rowPitch*levelSize);
   1049 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, levelSize, levelSize, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
   1050 
   1051 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1052 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, &data[0]);
   1053 		}
   1054 	}
   1055 
   1056 	deUint32	m_internalFormat;
   1057 	deUint32	m_format;
   1058 	deUint32	m_dataType;
   1059 	int			m_alignment;
   1060 };
   1061 
   1062 // TexImage2D() unpack parameters case.
   1063 class TexImage2DParamsCase : public Texture2DSpecCase
   1064 {
   1065 public:
   1066 	TexImage2DParamsCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int rowLength, int skipRows, int skipPixels, int alignment)
   1067 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   1068 		, m_internalFormat	(internalFormat)
   1069 		, m_rowLength		(rowLength)
   1070 		, m_skipRows		(skipRows)
   1071 		, m_skipPixels		(skipPixels)
   1072 		, m_alignment		(alignment)
   1073 	{
   1074 	}
   1075 
   1076 protected:
   1077 	void createTexture (void)
   1078 	{
   1079 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1080 		int						pixelSize		= m_texFormat.getPixelSize();
   1081 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   1082 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   1083 		int						height			= m_height + m_skipRows;
   1084 		deUint32				tex				= 0;
   1085 		vector<deUint8>			data;
   1086 
   1087 		DE_ASSERT(m_numLevels == 1);
   1088 
   1089 		// Fill data with grid.
   1090 		data.resize(rowPitch*height);
   1091 		{
   1092 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1093 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1094 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1095 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1096 
   1097 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1098 		}
   1099 
   1100 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1101 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1102 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1103 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1104 
   1105 		glGenTextures(1, &tex);
   1106 		glBindTexture(GL_TEXTURE_2D, tex);
   1107 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1108 	}
   1109 
   1110 	deUint32	m_internalFormat;
   1111 	int			m_rowLength;
   1112 	int			m_skipRows;
   1113 	int			m_skipPixels;
   1114 	int			m_alignment;
   1115 };
   1116 
   1117 // TexImage3D() unpack parameters case.
   1118 class TexImage3DParamsCase : public Texture3DSpecCase
   1119 {
   1120 public:
   1121 	TexImage3DParamsCase (Context&		context,
   1122 						   const char*	name,
   1123 						   const char*	desc,
   1124 						   deUint32		internalFormat,
   1125 						   int			width,
   1126 						   int			height,
   1127 						   int			depth,
   1128 						   int			imageHeight,
   1129 						   int			rowLength,
   1130 						   int			skipImages,
   1131 						   int			skipRows,
   1132 						   int			skipPixels,
   1133 						   int			alignment)
   1134 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   1135 		, m_internalFormat	(internalFormat)
   1136 		, m_imageHeight		(imageHeight)
   1137 		, m_rowLength		(rowLength)
   1138 		, m_skipImages		(skipImages)
   1139 		, m_skipRows		(skipRows)
   1140 		, m_skipPixels		(skipPixels)
   1141 		, m_alignment		(alignment)
   1142 	{
   1143 	}
   1144 
   1145 protected:
   1146 	void createTexture (void)
   1147 	{
   1148 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1149 		int						pixelSize		= m_texFormat.getPixelSize();
   1150 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   1151 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   1152 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   1153 		int						slicePitch		= imageHeight*rowPitch;
   1154 		deUint32				tex				= 0;
   1155 		vector<deUint8>			data;
   1156 
   1157 		DE_ASSERT(m_numLevels == 1);
   1158 
   1159 		// Fill data with grid.
   1160 		data.resize(slicePitch*(m_depth+m_skipImages));
   1161 		{
   1162 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1163 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1164 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1165 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1166 
   1167 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1168 		}
   1169 
   1170 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   1171 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1172 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   1173 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1174 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1175 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1176 
   1177 		glGenTextures(1, &tex);
   1178 		glBindTexture(GL_TEXTURE_3D, tex);
   1179 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1180 	}
   1181 
   1182 	deUint32	m_internalFormat;
   1183 	int			m_imageHeight;
   1184 	int			m_rowLength;
   1185 	int			m_skipImages;
   1186 	int			m_skipRows;
   1187 	int			m_skipPixels;
   1188 	int			m_alignment;
   1189 };
   1190 
   1191 // Basic TexSubImage2D() with 2D texture usage
   1192 class BasicTexSubImage2DCase : public Texture2DSpecCase
   1193 {
   1194 public:
   1195 	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1196 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1197 		, m_internalFormat	(format)
   1198 		, m_format			(format)
   1199 		, m_dataType		(dataType)
   1200 	{
   1201 	}
   1202 
   1203 	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1204 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
   1205 		, m_internalFormat	(internalFormat)
   1206 		, m_format			(GL_NONE)
   1207 		, m_dataType		(GL_NONE)
   1208 	{
   1209 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1210 		m_format	= fmt.format;
   1211 		m_dataType	= fmt.dataType;
   1212 	}
   1213 
   1214 protected:
   1215 	void createTexture (void)
   1216 	{
   1217 		deUint32			tex			= 0;
   1218 		tcu::TextureLevel	data		(m_texFormat);
   1219 		de::Random			rnd			(deStringHash(getName()));
   1220 
   1221 		glGenTextures(1, &tex);
   1222 		glBindTexture(GL_TEXTURE_2D, tex);
   1223 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1224 
   1225 		// First specify full texture.
   1226 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1227 		{
   1228 			int		levelW		= de::max(1, m_width >> ndx);
   1229 			int		levelH		= de::max(1, m_height >> ndx);
   1230 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1231 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1232 
   1233 			data.setSize(levelW, levelH);
   1234 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1235 
   1236 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   1237 		}
   1238 
   1239 		// Re-specify parts of each level.
   1240 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1241 		{
   1242 			int		levelW		= de::max(1, m_width >> ndx);
   1243 			int		levelH		= de::max(1, m_height >> ndx);
   1244 
   1245 			int		w			= rnd.getInt(1, levelW);
   1246 			int		h			= rnd.getInt(1, levelH);
   1247 			int		x			= rnd.getInt(0, levelW-w);
   1248 			int		y			= rnd.getInt(0, levelH-h);
   1249 
   1250 			Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1251 			Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1252 			int		cellSize	= rnd.getInt(2, 16);
   1253 
   1254 			data.setSize(w, h);
   1255 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1256 
   1257 			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
   1258 		}
   1259 	}
   1260 
   1261 	deUint32	m_internalFormat;
   1262 	deUint32	m_format;
   1263 	deUint32	m_dataType;
   1264 };
   1265 
   1266 // Basic TexSubImage2D() with cubemap usage
   1267 class BasicTexSubImageCubeCase : public TextureCubeSpecCase
   1268 {
   1269 public:
   1270 	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   1271 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   1272 		, m_internalFormat		(format)
   1273 		, m_format				(format)
   1274 		, m_dataType			(dataType)
   1275 	{
   1276 	}
   1277 
   1278 	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1279 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
   1280 		, m_internalFormat		(internalFormat)
   1281 		, m_format				(GL_NONE)
   1282 		, m_dataType			(GL_NONE)
   1283 	{
   1284 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1285 		m_format	= fmt.format;
   1286 		m_dataType	= fmt.dataType;
   1287 	}
   1288 
   1289 protected:
   1290 	void createTexture (void)
   1291 	{
   1292 		deUint32			tex			= 0;
   1293 		tcu::TextureLevel	data		(m_texFormat);
   1294 		de::Random			rnd			(deStringHash(getName()));
   1295 
   1296 		glGenTextures(1, &tex);
   1297 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1298 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1299 
   1300 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1301 		{
   1302 			int levelSize = de::max(1, m_size >> ndx);
   1303 
   1304 			data.setSize(levelSize, levelSize);
   1305 
   1306 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1307 			{
   1308 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1309 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1310 
   1311 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1312 
   1313 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   1314 			}
   1315 		}
   1316 
   1317 		// Re-specify parts of each face and level.
   1318 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1319 		{
   1320 			int levelSize = de::max(1, m_size >> ndx);
   1321 
   1322 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1323 			{
   1324 				int		w			= rnd.getInt(1, levelSize);
   1325 				int		h			= rnd.getInt(1, levelSize);
   1326 				int		x			= rnd.getInt(0, levelSize-w);
   1327 				int		y			= rnd.getInt(0, levelSize-h);
   1328 
   1329 				Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1330 				Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1331 				int		cellSize	= rnd.getInt(2, 16);
   1332 
   1333 				data.setSize(w, h);
   1334 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1335 
   1336 				glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
   1337 			}
   1338 		}
   1339 	}
   1340 
   1341 	deUint32	m_internalFormat;
   1342 	deUint32	m_format;
   1343 	deUint32	m_dataType;
   1344 };
   1345 
   1346 // TexSubImage2D() unpack parameters case.
   1347 class TexSubImage2DParamsCase : public Texture2DSpecCase
   1348 {
   1349 public:
   1350 	TexSubImage2DParamsCase (Context&		context,
   1351 							 const char*	name,
   1352 							 const char*	desc,
   1353 							 deUint32		internalFormat,
   1354 							 int			width,
   1355 							 int			height,
   1356 							 int			subX,
   1357 							 int			subY,
   1358 							 int			subW,
   1359 							 int			subH,
   1360 							 int			rowLength,
   1361 							 int			skipRows,
   1362 							 int			skipPixels,
   1363 							 int			alignment)
   1364 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   1365 		, m_internalFormat	(internalFormat)
   1366 		, m_subX			(subX)
   1367 		, m_subY			(subY)
   1368 		, m_subW			(subW)
   1369 		, m_subH			(subH)
   1370 		, m_rowLength		(rowLength)
   1371 		, m_skipRows		(skipRows)
   1372 		, m_skipPixels		(skipPixels)
   1373 		, m_alignment		(alignment)
   1374 	{
   1375 	}
   1376 
   1377 protected:
   1378 	void createTexture (void)
   1379 	{
   1380 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1381 		int						pixelSize		= m_texFormat.getPixelSize();
   1382 		deUint32				tex				= 0;
   1383 		vector<deUint8>			data;
   1384 
   1385 		DE_ASSERT(m_numLevels == 1);
   1386 
   1387 		glGenTextures(1, &tex);
   1388 		glBindTexture(GL_TEXTURE_2D, tex);
   1389 
   1390 		// First fill texture with gradient.
   1391 		data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
   1392 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1393 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1394 
   1395 		// Fill data with grid.
   1396 		{
   1397 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   1398 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   1399 			int		height		= m_subH + m_skipRows;
   1400 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1401 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1402 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1403 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1404 
   1405 			data.resize(rowPitch*height);
   1406 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1407 		}
   1408 
   1409 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1410 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1411 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1412 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1413 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, &data[0]);
   1414 	}
   1415 
   1416 	deUint32	m_internalFormat;
   1417 	int			m_subX;
   1418 	int			m_subY;
   1419 	int			m_subW;
   1420 	int			m_subH;
   1421 	int			m_rowLength;
   1422 	int			m_skipRows;
   1423 	int			m_skipPixels;
   1424 	int			m_alignment;
   1425 };
   1426 
   1427 // Basic TexSubImage3D() with 3D texture usage
   1428 class BasicTexSubImage3DCase : public Texture3DSpecCase
   1429 {
   1430 public:
   1431 	BasicTexSubImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
   1432 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
   1433 		, m_internalFormat	(internalFormat)
   1434 	{
   1435 	}
   1436 
   1437 protected:
   1438 	void createTexture (void)
   1439 	{
   1440 		deUint32				tex				= 0;
   1441 		tcu::TextureLevel		data			(m_texFormat);
   1442 		de::Random				rnd				(deStringHash(getName()));
   1443 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1444 
   1445 		glGenTextures(1, &tex);
   1446 		glBindTexture(GL_TEXTURE_3D, tex);
   1447 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1448 
   1449 		// First specify full texture.
   1450 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1451 		{
   1452 			int		levelW		= de::max(1, m_width >> ndx);
   1453 			int		levelH		= de::max(1, m_height >> ndx);
   1454 			int		levelD		= de::max(1, m_depth >> ndx);
   1455 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1456 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1457 
   1458 			data.setSize(levelW, levelH, levelD);
   1459 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1460 
   1461 			glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
   1462 		}
   1463 
   1464 		// Re-specify parts of each level.
   1465 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1466 		{
   1467 			int		levelW		= de::max(1, m_width >> ndx);
   1468 			int		levelH		= de::max(1, m_height >> ndx);
   1469 			int		levelD		= de::max(1, m_depth >> ndx);
   1470 
   1471 			int		w			= rnd.getInt(1, levelW);
   1472 			int		h			= rnd.getInt(1, levelH);
   1473 			int		d			= rnd.getInt(1, levelD);
   1474 			int		x			= rnd.getInt(0, levelW-w);
   1475 			int		y			= rnd.getInt(0, levelH-h);
   1476 			int		z			= rnd.getInt(0, levelD-d);
   1477 
   1478 			Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1479 			Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1480 			int		cellSize	= rnd.getInt(2, 16);
   1481 
   1482 			data.setSize(w, h, d);
   1483 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1484 
   1485 			glTexSubImage3D(GL_TEXTURE_3D, ndx, x, y, z, w, h, d, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
   1486 		}
   1487 	}
   1488 
   1489 	deUint32 m_internalFormat;
   1490 };
   1491 
   1492 // TexSubImage2D() to texture initialized with empty data
   1493 class TexSubImage2DEmptyTexCase : public Texture2DSpecCase
   1494 {
   1495 public:
   1496 	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1497 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1498 		, m_internalFormat	(format)
   1499 		, m_format			(format)
   1500 		, m_dataType		(dataType)
   1501 	{
   1502 	}
   1503 
   1504 	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1505 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
   1506 		, m_internalFormat	(internalFormat)
   1507 		, m_format			(GL_NONE)
   1508 		, m_dataType		(GL_NONE)
   1509 	{
   1510 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1511 		m_format	= fmt.format;
   1512 		m_dataType	= fmt.dataType;
   1513 	}
   1514 
   1515 protected:
   1516 	void createTexture (void)
   1517 	{
   1518 		deUint32			tex			= 0;
   1519 		tcu::TextureLevel	data		(m_texFormat);
   1520 		de::Random			rnd			(deStringHash(getName()));
   1521 
   1522 		glGenTextures(1, &tex);
   1523 		glBindTexture(GL_TEXTURE_2D, tex);
   1524 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1525 
   1526 		// First allocate storage for each level.
   1527 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1528 		{
   1529 			int		levelW		= de::max(1, m_width >> ndx);
   1530 			int		levelH		= de::max(1, m_height >> ndx);
   1531 
   1532 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
   1533 		}
   1534 
   1535 		// Specify pixel data to all levels using glTexSubImage2D()
   1536 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1537 		{
   1538 			int		levelW		= de::max(1, m_width >> ndx);
   1539 			int		levelH		= de::max(1, m_height >> ndx);
   1540 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1541 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1542 
   1543 			data.setSize(levelW, levelH);
   1544 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1545 
   1546 			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
   1547 		}
   1548 	}
   1549 
   1550 	deUint32	m_internalFormat;
   1551 	deUint32	m_format;
   1552 	deUint32	m_dataType;
   1553 };
   1554 
   1555 // TexSubImage2D() to empty cubemap texture
   1556 class TexSubImageCubeEmptyTexCase : public TextureCubeSpecCase
   1557 {
   1558 public:
   1559 	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   1560 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   1561 		, m_internalFormat		(format)
   1562 		, m_format				(format)
   1563 		, m_dataType			(dataType)
   1564 	{
   1565 	}
   1566 
   1567 	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1568 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
   1569 		, m_internalFormat		(internalFormat)
   1570 		, m_format				(GL_NONE)
   1571 		, m_dataType			(GL_NONE)
   1572 	{
   1573 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1574 		m_format	= fmt.format;
   1575 		m_dataType	= fmt.dataType;
   1576 	}
   1577 
   1578 protected:
   1579 	void createTexture (void)
   1580 	{
   1581 		deUint32			tex			= 0;
   1582 		tcu::TextureLevel	data		(m_texFormat);
   1583 		de::Random			rnd			(deStringHash(getName()));
   1584 
   1585 		glGenTextures(1, &tex);
   1586 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1587 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1588 
   1589 		// Specify storage for each level.
   1590 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1591 		{
   1592 			int levelSize = de::max(1, m_size >> ndx);
   1593 
   1594 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1595 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, DE_NULL);
   1596 		}
   1597 
   1598 		// Specify data using glTexSubImage2D()
   1599 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1600 		{
   1601 			int levelSize = de::max(1, m_size >> ndx);
   1602 
   1603 			data.setSize(levelSize, levelSize);
   1604 
   1605 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1606 			{
   1607 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1608 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1609 
   1610 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1611 
   1612 				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, m_format, m_dataType, data.getAccess().getDataPtr());
   1613 			}
   1614 		}
   1615 	}
   1616 
   1617 	deUint32	m_internalFormat;
   1618 	deUint32	m_format;
   1619 	deUint32	m_dataType;
   1620 };
   1621 
   1622 // TexSubImage2D() unpack alignment with 2D texture
   1623 class TexSubImage2DAlignCase : public Texture2DSpecCase
   1624 {
   1625 public:
   1626 	TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int subX, int subY, int subW, int subH, int alignment)
   1627 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, 1)
   1628 		, m_internalFormat	(format)
   1629 		, m_format			(format)
   1630 		, m_dataType		(dataType)
   1631 		, m_subX			(subX)
   1632 		, m_subY			(subY)
   1633 		, m_subW			(subW)
   1634 		, m_subH			(subH)
   1635 		, m_alignment		(alignment)
   1636 	{
   1637 	}
   1638 
   1639 	TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int subX, int subY, int subW, int subH, int alignment)
   1640 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   1641 		, m_internalFormat	(internalFormat)
   1642 		, m_format			(GL_NONE)
   1643 		, m_dataType		(GL_NONE)
   1644 		, m_subX			(subX)
   1645 		, m_subY			(subY)
   1646 		, m_subW			(subW)
   1647 		, m_subH			(subH)
   1648 		, m_alignment		(alignment)
   1649 	{
   1650 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1651 		m_format	= fmt.format;
   1652 		m_dataType	= fmt.dataType;
   1653 	}
   1654 
   1655 protected:
   1656 	void createTexture (void)
   1657 	{
   1658 		deUint32			tex			= 0;
   1659 		vector<deUint8>		data;
   1660 
   1661 		glGenTextures(1, &tex);
   1662 		glBindTexture(GL_TEXTURE_2D, tex);
   1663 
   1664 		// Specify base level.
   1665 		data.resize(m_texFormat.getPixelSize()*m_width*m_height);
   1666 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
   1667 
   1668 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1669 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, m_format, m_dataType, &data[0]);
   1670 
   1671 		// Re-specify subrectangle.
   1672 		int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
   1673 		data.resize(rowPitch*m_subH);
   1674 		tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
   1675 
   1676 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
   1677 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
   1678 	}
   1679 
   1680 	deUint32	m_internalFormat;
   1681 	deUint32	m_format;
   1682 	deUint32	m_dataType;
   1683 	int			m_subX;
   1684 	int			m_subY;
   1685 	int			m_subW;
   1686 	int			m_subH;
   1687 	int			m_alignment;
   1688 };
   1689 
   1690 // TexSubImage2D() unpack alignment with cubemap texture
   1691 class TexSubImageCubeAlignCase : public TextureCubeSpecCase
   1692 {
   1693 public:
   1694 	TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size, int subX, int subY, int subW, int subH, int alignment)
   1695 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, 1)
   1696 		, m_internalFormat		(format)
   1697 		, m_format				(format)
   1698 		, m_dataType			(dataType)
   1699 		, m_subX				(subX)
   1700 		, m_subY				(subY)
   1701 		, m_subW				(subW)
   1702 		, m_subH				(subH)
   1703 		, m_alignment			(alignment)
   1704 	{
   1705 	}
   1706 
   1707 	TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int alignment)
   1708 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   1709 		, m_internalFormat		(internalFormat)
   1710 		, m_format				(GL_NONE)
   1711 		, m_dataType			(GL_NONE)
   1712 		, m_subX				(subX)
   1713 		, m_subY				(subY)
   1714 		, m_subW				(subW)
   1715 		, m_subH				(subH)
   1716 		, m_alignment			(alignment)
   1717 	{
   1718 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1719 		m_format	= fmt.format;
   1720 		m_dataType	= fmt.dataType;
   1721 	}
   1722 
   1723 protected:
   1724 	void createTexture (void)
   1725 	{
   1726 		deUint32			tex			= 0;
   1727 		vector<deUint8>		data;
   1728 
   1729 		glGenTextures(1, &tex);
   1730 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1731 
   1732 		// Specify base level.
   1733 		data.resize(m_texFormat.getPixelSize()*m_size*m_size);
   1734 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
   1735 
   1736 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1737 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   1738 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, m_format, m_dataType, &data[0]);
   1739 
   1740 		// Re-specify subrectangle.
   1741 		int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
   1742 		data.resize(rowPitch*m_subH);
   1743 		tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));
   1744 
   1745 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
   1746 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   1747 			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
   1748 	}
   1749 
   1750 	deUint32	m_internalFormat;
   1751 	deUint32	m_format;
   1752 	deUint32	m_dataType;
   1753 	int			m_subX;
   1754 	int			m_subY;
   1755 	int			m_subW;
   1756 	int			m_subH;
   1757 	int			m_alignment;
   1758 };
   1759 
   1760 // TexSubImage3D() unpack parameters case.
   1761 class TexSubImage3DParamsCase : public Texture3DSpecCase
   1762 {
   1763 public:
   1764 	TexSubImage3DParamsCase (Context&		context,
   1765 							 const char*	name,
   1766 							 const char*	desc,
   1767 							 deUint32		internalFormat,
   1768 							 int			width,
   1769 							 int			height,
   1770 							 int			depth,
   1771 							 int			subX,
   1772 							 int			subY,
   1773 							 int			subZ,
   1774 							 int			subW,
   1775 							 int			subH,
   1776 							 int			subD,
   1777 							 int			imageHeight,
   1778 							 int			rowLength,
   1779 							 int			skipImages,
   1780 							 int			skipRows,
   1781 							 int			skipPixels,
   1782 							 int			alignment)
   1783 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   1784 		, m_internalFormat	(internalFormat)
   1785 		, m_subX			(subX)
   1786 		, m_subY			(subY)
   1787 		, m_subZ			(subZ)
   1788 		, m_subW			(subW)
   1789 		, m_subH			(subH)
   1790 		, m_subD			(subD)
   1791 		, m_imageHeight		(imageHeight)
   1792 		, m_rowLength		(rowLength)
   1793 		, m_skipImages		(skipImages)
   1794 		, m_skipRows		(skipRows)
   1795 		, m_skipPixels		(skipPixels)
   1796 		, m_alignment		(alignment)
   1797 	{
   1798 	}
   1799 
   1800 protected:
   1801 	void createTexture (void)
   1802 	{
   1803 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1804 		int						pixelSize		= m_texFormat.getPixelSize();
   1805 		deUint32				tex				= 0;
   1806 		vector<deUint8>			data;
   1807 
   1808 		DE_ASSERT(m_numLevels == 1);
   1809 
   1810 		glGenTextures(1, &tex);
   1811 		glBindTexture(GL_TEXTURE_3D, tex);
   1812 
   1813 		// Fill with gradient.
   1814 		{
   1815 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   1816 			int		slicePitch		= rowPitch*m_height;
   1817 
   1818 			data.resize(slicePitch*m_depth);
   1819 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1820 		}
   1821 
   1822 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1823 
   1824 		// Fill data with grid.
   1825 		{
   1826 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   1827 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   1828 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   1829 			int		slicePitch		= imageHeight*rowPitch;
   1830 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1831 			Vec4	cBias			= m_texFormatInfo.valueMin;
   1832 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1833 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1834 
   1835 			data.resize(slicePitch*(m_depth+m_skipImages));
   1836 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1837 		}
   1838 
   1839 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   1840 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1841 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   1842 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1843 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1844 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1845 		glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, &data[0]);
   1846 	}
   1847 
   1848 	deUint32	m_internalFormat;
   1849 	int			m_subX;
   1850 	int			m_subY;
   1851 	int			m_subZ;
   1852 	int			m_subW;
   1853 	int			m_subH;
   1854 	int			m_subD;
   1855 	int			m_imageHeight;
   1856 	int			m_rowLength;
   1857 	int			m_skipImages;
   1858 	int			m_skipRows;
   1859 	int			m_skipPixels;
   1860 	int			m_alignment;
   1861 };
   1862 
   1863 // Basic CopyTexImage2D() with 2D texture usage
   1864 class BasicCopyTexImage2DCase : public Texture2DSpecCase
   1865 {
   1866 public:
   1867 	BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1868 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), width, height, maxLevelCount(width, height))
   1869 		, m_internalFormat	(internalFormat)
   1870 	{
   1871 	}
   1872 
   1873 protected:
   1874 	void createTexture (void)
   1875 	{
   1876 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1877 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1878 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1879 		tcu::TextureFormat			fmt				= mapGLUnsizedInternalFormat(m_internalFormat);
   1880 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1881 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1882 		deUint32					tex				= 0;
   1883 		de::Random					rnd				(deStringHash(getName()));
   1884 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1885 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1886 
   1887 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1888 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1889 
   1890 		// Fill render target with gradient.
   1891 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   1892 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   1893 
   1894 		glGenTextures(1, &tex);
   1895 		glBindTexture(GL_TEXTURE_2D, tex);
   1896 
   1897 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1898 		{
   1899 			int		levelW		= de::max(1, m_width >> ndx);
   1900 			int		levelH		= de::max(1, m_height >> ndx);
   1901 			int		x			= rnd.getInt(0, getWidth()	- levelW);
   1902 			int		y			= rnd.getInt(0, getHeight()	- levelH);
   1903 
   1904 			glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
   1905 		}
   1906 	}
   1907 
   1908 	deUint32 m_internalFormat;
   1909 };
   1910 
   1911 // Basic CopyTexImage2D() with cubemap usage
   1912 class BasicCopyTexImageCubeCase : public TextureCubeSpecCase
   1913 {
   1914 public:
   1915 	BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1916 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), size, deLog2Floor32(size)+1)
   1917 		, m_internalFormat		(internalFormat)
   1918 	{
   1919 	}
   1920 
   1921 protected:
   1922 	void createTexture (void)
   1923 	{
   1924 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1925 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1926 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1927 		tcu::TextureFormat			fmt				= mapGLUnsizedInternalFormat(m_internalFormat);
   1928 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1929 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1930 		deUint32					tex				= 0;
   1931 		de::Random					rnd				(deStringHash(getName()));
   1932 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1933 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1934 
   1935 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1936 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1937 
   1938 		// Fill render target with gradient.
   1939 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   1940 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   1941 
   1942 		glGenTextures(1, &tex);
   1943 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1944 
   1945 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1946 		{
   1947 			int levelSize = de::max(1, m_size >> ndx);
   1948 
   1949 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1950 			{
   1951 				int x = rnd.getInt(0, getWidth()	- levelSize);
   1952 				int y = rnd.getInt(0, getHeight()	- levelSize);
   1953 
   1954 				glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelSize, levelSize, 0);
   1955 			}
   1956 		}
   1957 	}
   1958 
   1959 	deUint32 m_internalFormat;
   1960 };
   1961 
   1962 // Basic CopyTexSubImage2D() with 2D texture usage
   1963 class BasicCopyTexSubImage2DCase : public Texture2DSpecCase
   1964 {
   1965 public:
   1966 	BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1967 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1968 		, m_format			(format)
   1969 		, m_dataType		(dataType)
   1970 	{
   1971 	}
   1972 
   1973 protected:
   1974 	void createTexture (void)
   1975 	{
   1976 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1977 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1978 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1979 		tcu::TextureFormat			fmt				= glu::mapGLTransferFormat(m_format, m_dataType);
   1980 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1981 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1982 		deUint32					tex				= 0;
   1983 		tcu::TextureLevel			data			(fmt);
   1984 		de::Random					rnd				(deStringHash(getName()));
   1985 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1986 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1987 
   1988 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1989 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1990 
   1991 		glGenTextures(1, &tex);
   1992 		glBindTexture(GL_TEXTURE_2D, tex);
   1993 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1994 
   1995 		// First specify full texture.
   1996 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1997 		{
   1998 			int		levelW		= de::max(1, m_width >> ndx);
   1999 			int		levelH		= de::max(1, m_height >> ndx);
   2000 
   2001 			Vec4	colorA		= randomVector<4>(rnd);
   2002 			Vec4	colorB		= randomVector<4>(rnd);
   2003 			int		cellSize	= rnd.getInt(2, 16);
   2004 
   2005 			data.setSize(levelW, levelH);
   2006 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   2007 
   2008 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   2009 		}
   2010 
   2011 		// Fill render target with gradient.
   2012 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   2013 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   2014 
   2015 		// Re-specify parts of each level.
   2016 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2017 		{
   2018 			int		levelW		= de::max(1, m_width >> ndx);
   2019 			int		levelH		= de::max(1, m_height >> ndx);
   2020 
   2021 			int		w			= rnd.getInt(1, levelW);
   2022 			int		h			= rnd.getInt(1, levelH);
   2023 			int		xo			= rnd.getInt(0, levelW-w);
   2024 			int		yo			= rnd.getInt(0, levelH-h);
   2025 
   2026 			int		x			= rnd.getInt(0, getWidth() - w);
   2027 			int		y			= rnd.getInt(0, getHeight() - h);
   2028 
   2029 			glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
   2030 		}
   2031 	}
   2032 
   2033 	deUint32	m_format;
   2034 	deUint32	m_dataType;
   2035 };
   2036 
   2037 // Basic CopyTexSubImage2D() with cubemap usage
   2038 class BasicCopyTexSubImageCubeCase : public TextureCubeSpecCase
   2039 {
   2040 public:
   2041 	BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   2042 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   2043 		, m_format				(format)
   2044 		, m_dataType			(dataType)
   2045 	{
   2046 	}
   2047 
   2048 protected:
   2049 	void createTexture (void)
   2050 	{
   2051 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   2052 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   2053 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   2054 		tcu::TextureFormat			fmt				= glu::mapGLTransferFormat(m_format, m_dataType);
   2055 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   2056 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   2057 		deUint32					tex				= 0;
   2058 		tcu::TextureLevel			data			(fmt);
   2059 		de::Random					rnd				(deStringHash(getName()));
   2060 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   2061 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   2062 
   2063 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   2064 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   2065 
   2066 		glGenTextures(1, &tex);
   2067 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2068 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2069 
   2070 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2071 		{
   2072 			int levelSize = de::max(1, m_size >> ndx);
   2073 
   2074 			data.setSize(levelSize, levelSize);
   2075 
   2076 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2077 			{
   2078 				Vec4	colorA		= randomVector<4>(rnd);
   2079 				Vec4	colorB		= randomVector<4>(rnd);
   2080 				int		cellSize	= rnd.getInt(2, 16);
   2081 
   2082 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   2083 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   2084 			}
   2085 		}
   2086 
   2087 		// Fill render target with gradient.
   2088 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   2089 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   2090 
   2091 		// Re-specify parts of each face and level.
   2092 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2093 		{
   2094 			int levelSize = de::max(1, m_size >> ndx);
   2095 
   2096 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2097 			{
   2098 				int		w			= rnd.getInt(1, levelSize);
   2099 				int		h			= rnd.getInt(1, levelSize);
   2100 				int		xo			= rnd.getInt(0, levelSize-w);
   2101 				int		yo			= rnd.getInt(0, levelSize-h);
   2102 
   2103 				int		x			= rnd.getInt(0, getWidth() - w);
   2104 				int		y			= rnd.getInt(0, getHeight() - h);
   2105 
   2106 				glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
   2107 			}
   2108 		}
   2109 	}
   2110 
   2111 	deUint32	m_format;
   2112 	deUint32	m_dataType;
   2113 };
   2114 
   2115 // Basic glTexStorage2D() with 2D texture usage
   2116 class BasicTexStorage2DCase : public Texture2DSpecCase
   2117 {
   2118 public:
   2119 	BasicTexStorage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels)
   2120 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
   2121 		, m_internalFormat	(internalFormat)
   2122 	{
   2123 	}
   2124 
   2125 protected:
   2126 	void createTexture (void)
   2127 	{
   2128 		tcu::TextureFormat		fmt				= glu::mapGLInternalFormat(m_internalFormat);
   2129 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(fmt);
   2130 		deUint32				tex				= 0;
   2131 		tcu::TextureLevel		levelData		(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2132 		de::Random				rnd				(deStringHash(getName()));
   2133 
   2134 		glGenTextures(1, &tex);
   2135 		glBindTexture(GL_TEXTURE_2D, tex);
   2136 		glTexStorage2D(GL_TEXTURE_2D, m_numLevels, m_internalFormat, m_width, m_height);
   2137 
   2138 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2139 
   2140 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2141 		{
   2142 			int		levelW		= de::max(1, m_width >> ndx);
   2143 			int		levelH		= de::max(1, m_height >> ndx);
   2144 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2145 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2146 
   2147 			levelData.setSize(levelW, levelH);
   2148 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2149 
   2150 			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2151 		}
   2152 	}
   2153 
   2154 	deUint32 m_internalFormat;
   2155 };
   2156 
   2157 // Basic glTexStorage2D() with cubemap usage
   2158 class BasicTexStorageCubeCase : public TextureCubeSpecCase
   2159 {
   2160 public:
   2161 	BasicTexStorageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels)
   2162 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
   2163 		, m_internalFormat		(internalFormat)
   2164 	{
   2165 	}
   2166 
   2167 protected:
   2168 	void createTexture (void)
   2169 	{
   2170 		tcu::TextureFormat		fmt				= glu::mapGLInternalFormat(m_internalFormat);
   2171 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(fmt);
   2172 		deUint32				tex				= 0;
   2173 		tcu::TextureLevel		levelData		(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2174 		de::Random				rnd				(deStringHash(getName()));
   2175 
   2176 		glGenTextures(1, &tex);
   2177 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2178 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, m_numLevels, m_internalFormat, m_size, m_size);
   2179 
   2180 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2181 
   2182 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2183 		{
   2184 			int levelSize = de::max(1, m_size >> ndx);
   2185 
   2186 			levelData.setSize(levelSize, levelSize);
   2187 
   2188 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2189 			{
   2190 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2191 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2192 
   2193 				tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2194 
   2195 				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2196 			}
   2197 		}
   2198 	}
   2199 
   2200 	deUint32 m_internalFormat;
   2201 };
   2202 
   2203 // Basic glTexStorage3D() with 2D array texture usage
   2204 class BasicTexStorage2DArrayCase : public Texture2DArraySpecCase
   2205 {
   2206 public:
   2207 	BasicTexStorage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers, int numLevels)
   2208 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, numLevels)
   2209 		, m_internalFormat			(internalFormat)
   2210 	{
   2211 	}
   2212 
   2213 protected:
   2214 	void createTexture (void)
   2215 	{
   2216 		deUint32				tex			= 0;
   2217 		de::Random				rnd			(deStringHash(getName()));
   2218 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
   2219 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2220 
   2221 		glGenTextures	(1, &tex);
   2222 		glBindTexture	(GL_TEXTURE_2D_ARRAY, tex);
   2223 		glTexStorage3D	(GL_TEXTURE_2D_ARRAY, m_numLevels, m_internalFormat, m_width, m_height, m_numLayers);
   2224 
   2225 		glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
   2226 
   2227 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2228 		{
   2229 			int		levelW		= de::max(1, m_width	>> ndx);
   2230 			int		levelH		= de::max(1, m_height	>> ndx);
   2231 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2232 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2233 
   2234 			levelData.setSize(levelW, levelH, m_numLayers);
   2235 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2236 
   2237 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH, m_numLayers, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2238 		}
   2239 	}
   2240 
   2241 	deUint32 m_internalFormat;
   2242 };
   2243 
   2244 // Basic TexStorage3D() with 3D texture usage
   2245 class BasicTexStorage3DCase : public Texture3DSpecCase
   2246 {
   2247 public:
   2248 	BasicTexStorage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int numLevels)
   2249 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, numLevels)
   2250 		, m_internalFormat	(internalFormat)
   2251 	{
   2252 	}
   2253 
   2254 protected:
   2255 	void createTexture (void)
   2256 	{
   2257 		deUint32				tex			= 0;
   2258 		de::Random				rnd			(deStringHash(getName()));
   2259 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
   2260 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2261 
   2262 		glGenTextures	(1, &tex);
   2263 		glBindTexture	(GL_TEXTURE_3D, tex);
   2264 		glTexStorage3D	(GL_TEXTURE_3D, m_numLevels, m_internalFormat, m_width, m_height, m_depth);
   2265 
   2266 		glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
   2267 
   2268 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2269 		{
   2270 			int		levelW		= de::max(1, m_width	>> ndx);
   2271 			int		levelH		= de::max(1, m_height	>> ndx);
   2272 			int		levelD		= de::max(1, m_depth	>> ndx);
   2273 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2274 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2275 
   2276 			levelData.setSize(levelW, levelH, levelD);
   2277 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2278 
   2279 			glTexSubImage3D(GL_TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH, levelD, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2280 		}
   2281 	}
   2282 
   2283 	deUint32 m_internalFormat;
   2284 };
   2285 
   2286 // Pixel buffer object cases.
   2287 
   2288 // TexImage2D() from pixel buffer object.
   2289 class TexImage2DBufferCase : public Texture2DSpecCase
   2290 {
   2291 public:
   2292 	TexImage2DBufferCase (Context&		context,
   2293 						  const char*	name,
   2294 						  const char*	desc,
   2295 						  deUint32		internalFormat,
   2296 						  int			width,
   2297 						  int			height,
   2298 						  int			rowLength,
   2299 						  int			skipRows,
   2300 						  int			skipPixels,
   2301 						  int			alignment,
   2302 						  int			offset)
   2303 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   2304 		, m_internalFormat	(internalFormat)
   2305 		, m_rowLength		(rowLength)
   2306 		, m_skipRows		(skipRows)
   2307 		, m_skipPixels		(skipPixels)
   2308 		, m_alignment		(alignment)
   2309 		, m_offset			(offset)
   2310 	{
   2311 	}
   2312 
   2313 protected:
   2314 	void createTexture (void)
   2315 	{
   2316 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2317 		int						pixelSize		= m_texFormat.getPixelSize();
   2318 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width + m_skipPixels;
   2319 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2320 		int						height			= m_height + m_skipRows;
   2321 		deUint32				buf				= 0;
   2322 		deUint32				tex				= 0;
   2323 		vector<deUint8>			data;
   2324 
   2325 		DE_ASSERT(m_numLevels == 1);
   2326 
   2327 		// Fill data with grid.
   2328 		data.resize(rowPitch*height + m_offset);
   2329 		{
   2330 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2331 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2332 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2333 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2334 
   2335 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2336 		}
   2337 
   2338 		// Create buffer and upload.
   2339 		glGenBuffers(1, &buf);
   2340 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2341 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2342 
   2343 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2344 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2345 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2346 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2347 
   2348 		glGenTextures(1, &tex);
   2349 		glBindTexture(GL_TEXTURE_2D, tex);
   2350 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2351 	}
   2352 
   2353 	deUint32	m_internalFormat;
   2354 	int			m_rowLength;
   2355 	int			m_skipRows;
   2356 	int			m_skipPixels;
   2357 	int			m_alignment;
   2358 	int			m_offset;
   2359 };
   2360 
   2361 // TexImage2D() cubemap from pixel buffer object case
   2362 class TexImageCubeBufferCase : public TextureCubeSpecCase
   2363 {
   2364 public:
   2365 	TexImageCubeBufferCase (Context&	context,
   2366 							const char*	name,
   2367 							const char*	desc,
   2368 							deUint32	internalFormat,
   2369 							int			size,
   2370 							int			rowLength,
   2371 							int			skipRows,
   2372 							int			skipPixels,
   2373 							int			alignment,
   2374 							int			offset)
   2375 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   2376 		, m_internalFormat		(internalFormat)
   2377 		, m_rowLength			(rowLength)
   2378 		, m_skipRows			(skipRows)
   2379 		, m_skipPixels			(skipPixels)
   2380 		, m_alignment			(alignment)
   2381 		, m_offset				(offset)
   2382 	{
   2383 	}
   2384 
   2385 protected:
   2386 	void createTexture (void)
   2387 	{
   2388 		de::Random					rnd			(deStringHash(getName()));
   2389 		deUint32					tex			= 0;
   2390 		glu::TransferFormat			fmt			= glu::getTransferFormat(m_texFormat);
   2391 		const int					pixelSize	= m_texFormat.getPixelSize();
   2392 		const int					rowLength	= m_rowLength > 0 ? m_rowLength : m_size + m_skipPixels;
   2393 		const int					rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2394 		const int					height		= m_size + m_skipRows;
   2395 		vector<vector<deUint8> >	data		(DE_LENGTH_OF_ARRAY(s_cubeMapFaces));
   2396 
   2397 		DE_ASSERT(m_numLevels == 1);
   2398 
   2399 		glGenTextures(1, &tex);
   2400 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2401 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2402 
   2403 		for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2404 		{
   2405 			deUint32 buf = 0;
   2406 
   2407 			{
   2408 				const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2409 				const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2410 
   2411 				data[face].resize(rowPitch*height + m_offset);
   2412 				tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, rowPitch, 0, &data[face][0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), gMin, gMax);
   2413 			}
   2414 
   2415 			// Create buffer and upload.
   2416 			glGenBuffers(1, &buf);
   2417 			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2418 			glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data[face].size(), &data[face][0], GL_STATIC_DRAW);
   2419 
   2420 			glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2421 			glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2422 			glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2423 			glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2424 
   2425 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, fmt.format, fmt.dataType, (const void*)(deUintptr)m_offset);
   2426 		}
   2427 	}
   2428 
   2429 	deUint32	m_internalFormat;
   2430 	int			m_rowLength;
   2431 	int			m_skipRows;
   2432 	int			m_skipPixels;
   2433 	int			m_alignment;
   2434 	int			m_offset;
   2435 };
   2436 
   2437 // TexImage3D() 2D array from pixel buffer object.
   2438 class TexImage2DArrayBufferCase : public Texture2DArraySpecCase
   2439 {
   2440 public:
   2441 	TexImage2DArrayBufferCase (Context&		context,
   2442 							   const char*	name,
   2443 							   const char*	desc,
   2444 							   deUint32		internalFormat,
   2445 							   int			width,
   2446 							   int			height,
   2447 							   int			depth,
   2448 							   int			imageHeight,
   2449 							   int			rowLength,
   2450 							   int			skipImages,
   2451 							   int			skipRows,
   2452 							   int			skipPixels,
   2453 							   int			alignment,
   2454 							   int			offset)
   2455 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2456 		, m_internalFormat			(internalFormat)
   2457 		, m_imageHeight				(imageHeight)
   2458 		, m_rowLength				(rowLength)
   2459 		, m_skipImages				(skipImages)
   2460 		, m_skipRows				(skipRows)
   2461 		, m_skipPixels				(skipPixels)
   2462 		, m_alignment				(alignment)
   2463 		, m_offset					(offset)
   2464 	{
   2465 	}
   2466 
   2467 protected:
   2468 	void createTexture (void)
   2469 	{
   2470 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2471 		int						pixelSize		= m_texFormat.getPixelSize();
   2472 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   2473 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2474 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   2475 		int						slicePitch		= imageHeight*rowPitch;
   2476 		deUint32				tex				= 0;
   2477 		deUint32				buf				= 0;
   2478 		vector<deUint8>			data;
   2479 
   2480 		DE_ASSERT(m_numLevels == 1);
   2481 
   2482 		// Fill data with grid.
   2483 		data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
   2484 		{
   2485 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2486 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2487 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2488 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2489 
   2490 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2491 		}
   2492 
   2493 		glGenBuffers(1, &buf);
   2494 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2495 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2496 
   2497 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2498 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2499 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2500 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2501 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2502 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2503 
   2504 		glGenTextures(1, &tex);
   2505 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   2506 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2507 	}
   2508 
   2509 	deUint32	m_internalFormat;
   2510 	int			m_imageHeight;
   2511 	int			m_rowLength;
   2512 	int			m_skipImages;
   2513 	int			m_skipRows;
   2514 	int			m_skipPixels;
   2515 	int			m_alignment;
   2516 	int			m_offset;
   2517 };
   2518 
   2519 // TexImage3D() from pixel buffer object.
   2520 class TexImage3DBufferCase : public Texture3DSpecCase
   2521 {
   2522 public:
   2523 	TexImage3DBufferCase (Context&		context,
   2524 						  const char*	name,
   2525 						  const char*	desc,
   2526 						  deUint32		internalFormat,
   2527 						  int			width,
   2528 						  int			height,
   2529 						  int			depth,
   2530 						  int			imageHeight,
   2531 						  int			rowLength,
   2532 						  int			skipImages,
   2533 						  int			skipRows,
   2534 						  int			skipPixels,
   2535 						  int			alignment,
   2536 						  int			offset)
   2537 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2538 		, m_internalFormat	(internalFormat)
   2539 		, m_imageHeight		(imageHeight)
   2540 		, m_rowLength		(rowLength)
   2541 		, m_skipImages		(skipImages)
   2542 		, m_skipRows		(skipRows)
   2543 		, m_skipPixels		(skipPixels)
   2544 		, m_alignment		(alignment)
   2545 		, m_offset			(offset)
   2546 	{
   2547 	}
   2548 
   2549 protected:
   2550 	void createTexture (void)
   2551 	{
   2552 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2553 		int						pixelSize		= m_texFormat.getPixelSize();
   2554 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   2555 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2556 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   2557 		int						slicePitch		= imageHeight*rowPitch;
   2558 		deUint32				tex				= 0;
   2559 		deUint32				buf				= 0;
   2560 		vector<deUint8>			data;
   2561 
   2562 		DE_ASSERT(m_numLevels == 1);
   2563 
   2564 		// Fill data with grid.
   2565 		data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
   2566 		{
   2567 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2568 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2569 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2570 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2571 
   2572 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2573 		}
   2574 
   2575 		glGenBuffers(1, &buf);
   2576 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2577 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2578 
   2579 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2580 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2581 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2582 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2583 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2584 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2585 
   2586 		glGenTextures(1, &tex);
   2587 		glBindTexture(GL_TEXTURE_3D, tex);
   2588 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2589 	}
   2590 
   2591 	deUint32	m_internalFormat;
   2592 	int			m_imageHeight;
   2593 	int			m_rowLength;
   2594 	int			m_skipImages;
   2595 	int			m_skipRows;
   2596 	int			m_skipPixels;
   2597 	int			m_alignment;
   2598 	int			m_offset;
   2599 };
   2600 
   2601 // TexSubImage2D() PBO case.
   2602 class TexSubImage2DBufferCase : public Texture2DSpecCase
   2603 {
   2604 public:
   2605 	TexSubImage2DBufferCase (Context&		context,
   2606 							 const char*	name,
   2607 							 const char*	desc,
   2608 							 deUint32		internalFormat,
   2609 							 int			width,
   2610 							 int			height,
   2611 							 int			subX,
   2612 							 int			subY,
   2613 							 int			subW,
   2614 							 int			subH,
   2615 							 int			rowLength,
   2616 							 int			skipRows,
   2617 							 int			skipPixels,
   2618 							 int			alignment,
   2619 							 int			offset)
   2620 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   2621 		, m_internalFormat	(internalFormat)
   2622 		, m_subX			(subX)
   2623 		, m_subY			(subY)
   2624 		, m_subW			(subW)
   2625 		, m_subH			(subH)
   2626 		, m_rowLength		(rowLength)
   2627 		, m_skipRows		(skipRows)
   2628 		, m_skipPixels		(skipPixels)
   2629 		, m_alignment		(alignment)
   2630 		, m_offset			(offset)
   2631 	{
   2632 	}
   2633 
   2634 protected:
   2635 	void createTexture (void)
   2636 	{
   2637 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2638 		int						pixelSize		= m_texFormat.getPixelSize();
   2639 		deUint32				tex				= 0;
   2640 		deUint32				buf				= 0;
   2641 		vector<deUint8>			data;
   2642 
   2643 		DE_ASSERT(m_numLevels == 1);
   2644 
   2645 		glGenTextures(1, &tex);
   2646 		glBindTexture(GL_TEXTURE_2D, tex);
   2647 
   2648 		// First fill texture with gradient.
   2649 		data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
   2650 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, deAlign32(m_width*pixelSize, 4), 0, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2651 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2652 
   2653 		// Fill data with grid.
   2654 		{
   2655 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   2656 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2657 			int		height		= m_subH + m_skipRows;
   2658 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2659 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2660 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2661 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2662 
   2663 			data.resize(rowPitch*height + m_offset);
   2664 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2665 		}
   2666 
   2667 		glGenBuffers(1, &buf);
   2668 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2669 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2670 
   2671 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2672 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2673 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2674 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2675 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2676 	}
   2677 
   2678 	deUint32	m_internalFormat;
   2679 	int			m_subX;
   2680 	int			m_subY;
   2681 	int			m_subW;
   2682 	int			m_subH;
   2683 	int			m_rowLength;
   2684 	int			m_skipRows;
   2685 	int			m_skipPixels;
   2686 	int			m_alignment;
   2687 	int			m_offset;
   2688 };
   2689 
   2690 // TexSubImage2D() cubemap PBO case.
   2691 class TexSubImageCubeBufferCase : public TextureCubeSpecCase
   2692 {
   2693 public:
   2694 	TexSubImageCubeBufferCase	(Context&		context,
   2695 								 const char*	name,
   2696 								 const char*	desc,
   2697 								 deUint32		internalFormat,
   2698 								 int			size,
   2699 								 int			subX,
   2700 								 int			subY,
   2701 								 int			subW,
   2702 								 int			subH,
   2703 								 int			rowLength,
   2704 								 int			skipRows,
   2705 								 int			skipPixels,
   2706 								 int			alignment,
   2707 								 int			offset)
   2708 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   2709 		, m_internalFormat		(internalFormat)
   2710 		, m_subX				(subX)
   2711 		, m_subY				(subY)
   2712 		, m_subW				(subW)
   2713 		, m_subH				(subH)
   2714 		, m_rowLength			(rowLength)
   2715 		, m_skipRows			(skipRows)
   2716 		, m_skipPixels			(skipPixels)
   2717 		, m_alignment			(alignment)
   2718 		, m_offset				(offset)
   2719 	{
   2720 	}
   2721 
   2722 protected:
   2723 	void createTexture (void)
   2724 	{
   2725 		de::Random				rnd				(deStringHash(getName()));
   2726 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2727 		int						pixelSize		= m_texFormat.getPixelSize();
   2728 		deUint32				tex				= 0;
   2729 		deUint32				buf				= 0;
   2730 		vector<deUint8>			data;
   2731 
   2732 		DE_ASSERT(m_numLevels == 1);
   2733 
   2734 		glGenTextures(1, &tex);
   2735 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2736 
   2737 		// Fill faces with different gradients.
   2738 
   2739 		data.resize(deAlign32(m_size*pixelSize, 4)*m_size);
   2740 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2741 
   2742 		for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2743 		{
   2744 			const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2745 			const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2746 
   2747 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, deAlign32(m_size*pixelSize, 4), 0, &data[0]), gMin, gMax);
   2748 
   2749 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2750 		}
   2751 
   2752 		// Fill data with grid.
   2753 		{
   2754 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   2755 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2756 			int		height		= m_subH + m_skipRows;
   2757 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2758 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2759 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2760 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2761 
   2762 			data.resize(rowPitch*height + m_offset);
   2763 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2764 		}
   2765 
   2766 		glGenBuffers(1, &buf);
   2767 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2768 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2769 
   2770 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2771 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2772 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2773 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2774 
   2775 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   2776 			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2777 	}
   2778 
   2779 	deUint32	m_internalFormat;
   2780 	int			m_subX;
   2781 	int			m_subY;
   2782 	int			m_subW;
   2783 	int			m_subH;
   2784 	int			m_rowLength;
   2785 	int			m_skipRows;
   2786 	int			m_skipPixels;
   2787 	int			m_alignment;
   2788 	int			m_offset;
   2789 };
   2790 
   2791 // TexSubImage3D() 2D array PBO case.
   2792 class TexSubImage2DArrayBufferCase : public Texture2DArraySpecCase
   2793 {
   2794 public:
   2795 	TexSubImage2DArrayBufferCase (Context&		context,
   2796 								 const char*	name,
   2797 								 const char*	desc,
   2798 								 deUint32		internalFormat,
   2799 								 int			width,
   2800 								 int			height,
   2801 								 int			depth,
   2802 								 int			subX,
   2803 								 int			subY,
   2804 								 int			subZ,
   2805 								 int			subW,
   2806 								 int			subH,
   2807 								 int			subD,
   2808 								 int			imageHeight,
   2809 								 int			rowLength,
   2810 								 int			skipImages,
   2811 								 int			skipRows,
   2812 								 int			skipPixels,
   2813 								 int			alignment,
   2814 								 int			offset)
   2815 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2816 		, m_internalFormat			(internalFormat)
   2817 		, m_subX					(subX)
   2818 		, m_subY					(subY)
   2819 		, m_subZ					(subZ)
   2820 		, m_subW					(subW)
   2821 		, m_subH					(subH)
   2822 		, m_subD					(subD)
   2823 		, m_imageHeight				(imageHeight)
   2824 		, m_rowLength				(rowLength)
   2825 		, m_skipImages				(skipImages)
   2826 		, m_skipRows				(skipRows)
   2827 		, m_skipPixels				(skipPixels)
   2828 		, m_alignment				(alignment)
   2829 		, m_offset					(offset)
   2830 	{
   2831 	}
   2832 
   2833 protected:
   2834 	void createTexture (void)
   2835 	{
   2836 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2837 		int						pixelSize		= m_texFormat.getPixelSize();
   2838 		deUint32				tex				= 0;
   2839 		deUint32				buf				= 0;
   2840 		vector<deUint8>			data;
   2841 
   2842 		DE_ASSERT(m_numLevels == 1);
   2843 
   2844 		glGenTextures(1, &tex);
   2845 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   2846 
   2847 		// Fill with gradient.
   2848 		{
   2849 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   2850 			int		slicePitch		= rowPitch*m_height;
   2851 
   2852 			data.resize(slicePitch*m_numLayers);
   2853 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2854 		}
   2855 
   2856 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2857 
   2858 		// Fill data with grid.
   2859 		{
   2860 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   2861 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2862 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   2863 			int		slicePitch		= imageHeight*rowPitch;
   2864 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2865 			Vec4	cBias			= m_texFormatInfo.valueMin;
   2866 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2867 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2868 
   2869 			data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
   2870 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2871 		}
   2872 
   2873 		glGenBuffers(1, &buf);
   2874 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2875 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2876 
   2877 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2878 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2879 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2880 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2881 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2882 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2883 		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
   2884 	}
   2885 
   2886 	deUint32	m_internalFormat;
   2887 	int			m_subX;
   2888 	int			m_subY;
   2889 	int			m_subZ;
   2890 	int			m_subW;
   2891 	int			m_subH;
   2892 	int			m_subD;
   2893 	int			m_imageHeight;
   2894 	int			m_rowLength;
   2895 	int			m_skipImages;
   2896 	int			m_skipRows;
   2897 	int			m_skipPixels;
   2898 	int			m_alignment;
   2899 	int			m_offset;
   2900 };
   2901 
   2902 // TexSubImage3D() PBO case.
   2903 class TexSubImage3DBufferCase : public Texture3DSpecCase
   2904 {
   2905 public:
   2906 	TexSubImage3DBufferCase (Context&		context,
   2907 							 const char*	name,
   2908 							 const char*	desc,
   2909 							 deUint32		internalFormat,
   2910 							 int			width,
   2911 							 int			height,
   2912 							 int			depth,
   2913 							 int			subX,
   2914 							 int			subY,
   2915 							 int			subZ,
   2916 							 int			subW,
   2917 							 int			subH,
   2918 							 int			subD,
   2919 							 int			imageHeight,
   2920 							 int			rowLength,
   2921 							 int			skipImages,
   2922 							 int			skipRows,
   2923 							 int			skipPixels,
   2924 							 int			alignment,
   2925 							 int			offset)
   2926 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2927 		, m_internalFormat	(internalFormat)
   2928 		, m_subX			(subX)
   2929 		, m_subY			(subY)
   2930 		, m_subZ			(subZ)
   2931 		, m_subW			(subW)
   2932 		, m_subH			(subH)
   2933 		, m_subD			(subD)
   2934 		, m_imageHeight		(imageHeight)
   2935 		, m_rowLength		(rowLength)
   2936 		, m_skipImages		(skipImages)
   2937 		, m_skipRows		(skipRows)
   2938 		, m_skipPixels		(skipPixels)
   2939 		, m_alignment		(alignment)
   2940 		, m_offset			(offset)
   2941 	{
   2942 	}
   2943 
   2944 protected:
   2945 	void createTexture (void)
   2946 	{
   2947 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2948 		int						pixelSize		= m_texFormat.getPixelSize();
   2949 		deUint32				tex				= 0;
   2950 		deUint32				buf				= 0;
   2951 		vector<deUint8>			data;
   2952 
   2953 		DE_ASSERT(m_numLevels == 1);
   2954 
   2955 		glGenTextures(1, &tex);
   2956 		glBindTexture(GL_TEXTURE_3D, tex);
   2957 
   2958 		// Fill with gradient.
   2959 		{
   2960 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   2961 			int		slicePitch		= rowPitch*m_height;
   2962 
   2963 			data.resize(slicePitch*m_depth);
   2964 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2965 		}
   2966 
   2967 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2968 
   2969 		// Fill data with grid.
   2970 		{
   2971 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   2972 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2973 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   2974 			int		slicePitch		= imageHeight*rowPitch;
   2975 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2976 			Vec4	cBias			= m_texFormatInfo.valueMin;
   2977 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2978 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2979 
   2980 			data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
   2981 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
   2982 		}
   2983 
   2984 		glGenBuffers(1, &buf);
   2985 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2986 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2987 
   2988 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2989 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2990 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2991 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2992 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2993 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2994 		glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
   2995 	}
   2996 
   2997 	deUint32	m_internalFormat;
   2998 	int			m_subX;
   2999 	int			m_subY;
   3000 	int			m_subZ;
   3001 	int			m_subW;
   3002 	int			m_subH;
   3003 	int			m_subD;
   3004 	int			m_imageHeight;
   3005 	int			m_rowLength;
   3006 	int			m_skipImages;
   3007 	int			m_skipRows;
   3008 	int			m_skipPixels;
   3009 	int			m_alignment;
   3010 	int			m_offset;
   3011 };
   3012 
   3013 // TexImage2D() depth case.
   3014 class TexImage2DDepthCase : public Texture2DSpecCase
   3015 {
   3016 public:
   3017 	TexImage2DDepthCase (Context&		context,
   3018 						 const char*	name,
   3019 						 const char*	desc,
   3020 						 deUint32		internalFormat,
   3021 						 int			imageWidth,
   3022 						 int			imageHeight)
   3023 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
   3024 		, m_internalFormat	(internalFormat)
   3025 	{
   3026 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3027 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3028 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3029 	}
   3030 
   3031 	void createTexture (void)
   3032 	{
   3033 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3034 		deUint32			tex			= 0;
   3035 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3036 
   3037 		glGenTextures(1, &tex);
   3038 		glBindTexture(GL_TEXTURE_2D, tex);
   3039 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3040 		GLU_CHECK();
   3041 
   3042 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3043 		{
   3044 			const int   levelW		= de::max(1, m_width >> ndx);
   3045 			const int   levelH		= de::max(1, m_height >> ndx);
   3046 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3047 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3048 
   3049 			levelData.setSize(levelW, levelH);
   3050 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3051 
   3052 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3053 		}
   3054 	}
   3055 
   3056 	const deUint32 m_internalFormat;
   3057 };
   3058 
   3059 // TexImage3D() depth case.
   3060 class TexImage2DArrayDepthCase : public Texture2DArraySpecCase
   3061 {
   3062 public:
   3063 	TexImage2DArrayDepthCase (Context&		context,
   3064 							  const char*	name,
   3065 							  const char*	desc,
   3066 							  deUint32		internalFormat,
   3067 							  int			imageWidth,
   3068 							  int			imageHeight,
   3069 							  int			numLayers)
   3070 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
   3071 		, m_internalFormat		(internalFormat)
   3072 	{
   3073 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3074 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3075 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3076 	}
   3077 
   3078 	void createTexture (void)
   3079 	{
   3080 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3081 		deUint32			tex			= 0;
   3082 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3083 
   3084 		glGenTextures(1, &tex);
   3085 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3086 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3087 		GLU_CHECK();
   3088 
   3089 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3090 		{
   3091 			const int   levelW		= de::max(1, m_width >> ndx);
   3092 			const int   levelH		= de::max(1, m_height >> ndx);
   3093 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3094 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3095 
   3096 			levelData.setSize(levelW, levelH, m_numLayers);
   3097 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3098 
   3099 			glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3100 		}
   3101 	}
   3102 
   3103 	const deUint32 m_internalFormat;
   3104 };
   3105 
   3106 // TexSubImage2D() depth case.
   3107 class TexSubImage2DDepthCase : public Texture2DSpecCase
   3108 {
   3109 public:
   3110 	TexSubImage2DDepthCase (Context&	context,
   3111 							const char*	name,
   3112 							const char*	desc,
   3113 							deUint32	internalFormat,
   3114 							int			imageWidth,
   3115 							int			imageHeight)
   3116 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
   3117 		, m_internalFormat	(internalFormat)
   3118 	{
   3119 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3120 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3121 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3122 	}
   3123 
   3124 	void createTexture (void)
   3125 	{
   3126 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3127 		de::Random			rnd			(deStringHash(getName()));
   3128 		deUint32			tex			= 0;
   3129 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3130 
   3131 		glGenTextures(1, &tex);
   3132 		glBindTexture(GL_TEXTURE_2D, tex);
   3133 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3134 		GLU_CHECK();
   3135 
   3136 		// First specify full texture.
   3137 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3138 		{
   3139 			const int   levelW		= de::max(1, m_width >> ndx);
   3140 			const int   levelH		= de::max(1, m_height >> ndx);
   3141 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3142 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3143 
   3144 			levelData.setSize(levelW, levelH);
   3145 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3146 
   3147 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3148 		}
   3149 
   3150 		// Re-specify parts of each level.
   3151 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3152 		{
   3153 			const int	levelW		= de::max(1, m_width >> ndx);
   3154 			const int	levelH		= de::max(1, m_height >> ndx);
   3155 
   3156 			const int	w			= rnd.getInt(1, levelW);
   3157 			const int	h			= rnd.getInt(1, levelH);
   3158 			const int	x			= rnd.getInt(0, levelW-w);
   3159 			const int	y			= rnd.getInt(0, levelH-h);
   3160 
   3161 			const Vec4	colorA		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3162 			const Vec4	colorB		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3163 			const int	cellSize	= rnd.getInt(2, 16);
   3164 
   3165 			levelData.setSize(w, h);
   3166 			tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
   3167 
   3168 			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3169 		}
   3170 	}
   3171 
   3172 	const deUint32 m_internalFormat;
   3173 };
   3174 
   3175 // TexSubImage3D() depth case.
   3176 class TexSubImage2DArrayDepthCase : public Texture2DArraySpecCase
   3177 {
   3178 public:
   3179 	TexSubImage2DArrayDepthCase (Context&		context,
   3180 								 const char*	name,
   3181 								 const char*	desc,
   3182 								 deUint32		internalFormat,
   3183 								 int			imageWidth,
   3184 								 int			imageHeight,
   3185 								 int			numLayers)
   3186 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
   3187 		, m_internalFormat		(internalFormat)
   3188 	{
   3189 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3190 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3191 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3192 	}
   3193 
   3194 	void createTexture (void)
   3195 	{
   3196 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3197 		de::Random			rnd			(deStringHash(getName()));
   3198 		deUint32			tex			= 0;
   3199 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3200 
   3201 		glGenTextures(1, &tex);
   3202 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3203 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3204 		GLU_CHECK();
   3205 
   3206 		// First specify full texture.
   3207 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3208 		{
   3209 			const int   levelW		= de::max(1, m_width >> ndx);
   3210 			const int   levelH		= de::max(1, m_height >> ndx);
   3211 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3212 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3213 
   3214 			levelData.setSize(levelW, levelH, m_numLayers);
   3215 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3216 
   3217 			glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3218 		}
   3219 
   3220 		// Re-specify parts of each level.
   3221 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3222 		{
   3223 			const int	levelW		= de::max(1, m_width >> ndx);
   3224 			const int	levelH		= de::max(1, m_height >> ndx);
   3225 
   3226 			const int	w			= rnd.getInt(1, levelW);
   3227 			const int	h			= rnd.getInt(1, levelH);
   3228 			const int	d			= rnd.getInt(1, m_numLayers);
   3229 			const int	x			= rnd.getInt(0, levelW-w);
   3230 			const int	y			= rnd.getInt(0, levelH-h);
   3231 			const int	z			= rnd.getInt(0, m_numLayers-d);
   3232 
   3233 			const Vec4	colorA		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3234 			const Vec4	colorB		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3235 			const int	cellSize	= rnd.getInt(2, 16);
   3236 
   3237 			levelData.setSize(w, h, d);
   3238 			tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
   3239 
   3240 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3241 		}
   3242 	}
   3243 
   3244 	const deUint32 m_internalFormat;
   3245 };
   3246 
   3247 // TexImage2D() depth case with pbo.
   3248 class TexImage2DDepthBufferCase : public Texture2DSpecCase
   3249 {
   3250 public:
   3251 	TexImage2DDepthBufferCase (Context&		context,
   3252 							   const char*	name,
   3253 							   const char*	desc,
   3254 							   deUint32		internalFormat,
   3255 							   int			imageWidth,
   3256 							   int			imageHeight)
   3257 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 1)
   3258 		, m_internalFormat	(internalFormat)
   3259 	{
   3260 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3261 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3262 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3263 	}
   3264 
   3265 	void createTexture (void)
   3266 	{
   3267 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   3268 		int						pixelSize		= m_texFormat.getPixelSize();
   3269 		int						rowLength		= m_width;
   3270 		int						alignment		= 4;
   3271 		int						rowPitch		= deAlign32(rowLength*pixelSize, alignment);
   3272 		int						height			= m_height;
   3273 		deUint32				buf				= 0;
   3274 		deUint32				tex				= 0;
   3275 		vector<deUint8>			data;
   3276 
   3277 		DE_ASSERT(m_numLevels == 1);
   3278 
   3279 		// Fill data with gradient
   3280 		data.resize(rowPitch*height);
   3281 		{
   3282 			const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3283 			const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3284 
   3285 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0]), gMin, gMax);
   3286 		}
   3287 
   3288 		// Create buffer and upload.
   3289 		glGenBuffers(1, &buf);
   3290 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   3291 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   3292 
   3293 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		rowLength);
   3294 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		0);
   3295 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
   3296 		glPixelStorei(GL_UNPACK_ALIGNMENT,		alignment);
   3297 
   3298 		glGenTextures(1, &tex);
   3299 		glBindTexture(GL_TEXTURE_2D, tex);
   3300 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
   3301 		glDeleteBuffers(1, &buf);
   3302 	}
   3303 
   3304 	const deUint32 m_internalFormat;
   3305 };
   3306 
   3307 // TexImage3D() depth case with pbo.
   3308 class TexImage2DArrayDepthBufferCase : public Texture2DArraySpecCase
   3309 {
   3310 public:
   3311 	TexImage2DArrayDepthBufferCase (Context&	context,
   3312 									const char*	name,
   3313 									const char*	desc,
   3314 									deUint32	internalFormat,
   3315 									int			imageWidth,
   3316 									int			imageHeight,
   3317 									int			numLayers)
   3318 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, 1)
   3319 		, m_internalFormat		(internalFormat)
   3320 	{
   3321 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3322 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3323 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3324 	}
   3325 
   3326 	void createTexture (void)
   3327 	{
   3328 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   3329 		int						pixelSize		= m_texFormat.getPixelSize();
   3330 		int						rowLength		= m_width;
   3331 		int						alignment		= 4;
   3332 		int						rowPitch		= deAlign32(rowLength*pixelSize, alignment);
   3333 		int						imageHeight		= m_height;
   3334 		int						slicePitch		= imageHeight*rowPitch;
   3335 		deUint32				tex				= 0;
   3336 		deUint32				buf				= 0;
   3337 		vector<deUint8>			data;
   3338 
   3339 		DE_ASSERT(m_numLevels == 1);
   3340 
   3341 		// Fill data with grid.
   3342 		data.resize(slicePitch*m_numLayers);
   3343 		{
   3344 			const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3345 			const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3346 
   3347 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), gMin, gMax);
   3348 		}
   3349 
   3350 		glGenBuffers(1, &buf);
   3351 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   3352 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   3353 
   3354 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	imageHeight);
   3355 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		rowLength);
   3356 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
   3357 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		0);
   3358 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
   3359 		glPixelStorei(GL_UNPACK_ALIGNMENT,		alignment);
   3360 
   3361 		glGenTextures(1, &tex);
   3362 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3363 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
   3364 		glDeleteBuffers(1, &buf);
   3365 	}
   3366 
   3367 	const deUint32 m_internalFormat;
   3368 };
   3369 
   3370 TextureSpecificationTests::TextureSpecificationTests (Context& context)
   3371 	: TestCaseGroup(context, "specification", "Texture Specification Tests")
   3372 {
   3373 }
   3374 
   3375 TextureSpecificationTests::~TextureSpecificationTests (void)
   3376 {
   3377 }
   3378 
   3379 void TextureSpecificationTests::init (void)
   3380 {
   3381 	struct
   3382 	{
   3383 		const char*	name;
   3384 		deUint32	format;
   3385 		deUint32	dataType;
   3386 	} unsizedFormats[] =
   3387 	{
   3388 		{ "alpha_unsigned_byte",			GL_ALPHA,			GL_UNSIGNED_BYTE },
   3389 		{ "luminance_unsigned_byte",		GL_LUMINANCE,		GL_UNSIGNED_BYTE },
   3390 		{ "luminance_alpha_unsigned_byte",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
   3391 		{ "rgb_unsigned_short_5_6_5",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
   3392 		{ "rgb_unsigned_byte",				GL_RGB,				GL_UNSIGNED_BYTE },
   3393 		{ "rgba_unsigned_short_4_4_4_4",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
   3394 		{ "rgba_unsigned_short_5_5_5_1",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
   3395 		{ "rgba_unsigned_byte",				GL_RGBA,			GL_UNSIGNED_BYTE }
   3396 	};
   3397 
   3398 	struct
   3399 	{
   3400 		const char*	name;
   3401 		deUint32	internalFormat;
   3402 	} colorFormats[] =
   3403 	{
   3404 		{ "rgba32f",			GL_RGBA32F,			},
   3405 		{ "rgba32i",			GL_RGBA32I,			},
   3406 		{ "rgba32ui",			GL_RGBA32UI,		},
   3407 		{ "rgba16f",			GL_RGBA16F,			},
   3408 		{ "rgba16i",			GL_RGBA16I,			},
   3409 		{ "rgba16ui",			GL_RGBA16UI,		},
   3410 		{ "rgba8",				GL_RGBA8,			},
   3411 		{ "rgba8i",				GL_RGBA8I,			},
   3412 		{ "rgba8ui",			GL_RGBA8UI,			},
   3413 		{ "srgb8_alpha8",		GL_SRGB8_ALPHA8,	},
   3414 		{ "rgb10_a2",			GL_RGB10_A2,		},
   3415 		{ "rgb10_a2ui",			GL_RGB10_A2UI,		},
   3416 		{ "rgba4",				GL_RGBA4,			},
   3417 		{ "rgb5_a1",			GL_RGB5_A1,			},
   3418 		{ "rgba8_snorm",		GL_RGBA8_SNORM,		},
   3419 		{ "rgb8",				GL_RGB8,			},
   3420 		{ "rgb565",				GL_RGB565,			},
   3421 		{ "r11f_g11f_b10f",		GL_R11F_G11F_B10F,	},
   3422 		{ "rgb32f",				GL_RGB32F,			},
   3423 		{ "rgb32i",				GL_RGB32I,			},
   3424 		{ "rgb32ui",			GL_RGB32UI,			},
   3425 		{ "rgb16f",				GL_RGB16F,			},
   3426 		{ "rgb16i",				GL_RGB16I,			},
   3427 		{ "rgb16ui",			GL_RGB16UI,			},
   3428 		{ "rgb8_snorm",			GL_RGB8_SNORM,		},
   3429 		{ "rgb8i",				GL_RGB8I,			},
   3430 		{ "rgb8ui",				GL_RGB8UI,			},
   3431 		{ "srgb8",				GL_SRGB8,			},
   3432 		{ "rgb9_e5",			GL_RGB9_E5,			},
   3433 		{ "rg32f",				GL_RG32F,			},
   3434 		{ "rg32i",				GL_RG32I,			},
   3435 		{ "rg32ui",				GL_RG32UI,			},
   3436 		{ "rg16f",				GL_RG16F,			},
   3437 		{ "rg16i",				GL_RG16I,			},
   3438 		{ "rg16ui",				GL_RG16UI,			},
   3439 		{ "rg8",				GL_RG8,				},
   3440 		{ "rg8i",				GL_RG8I,			},
   3441 		{ "rg8ui",				GL_RG8UI,			},
   3442 		{ "rg8_snorm",			GL_RG8_SNORM,		},
   3443 		{ "r32f",				GL_R32F,			},
   3444 		{ "r32i",				GL_R32I,			},
   3445 		{ "r32ui",				GL_R32UI,			},
   3446 		{ "r16f",				GL_R16F,			},
   3447 		{ "r16i",				GL_R16I,			},
   3448 		{ "r16ui",				GL_R16UI,			},
   3449 		{ "r8",					GL_R8,				},
   3450 		{ "r8i",				GL_R8I,				},
   3451 		{ "r8ui",				GL_R8UI,			},
   3452 		{ "r8_snorm",			GL_R8_SNORM,		}
   3453 	};
   3454 
   3455 	static const struct
   3456 	{
   3457 		const char*	name;
   3458 		deUint32	internalFormat;
   3459 	} depthStencilFormats[] =
   3460 	{
   3461 		// Depth and stencil formats
   3462 		{ "depth_component32f",	GL_DEPTH_COMPONENT32F	},
   3463 		{ "depth_component24",	GL_DEPTH_COMPONENT24	},
   3464 		{ "depth_component16",	GL_DEPTH_COMPONENT16	},
   3465 		{ "depth32f_stencil8",	GL_DEPTH32F_STENCIL8	},
   3466 		{ "depth24_stencil8",	GL_DEPTH24_STENCIL8		}
   3467 	};
   3468 
   3469 	// Basic TexImage2D usage.
   3470 	{
   3471 		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
   3472 		addChild(basicTexImageGroup);
   3473 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3474 		{
   3475 			const char*	fmtName		= colorFormats[formatNdx].name;
   3476 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   3477 			const int	tex2DWidth	= 64;
   3478 			const int	tex2DHeight	= 128;
   3479 			const int	texCubeSize	= 64;
   3480 
   3481 			basicTexImageGroup->addChild(new BasicTexImage2DCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, tex2DWidth, tex2DHeight));
   3482 			basicTexImageGroup->addChild(new BasicTexImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, texCubeSize));
   3483 		}
   3484 	}
   3485 
   3486 	// Randomized TexImage2D order.
   3487 	{
   3488 		tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
   3489 		addChild(randomTexImageGroup);
   3490 
   3491 		de::Random rnd(9);
   3492 
   3493 		// 2D cases.
   3494 		for (int ndx = 0; ndx < 10; ndx++)
   3495 		{
   3496 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
   3497 			int		width		= 1 << rnd.getInt(2, 8);
   3498 			int		height		= 1 << rnd.getInt(2, 8);
   3499 
   3500 			randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, width, height));
   3501 		}
   3502 
   3503 		// Cubemap cases.
   3504 		for (int ndx = 0; ndx < 10; ndx++)
   3505 		{
   3506 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
   3507 			int		size		= 1 << rnd.getInt(2, 8);
   3508 
   3509 			randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, size));
   3510 		}
   3511 	}
   3512 
   3513 	// TexImage2D unpack alignment.
   3514 	{
   3515 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
   3516 		addChild(alignGroup);
   3517 
   3518 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_4_8",			"",	GL_R8,			 4,  8, 4, 8));
   3519 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_1",			"",	GL_R8,			63, 30, 1, 1));
   3520 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_2",			"",	GL_R8,			63, 30, 1, 2));
   3521 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_4",			"",	GL_R8,			63, 30, 1, 4));
   3522 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_8",			"",	GL_R8,			63, 30, 1, 8));
   3523 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_1",		"",	GL_RGBA4,		51, 30, 1, 1));
   3524 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_2",		"",	GL_RGBA4,		51, 30, 1, 2));
   3525 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_4",		"",	GL_RGBA4,		51, 30, 1, 4));
   3526 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_8",		"",	GL_RGBA4,		51, 30, 1, 8));
   3527 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_1",			"",	GL_RGB8,		39, 43, 1, 1));
   3528 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_2",			"",	GL_RGB8,		39, 43, 1, 2));
   3529 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_4",			"",	GL_RGB8,		39, 43, 1, 4));
   3530 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_8",			"",	GL_RGB8,		39, 43, 1, 8));
   3531 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_1",		"",	GL_RGBA8,		47, 27, 1, 1));
   3532 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_2",		"",	GL_RGBA8,		47, 27, 1, 2));
   3533 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_4",		"",	GL_RGBA8,		47, 27, 1, 4));
   3534 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_8",		"",	GL_RGBA8,		47, 27, 1, 8));
   3535 
   3536 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_4_8",			"",	GL_R8,			 4, 3, 8));
   3537 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_1",			"",	GL_R8,			63, 1, 1));
   3538 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_2",			"",	GL_R8,			63, 1, 2));
   3539 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_4",			"",	GL_R8,			63, 1, 4));
   3540 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_8",			"",	GL_R8,			63, 1, 8));
   3541 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_1",		"",	GL_RGBA4,		51, 1, 1));
   3542 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_2",		"",	GL_RGBA4,		51, 1, 2));
   3543 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_4",		"",	GL_RGBA4,		51, 1, 4));
   3544 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_8",		"",	GL_RGBA4,		51, 1, 8));
   3545 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_1",		"",	GL_RGB8,		39, 1, 1));
   3546 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_2",		"",	GL_RGB8,		39, 1, 2));
   3547 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_4",		"",	GL_RGB8,		39, 1, 4));
   3548 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_8",		"",	GL_RGB8,		39, 1, 8));
   3549 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_1",		"",	GL_RGBA8,		47, 1, 1));
   3550 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_2",		"",	GL_RGBA8,		47, 1, 2));
   3551 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_4",		"",	GL_RGBA8,		47, 1, 4));
   3552 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_8",		"",	GL_RGBA8,		47, 1, 8));
   3553 	}
   3554 
   3555 	// glTexImage2D() unpack parameter cases.
   3556 	{
   3557 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_unpack_params", "glTexImage2D() pixel transfer mode cases");
   3558 		addChild(paramGroup);
   3559 
   3560 		static const struct
   3561 		{
   3562 			const char*	name;
   3563 			deUint32	format;
   3564 			int			width;
   3565 			int			height;
   3566 			int			rowLength;
   3567 			int			skipRows;
   3568 			int			skipPixels;
   3569 			int			alignment;
   3570 		} cases[] =
   3571 		{
   3572 			{ "rgb8_alignment",		GL_RGB8,	31,	30,	0,	0,	0,	2 },
   3573 			{ "rgb8_row_length",	GL_RGB8,	31,	30,	50,	0,	0,	4 },
   3574 			{ "rgb8_skip_rows",		GL_RGB8,	31,	30,	0,	3,	0,	4 },
   3575 			{ "rgb8_skip_pixels",	GL_RGB8,	31,	30,	36,	0,	5,	4 },
   3576 			{ "r8_complex1",		GL_R8,		31, 30, 64, 1,	3,	1 },
   3577 			{ "r8_complex2",		GL_R8,		31, 30, 64, 1,	3,	2 },
   3578 			{ "r8_complex3",		GL_R8,		31, 30, 64, 1,	3,	4 },
   3579 			{ "r8_complex4",		GL_R8,		31, 30, 64, 1,	3,	8 },
   3580 			{ "rgba8_complex1",		GL_RGBA8,	56,	61,	69,	0,	0,	8 },
   3581 			{ "rgba8_complex2",		GL_RGBA8,	56,	61,	69,	0,	7,	8 },
   3582 			{ "rgba8_complex3",		GL_RGBA8,	56,	61,	69,	3,	0,	8 },
   3583 			{ "rgba8_complex4",		GL_RGBA8,	56,	61,	69,	3,	7,	8 },
   3584 			{ "rgba32f_complex",	GL_RGBA32F,	19,	10,	27,	1,	7,	8 }
   3585 		};
   3586 
   3587 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   3588 			paramGroup->addChild(new TexImage2DParamsCase(m_context, cases[ndx].name, "",
   3589 														  cases[ndx].format,
   3590 														  cases[ndx].width,
   3591 														  cases[ndx].height,
   3592 														  cases[ndx].rowLength,
   3593 														  cases[ndx].skipRows,
   3594 														  cases[ndx].skipPixels,
   3595 														  cases[ndx].alignment));
   3596 	}
   3597 
   3598 	// glTexImage2D() pbo cases.
   3599 	{
   3600 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_pbo", "glTexImage2D() from PBO");
   3601 		addChild(pboGroup);
   3602 
   3603 		// Parameter cases
   3604 		static const struct
   3605 		{
   3606 			const char*	name;
   3607 			deUint32	format;
   3608 			int			width;
   3609 			int			height;
   3610 			int			rowLength;
   3611 			int			skipRows;
   3612 			int			skipPixels;
   3613 			int			alignment;
   3614 			int			offset;
   3615 		} parameterCases[] =
   3616 		{
   3617 			{ "rgb8_offset",		GL_RGB8,	31,	30,	0,	0,	0,	4,	67 },
   3618 			{ "rgb8_alignment",		GL_RGB8,	31,	30,	0,	0,	0,	2,	0 },
   3619 			{ "rgb8_row_length",	GL_RGB8,	31,	30,	50,	0,	0,	4,	0 },
   3620 			{ "rgb8_skip_rows",		GL_RGB8,	31,	30,	0,	3,	0,	4,	0 },
   3621 			{ "rgb8_skip_pixels",	GL_RGB8,	31,	30,	36,	0,	5,	4,	0 }
   3622 		};
   3623 
   3624 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3625 		{
   3626 			const string	fmtName		= colorFormats[formatNdx].name;
   3627 			const deUint32	format		= colorFormats[formatNdx].internalFormat;
   3628 			const int		tex2DWidth	= 65;
   3629 			const int		tex2DHeight	= 37;
   3630 			const int		texCubeSize	= 64;
   3631 
   3632 			pboGroup->addChild(new TexImage2DBufferCase		(m_context,	(fmtName + "_2d").c_str(),		"", format, tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0));
   3633 			pboGroup->addChild(new TexImageCubeBufferCase	(m_context,	(fmtName + "_cube").c_str(),	"", format, texCubeSize, 0, 0, 0, 4, 0));
   3634 		}
   3635 
   3636 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
   3637 		{
   3638 			pboGroup->addChild(new TexImage2DBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d").c_str(), "",
   3639 														parameterCases[ndx].format,
   3640 														parameterCases[ndx].width,
   3641 														parameterCases[ndx].height,
   3642 														parameterCases[ndx].rowLength,
   3643 														parameterCases[ndx].skipRows,
   3644 														parameterCases[ndx].skipPixels,
   3645 														parameterCases[ndx].alignment,
   3646 														parameterCases[ndx].offset));
   3647 			pboGroup->addChild(new TexImageCubeBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube").c_str(), "",
   3648 														parameterCases[ndx].format,
   3649 														parameterCases[ndx].width,
   3650 														parameterCases[ndx].rowLength,
   3651 														parameterCases[ndx].skipRows,
   3652 														parameterCases[ndx].skipPixels,
   3653 														parameterCases[ndx].alignment,
   3654 														parameterCases[ndx].offset));
   3655 		}
   3656 	}
   3657 
   3658 	// glTexImage2D() depth cases.
   3659 	{
   3660 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth", "glTexImage2D() with depth or depth/stencil format");
   3661 		addChild(shadow2dGroup);
   3662 
   3663 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3664 		{
   3665 			const int tex2DWidth	= 64;
   3666 			const int tex2DHeight	= 128;
   3667 
   3668 			shadow2dGroup->addChild(new TexImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3669 		}
   3670 	}
   3671 
   3672 	// glTexImage2D() depth cases with pbo.
   3673 	{
   3674 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth_pbo", "glTexImage2D() with depth or depth/stencil format with pbo");
   3675 		addChild(shadow2dGroup);
   3676 
   3677 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3678 		{
   3679 			const int tex2DWidth	= 64;
   3680 			const int tex2DHeight	= 128;
   3681 
   3682 			shadow2dGroup->addChild(new TexImage2DDepthBufferCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3683 		}
   3684 	}
   3685 
   3686 	// Basic TexSubImage2D usage.
   3687 	{
   3688 		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
   3689 		addChild(basicTexSubImageGroup);
   3690 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3691 		{
   3692 			const char*	fmtName		= colorFormats[formatNdx].name;
   3693 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   3694 			const int	tex2DWidth	= 64;
   3695 			const int	tex2DHeight	= 128;
   3696 			const int	texCubeSize	= 64;
   3697 
   3698 			basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase		(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, tex2DWidth, tex2DHeight));
   3699 			basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, texCubeSize));
   3700 		}
   3701 	}
   3702 
   3703 	// TexSubImage2D to empty texture.
   3704 	{
   3705 		tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
   3706 		addChild(texSubImageEmptyTexGroup);
   3707 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(unsizedFormats); formatNdx++)
   3708 		{
   3709 			const char*	fmtName		= unsizedFormats[formatNdx].name;
   3710 			deUint32	format		= unsizedFormats[formatNdx].format;
   3711 			deUint32	dataType	= unsizedFormats[formatNdx].dataType;
   3712 			const int	tex2DWidth	= 64;
   3713 			const int	tex2DHeight	= 32;
   3714 			const int	texCubeSize	= 32;
   3715 
   3716 			texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, tex2DWidth, tex2DHeight));
   3717 			texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, texCubeSize));
   3718 		}
   3719 	}
   3720 
   3721 	// TexSubImage2D alignment cases.
   3722 	{
   3723 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
   3724 		addChild(alignGroup);
   3725 
   3726 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_1",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 1));
   3727 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_2",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 2));
   3728 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_4",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 4));
   3729 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_8",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 8));
   3730 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_1",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 1));
   3731 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_2",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 2));
   3732 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_4",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 4));
   3733 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_8",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 8));
   3734 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_1",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 1));
   3735 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_2",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 2));
   3736 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_4",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 4));
   3737 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_8",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 8));
   3738 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_1",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 1));
   3739 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_2",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 2));
   3740 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_4",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 4));
   3741 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_8",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 8));
   3742 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_1",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 1));
   3743 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_2",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 2));
   3744 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_4",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 4));
   3745 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_8",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 8));
   3746 
   3747 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_1",			"",	GL_R8,			64, 13, 17,  1,  6, 1));
   3748 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_2",			"",	GL_R8,			64, 13, 17,  1,  6, 2));
   3749 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_4",			"",	GL_R8,			64, 13, 17,  1,  6, 4));
   3750 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_8",			"",	GL_R8,			64, 13, 17,  1,  6, 8));
   3751 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_1",			"",	GL_R8,			64,  1,  9, 63, 30, 1));
   3752 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_2",			"",	GL_R8,			64,  1,  9, 63, 30, 2));
   3753 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_4",			"",	GL_R8,			64,  1,  9, 63, 30, 4));
   3754 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_8",			"",	GL_R8,			64,  1,  9, 63, 30, 8));
   3755 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_1",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 1));
   3756 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_2",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 2));
   3757 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_4",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 4));
   3758 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_8",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 8));
   3759 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_1",		"",	GL_RGB8,		64, 11,  8, 39, 43, 1));
   3760 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_2",		"",	GL_RGB8,		64, 11,  8, 39, 43, 2));
   3761 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_4",		"",	GL_RGB8,		64, 11,  8, 39, 43, 4));
   3762 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_8",		"",	GL_RGB8,		64, 11,  8, 39, 43, 8));
   3763 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_1",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 1));
   3764 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_2",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 2));
   3765 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_4",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 4));
   3766 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_8",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 8));
   3767 	}
   3768 
   3769 	// glTexSubImage2D() pixel transfer mode cases.
   3770 	{
   3771 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_unpack_params", "glTexSubImage2D() pixel transfer mode cases");
   3772 		addChild(paramGroup);
   3773 
   3774 		static const struct
   3775 		{
   3776 			const char*	name;
   3777 			deUint32	format;
   3778 			int			width;
   3779 			int			height;
   3780 			int			subX;
   3781 			int			subY;
   3782 			int			subW;
   3783 			int			subH;
   3784 			int			rowLength;
   3785 			int			skipRows;
   3786 			int			skipPixels;
   3787 			int			alignment;
   3788 		} cases[] =
   3789 		{
   3790 			{ "rgb8_alignment",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	2 },
   3791 			{ "rgb8_row_length",	GL_RGB8,	54,	60,	11,	7,	31,	30,	50,	0,	0,	4 },
   3792 			{ "rgb8_skip_rows",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	3,	0,	4 },
   3793 			{ "rgb8_skip_pixels",	GL_RGB8,	54,	60,	11,	7,	31,	30,	36,	0,	5,	4 },
   3794 			{ "r8_complex1",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	1 },
   3795 			{ "r8_complex2",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	2 },
   3796 			{ "r8_complex3",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	4 },
   3797 			{ "r8_complex4",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	8 },
   3798 			{ "rgba8_complex1",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	0,	0,	8 },
   3799 			{ "rgba8_complex2",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	0,	7,	8 },
   3800 			{ "rgba8_complex3",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	3,	0,	8 },
   3801 			{ "rgba8_complex4",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	3,	7,	8 },
   3802 			{ "rgba32f_complex",	GL_RGBA32F,	92,	84,	13,	19,	56,	61,	69,	3,	7,	8 }
   3803 		};
   3804 
   3805 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   3806 			paramGroup->addChild(new TexSubImage2DParamsCase(m_context, cases[ndx].name, "",
   3807 															 cases[ndx].format,
   3808 															 cases[ndx].width,
   3809 															 cases[ndx].height,
   3810 															 cases[ndx].subX,
   3811 															 cases[ndx].subY,
   3812 															 cases[ndx].subW,
   3813 															 cases[ndx].subH,
   3814 															 cases[ndx].rowLength,
   3815 															 cases[ndx].skipRows,
   3816 															 cases[ndx].skipPixels,
   3817 															 cases[ndx].alignment));
   3818 	}
   3819 
   3820 	// glTexSubImage2D() PBO cases.
   3821 	{
   3822 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_pbo", "glTexSubImage2D() pixel buffer object tests");
   3823 		addChild(pboGroup);
   3824 
   3825 		static const struct
   3826 		{
   3827 			const char*	name;
   3828 			deUint32	format;
   3829 			int			width;
   3830 			int			height;
   3831 			int			subX;
   3832 			int			subY;
   3833 			int			subW;
   3834 			int			subH;
   3835 			int			rowLength;
   3836 			int			skipRows;
   3837 			int			skipPixels;
   3838 			int			alignment;
   3839 			int			offset;
   3840 		} paramCases[] =
   3841 		{
   3842 			{ "rgb8_offset",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	4,	67 },
   3843 			{ "rgb8_alignment",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	2,	0 },
   3844 			{ "rgb8_row_length",	GL_RGB8,	54,	60,	11,	7,	31,	30,	50,	0,	0,	4,	0 },
   3845 			{ "rgb8_skip_rows",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	3,	0,	4,	0 },
   3846 			{ "rgb8_skip_pixels",	GL_RGB8,	54,	60,	11,	7,	31,	30,	36,	0,	5,	4,	0 }
   3847 		};
   3848 
   3849 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   3850 		{
   3851 			pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d").c_str(), "",
   3852 														   colorFormats[ndx].internalFormat,
   3853 														   54,	// Width
   3854 														   60,	// Height
   3855 														   11,	// Sub X
   3856 														   7,	// Sub Y
   3857 														   31,	// Sub W
   3858 														   30,	// Sub H
   3859 														   0,	// Row len
   3860 														   0,	// Skip rows
   3861 														   0,	// Skip pixels
   3862 														   4,	// Alignment
   3863 														   0	/* offset */));
   3864 			pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube").c_str(), "",
   3865 														   colorFormats[ndx].internalFormat,
   3866 														   64,	// Size
   3867 														   11,	// Sub X
   3868 														   7,	// Sub Y
   3869 														   31,	// Sub W
   3870 														   30,	// Sub H
   3871 														   0,	// Row len
   3872 														   0,	// Skip rows
   3873 														   0,	// Skip pixels
   3874 														   4,	// Alignment
   3875 														   0	/* offset */));
   3876 		}
   3877 
   3878 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
   3879 		{
   3880 			pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d").c_str(), "",
   3881 														   paramCases[ndx].format,
   3882 														   paramCases[ndx].width,
   3883 														   paramCases[ndx].height,
   3884 														   paramCases[ndx].subX,
   3885 														   paramCases[ndx].subY,
   3886 														   paramCases[ndx].subW,
   3887 														   paramCases[ndx].subH,
   3888 														   paramCases[ndx].rowLength,
   3889 														   paramCases[ndx].skipRows,
   3890 														   paramCases[ndx].skipPixels,
   3891 														   paramCases[ndx].alignment,
   3892 														   paramCases[ndx].offset));
   3893 			pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube").c_str(), "",
   3894 														   paramCases[ndx].format,
   3895 														   paramCases[ndx].width,
   3896 														   paramCases[ndx].subX,
   3897 														   paramCases[ndx].subY,
   3898 														   paramCases[ndx].subW,
   3899 														   paramCases[ndx].subH,
   3900 														   paramCases[ndx].rowLength,
   3901 														   paramCases[ndx].skipRows,
   3902 														   paramCases[ndx].skipPixels,
   3903 														   paramCases[ndx].alignment,
   3904 														   paramCases[ndx].offset));
   3905 		}
   3906 	}
   3907 
   3908 	// glTexSubImage2D() depth cases.
   3909 	{
   3910 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_depth", "glTexSubImage2D() with depth or depth/stencil format");
   3911 		addChild(shadow2dGroup);
   3912 
   3913 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3914 		{
   3915 			const int	tex2DWidth	= 64;
   3916 			const int	tex2DHeight	= 32;
   3917 
   3918 			shadow2dGroup->addChild(new TexSubImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3919 		}
   3920 	}
   3921 
   3922 	// Basic glCopyTexImage2D() cases
   3923 	{
   3924 		tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
   3925 		addChild(copyTexImageGroup);
   3926 
   3927 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_alpha",				"",	GL_ALPHA,			128, 64));
   3928 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance",			"",	GL_LUMINANCE,		128, 64));
   3929 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	128, 64));
   3930 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgb",				"",	GL_RGB,				128, 64));
   3931 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgba",				"",	GL_RGBA,			128, 64));
   3932 
   3933 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			64));
   3934 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		64));
   3935 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	64));
   3936 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				64));
   3937 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			64));
   3938 	}
   3939 
   3940 	// Basic glCopyTexSubImage2D() cases
   3941 	{
   3942 		tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
   3943 		addChild(copyTexSubImageGroup);
   3944 
   3945 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_alpha",				"",	GL_ALPHA,			GL_UNSIGNED_BYTE, 128, 64));
   3946 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance",			"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, 128, 64));
   3947 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, 128, 64));
   3948 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, 128, 64));
   3949 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgba",				"",	GL_RGBA,			GL_UNSIGNED_BYTE, 128, 64));
   3950 
   3951 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			GL_UNSIGNED_BYTE, 64));
   3952 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, 64));
   3953 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, 64));
   3954 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, 64));
   3955 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			GL_UNSIGNED_BYTE, 64));
   3956 	}
   3957 
   3958 	// Basic TexImage3D usage.
   3959 	{
   3960 		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
   3961 		addChild(basicTexImageGroup);
   3962 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3963 		{
   3964 			const char*	fmtName				= colorFormats[formatNdx].name;
   3965 			deUint32	format				= colorFormats[formatNdx].internalFormat;
   3966 			const int	tex2DArrayWidth		= 57;
   3967 			const int	tex2DArrayHeight	= 44;
   3968 			const int	tex2DArrayLevels	= 5;
   3969 			const int	tex3DWidth			= 63;
   3970 			const int	tex3DHeight			= 29;
   3971 			const int	tex3DDepth			= 11;
   3972 
   3973 			basicTexImageGroup->addChild(new BasicTexImage2DArrayCase	(m_context,	(string(fmtName) + "_2d_array").c_str(),	"",	format, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
   3974 			basicTexImageGroup->addChild(new BasicTexImage3DCase		(m_context,	(string(fmtName) + "_3d").c_str(),			"",	format, tex3DWidth, tex3DHeight, tex3DDepth));
   3975 		}
   3976 	}
   3977 
   3978 	// glTexImage3D() unpack params cases.
   3979 	{
   3980 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_unpack_params", "glTexImage3D() unpack parameters");
   3981 		addChild(paramGroup);
   3982 
   3983 		static const struct
   3984 		{
   3985 			const char*	name;
   3986 			deUint32	format;
   3987 			int			width;
   3988 			int			height;
   3989 			int			depth;
   3990 			int			imageHeight;
   3991 			int			rowLength;
   3992 			int			skipImages;
   3993 			int			skipRows;
   3994 			int			skipPixels;
   3995 			int			alignment;
   3996 		} cases[] =
   3997 		{
   3998 			{ "rgb8_image_height",	GL_RGB8,	23,	19,	8,	26,	0,	0,	0,	0,	4 },
   3999 			{ "rgb8_row_length",	GL_RGB8,	23,	19,	8,	0,	27,	0,	0,	0,	4 },
   4000 			{ "rgb8_skip_images",	GL_RGB8,	23,	19,	8,	0,	0,	3,	0,	0,	4 },
   4001 			{ "rgb8_skip_rows",		GL_RGB8,	23,	19,	8,	22,	0,	0,	3,	0,	4 },
   4002 			{ "rgb8_skip_pixels",	GL_RGB8,	23,	19,	8,	0,	25,	0,	0,	2,	4 },
   4003 			{ "r8_complex1",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	1 },
   4004 			{ "r8_complex2",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	2 },
   4005 			{ "r8_complex3",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	4 },
   4006 			{ "r8_complex4",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	8 },
   4007 			{ "rgba8_complex1",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	0,	0,	8 },
   4008 			{ "rgba8_complex2",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	2,	0,	8 },
   4009 			{ "rgba8_complex3",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	0,	3,	8 },
   4010 			{ "rgba8_complex4",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	2,	3,	8 },
   4011 			{ "rgba32f_complex",	GL_RGBA32F,	11,	20,	8,	25,	14,	0,	2,	3,	8 }
   4012 		};
   4013 
   4014 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   4015 			paramGroup->addChild(new TexImage3DParamsCase(m_context, cases[ndx].name, "",
   4016 														  cases[ndx].format,
   4017 														  cases[ndx].width,
   4018 														  cases[ndx].height,
   4019 														  cases[ndx].depth,
   4020 														  cases[ndx].imageHeight,
   4021 														  cases[ndx].rowLength,
   4022 														  cases[ndx].skipImages,
   4023 														  cases[ndx].skipRows,
   4024 														  cases[ndx].skipPixels,
   4025 														  cases[ndx].alignment));
   4026 	}
   4027 
   4028 	// glTexImage3D() pbo cases.
   4029 	{
   4030 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
   4031 		addChild(pboGroup);
   4032 
   4033 		// Parameter cases
   4034 		static const struct
   4035 		{
   4036 			const char*	name;
   4037 			deUint32	format;
   4038 			int			width;
   4039 			int			height;
   4040 			int			depth;
   4041 			int			imageHeight;
   4042 			int			rowLength;
   4043 			int			skipImages;
   4044 			int			skipRows;
   4045 			int			skipPixels;
   4046 			int			alignment;
   4047 			int			offset;
   4048 		} parameterCases[] =
   4049 		{
   4050 			{ "rgb8_offset",		GL_RGB8,	23,	19,	8,	0,	0,	0,	0,	0,	1,	67 },
   4051 			{ "rgb8_alignment",		GL_RGB8,	23,	19,	8,	0,	0,	0,	0,	0,	2,	0 },
   4052 			{ "rgb8_image_height",	GL_RGB8,	23,	19,	8,	26,	0,	0,	0,	0,	4,	0 },
   4053 			{ "rgb8_row_length",	GL_RGB8,	23,	19,	8,	0,	27,	0,	0,	0,	4,	0 },
   4054 			{ "rgb8_skip_images",	GL_RGB8,	23,	19,	8,	0,	0,	3,	0,	0,	4,	0 },
   4055 			{ "rgb8_skip_rows",		GL_RGB8,	23,	19,	8,	22,	0,	0,	3,	0,	4,	0 },
   4056 			{ "rgb8_skip_pixels",	GL_RGB8,	23,	19,	8,	0,	25,	0,	0,	2,	4,	0 }
   4057 		};
   4058 
   4059 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4060 		{
   4061 			const string	fmtName		= colorFormats[formatNdx].name;
   4062 			const deUint32	format		= colorFormats[formatNdx].internalFormat;
   4063 			const int		tex3DWidth	= 11;
   4064 			const int		tex3DHeight	= 20;
   4065 			const int		tex3DDepth	= 8;
   4066 
   4067 			pboGroup->addChild(new TexImage2DArrayBufferCase	(m_context, (fmtName + "_2d_array").c_str(),	"", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
   4068 			pboGroup->addChild(new TexImage3DBufferCase			(m_context, (fmtName + "_3d").c_str(),			"", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
   4069 		}
   4070 
   4071 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
   4072 		{
   4073 			pboGroup->addChild(new TexImage2DArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d_array").c_str(), "",
   4074 														parameterCases[ndx].format,
   4075 														parameterCases[ndx].width,
   4076 														parameterCases[ndx].depth,
   4077 														parameterCases[ndx].height,
   4078 														parameterCases[ndx].imageHeight,
   4079 														parameterCases[ndx].rowLength,
   4080 														parameterCases[ndx].skipImages,
   4081 														parameterCases[ndx].skipRows,
   4082 														parameterCases[ndx].skipPixels,
   4083 														parameterCases[ndx].alignment,
   4084 														parameterCases[ndx].offset));
   4085 			pboGroup->addChild(new TexImage3DBufferCase(m_context, (string(parameterCases[ndx].name) + "_3d").c_str(), "",
   4086 														parameterCases[ndx].format,
   4087 														parameterCases[ndx].width,
   4088 														parameterCases[ndx].depth,
   4089 														parameterCases[ndx].height,
   4090 														parameterCases[ndx].imageHeight,
   4091 														parameterCases[ndx].rowLength,
   4092 														parameterCases[ndx].skipImages,
   4093 														parameterCases[ndx].skipRows,
   4094 														parameterCases[ndx].skipPixels,
   4095 														parameterCases[ndx].alignment,
   4096 														parameterCases[ndx].offset));
   4097 		}
   4098 	}
   4099 
   4100 	// glTexImage3D() depth cases.
   4101 	{
   4102 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
   4103 		addChild(shadow3dGroup);
   4104 
   4105 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4106 		{
   4107 			const int	tex3DWidth	= 32;
   4108 			const int	tex3DHeight	= 64;
   4109 			const int	tex3DDepth	= 8;
   4110 
   4111 			shadow3dGroup->addChild(new TexImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
   4112 		}
   4113 	}
   4114 
   4115 	// glTexImage3D() depth cases with pbo.
   4116 	{
   4117 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
   4118 		addChild(shadow3dGroup);
   4119 
   4120 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4121 		{
   4122 			const int	tex3DWidth	= 32;
   4123 			const int	tex3DHeight	= 64;
   4124 			const int	tex3DDepth	= 8;
   4125 
   4126 			shadow3dGroup->addChild(new TexImage2DArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
   4127 		}
   4128 	}
   4129 
   4130 	// Basic TexSubImage3D usage.
   4131 	{
   4132 		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage3d", "Basic glTexSubImage3D() usage");
   4133 		addChild(basicTexSubImageGroup);
   4134 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4135 		{
   4136 			const char*	fmtName		= colorFormats[formatNdx].name;
   4137 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   4138 			const int	tex3DWidth	= 32;
   4139 			const int	tex3DHeight	= 64;
   4140 			const int	tex3DDepth	= 8;
   4141 
   4142 			basicTexSubImageGroup->addChild(new BasicTexSubImage3DCase(m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth));
   4143 		}
   4144 	}
   4145 
   4146 	// glTexSubImage3D() unpack params cases.
   4147 	{
   4148 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_unpack_params", "glTexSubImage3D() unpack parameters");
   4149 		addChild(paramGroup);
   4150 
   4151 		static const struct
   4152 		{
   4153 			const char*	name;
   4154 			deUint32	format;
   4155 			int			width;
   4156 			int			height;
   4157 			int			depth;
   4158 			int			subX;
   4159 			int			subY;
   4160 			int			subZ;
   4161 			int			subW;
   4162 			int			subH;
   4163 			int			subD;
   4164 			int			imageHeight;
   4165 			int			rowLength;
   4166 			int			skipImages;
   4167 			int			skipRows;
   4168 			int			skipPixels;
   4169 			int			alignment;
   4170 		} cases[] =
   4171 		{
   4172 			{ "rgb8_image_height",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	26,	0,	0,	0,	0,	4 },
   4173 			{ "rgb8_row_length",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	27,	0,	0,	0,	4 },
   4174 			{ "rgb8_skip_images",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	3,	0,	0,	4 },
   4175 			{ "rgb8_skip_rows",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	22,	0,	0,	3,	0,	4 },
   4176 			{ "rgb8_skip_pixels",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	25,	0,	0,	2,	4 },
   4177 			{ "r8_complex1",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	1 },
   4178 			{ "r8_complex2",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	2 },
   4179 			{ "r8_complex3",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	4 },
   4180 			{ "r8_complex4",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	8 },
   4181 			{ "rgba8_complex1",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	0,	0,	8 },
   4182 			{ "rgba8_complex2",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	0,	8 },
   4183 			{ "rgba8_complex3",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	0,	3,	8 },
   4184 			{ "rgba8_complex4",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	3,	8 },
   4185 			{ "rgba32f_complex",	GL_RGBA32F,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	3,	8 }
   4186 		};
   4187 
   4188 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   4189 			paramGroup->addChild(new TexSubImage3DParamsCase(m_context, cases[ndx].name, "",
   4190 															 cases[ndx].format,
   4191 															 cases[ndx].width,
   4192 															 cases[ndx].height,
   4193 															 cases[ndx].depth,
   4194 															 cases[ndx].subX,
   4195 															 cases[ndx].subY,
   4196 															 cases[ndx].subZ,
   4197 															 cases[ndx].subW,
   4198 															 cases[ndx].subH,
   4199 															 cases[ndx].subD,
   4200 															 cases[ndx].imageHeight,
   4201 															 cases[ndx].rowLength,
   4202 															 cases[ndx].skipImages,
   4203 															 cases[ndx].skipRows,
   4204 															 cases[ndx].skipPixels,
   4205 															 cases[ndx].alignment));
   4206 	}
   4207 
   4208 	// glTexSubImage3D() PBO cases.
   4209 	{
   4210 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
   4211 		addChild(pboGroup);
   4212 
   4213 		static const struct
   4214 		{
   4215 			const char*	name;
   4216 			deUint32	format;
   4217 			int			width;
   4218 			int			height;
   4219 			int			depth;
   4220 			int			subX;
   4221 			int			subY;
   4222 			int			subZ;
   4223 			int			subW;
   4224 			int			subH;
   4225 			int			subD;
   4226 			int			imageHeight;
   4227 			int			rowLength;
   4228 			int			skipImages;
   4229 			int			skipRows;
   4230 			int			skipPixels;
   4231 			int			alignment;
   4232 			int			offset;
   4233 		} paramCases[] =
   4234 		{
   4235 			{ "rgb8_offset",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	0,	0,	0,	4,	67 },
   4236 			{ "rgb8_image_height",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	26,	0,	0,	0,	0,	4,	0 },
   4237 			{ "rgb8_row_length",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	27,	0,	0,	0,	4,	0 },
   4238 			{ "rgb8_skip_images",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	3,	0,	0,	4,	0 },
   4239 			{ "rgb8_skip_rows",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	22,	0,	0,	3,	0,	4,	0 },
   4240 			{ "rgb8_skip_pixels",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	25,	0,	0,	2,	4,	0 }
   4241 		};
   4242 
   4243 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   4244 		{
   4245 			pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d_array").c_str(), "",
   4246 														   colorFormats[ndx].internalFormat,
   4247 														   26,	// Width
   4248 														   25,	// Height
   4249 														   10,	// Depth
   4250 														   1,	// Sub X
   4251 														   2,	// Sub Y
   4252 														   0,	// Sub Z
   4253 														   23,	// Sub W
   4254 														   19,	// Sub H
   4255 														   8,	// Sub D
   4256 														   0,	// Image height
   4257 														   0,	// Row length
   4258 														   0,	// Skip images
   4259 														   0,	// Skip rows
   4260 														   0,	// Skip pixels
   4261 														   4,	// Alignment
   4262 														   0	/* offset */));
   4263 			pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_3d").c_str(), "",
   4264 														   colorFormats[ndx].internalFormat,
   4265 														   26,	// Width
   4266 														   25,	// Height
   4267 														   10,	// Depth
   4268 														   1,	// Sub X
   4269 														   2,	// Sub Y
   4270 														   0,	// Sub Z
   4271 														   23,	// Sub W
   4272 														   19,	// Sub H
   4273 														   8,	// Sub D
   4274 														   0,	// Image height
   4275 														   0,	// Row length
   4276 														   0,	// Skip images
   4277 														   0,	// Skip rows
   4278 														   0,	// Skip pixels
   4279 														   4,	// Alignment
   4280 														   0	/* offset */));
   4281 		}
   4282 
   4283 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
   4284 		{
   4285 			pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d_array").c_str(), "",
   4286 														   paramCases[ndx].format,
   4287 														   paramCases[ndx].width,
   4288 														   paramCases[ndx].height,
   4289 														   paramCases[ndx].depth,
   4290 														   paramCases[ndx].subX,
   4291 														   paramCases[ndx].subY,
   4292 														   paramCases[ndx].subZ,
   4293 														   paramCases[ndx].subW,
   4294 														   paramCases[ndx].subH,
   4295 														   paramCases[ndx].subD,
   4296 														   paramCases[ndx].imageHeight,
   4297 														   paramCases[ndx].rowLength,
   4298 														   paramCases[ndx].skipImages,
   4299 														   paramCases[ndx].skipRows,
   4300 														   paramCases[ndx].skipPixels,
   4301 														   paramCases[ndx].alignment,
   4302 														   paramCases[ndx].offset));
   4303 			pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_3d").c_str(), "",
   4304 														   paramCases[ndx].format,
   4305 														   paramCases[ndx].width,
   4306 														   paramCases[ndx].height,
   4307 														   paramCases[ndx].depth,
   4308 														   paramCases[ndx].subX,
   4309 														   paramCases[ndx].subY,
   4310 														   paramCases[ndx].subZ,
   4311 														   paramCases[ndx].subW,
   4312 														   paramCases[ndx].subH,
   4313 														   paramCases[ndx].subD,
   4314 														   paramCases[ndx].imageHeight,
   4315 														   paramCases[ndx].rowLength,
   4316 														   paramCases[ndx].skipImages,
   4317 														   paramCases[ndx].skipRows,
   4318 														   paramCases[ndx].skipPixels,
   4319 														   paramCases[ndx].alignment,
   4320 														   paramCases[ndx].offset));
   4321 		}
   4322 	}
   4323 
   4324 	// glTexSubImage3D() depth cases.
   4325 	{
   4326 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
   4327 		addChild(shadow3dGroup);
   4328 
   4329 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4330 		{
   4331 			const int	tex2DArrayWidth		= 57;
   4332 			const int	tex2DArrayHeight	= 44;
   4333 			const int	tex2DArrayLevels	= 5;
   4334 
   4335 			shadow3dGroup->addChild(new TexSubImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
   4336 		}
   4337 	}
   4338 
   4339 	// glTexStorage2D() cases.
   4340 	{
   4341 		tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage2d", "Basic glTexStorage2D() usage");
   4342 		addChild(texStorageGroup);
   4343 
   4344 		// All formats.
   4345 		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage2D() with all formats");
   4346 		texStorageGroup->addChild(formatGroup);
   4347 
   4348 		// Color formats.
   4349 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4350 		{
   4351 			const char*	fmtName			= colorFormats[formatNdx].name;
   4352 			deUint32	internalFormat	= colorFormats[formatNdx].internalFormat;
   4353 			const int	tex2DWidth		= 117;
   4354 			const int	tex2DHeight		= 97;
   4355 			int			tex2DLevels		= maxLevelCount(tex2DWidth, tex2DHeight);
   4356 			const int	cubeSize		= 57;
   4357 			int			cubeLevels		= maxLevelCount(cubeSize, cubeSize);
   4358 
   4359 			formatGroup->addChild(new BasicTexStorage2DCase		(m_context, (string(fmtName) + "_2d").c_str(),		"", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
   4360 			formatGroup->addChild(new BasicTexStorageCubeCase	(m_context, (string(fmtName) + "_cube").c_str(),	"", internalFormat, cubeSize, cubeLevels));
   4361 		}
   4362 
   4363 		// Depth / stencil formats.
   4364 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
   4365 		{
   4366 			const char*	fmtName			= depthStencilFormats[formatNdx].name;
   4367 			deUint32	internalFormat	= depthStencilFormats[formatNdx].internalFormat;
   4368 			const int	tex2DWidth		= 117;
   4369 			const int	tex2DHeight		= 97;
   4370 			int			tex2DLevels		= maxLevelCount(tex2DWidth, tex2DHeight);
   4371 			const int	cubeSize		= 57;
   4372 			int			cubeLevels		= maxLevelCount(cubeSize, cubeSize);
   4373 
   4374 			formatGroup->addChild(new BasicTexStorage2DCase		(m_context, (string(fmtName) + "_2d").c_str(),		"", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
   4375 			formatGroup->addChild(new BasicTexStorageCubeCase	(m_context, (string(fmtName) + "_cube").c_str(),	"", internalFormat, cubeSize, cubeLevels));
   4376 		}
   4377 
   4378 		// Sizes.
   4379 		static const struct
   4380 		{
   4381 			int				width;
   4382 			int				height;
   4383 			int				levels;
   4384 		} tex2DSizes[] =
   4385 		{
   4386 			//	W	H	L
   4387 			{	1,	1,	1 },
   4388 			{	2,	2,	2 },
   4389 			{	64,	32,	7 },
   4390 			{	32,	64,	4 },
   4391 			{	57,	63,	1 },
   4392 			{	57,	63,	2 },
   4393 			{	57,	63,	6 }
   4394 		};
   4395 		static const struct
   4396 		{
   4397 			int		size;
   4398 			int		levels;
   4399 		} cubeSizes[] =
   4400 		{
   4401 			//	S	L
   4402 			{	1,	1 },
   4403 			{	2,	2 },
   4404 			{	57,	1 },
   4405 			{	57,	2 },
   4406 			{	57,	6 },
   4407 			{	64,	4 },
   4408 			{	64,	7 },
   4409 		};
   4410 
   4411 		tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
   4412 		texStorageGroup->addChild(sizeGroup);
   4413 
   4414 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DSizes); ndx++)
   4415 		{
   4416 			const deUint32		format		= GL_RGBA8;
   4417 			int					width		= tex2DSizes[ndx].width;
   4418 			int					height		= tex2DSizes[ndx].height;
   4419 			int					levels		= tex2DSizes[ndx].levels;
   4420 			string				name		= string("2d_") + de::toString(width) + "x" + de::toString(height) + "_" + de::toString(levels) + "_levels";
   4421 
   4422 			sizeGroup->addChild(new BasicTexStorage2DCase(m_context, name.c_str(), "", format, width, height, levels));
   4423 		}
   4424 
   4425 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeSizes); ndx++)
   4426 		{
   4427 			const deUint32		format		= GL_RGBA8;
   4428 			int					size		= cubeSizes[ndx].size;
   4429 			int					levels		= cubeSizes[ndx].levels;
   4430 			string				name		= string("cube_") + de::toString(size) + "x" + de::toString(size) + "_" + de::toString(levels) + "_levels";
   4431 
   4432 			sizeGroup->addChild(new BasicTexStorageCubeCase(m_context, name.c_str(), "", format, size, levels));
   4433 		}
   4434 	}
   4435 
   4436 	// glTexStorage3D() cases.
   4437 	{
   4438 		tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
   4439 		addChild(texStorageGroup);
   4440 
   4441 		// All formats.
   4442 		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
   4443 		texStorageGroup->addChild(formatGroup);
   4444 
   4445 		// Color formats.
   4446 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4447 		{
   4448 			const char*	fmtName				= colorFormats[formatNdx].name;
   4449 			deUint32	internalFormat		= colorFormats[formatNdx].internalFormat;
   4450 			const int	tex2DArrayWidth		= 57;
   4451 			const int	tex2DArrayHeight	= 13;
   4452 			const int	tex2DArrayLayers	= 7;
   4453 			int			tex2DArrayLevels	= maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
   4454 			const int	tex3DWidth			= 59;
   4455 			const int	tex3DHeight			= 37;
   4456 			const int	tex3DDepth			= 11;
   4457 			int			tex3DLevels			= maxLevelCount(tex3DWidth, tex3DHeight, tex3DDepth);
   4458 
   4459 			formatGroup->addChild(new BasicTexStorage2DArrayCase	(m_context, (string(fmtName) + "_2d_array").c_str(),	"", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
   4460 			formatGroup->addChild(new BasicTexStorage3DCase			(m_context, (string(fmtName) + "_3d").c_str(),			"", internalFormat, tex3DWidth, tex3DHeight, tex3DDepth, tex3DLevels));
   4461 		}
   4462 
   4463 		// Depth/stencil formats (only 2D texture array is supported).
   4464 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
   4465 		{
   4466 			const char*	fmtName				= depthStencilFormats[formatNdx].name;
   4467 			deUint32	internalFormat		= depthStencilFormats[formatNdx].internalFormat;
   4468 			const int	tex2DArrayWidth		= 57;
   4469 			const int	tex2DArrayHeight	= 13;
   4470 			const int	tex2DArrayLayers	= 7;
   4471 			int			tex2DArrayLevels	= maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
   4472 
   4473 			formatGroup->addChild(new BasicTexStorage2DArrayCase	(m_context, (string(fmtName) + "_2d_array").c_str(),	"", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
   4474 		}
   4475 
   4476 		// Sizes.
   4477 		static const struct
   4478 		{
   4479 			int				width;
   4480 			int				height;
   4481 			int				layers;
   4482 			int				levels;
   4483 		} tex2DArraySizes[] =
   4484 		{
   4485 			//	W	H	La	Le
   4486 			{	1,	1,	1,	1 },
   4487 			{	2,	2,	2,	2 },
   4488 			{	64,	32,	3,	7 },
   4489 			{	32,	64,	3,	4 },
   4490 			{	57,	63,	5,	1 },
   4491 			{	57,	63,	5,	2 },
   4492 			{	57,	63,	5,	6 }
   4493 		};
   4494 		static const struct
   4495 		{
   4496 			int				width;
   4497 			int				height;
   4498 			int				depth;
   4499 			int				levels;
   4500 		} tex3DSizes[] =
   4501 		{
   4502 			//	W	H	D	L
   4503 			{	1,	1,	1,	1 },
   4504 			{	2,	2,	2,	2 },
   4505 			{	64,	32,	16,	7 },
   4506 			{	32,	64,	16,	4 },
   4507 			{	32,	16,	64,	4 },
   4508 			{	57,	63,	11,	1 },
   4509 			{	57,	63,	11,	2 },
   4510 			{	57,	63,	11,	6 }
   4511 		};
   4512 
   4513 		tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
   4514 		texStorageGroup->addChild(sizeGroup);
   4515 
   4516 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DArraySizes); ndx++)
   4517 		{
   4518 			const deUint32		format		= GL_RGBA8;
   4519 			int					width		= tex2DArraySizes[ndx].width;
   4520 			int					height		= tex2DArraySizes[ndx].height;
   4521 			int					layers		= tex2DArraySizes[ndx].layers;
   4522 			int					levels		= tex2DArraySizes[ndx].levels;
   4523 			string				name		= string("2d_array_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
   4524 
   4525 			sizeGroup->addChild(new BasicTexStorage2DArrayCase(m_context, name.c_str(), "", format, width, height, layers, levels));
   4526 		}
   4527 
   4528 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex3DSizes); ndx++)
   4529 		{
   4530 			const deUint32		format		= GL_RGBA8;
   4531 			int					width		= tex3DSizes[ndx].width;
   4532 			int					height		= tex3DSizes[ndx].height;
   4533 			int					depth		= tex3DSizes[ndx].depth;
   4534 			int					levels		= tex3DSizes[ndx].levels;
   4535 			string				name		= string("3d_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + de::toString(levels) + "_levels";
   4536 
   4537 			sizeGroup->addChild(new BasicTexStorage3DCase(m_context, name.c_str(), "", format, width, height, depth, levels));
   4538 		}
   4539 	}
   4540 }
   4541 
   4542 } // Functional
   4543 } // gles3
   4544 } // deqp
   4545