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 		deUint32				tex				= 0;
   1084 		vector<deUint8>			data;
   1085 
   1086 		DE_ASSERT(m_numLevels == 1);
   1087 
   1088 		// Fill data with grid.
   1089 		data.resize(pixelSize * m_skipPixels + rowPitch * (m_height + m_skipRows));
   1090 		{
   1091 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1092 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1093 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1094 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1095 
   1096 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1097 		}
   1098 
   1099 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1100 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1101 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1102 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1103 
   1104 		glGenTextures(1, &tex);
   1105 		glBindTexture(GL_TEXTURE_2D, tex);
   1106 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1107 	}
   1108 
   1109 	deUint32	m_internalFormat;
   1110 	int			m_rowLength;
   1111 	int			m_skipRows;
   1112 	int			m_skipPixels;
   1113 	int			m_alignment;
   1114 };
   1115 
   1116 // TexImage3D() unpack parameters case.
   1117 class TexImage3DParamsCase : public Texture3DSpecCase
   1118 {
   1119 public:
   1120 	TexImage3DParamsCase (Context&		context,
   1121 						   const char*	name,
   1122 						   const char*	desc,
   1123 						   deUint32		internalFormat,
   1124 						   int			width,
   1125 						   int			height,
   1126 						   int			depth,
   1127 						   int			imageHeight,
   1128 						   int			rowLength,
   1129 						   int			skipImages,
   1130 						   int			skipRows,
   1131 						   int			skipPixels,
   1132 						   int			alignment)
   1133 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   1134 		, m_internalFormat	(internalFormat)
   1135 		, m_imageHeight		(imageHeight)
   1136 		, m_rowLength		(rowLength)
   1137 		, m_skipImages		(skipImages)
   1138 		, m_skipRows		(skipRows)
   1139 		, m_skipPixels		(skipPixels)
   1140 		, m_alignment		(alignment)
   1141 	{
   1142 	}
   1143 
   1144 protected:
   1145 	void createTexture (void)
   1146 	{
   1147 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1148 		int						pixelSize		= m_texFormat.getPixelSize();
   1149 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   1150 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   1151 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   1152 		int						slicePitch		= imageHeight*rowPitch;
   1153 		deUint32				tex				= 0;
   1154 		vector<deUint8>			data;
   1155 
   1156 		DE_ASSERT(m_numLevels == 1);
   1157 
   1158 		// Fill data with grid.
   1159 		data.resize(pixelSize * m_skipPixels + rowPitch * m_skipRows + slicePitch * (m_skipImages + m_depth));
   1160 		{
   1161 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1162 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1163 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1164 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1165 
   1166 			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);
   1167 		}
   1168 
   1169 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   1170 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1171 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   1172 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1173 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1174 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1175 
   1176 		glGenTextures(1, &tex);
   1177 		glBindTexture(GL_TEXTURE_3D, tex);
   1178 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1179 	}
   1180 
   1181 	deUint32	m_internalFormat;
   1182 	int			m_imageHeight;
   1183 	int			m_rowLength;
   1184 	int			m_skipImages;
   1185 	int			m_skipRows;
   1186 	int			m_skipPixels;
   1187 	int			m_alignment;
   1188 };
   1189 
   1190 // Basic TexSubImage2D() with 2D texture usage
   1191 class BasicTexSubImage2DCase : public Texture2DSpecCase
   1192 {
   1193 public:
   1194 	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1195 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1196 		, m_internalFormat	(format)
   1197 		, m_format			(format)
   1198 		, m_dataType		(dataType)
   1199 	{
   1200 	}
   1201 
   1202 	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1203 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
   1204 		, m_internalFormat	(internalFormat)
   1205 		, m_format			(GL_NONE)
   1206 		, m_dataType		(GL_NONE)
   1207 	{
   1208 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1209 		m_format	= fmt.format;
   1210 		m_dataType	= fmt.dataType;
   1211 	}
   1212 
   1213 protected:
   1214 	void createTexture (void)
   1215 	{
   1216 		deUint32			tex			= 0;
   1217 		tcu::TextureLevel	data		(m_texFormat);
   1218 		de::Random			rnd			(deStringHash(getName()));
   1219 
   1220 		glGenTextures(1, &tex);
   1221 		glBindTexture(GL_TEXTURE_2D, tex);
   1222 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1223 
   1224 		// First specify full texture.
   1225 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1226 		{
   1227 			int		levelW		= de::max(1, m_width >> ndx);
   1228 			int		levelH		= de::max(1, m_height >> ndx);
   1229 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1230 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1231 
   1232 			data.setSize(levelW, levelH);
   1233 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1234 
   1235 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   1236 		}
   1237 
   1238 		// Re-specify parts of each level.
   1239 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1240 		{
   1241 			int		levelW		= de::max(1, m_width >> ndx);
   1242 			int		levelH		= de::max(1, m_height >> ndx);
   1243 
   1244 			int		w			= rnd.getInt(1, levelW);
   1245 			int		h			= rnd.getInt(1, levelH);
   1246 			int		x			= rnd.getInt(0, levelW-w);
   1247 			int		y			= rnd.getInt(0, levelH-h);
   1248 
   1249 			Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1250 			Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1251 			int		cellSize	= rnd.getInt(2, 16);
   1252 
   1253 			data.setSize(w, h);
   1254 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1255 
   1256 			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
   1257 		}
   1258 	}
   1259 
   1260 	deUint32	m_internalFormat;
   1261 	deUint32	m_format;
   1262 	deUint32	m_dataType;
   1263 };
   1264 
   1265 // Basic TexSubImage2D() with cubemap usage
   1266 class BasicTexSubImageCubeCase : public TextureCubeSpecCase
   1267 {
   1268 public:
   1269 	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   1270 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   1271 		, m_internalFormat		(format)
   1272 		, m_format				(format)
   1273 		, m_dataType			(dataType)
   1274 	{
   1275 	}
   1276 
   1277 	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1278 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
   1279 		, m_internalFormat		(internalFormat)
   1280 		, m_format				(GL_NONE)
   1281 		, m_dataType			(GL_NONE)
   1282 	{
   1283 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1284 		m_format	= fmt.format;
   1285 		m_dataType	= fmt.dataType;
   1286 	}
   1287 
   1288 protected:
   1289 	void createTexture (void)
   1290 	{
   1291 		deUint32			tex			= 0;
   1292 		tcu::TextureLevel	data		(m_texFormat);
   1293 		de::Random			rnd			(deStringHash(getName()));
   1294 
   1295 		glGenTextures(1, &tex);
   1296 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1297 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1298 
   1299 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1300 		{
   1301 			int levelSize = de::max(1, m_size >> ndx);
   1302 
   1303 			data.setSize(levelSize, levelSize);
   1304 
   1305 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1306 			{
   1307 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1308 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1309 
   1310 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1311 
   1312 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   1313 			}
   1314 		}
   1315 
   1316 		// Re-specify parts of each face and level.
   1317 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1318 		{
   1319 			int levelSize = de::max(1, m_size >> ndx);
   1320 
   1321 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1322 			{
   1323 				int		w			= rnd.getInt(1, levelSize);
   1324 				int		h			= rnd.getInt(1, levelSize);
   1325 				int		x			= rnd.getInt(0, levelSize-w);
   1326 				int		y			= rnd.getInt(0, levelSize-h);
   1327 
   1328 				Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1329 				Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1330 				int		cellSize	= rnd.getInt(2, 16);
   1331 
   1332 				data.setSize(w, h);
   1333 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1334 
   1335 				glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
   1336 			}
   1337 		}
   1338 	}
   1339 
   1340 	deUint32	m_internalFormat;
   1341 	deUint32	m_format;
   1342 	deUint32	m_dataType;
   1343 };
   1344 
   1345 // TexSubImage2D() unpack parameters case.
   1346 class TexSubImage2DParamsCase : public Texture2DSpecCase
   1347 {
   1348 public:
   1349 	TexSubImage2DParamsCase (Context&		context,
   1350 							 const char*	name,
   1351 							 const char*	desc,
   1352 							 deUint32		internalFormat,
   1353 							 int			width,
   1354 							 int			height,
   1355 							 int			subX,
   1356 							 int			subY,
   1357 							 int			subW,
   1358 							 int			subH,
   1359 							 int			rowLength,
   1360 							 int			skipRows,
   1361 							 int			skipPixels,
   1362 							 int			alignment)
   1363 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   1364 		, m_internalFormat	(internalFormat)
   1365 		, m_subX			(subX)
   1366 		, m_subY			(subY)
   1367 		, m_subW			(subW)
   1368 		, m_subH			(subH)
   1369 		, m_rowLength		(rowLength)
   1370 		, m_skipRows		(skipRows)
   1371 		, m_skipPixels		(skipPixels)
   1372 		, m_alignment		(alignment)
   1373 	{
   1374 	}
   1375 
   1376 protected:
   1377 	void createTexture (void)
   1378 	{
   1379 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1380 		int						pixelSize		= m_texFormat.getPixelSize();
   1381 		deUint32				tex				= 0;
   1382 		vector<deUint8>			data;
   1383 
   1384 		DE_ASSERT(m_numLevels == 1);
   1385 
   1386 		glGenTextures(1, &tex);
   1387 		glBindTexture(GL_TEXTURE_2D, tex);
   1388 
   1389 		// First fill texture with gradient.
   1390 		data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
   1391 		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);
   1392 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1393 
   1394 		// Fill data with grid.
   1395 		{
   1396 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   1397 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   1398 			int		height		= m_subH + m_skipRows;
   1399 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1400 			Vec4	cBias		= m_texFormatInfo.valueMin;
   1401 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1402 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1403 
   1404 			data.resize(rowPitch*height);
   1405 			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, 1, rowPitch, 0, &data[0] + m_skipRows*rowPitch + m_skipPixels*pixelSize), 4, colorA, colorB);
   1406 		}
   1407 
   1408 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1409 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1410 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1411 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1412 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, &data[0]);
   1413 	}
   1414 
   1415 	deUint32	m_internalFormat;
   1416 	int			m_subX;
   1417 	int			m_subY;
   1418 	int			m_subW;
   1419 	int			m_subH;
   1420 	int			m_rowLength;
   1421 	int			m_skipRows;
   1422 	int			m_skipPixels;
   1423 	int			m_alignment;
   1424 };
   1425 
   1426 // Basic TexSubImage3D() with 3D texture usage
   1427 class BasicTexSubImage3DCase : public Texture3DSpecCase
   1428 {
   1429 public:
   1430 	BasicTexSubImage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth)
   1431 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, maxLevelCount(width, height, depth))
   1432 		, m_internalFormat	(internalFormat)
   1433 	{
   1434 	}
   1435 
   1436 protected:
   1437 	void createTexture (void)
   1438 	{
   1439 		deUint32				tex				= 0;
   1440 		tcu::TextureLevel		data			(m_texFormat);
   1441 		de::Random				rnd				(deStringHash(getName()));
   1442 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1443 
   1444 		glGenTextures(1, &tex);
   1445 		glBindTexture(GL_TEXTURE_3D, tex);
   1446 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1447 
   1448 		// First specify full texture.
   1449 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1450 		{
   1451 			int		levelW		= de::max(1, m_width >> ndx);
   1452 			int		levelH		= de::max(1, m_height >> ndx);
   1453 			int		levelD		= de::max(1, m_depth >> ndx);
   1454 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1455 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1456 
   1457 			data.setSize(levelW, levelH, levelD);
   1458 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1459 
   1460 			glTexImage3D(GL_TEXTURE_3D, ndx, m_internalFormat, levelW, levelH, levelD, 0, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
   1461 		}
   1462 
   1463 		// Re-specify parts of each level.
   1464 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1465 		{
   1466 			int		levelW		= de::max(1, m_width >> ndx);
   1467 			int		levelH		= de::max(1, m_height >> ndx);
   1468 			int		levelD		= de::max(1, m_depth >> ndx);
   1469 
   1470 			int		w			= rnd.getInt(1, levelW);
   1471 			int		h			= rnd.getInt(1, levelH);
   1472 			int		d			= rnd.getInt(1, levelD);
   1473 			int		x			= rnd.getInt(0, levelW-w);
   1474 			int		y			= rnd.getInt(0, levelH-h);
   1475 			int		z			= rnd.getInt(0, levelD-d);
   1476 
   1477 			Vec4	colorA		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1478 			Vec4	colorB		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1479 			int		cellSize	= rnd.getInt(2, 16);
   1480 
   1481 			data.setSize(w, h, d);
   1482 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   1483 
   1484 			glTexSubImage3D(GL_TEXTURE_3D, ndx, x, y, z, w, h, d, transferFmt.format, transferFmt.dataType, data.getAccess().getDataPtr());
   1485 		}
   1486 	}
   1487 
   1488 	deUint32 m_internalFormat;
   1489 };
   1490 
   1491 // TexSubImage2D() to texture initialized with empty data
   1492 class TexSubImage2DEmptyTexCase : public Texture2DSpecCase
   1493 {
   1494 public:
   1495 	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1496 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1497 		, m_internalFormat	(format)
   1498 		, m_format			(format)
   1499 		, m_dataType		(dataType)
   1500 	{
   1501 	}
   1502 
   1503 	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1504 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, maxLevelCount(width, height))
   1505 		, m_internalFormat	(internalFormat)
   1506 		, m_format			(GL_NONE)
   1507 		, m_dataType		(GL_NONE)
   1508 	{
   1509 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1510 		m_format	= fmt.format;
   1511 		m_dataType	= fmt.dataType;
   1512 	}
   1513 
   1514 protected:
   1515 	void createTexture (void)
   1516 	{
   1517 		deUint32			tex			= 0;
   1518 		tcu::TextureLevel	data		(m_texFormat);
   1519 		de::Random			rnd			(deStringHash(getName()));
   1520 
   1521 		glGenTextures(1, &tex);
   1522 		glBindTexture(GL_TEXTURE_2D, tex);
   1523 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1524 
   1525 		// First allocate storage for each level.
   1526 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1527 		{
   1528 			int		levelW		= de::max(1, m_width >> ndx);
   1529 			int		levelH		= de::max(1, m_height >> ndx);
   1530 
   1531 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
   1532 		}
   1533 
   1534 		// Specify pixel data to all levels using glTexSubImage2D()
   1535 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1536 		{
   1537 			int		levelW		= de::max(1, m_width >> ndx);
   1538 			int		levelH		= de::max(1, m_height >> ndx);
   1539 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1540 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1541 
   1542 			data.setSize(levelW, levelH);
   1543 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1544 
   1545 			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
   1546 		}
   1547 	}
   1548 
   1549 	deUint32	m_internalFormat;
   1550 	deUint32	m_format;
   1551 	deUint32	m_dataType;
   1552 };
   1553 
   1554 // TexSubImage2D() to empty cubemap texture
   1555 class TexSubImageCubeEmptyTexCase : public TextureCubeSpecCase
   1556 {
   1557 public:
   1558 	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   1559 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   1560 		, m_internalFormat		(format)
   1561 		, m_format				(format)
   1562 		, m_dataType			(dataType)
   1563 	{
   1564 	}
   1565 
   1566 	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1567 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, deLog2Floor32(size)+1)
   1568 		, m_internalFormat		(internalFormat)
   1569 		, m_format				(GL_NONE)
   1570 		, m_dataType			(GL_NONE)
   1571 	{
   1572 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1573 		m_format	= fmt.format;
   1574 		m_dataType	= fmt.dataType;
   1575 	}
   1576 
   1577 protected:
   1578 	void createTexture (void)
   1579 	{
   1580 		deUint32			tex			= 0;
   1581 		tcu::TextureLevel	data		(m_texFormat);
   1582 		de::Random			rnd			(deStringHash(getName()));
   1583 
   1584 		glGenTextures(1, &tex);
   1585 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1586 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1587 
   1588 		// Specify storage for each level.
   1589 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1590 		{
   1591 			int levelSize = de::max(1, m_size >> ndx);
   1592 
   1593 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1594 				glTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, levelSize, levelSize, 0, m_format, m_dataType, DE_NULL);
   1595 		}
   1596 
   1597 		// Specify data using glTexSubImage2D()
   1598 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1599 		{
   1600 			int levelSize = de::max(1, m_size >> ndx);
   1601 
   1602 			data.setSize(levelSize, levelSize);
   1603 
   1604 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1605 			{
   1606 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1607 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1608 
   1609 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
   1610 
   1611 				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, m_format, m_dataType, data.getAccess().getDataPtr());
   1612 			}
   1613 		}
   1614 	}
   1615 
   1616 	deUint32	m_internalFormat;
   1617 	deUint32	m_format;
   1618 	deUint32	m_dataType;
   1619 };
   1620 
   1621 // TexSubImage2D() unpack alignment with 2D texture
   1622 class TexSubImage2DAlignCase : public Texture2DSpecCase
   1623 {
   1624 public:
   1625 	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)
   1626 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, 1)
   1627 		, m_internalFormat	(format)
   1628 		, m_format			(format)
   1629 		, m_dataType		(dataType)
   1630 		, m_subX			(subX)
   1631 		, m_subY			(subY)
   1632 		, m_subW			(subW)
   1633 		, m_subH			(subH)
   1634 		, m_alignment		(alignment)
   1635 	{
   1636 	}
   1637 
   1638 	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)
   1639 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   1640 		, m_internalFormat	(internalFormat)
   1641 		, m_format			(GL_NONE)
   1642 		, m_dataType		(GL_NONE)
   1643 		, m_subX			(subX)
   1644 		, m_subY			(subY)
   1645 		, m_subW			(subW)
   1646 		, m_subH			(subH)
   1647 		, m_alignment		(alignment)
   1648 	{
   1649 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1650 		m_format	= fmt.format;
   1651 		m_dataType	= fmt.dataType;
   1652 	}
   1653 
   1654 protected:
   1655 	void createTexture (void)
   1656 	{
   1657 		deUint32			tex			= 0;
   1658 		vector<deUint8>		data;
   1659 
   1660 		glGenTextures(1, &tex);
   1661 		glBindTexture(GL_TEXTURE_2D, tex);
   1662 
   1663 		// Specify base level.
   1664 		data.resize(m_texFormat.getPixelSize()*m_width*m_height);
   1665 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
   1666 
   1667 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1668 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, m_format, m_dataType, &data[0]);
   1669 
   1670 		// Re-specify subrectangle.
   1671 		int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
   1672 		data.resize(rowPitch*m_subH);
   1673 		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));
   1674 
   1675 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
   1676 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
   1677 	}
   1678 
   1679 	deUint32	m_internalFormat;
   1680 	deUint32	m_format;
   1681 	deUint32	m_dataType;
   1682 	int			m_subX;
   1683 	int			m_subY;
   1684 	int			m_subW;
   1685 	int			m_subH;
   1686 	int			m_alignment;
   1687 };
   1688 
   1689 // TexSubImage2D() unpack alignment with cubemap texture
   1690 class TexSubImageCubeAlignCase : public TextureCubeSpecCase
   1691 {
   1692 public:
   1693 	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)
   1694 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, 1)
   1695 		, m_internalFormat		(format)
   1696 		, m_format				(format)
   1697 		, m_dataType			(dataType)
   1698 		, m_subX				(subX)
   1699 		, m_subY				(subY)
   1700 		, m_subW				(subW)
   1701 		, m_subH				(subH)
   1702 		, m_alignment			(alignment)
   1703 	{
   1704 	}
   1705 
   1706 	TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int subX, int subY, int subW, int subH, int alignment)
   1707 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   1708 		, m_internalFormat		(internalFormat)
   1709 		, m_format				(GL_NONE)
   1710 		, m_dataType			(GL_NONE)
   1711 		, m_subX				(subX)
   1712 		, m_subY				(subY)
   1713 		, m_subW				(subW)
   1714 		, m_subH				(subH)
   1715 		, m_alignment			(alignment)
   1716 	{
   1717 		glu::TransferFormat fmt = glu::getTransferFormat(m_texFormat);
   1718 		m_format	= fmt.format;
   1719 		m_dataType	= fmt.dataType;
   1720 	}
   1721 
   1722 protected:
   1723 	void createTexture (void)
   1724 	{
   1725 		deUint32			tex			= 0;
   1726 		vector<deUint8>		data;
   1727 
   1728 		glGenTextures(1, &tex);
   1729 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1730 
   1731 		// Specify base level.
   1732 		data.resize(m_texFormat.getPixelSize()*m_size*m_size);
   1733 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
   1734 
   1735 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1736 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   1737 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, m_format, m_dataType, &data[0]);
   1738 
   1739 		// Re-specify subrectangle.
   1740 		int rowPitch = deAlign32(m_texFormat.getPixelSize()*m_subW, m_alignment);
   1741 		data.resize(rowPitch*m_subH);
   1742 		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));
   1743 
   1744 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
   1745 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   1746 			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
   1747 	}
   1748 
   1749 	deUint32	m_internalFormat;
   1750 	deUint32	m_format;
   1751 	deUint32	m_dataType;
   1752 	int			m_subX;
   1753 	int			m_subY;
   1754 	int			m_subW;
   1755 	int			m_subH;
   1756 	int			m_alignment;
   1757 };
   1758 
   1759 // TexSubImage3D() unpack parameters case.
   1760 class TexSubImage3DParamsCase : public Texture3DSpecCase
   1761 {
   1762 public:
   1763 	TexSubImage3DParamsCase (Context&		context,
   1764 							 const char*	name,
   1765 							 const char*	desc,
   1766 							 deUint32		internalFormat,
   1767 							 int			width,
   1768 							 int			height,
   1769 							 int			depth,
   1770 							 int			subX,
   1771 							 int			subY,
   1772 							 int			subZ,
   1773 							 int			subW,
   1774 							 int			subH,
   1775 							 int			subD,
   1776 							 int			imageHeight,
   1777 							 int			rowLength,
   1778 							 int			skipImages,
   1779 							 int			skipRows,
   1780 							 int			skipPixels,
   1781 							 int			alignment)
   1782 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   1783 		, m_internalFormat	(internalFormat)
   1784 		, m_subX			(subX)
   1785 		, m_subY			(subY)
   1786 		, m_subZ			(subZ)
   1787 		, m_subW			(subW)
   1788 		, m_subH			(subH)
   1789 		, m_subD			(subD)
   1790 		, m_imageHeight		(imageHeight)
   1791 		, m_rowLength		(rowLength)
   1792 		, m_skipImages		(skipImages)
   1793 		, m_skipRows		(skipRows)
   1794 		, m_skipPixels		(skipPixels)
   1795 		, m_alignment		(alignment)
   1796 	{
   1797 	}
   1798 
   1799 protected:
   1800 	void createTexture (void)
   1801 	{
   1802 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   1803 		int						pixelSize		= m_texFormat.getPixelSize();
   1804 		deUint32				tex				= 0;
   1805 		vector<deUint8>			data;
   1806 
   1807 		DE_ASSERT(m_numLevels == 1);
   1808 
   1809 		glGenTextures(1, &tex);
   1810 		glBindTexture(GL_TEXTURE_3D, tex);
   1811 
   1812 		// Fill with gradient.
   1813 		{
   1814 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   1815 			int		slicePitch		= rowPitch*m_height;
   1816 
   1817 			data.resize(slicePitch*m_depth);
   1818 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   1819 		}
   1820 
   1821 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   1822 
   1823 		// Fill data with grid.
   1824 		{
   1825 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   1826 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   1827 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   1828 			int		slicePitch		= imageHeight*rowPitch;
   1829 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   1830 			Vec4	cBias			= m_texFormatInfo.valueMin;
   1831 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   1832 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   1833 
   1834 			data.resize(slicePitch*(m_depth+m_skipImages));
   1835 			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);
   1836 		}
   1837 
   1838 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   1839 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   1840 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   1841 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   1842 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   1843 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   1844 		glTexSubImage3D(GL_TEXTURE_3D, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, &data[0]);
   1845 	}
   1846 
   1847 	deUint32	m_internalFormat;
   1848 	int			m_subX;
   1849 	int			m_subY;
   1850 	int			m_subZ;
   1851 	int			m_subW;
   1852 	int			m_subH;
   1853 	int			m_subD;
   1854 	int			m_imageHeight;
   1855 	int			m_rowLength;
   1856 	int			m_skipImages;
   1857 	int			m_skipRows;
   1858 	int			m_skipPixels;
   1859 	int			m_alignment;
   1860 };
   1861 
   1862 // Basic CopyTexImage2D() with 2D texture usage
   1863 class BasicCopyTexImage2DCase : public Texture2DSpecCase
   1864 {
   1865 public:
   1866 	BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height)
   1867 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), width, height, maxLevelCount(width, height))
   1868 		, m_internalFormat	(internalFormat)
   1869 	{
   1870 	}
   1871 
   1872 protected:
   1873 	void createTexture (void)
   1874 	{
   1875 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1876 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1877 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1878 		tcu::TextureFormat			fmt				= mapGLUnsizedInternalFormat(m_internalFormat);
   1879 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1880 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1881 		deUint32					tex				= 0;
   1882 		de::Random					rnd				(deStringHash(getName()));
   1883 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1884 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1885 
   1886 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1887 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1888 
   1889 		// Fill render target with gradient.
   1890 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   1891 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   1892 
   1893 		glGenTextures(1, &tex);
   1894 		glBindTexture(GL_TEXTURE_2D, tex);
   1895 
   1896 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1897 		{
   1898 			int		levelW		= de::max(1, m_width >> ndx);
   1899 			int		levelH		= de::max(1, m_height >> ndx);
   1900 			int		x			= rnd.getInt(0, getWidth()	- levelW);
   1901 			int		y			= rnd.getInt(0, getHeight()	- levelH);
   1902 
   1903 			glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
   1904 		}
   1905 	}
   1906 
   1907 	deUint32 m_internalFormat;
   1908 };
   1909 
   1910 // Basic CopyTexImage2D() with cubemap usage
   1911 class BasicCopyTexImageCubeCase : public TextureCubeSpecCase
   1912 {
   1913 public:
   1914 	BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size)
   1915 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(internalFormat, GL_UNSIGNED_BYTE), size, deLog2Floor32(size)+1)
   1916 		, m_internalFormat		(internalFormat)
   1917 	{
   1918 	}
   1919 
   1920 protected:
   1921 	void createTexture (void)
   1922 	{
   1923 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1924 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1925 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1926 		tcu::TextureFormat			fmt				= mapGLUnsizedInternalFormat(m_internalFormat);
   1927 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1928 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1929 		deUint32					tex				= 0;
   1930 		de::Random					rnd				(deStringHash(getName()));
   1931 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1932 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1933 
   1934 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1935 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1936 
   1937 		// Fill render target with gradient.
   1938 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   1939 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   1940 
   1941 		glGenTextures(1, &tex);
   1942 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   1943 
   1944 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1945 		{
   1946 			int levelSize = de::max(1, m_size >> ndx);
   1947 
   1948 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   1949 			{
   1950 				int x = rnd.getInt(0, getWidth()	- levelSize);
   1951 				int y = rnd.getInt(0, getHeight()	- levelSize);
   1952 
   1953 				glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelSize, levelSize, 0);
   1954 			}
   1955 		}
   1956 	}
   1957 
   1958 	deUint32 m_internalFormat;
   1959 };
   1960 
   1961 // Basic CopyTexSubImage2D() with 2D texture usage
   1962 class BasicCopyTexSubImage2DCase : public Texture2DSpecCase
   1963 {
   1964 public:
   1965 	BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height)
   1966 		: Texture2DSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), width, height, maxLevelCount(width, height))
   1967 		, m_format			(format)
   1968 		, m_dataType		(dataType)
   1969 	{
   1970 	}
   1971 
   1972 protected:
   1973 	void createTexture (void)
   1974 	{
   1975 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   1976 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   1977 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   1978 		tcu::TextureFormat			fmt				= glu::mapGLTransferFormat(m_format, m_dataType);
   1979 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   1980 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   1981 		deUint32					tex				= 0;
   1982 		tcu::TextureLevel			data			(fmt);
   1983 		de::Random					rnd				(deStringHash(getName()));
   1984 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   1985 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   1986 
   1987 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   1988 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   1989 
   1990 		glGenTextures(1, &tex);
   1991 		glBindTexture(GL_TEXTURE_2D, tex);
   1992 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1993 
   1994 		// First specify full texture.
   1995 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   1996 		{
   1997 			int		levelW		= de::max(1, m_width >> ndx);
   1998 			int		levelH		= de::max(1, m_height >> ndx);
   1999 
   2000 			Vec4	colorA		= randomVector<4>(rnd);
   2001 			Vec4	colorB		= randomVector<4>(rnd);
   2002 			int		cellSize	= rnd.getInt(2, 16);
   2003 
   2004 			data.setSize(levelW, levelH);
   2005 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   2006 
   2007 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   2008 		}
   2009 
   2010 		// Fill render target with gradient.
   2011 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   2012 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   2013 
   2014 		// Re-specify parts of each level.
   2015 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2016 		{
   2017 			int		levelW		= de::max(1, m_width >> ndx);
   2018 			int		levelH		= de::max(1, m_height >> ndx);
   2019 
   2020 			int		w			= rnd.getInt(1, levelW);
   2021 			int		h			= rnd.getInt(1, levelH);
   2022 			int		xo			= rnd.getInt(0, levelW-w);
   2023 			int		yo			= rnd.getInt(0, levelH-h);
   2024 
   2025 			int		x			= rnd.getInt(0, getWidth() - w);
   2026 			int		y			= rnd.getInt(0, getHeight() - h);
   2027 
   2028 			glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
   2029 		}
   2030 	}
   2031 
   2032 	deUint32	m_format;
   2033 	deUint32	m_dataType;
   2034 };
   2035 
   2036 // Basic CopyTexSubImage2D() with cubemap usage
   2037 class BasicCopyTexSubImageCubeCase : public TextureCubeSpecCase
   2038 {
   2039 public:
   2040 	BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int size)
   2041 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLTransferFormat(format, dataType), size, deLog2Floor32(size)+1)
   2042 		, m_format				(format)
   2043 		, m_dataType			(dataType)
   2044 	{
   2045 	}
   2046 
   2047 protected:
   2048 	void createTexture (void)
   2049 	{
   2050 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
   2051 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
   2052 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
   2053 		tcu::TextureFormat			fmt				= glu::mapGLTransferFormat(m_format, m_dataType);
   2054 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
   2055 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
   2056 		deUint32					tex				= 0;
   2057 		tcu::TextureLevel			data			(fmt);
   2058 		de::Random					rnd				(deStringHash(getName()));
   2059 		GradientShader				shader			(glu::TYPE_FLOAT_VEC4);
   2060 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
   2061 
   2062 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
   2063 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
   2064 
   2065 		glGenTextures(1, &tex);
   2066 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2067 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2068 
   2069 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2070 		{
   2071 			int levelSize = de::max(1, m_size >> ndx);
   2072 
   2073 			data.setSize(levelSize, levelSize);
   2074 
   2075 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2076 			{
   2077 				Vec4	colorA		= randomVector<4>(rnd);
   2078 				Vec4	colorB		= randomVector<4>(rnd);
   2079 				int		cellSize	= rnd.getInt(2, 16);
   2080 
   2081 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
   2082 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelSize, levelSize, 0, m_format, m_dataType, data.getAccess().getDataPtr());
   2083 			}
   2084 		}
   2085 
   2086 		// Fill render target with gradient.
   2087 		shader.setGradient(*getCurrentContext(), shaderID, Vec4(0.0f), Vec4(1.0f));
   2088 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
   2089 
   2090 		// Re-specify parts of each face and level.
   2091 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2092 		{
   2093 			int levelSize = de::max(1, m_size >> ndx);
   2094 
   2095 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2096 			{
   2097 				int		w			= rnd.getInt(1, levelSize);
   2098 				int		h			= rnd.getInt(1, levelSize);
   2099 				int		xo			= rnd.getInt(0, levelSize-w);
   2100 				int		yo			= rnd.getInt(0, levelSize-h);
   2101 
   2102 				int		x			= rnd.getInt(0, getWidth() - w);
   2103 				int		y			= rnd.getInt(0, getHeight() - h);
   2104 
   2105 				glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
   2106 			}
   2107 		}
   2108 	}
   2109 
   2110 	deUint32	m_format;
   2111 	deUint32	m_dataType;
   2112 };
   2113 
   2114 // Basic glTexStorage2D() with 2D texture usage
   2115 class BasicTexStorage2DCase : public Texture2DSpecCase
   2116 {
   2117 public:
   2118 	BasicTexStorage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLevels)
   2119 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLevels)
   2120 		, m_internalFormat	(internalFormat)
   2121 	{
   2122 	}
   2123 
   2124 protected:
   2125 	void createTexture (void)
   2126 	{
   2127 		tcu::TextureFormat		fmt				= glu::mapGLInternalFormat(m_internalFormat);
   2128 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(fmt);
   2129 		deUint32				tex				= 0;
   2130 		tcu::TextureLevel		levelData		(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2131 		de::Random				rnd				(deStringHash(getName()));
   2132 
   2133 		glGenTextures(1, &tex);
   2134 		glBindTexture(GL_TEXTURE_2D, tex);
   2135 		glTexStorage2D(GL_TEXTURE_2D, m_numLevels, m_internalFormat, m_width, m_height);
   2136 
   2137 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2138 
   2139 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2140 		{
   2141 			int		levelW		= de::max(1, m_width >> ndx);
   2142 			int		levelH		= de::max(1, m_height >> ndx);
   2143 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2144 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2145 
   2146 			levelData.setSize(levelW, levelH);
   2147 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2148 
   2149 			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2150 		}
   2151 	}
   2152 
   2153 	deUint32 m_internalFormat;
   2154 };
   2155 
   2156 // Basic glTexStorage2D() with cubemap usage
   2157 class BasicTexStorageCubeCase : public TextureCubeSpecCase
   2158 {
   2159 public:
   2160 	BasicTexStorageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLevels)
   2161 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLevels)
   2162 		, m_internalFormat		(internalFormat)
   2163 	{
   2164 	}
   2165 
   2166 protected:
   2167 	void createTexture (void)
   2168 	{
   2169 		tcu::TextureFormat		fmt				= glu::mapGLInternalFormat(m_internalFormat);
   2170 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(fmt);
   2171 		deUint32				tex				= 0;
   2172 		tcu::TextureLevel		levelData		(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2173 		de::Random				rnd				(deStringHash(getName()));
   2174 
   2175 		glGenTextures(1, &tex);
   2176 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2177 		glTexStorage2D(GL_TEXTURE_CUBE_MAP, m_numLevels, m_internalFormat, m_size, m_size);
   2178 
   2179 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2180 
   2181 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2182 		{
   2183 			int levelSize = de::max(1, m_size >> ndx);
   2184 
   2185 			levelData.setSize(levelSize, levelSize);
   2186 
   2187 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2188 			{
   2189 				Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2190 				Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2191 
   2192 				tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2193 
   2194 				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelSize, levelSize, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2195 			}
   2196 		}
   2197 	}
   2198 
   2199 	deUint32 m_internalFormat;
   2200 };
   2201 
   2202 // Basic glTexStorage3D() with 2D array texture usage
   2203 class BasicTexStorage2DArrayCase : public Texture2DArraySpecCase
   2204 {
   2205 public:
   2206 	BasicTexStorage2DArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int numLayers, int numLevels)
   2207 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, numLayers, numLevels)
   2208 		, m_internalFormat			(internalFormat)
   2209 	{
   2210 	}
   2211 
   2212 protected:
   2213 	void createTexture (void)
   2214 	{
   2215 		deUint32				tex			= 0;
   2216 		de::Random				rnd			(deStringHash(getName()));
   2217 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
   2218 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2219 
   2220 		glGenTextures	(1, &tex);
   2221 		glBindTexture	(GL_TEXTURE_2D_ARRAY, tex);
   2222 		glTexStorage3D	(GL_TEXTURE_2D_ARRAY, m_numLevels, m_internalFormat, m_width, m_height, m_numLayers);
   2223 
   2224 		glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
   2225 
   2226 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2227 		{
   2228 			int		levelW		= de::max(1, m_width	>> ndx);
   2229 			int		levelH		= de::max(1, m_height	>> ndx);
   2230 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2231 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2232 
   2233 			levelData.setSize(levelW, levelH, m_numLayers);
   2234 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2235 
   2236 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH, m_numLayers, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2237 		}
   2238 	}
   2239 
   2240 	deUint32 m_internalFormat;
   2241 };
   2242 
   2243 // Basic TexStorage3D() with 3D texture usage
   2244 class BasicTexStorage3DCase : public Texture3DSpecCase
   2245 {
   2246 public:
   2247 	BasicTexStorage3DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int width, int height, int depth, int numLevels)
   2248 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, numLevels)
   2249 		, m_internalFormat	(internalFormat)
   2250 	{
   2251 	}
   2252 
   2253 protected:
   2254 	void createTexture (void)
   2255 	{
   2256 		deUint32				tex			= 0;
   2257 		de::Random				rnd			(deStringHash(getName()));
   2258 		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
   2259 		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));
   2260 
   2261 		glGenTextures	(1, &tex);
   2262 		glBindTexture	(GL_TEXTURE_3D, tex);
   2263 		glTexStorage3D	(GL_TEXTURE_3D, m_numLevels, m_internalFormat, m_width, m_height, m_depth);
   2264 
   2265 		glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
   2266 
   2267 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   2268 		{
   2269 			int		levelW		= de::max(1, m_width	>> ndx);
   2270 			int		levelH		= de::max(1, m_height	>> ndx);
   2271 			int		levelD		= de::max(1, m_depth	>> ndx);
   2272 			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2273 			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2274 
   2275 			levelData.setSize(levelW, levelH, levelD);
   2276 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   2277 
   2278 			glTexSubImage3D(GL_TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH, levelD, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
   2279 		}
   2280 	}
   2281 
   2282 	deUint32 m_internalFormat;
   2283 };
   2284 
   2285 // Pixel buffer object cases.
   2286 
   2287 // TexImage2D() from pixel buffer object.
   2288 class TexImage2DBufferCase : public Texture2DSpecCase
   2289 {
   2290 public:
   2291 	TexImage2DBufferCase (Context&		context,
   2292 						  const char*	name,
   2293 						  const char*	desc,
   2294 						  deUint32		internalFormat,
   2295 						  int			width,
   2296 						  int			height,
   2297 						  int			rowLength,
   2298 						  int			skipRows,
   2299 						  int			skipPixels,
   2300 						  int			alignment,
   2301 						  int			offset)
   2302 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   2303 		, m_internalFormat	(internalFormat)
   2304 		, m_rowLength		(rowLength)
   2305 		, m_skipRows		(skipRows)
   2306 		, m_skipPixels		(skipPixels)
   2307 		, m_alignment		(alignment)
   2308 		, m_offset			(offset)
   2309 	{
   2310 	}
   2311 
   2312 protected:
   2313 	void createTexture (void)
   2314 	{
   2315 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2316 		int						pixelSize		= m_texFormat.getPixelSize();
   2317 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width + m_skipPixels;
   2318 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2319 		int						height			= m_height + m_skipRows;
   2320 		deUint32				buf				= 0;
   2321 		deUint32				tex				= 0;
   2322 		vector<deUint8>			data;
   2323 
   2324 		DE_ASSERT(m_numLevels == 1);
   2325 
   2326 		// Fill data with grid.
   2327 		data.resize(rowPitch*height + m_offset);
   2328 		{
   2329 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2330 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2331 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2332 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2333 
   2334 			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);
   2335 		}
   2336 
   2337 		// Create buffer and upload.
   2338 		glGenBuffers(1, &buf);
   2339 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2340 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2341 
   2342 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2343 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2344 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2345 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2346 
   2347 		glGenTextures(1, &tex);
   2348 		glBindTexture(GL_TEXTURE_2D, tex);
   2349 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2350 	}
   2351 
   2352 	deUint32	m_internalFormat;
   2353 	int			m_rowLength;
   2354 	int			m_skipRows;
   2355 	int			m_skipPixels;
   2356 	int			m_alignment;
   2357 	int			m_offset;
   2358 };
   2359 
   2360 // TexImage2D() cubemap from pixel buffer object case
   2361 class TexImageCubeBufferCase : public TextureCubeSpecCase
   2362 {
   2363 public:
   2364 	TexImageCubeBufferCase (Context&	context,
   2365 							const char*	name,
   2366 							const char*	desc,
   2367 							deUint32	internalFormat,
   2368 							int			size,
   2369 							int			rowLength,
   2370 							int			skipRows,
   2371 							int			skipPixels,
   2372 							int			alignment,
   2373 							int			offset)
   2374 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   2375 		, m_internalFormat		(internalFormat)
   2376 		, m_rowLength			(rowLength)
   2377 		, m_skipRows			(skipRows)
   2378 		, m_skipPixels			(skipPixels)
   2379 		, m_alignment			(alignment)
   2380 		, m_offset				(offset)
   2381 	{
   2382 	}
   2383 
   2384 protected:
   2385 	void createTexture (void)
   2386 	{
   2387 		de::Random					rnd			(deStringHash(getName()));
   2388 		deUint32					tex			= 0;
   2389 		glu::TransferFormat			fmt			= glu::getTransferFormat(m_texFormat);
   2390 		const int					pixelSize	= m_texFormat.getPixelSize();
   2391 		const int					rowLength	= m_rowLength > 0 ? m_rowLength : m_size + m_skipPixels;
   2392 		const int					rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2393 		const int					height		= m_size + m_skipRows;
   2394 		vector<vector<deUint8> >	data		(DE_LENGTH_OF_ARRAY(s_cubeMapFaces));
   2395 
   2396 		DE_ASSERT(m_numLevels == 1);
   2397 
   2398 		glGenTextures(1, &tex);
   2399 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2400 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2401 
   2402 		for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2403 		{
   2404 			deUint32 buf = 0;
   2405 
   2406 			{
   2407 				const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2408 				const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2409 
   2410 				data[face].resize(rowPitch*height + m_offset);
   2411 				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);
   2412 			}
   2413 
   2414 			// Create buffer and upload.
   2415 			glGenBuffers(1, &buf);
   2416 			glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2417 			glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data[face].size(), &data[face][0], GL_STATIC_DRAW);
   2418 
   2419 			glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2420 			glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2421 			glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2422 			glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2423 
   2424 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, fmt.format, fmt.dataType, (const void*)(deUintptr)m_offset);
   2425 		}
   2426 	}
   2427 
   2428 	deUint32	m_internalFormat;
   2429 	int			m_rowLength;
   2430 	int			m_skipRows;
   2431 	int			m_skipPixels;
   2432 	int			m_alignment;
   2433 	int			m_offset;
   2434 };
   2435 
   2436 // TexImage3D() 2D array from pixel buffer object.
   2437 class TexImage2DArrayBufferCase : public Texture2DArraySpecCase
   2438 {
   2439 public:
   2440 	TexImage2DArrayBufferCase (Context&		context,
   2441 							   const char*	name,
   2442 							   const char*	desc,
   2443 							   deUint32		internalFormat,
   2444 							   int			width,
   2445 							   int			height,
   2446 							   int			depth,
   2447 							   int			imageHeight,
   2448 							   int			rowLength,
   2449 							   int			skipImages,
   2450 							   int			skipRows,
   2451 							   int			skipPixels,
   2452 							   int			alignment,
   2453 							   int			offset)
   2454 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2455 		, m_internalFormat			(internalFormat)
   2456 		, m_imageHeight				(imageHeight)
   2457 		, m_rowLength				(rowLength)
   2458 		, m_skipImages				(skipImages)
   2459 		, m_skipRows				(skipRows)
   2460 		, m_skipPixels				(skipPixels)
   2461 		, m_alignment				(alignment)
   2462 		, m_offset					(offset)
   2463 	{
   2464 	}
   2465 
   2466 protected:
   2467 	void createTexture (void)
   2468 	{
   2469 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2470 		int						pixelSize		= m_texFormat.getPixelSize();
   2471 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   2472 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2473 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   2474 		int						slicePitch		= imageHeight*rowPitch;
   2475 		deUint32				tex				= 0;
   2476 		deUint32				buf				= 0;
   2477 		vector<deUint8>			data;
   2478 
   2479 		DE_ASSERT(m_numLevels == 1);
   2480 
   2481 		// Fill data with grid.
   2482 		data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
   2483 		{
   2484 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2485 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2486 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2487 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2488 
   2489 			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);
   2490 		}
   2491 
   2492 		glGenBuffers(1, &buf);
   2493 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2494 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2495 
   2496 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2497 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2498 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2499 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2500 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2501 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2502 
   2503 		glGenTextures(1, &tex);
   2504 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   2505 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2506 	}
   2507 
   2508 	deUint32	m_internalFormat;
   2509 	int			m_imageHeight;
   2510 	int			m_rowLength;
   2511 	int			m_skipImages;
   2512 	int			m_skipRows;
   2513 	int			m_skipPixels;
   2514 	int			m_alignment;
   2515 	int			m_offset;
   2516 };
   2517 
   2518 // TexImage3D() from pixel buffer object.
   2519 class TexImage3DBufferCase : public Texture3DSpecCase
   2520 {
   2521 public:
   2522 	TexImage3DBufferCase (Context&		context,
   2523 						  const char*	name,
   2524 						  const char*	desc,
   2525 						  deUint32		internalFormat,
   2526 						  int			width,
   2527 						  int			height,
   2528 						  int			depth,
   2529 						  int			imageHeight,
   2530 						  int			rowLength,
   2531 						  int			skipImages,
   2532 						  int			skipRows,
   2533 						  int			skipPixels,
   2534 						  int			alignment,
   2535 						  int			offset)
   2536 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2537 		, m_internalFormat	(internalFormat)
   2538 		, m_imageHeight		(imageHeight)
   2539 		, m_rowLength		(rowLength)
   2540 		, m_skipImages		(skipImages)
   2541 		, m_skipRows		(skipRows)
   2542 		, m_skipPixels		(skipPixels)
   2543 		, m_alignment		(alignment)
   2544 		, m_offset			(offset)
   2545 	{
   2546 	}
   2547 
   2548 protected:
   2549 	void createTexture (void)
   2550 	{
   2551 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2552 		int						pixelSize		= m_texFormat.getPixelSize();
   2553 		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_width;
   2554 		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2555 		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_height;
   2556 		int						slicePitch		= imageHeight*rowPitch;
   2557 		deUint32				tex				= 0;
   2558 		deUint32				buf				= 0;
   2559 		vector<deUint8>			data;
   2560 
   2561 		DE_ASSERT(m_numLevels == 1);
   2562 
   2563 		// Fill data with grid.
   2564 		data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
   2565 		{
   2566 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2567 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2568 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2569 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2570 
   2571 			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);
   2572 		}
   2573 
   2574 		glGenBuffers(1, &buf);
   2575 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   2576 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   2577 
   2578 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2579 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2580 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2581 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2582 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2583 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2584 
   2585 		glGenTextures(1, &tex);
   2586 		glBindTexture(GL_TEXTURE_3D, tex);
   2587 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2588 	}
   2589 
   2590 	deUint32	m_internalFormat;
   2591 	int			m_imageHeight;
   2592 	int			m_rowLength;
   2593 	int			m_skipImages;
   2594 	int			m_skipRows;
   2595 	int			m_skipPixels;
   2596 	int			m_alignment;
   2597 	int			m_offset;
   2598 };
   2599 
   2600 // TexSubImage2D() PBO case.
   2601 class TexSubImage2DBufferCase : public Texture2DSpecCase
   2602 {
   2603 public:
   2604 	TexSubImage2DBufferCase (Context&		context,
   2605 							 const char*	name,
   2606 							 const char*	desc,
   2607 							 deUint32		internalFormat,
   2608 							 int			width,
   2609 							 int			height,
   2610 							 int			subX,
   2611 							 int			subY,
   2612 							 int			subW,
   2613 							 int			subH,
   2614 							 int			rowLength,
   2615 							 int			skipRows,
   2616 							 int			skipPixels,
   2617 							 int			alignment,
   2618 							 int			offset)
   2619 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, 1)
   2620 		, m_internalFormat	(internalFormat)
   2621 		, m_subX			(subX)
   2622 		, m_subY			(subY)
   2623 		, m_subW			(subW)
   2624 		, m_subH			(subH)
   2625 		, m_rowLength		(rowLength)
   2626 		, m_skipRows		(skipRows)
   2627 		, m_skipPixels		(skipPixels)
   2628 		, m_alignment		(alignment)
   2629 		, m_offset			(offset)
   2630 	{
   2631 	}
   2632 
   2633 protected:
   2634 	void createTexture (void)
   2635 	{
   2636 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2637 		int						pixelSize		= m_texFormat.getPixelSize();
   2638 		deUint32				tex				= 0;
   2639 		deUint32				buf				= 0;
   2640 		vector<deUint8>			data;
   2641 
   2642 		DE_ASSERT(m_numLevels == 1);
   2643 
   2644 		glGenTextures(1, &tex);
   2645 		glBindTexture(GL_TEXTURE_2D, tex);
   2646 
   2647 		// First fill texture with gradient.
   2648 		data.resize(deAlign32(m_width*pixelSize, 4)*m_height);
   2649 		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);
   2650 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2651 
   2652 		// Fill data with grid.
   2653 		{
   2654 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   2655 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2656 			int		height		= m_subH + m_skipRows;
   2657 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2658 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2659 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2660 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2661 
   2662 			data.resize(rowPitch*height + m_offset);
   2663 			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);
   2664 		}
   2665 
   2666 		glGenBuffers(1, &buf);
   2667 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2668 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2669 
   2670 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2671 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2672 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2673 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2674 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2675 	}
   2676 
   2677 	deUint32	m_internalFormat;
   2678 	int			m_subX;
   2679 	int			m_subY;
   2680 	int			m_subW;
   2681 	int			m_subH;
   2682 	int			m_rowLength;
   2683 	int			m_skipRows;
   2684 	int			m_skipPixels;
   2685 	int			m_alignment;
   2686 	int			m_offset;
   2687 };
   2688 
   2689 // TexSubImage2D() cubemap PBO case.
   2690 class TexSubImageCubeBufferCase : public TextureCubeSpecCase
   2691 {
   2692 public:
   2693 	TexSubImageCubeBufferCase	(Context&		context,
   2694 								 const char*	name,
   2695 								 const char*	desc,
   2696 								 deUint32		internalFormat,
   2697 								 int			size,
   2698 								 int			subX,
   2699 								 int			subY,
   2700 								 int			subW,
   2701 								 int			subH,
   2702 								 int			rowLength,
   2703 								 int			skipRows,
   2704 								 int			skipPixels,
   2705 								 int			alignment,
   2706 								 int			offset)
   2707 		: TextureCubeSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, 1)
   2708 		, m_internalFormat		(internalFormat)
   2709 		, m_subX				(subX)
   2710 		, m_subY				(subY)
   2711 		, m_subW				(subW)
   2712 		, m_subH				(subH)
   2713 		, m_rowLength			(rowLength)
   2714 		, m_skipRows			(skipRows)
   2715 		, m_skipPixels			(skipPixels)
   2716 		, m_alignment			(alignment)
   2717 		, m_offset				(offset)
   2718 	{
   2719 	}
   2720 
   2721 protected:
   2722 	void createTexture (void)
   2723 	{
   2724 		de::Random				rnd				(deStringHash(getName()));
   2725 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2726 		int						pixelSize		= m_texFormat.getPixelSize();
   2727 		deUint32				tex				= 0;
   2728 		deUint32				buf				= 0;
   2729 		vector<deUint8>			data;
   2730 
   2731 		DE_ASSERT(m_numLevels == 1);
   2732 
   2733 		glGenTextures(1, &tex);
   2734 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
   2735 
   2736 		// Fill faces with different gradients.
   2737 
   2738 		data.resize(deAlign32(m_size*pixelSize, 4)*m_size);
   2739 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   2740 
   2741 		for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
   2742 		{
   2743 			const Vec4 gMin = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2744 			const Vec4 gMax = randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2745 
   2746 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, 1, deAlign32(m_size*pixelSize, 4), 0, &data[0]), gMin, gMax);
   2747 
   2748 			glTexImage2D(s_cubeMapFaces[face], 0, m_internalFormat, m_size, m_size, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2749 		}
   2750 
   2751 		// Fill data with grid.
   2752 		{
   2753 			int		rowLength	= m_rowLength > 0 ? m_rowLength : m_subW;
   2754 			int		rowPitch	= deAlign32(rowLength*pixelSize, m_alignment);
   2755 			int		height		= m_subH + m_skipRows;
   2756 			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2757 			Vec4	cBias		= m_texFormatInfo.valueMin;
   2758 			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2759 			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2760 
   2761 			data.resize(rowPitch*height + m_offset);
   2762 			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);
   2763 		}
   2764 
   2765 		glGenBuffers(1, &buf);
   2766 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2767 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2768 
   2769 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2770 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2771 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2772 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2773 
   2774 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
   2775 			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
   2776 	}
   2777 
   2778 	deUint32	m_internalFormat;
   2779 	int			m_subX;
   2780 	int			m_subY;
   2781 	int			m_subW;
   2782 	int			m_subH;
   2783 	int			m_rowLength;
   2784 	int			m_skipRows;
   2785 	int			m_skipPixels;
   2786 	int			m_alignment;
   2787 	int			m_offset;
   2788 };
   2789 
   2790 // TexSubImage3D() 2D array PBO case.
   2791 class TexSubImage2DArrayBufferCase : public Texture2DArraySpecCase
   2792 {
   2793 public:
   2794 	TexSubImage2DArrayBufferCase (Context&		context,
   2795 								 const char*	name,
   2796 								 const char*	desc,
   2797 								 deUint32		internalFormat,
   2798 								 int			width,
   2799 								 int			height,
   2800 								 int			depth,
   2801 								 int			subX,
   2802 								 int			subY,
   2803 								 int			subZ,
   2804 								 int			subW,
   2805 								 int			subH,
   2806 								 int			subD,
   2807 								 int			imageHeight,
   2808 								 int			rowLength,
   2809 								 int			skipImages,
   2810 								 int			skipRows,
   2811 								 int			skipPixels,
   2812 								 int			alignment,
   2813 								 int			offset)
   2814 		: Texture2DArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2815 		, m_internalFormat			(internalFormat)
   2816 		, m_subX					(subX)
   2817 		, m_subY					(subY)
   2818 		, m_subZ					(subZ)
   2819 		, m_subW					(subW)
   2820 		, m_subH					(subH)
   2821 		, m_subD					(subD)
   2822 		, m_imageHeight				(imageHeight)
   2823 		, m_rowLength				(rowLength)
   2824 		, m_skipImages				(skipImages)
   2825 		, m_skipRows				(skipRows)
   2826 		, m_skipPixels				(skipPixels)
   2827 		, m_alignment				(alignment)
   2828 		, m_offset					(offset)
   2829 	{
   2830 	}
   2831 
   2832 protected:
   2833 	void createTexture (void)
   2834 	{
   2835 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2836 		int						pixelSize		= m_texFormat.getPixelSize();
   2837 		deUint32				tex				= 0;
   2838 		deUint32				buf				= 0;
   2839 		vector<deUint8>			data;
   2840 
   2841 		DE_ASSERT(m_numLevels == 1);
   2842 
   2843 		glGenTextures(1, &tex);
   2844 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   2845 
   2846 		// Fill with gradient.
   2847 		{
   2848 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   2849 			int		slicePitch		= rowPitch*m_height;
   2850 
   2851 			data.resize(slicePitch*m_numLayers);
   2852 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2853 		}
   2854 
   2855 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2856 
   2857 		// Fill data with grid.
   2858 		{
   2859 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   2860 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2861 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   2862 			int		slicePitch		= imageHeight*rowPitch;
   2863 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2864 			Vec4	cBias			= m_texFormatInfo.valueMin;
   2865 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2866 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2867 
   2868 			data.resize(slicePitch*(m_numLayers+m_skipImages) + m_offset);
   2869 			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);
   2870 		}
   2871 
   2872 		glGenBuffers(1, &buf);
   2873 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2874 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2875 
   2876 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2877 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2878 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2879 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2880 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2881 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2882 		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);
   2883 	}
   2884 
   2885 	deUint32	m_internalFormat;
   2886 	int			m_subX;
   2887 	int			m_subY;
   2888 	int			m_subZ;
   2889 	int			m_subW;
   2890 	int			m_subH;
   2891 	int			m_subD;
   2892 	int			m_imageHeight;
   2893 	int			m_rowLength;
   2894 	int			m_skipImages;
   2895 	int			m_skipRows;
   2896 	int			m_skipPixels;
   2897 	int			m_alignment;
   2898 	int			m_offset;
   2899 };
   2900 
   2901 // TexSubImage3D() PBO case.
   2902 class TexSubImage3DBufferCase : public Texture3DSpecCase
   2903 {
   2904 public:
   2905 	TexSubImage3DBufferCase (Context&		context,
   2906 							 const char*	name,
   2907 							 const char*	desc,
   2908 							 deUint32		internalFormat,
   2909 							 int			width,
   2910 							 int			height,
   2911 							 int			depth,
   2912 							 int			subX,
   2913 							 int			subY,
   2914 							 int			subZ,
   2915 							 int			subW,
   2916 							 int			subH,
   2917 							 int			subD,
   2918 							 int			imageHeight,
   2919 							 int			rowLength,
   2920 							 int			skipImages,
   2921 							 int			skipRows,
   2922 							 int			skipPixels,
   2923 							 int			alignment,
   2924 							 int			offset)
   2925 		: Texture3DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), width, height, depth, 1)
   2926 		, m_internalFormat	(internalFormat)
   2927 		, m_subX			(subX)
   2928 		, m_subY			(subY)
   2929 		, m_subZ			(subZ)
   2930 		, m_subW			(subW)
   2931 		, m_subH			(subH)
   2932 		, m_subD			(subD)
   2933 		, m_imageHeight		(imageHeight)
   2934 		, m_rowLength		(rowLength)
   2935 		, m_skipImages		(skipImages)
   2936 		, m_skipRows		(skipRows)
   2937 		, m_skipPixels		(skipPixels)
   2938 		, m_alignment		(alignment)
   2939 		, m_offset			(offset)
   2940 	{
   2941 	}
   2942 
   2943 protected:
   2944 	void createTexture (void)
   2945 	{
   2946 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   2947 		int						pixelSize		= m_texFormat.getPixelSize();
   2948 		deUint32				tex				= 0;
   2949 		deUint32				buf				= 0;
   2950 		vector<deUint8>			data;
   2951 
   2952 		DE_ASSERT(m_numLevels == 1);
   2953 
   2954 		glGenTextures(1, &tex);
   2955 		glBindTexture(GL_TEXTURE_3D, tex);
   2956 
   2957 		// Fill with gradient.
   2958 		{
   2959 			int		rowPitch		= deAlign32(pixelSize*m_width,  4);
   2960 			int		slicePitch		= rowPitch*m_height;
   2961 
   2962 			data.resize(slicePitch*m_depth);
   2963 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
   2964 		}
   2965 
   2966 		glTexImage3D(GL_TEXTURE_3D, 0, m_internalFormat, m_width, m_height, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);
   2967 
   2968 		// Fill data with grid.
   2969 		{
   2970 			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
   2971 			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
   2972 			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
   2973 			int		slicePitch		= imageHeight*rowPitch;
   2974 			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
   2975 			Vec4	cBias			= m_texFormatInfo.valueMin;
   2976 			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
   2977 			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;
   2978 
   2979 			data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
   2980 			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);
   2981 		}
   2982 
   2983 		glGenBuffers(1, &buf);
   2984 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
   2985 		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);
   2986 
   2987 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
   2988 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
   2989 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
   2990 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
   2991 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
   2992 		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
   2993 		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);
   2994 	}
   2995 
   2996 	deUint32	m_internalFormat;
   2997 	int			m_subX;
   2998 	int			m_subY;
   2999 	int			m_subZ;
   3000 	int			m_subW;
   3001 	int			m_subH;
   3002 	int			m_subD;
   3003 	int			m_imageHeight;
   3004 	int			m_rowLength;
   3005 	int			m_skipImages;
   3006 	int			m_skipRows;
   3007 	int			m_skipPixels;
   3008 	int			m_alignment;
   3009 	int			m_offset;
   3010 };
   3011 
   3012 // TexImage2D() depth case.
   3013 class TexImage2DDepthCase : public Texture2DSpecCase
   3014 {
   3015 public:
   3016 	TexImage2DDepthCase (Context&		context,
   3017 						 const char*	name,
   3018 						 const char*	desc,
   3019 						 deUint32		internalFormat,
   3020 						 int			imageWidth,
   3021 						 int			imageHeight)
   3022 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
   3023 		, m_internalFormat	(internalFormat)
   3024 	{
   3025 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3026 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3027 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3028 	}
   3029 
   3030 	void createTexture (void)
   3031 	{
   3032 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3033 		deUint32			tex			= 0;
   3034 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3035 
   3036 		glGenTextures(1, &tex);
   3037 		glBindTexture(GL_TEXTURE_2D, tex);
   3038 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3039 		GLU_CHECK();
   3040 
   3041 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3042 		{
   3043 			const int   levelW		= de::max(1, m_width >> ndx);
   3044 			const int   levelH		= de::max(1, m_height >> ndx);
   3045 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3046 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3047 
   3048 			levelData.setSize(levelW, levelH);
   3049 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3050 
   3051 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3052 		}
   3053 	}
   3054 
   3055 	const deUint32 m_internalFormat;
   3056 };
   3057 
   3058 // TexImage3D() depth case.
   3059 class TexImage2DArrayDepthCase : public Texture2DArraySpecCase
   3060 {
   3061 public:
   3062 	TexImage2DArrayDepthCase (Context&		context,
   3063 							  const char*	name,
   3064 							  const char*	desc,
   3065 							  deUint32		internalFormat,
   3066 							  int			imageWidth,
   3067 							  int			imageHeight,
   3068 							  int			numLayers)
   3069 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
   3070 		, m_internalFormat		(internalFormat)
   3071 	{
   3072 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3073 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3074 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3075 	}
   3076 
   3077 	void createTexture (void)
   3078 	{
   3079 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3080 		deUint32			tex			= 0;
   3081 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3082 
   3083 		glGenTextures(1, &tex);
   3084 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3085 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3086 		GLU_CHECK();
   3087 
   3088 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3089 		{
   3090 			const int   levelW		= de::max(1, m_width >> ndx);
   3091 			const int   levelH		= de::max(1, m_height >> ndx);
   3092 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3093 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3094 
   3095 			levelData.setSize(levelW, levelH, m_numLayers);
   3096 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3097 
   3098 			glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3099 		}
   3100 	}
   3101 
   3102 	const deUint32 m_internalFormat;
   3103 };
   3104 
   3105 // TexSubImage2D() depth case.
   3106 class TexSubImage2DDepthCase : public Texture2DSpecCase
   3107 {
   3108 public:
   3109 	TexSubImage2DDepthCase (Context&	context,
   3110 							const char*	name,
   3111 							const char*	desc,
   3112 							deUint32	internalFormat,
   3113 							int			imageWidth,
   3114 							int			imageHeight)
   3115 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, maxLevelCount(imageWidth, imageHeight))
   3116 		, m_internalFormat	(internalFormat)
   3117 	{
   3118 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3119 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3120 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3121 	}
   3122 
   3123 	void createTexture (void)
   3124 	{
   3125 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3126 		de::Random			rnd			(deStringHash(getName()));
   3127 		deUint32			tex			= 0;
   3128 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3129 
   3130 		glGenTextures(1, &tex);
   3131 		glBindTexture(GL_TEXTURE_2D, tex);
   3132 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3133 		GLU_CHECK();
   3134 
   3135 		// First specify full texture.
   3136 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3137 		{
   3138 			const int   levelW		= de::max(1, m_width >> ndx);
   3139 			const int   levelH		= de::max(1, m_height >> ndx);
   3140 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3141 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3142 
   3143 			levelData.setSize(levelW, levelH);
   3144 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3145 
   3146 			glTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, levelW, levelH, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3147 		}
   3148 
   3149 		// Re-specify parts of each level.
   3150 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3151 		{
   3152 			const int	levelW		= de::max(1, m_width >> ndx);
   3153 			const int	levelH		= de::max(1, m_height >> ndx);
   3154 
   3155 			const int	w			= rnd.getInt(1, levelW);
   3156 			const int	h			= rnd.getInt(1, levelH);
   3157 			const int	x			= rnd.getInt(0, levelW-w);
   3158 			const int	y			= rnd.getInt(0, levelH-h);
   3159 
   3160 			const Vec4	colorA		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3161 			const Vec4	colorB		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3162 			const int	cellSize	= rnd.getInt(2, 16);
   3163 
   3164 			levelData.setSize(w, h);
   3165 			tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
   3166 
   3167 			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3168 		}
   3169 	}
   3170 
   3171 	const deUint32 m_internalFormat;
   3172 };
   3173 
   3174 // TexSubImage3D() depth case.
   3175 class TexSubImage2DArrayDepthCase : public Texture2DArraySpecCase
   3176 {
   3177 public:
   3178 	TexSubImage2DArrayDepthCase (Context&		context,
   3179 								 const char*	name,
   3180 								 const char*	desc,
   3181 								 deUint32		internalFormat,
   3182 								 int			imageWidth,
   3183 								 int			imageHeight,
   3184 								 int			numLayers)
   3185 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, maxLevelCount(imageWidth, imageHeight))
   3186 		, m_internalFormat		(internalFormat)
   3187 	{
   3188 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3189 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3190 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3191 	}
   3192 
   3193 	void createTexture (void)
   3194 	{
   3195 		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
   3196 		de::Random			rnd			(deStringHash(getName()));
   3197 		deUint32			tex			= 0;
   3198 		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));
   3199 
   3200 		glGenTextures(1, &tex);
   3201 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3202 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   3203 		GLU_CHECK();
   3204 
   3205 		// First specify full texture.
   3206 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3207 		{
   3208 			const int   levelW		= de::max(1, m_width >> ndx);
   3209 			const int   levelH		= de::max(1, m_height >> ndx);
   3210 			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3211 			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3212 
   3213 			levelData.setSize(levelW, levelH, m_numLayers);
   3214 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
   3215 
   3216 			glTexImage3D(GL_TEXTURE_2D_ARRAY, ndx, m_internalFormat, levelW, levelH, m_numLayers, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3217 		}
   3218 
   3219 		// Re-specify parts of each level.
   3220 		for (int ndx = 0; ndx < m_numLevels; ndx++)
   3221 		{
   3222 			const int	levelW		= de::max(1, m_width >> ndx);
   3223 			const int	levelH		= de::max(1, m_height >> ndx);
   3224 
   3225 			const int	w			= rnd.getInt(1, levelW);
   3226 			const int	h			= rnd.getInt(1, levelH);
   3227 			const int	d			= rnd.getInt(1, m_numLayers);
   3228 			const int	x			= rnd.getInt(0, levelW-w);
   3229 			const int	y			= rnd.getInt(0, levelH-h);
   3230 			const int	z			= rnd.getInt(0, m_numLayers-d);
   3231 
   3232 			const Vec4	colorA		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3233 			const Vec4	colorB		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3234 			const int	cellSize	= rnd.getInt(2, 16);
   3235 
   3236 			levelData.setSize(w, h, d);
   3237 			tcu::fillWithGrid(levelData.getAccess(), cellSize, colorA, colorB);
   3238 
   3239 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
   3240 		}
   3241 	}
   3242 
   3243 	const deUint32 m_internalFormat;
   3244 };
   3245 
   3246 // TexImage2D() depth case with pbo.
   3247 class TexImage2DDepthBufferCase : public Texture2DSpecCase
   3248 {
   3249 public:
   3250 	TexImage2DDepthBufferCase (Context&		context,
   3251 							   const char*	name,
   3252 							   const char*	desc,
   3253 							   deUint32		internalFormat,
   3254 							   int			imageWidth,
   3255 							   int			imageHeight)
   3256 		: Texture2DSpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, 1)
   3257 		, m_internalFormat	(internalFormat)
   3258 	{
   3259 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3260 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3261 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3262 	}
   3263 
   3264 	void createTexture (void)
   3265 	{
   3266 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   3267 		int						pixelSize		= m_texFormat.getPixelSize();
   3268 		int						rowLength		= m_width;
   3269 		int						alignment		= 4;
   3270 		int						rowPitch		= deAlign32(rowLength*pixelSize, alignment);
   3271 		int						height			= m_height;
   3272 		deUint32				buf				= 0;
   3273 		deUint32				tex				= 0;
   3274 		vector<deUint8>			data;
   3275 
   3276 		DE_ASSERT(m_numLevels == 1);
   3277 
   3278 		// Fill data with gradient
   3279 		data.resize(rowPitch*height);
   3280 		{
   3281 			const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3282 			const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3283 
   3284 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, 1, rowPitch, 0, &data[0]), gMin, gMax);
   3285 		}
   3286 
   3287 		// Create buffer and upload.
   3288 		glGenBuffers(1, &buf);
   3289 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   3290 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   3291 
   3292 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		rowLength);
   3293 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		0);
   3294 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
   3295 		glPixelStorei(GL_UNPACK_ALIGNMENT,		alignment);
   3296 
   3297 		glGenTextures(1, &tex);
   3298 		glBindTexture(GL_TEXTURE_2D, tex);
   3299 		glTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
   3300 		glDeleteBuffers(1, &buf);
   3301 	}
   3302 
   3303 	const deUint32 m_internalFormat;
   3304 };
   3305 
   3306 // TexImage3D() depth case with pbo.
   3307 class TexImage2DArrayDepthBufferCase : public Texture2DArraySpecCase
   3308 {
   3309 public:
   3310 	TexImage2DArrayDepthBufferCase (Context&	context,
   3311 									const char*	name,
   3312 									const char*	desc,
   3313 									deUint32	internalFormat,
   3314 									int			imageWidth,
   3315 									int			imageHeight,
   3316 									int			numLayers)
   3317 		: Texture2DArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageWidth, imageHeight, numLayers, 1)
   3318 		, m_internalFormat		(internalFormat)
   3319 	{
   3320 		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
   3321 		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
   3322 		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
   3323 	}
   3324 
   3325 	void createTexture (void)
   3326 	{
   3327 		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
   3328 		int						pixelSize		= m_texFormat.getPixelSize();
   3329 		int						rowLength		= m_width;
   3330 		int						alignment		= 4;
   3331 		int						rowPitch		= deAlign32(rowLength*pixelSize, alignment);
   3332 		int						imageHeight		= m_height;
   3333 		int						slicePitch		= imageHeight*rowPitch;
   3334 		deUint32				tex				= 0;
   3335 		deUint32				buf				= 0;
   3336 		vector<deUint8>			data;
   3337 
   3338 		DE_ASSERT(m_numLevels == 1);
   3339 
   3340 		// Fill data with grid.
   3341 		data.resize(slicePitch*m_numLayers);
   3342 		{
   3343 			const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
   3344 			const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);
   3345 
   3346 			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_width, m_height, m_numLayers, rowPitch, slicePitch, &data[0]), gMin, gMax);
   3347 		}
   3348 
   3349 		glGenBuffers(1, &buf);
   3350 		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
   3351 		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);
   3352 
   3353 		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	imageHeight);
   3354 		glPixelStorei(GL_UNPACK_ROW_LENGTH,		rowLength);
   3355 		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
   3356 		glPixelStorei(GL_UNPACK_SKIP_ROWS,		0);
   3357 		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
   3358 		glPixelStorei(GL_UNPACK_ALIGNMENT,		alignment);
   3359 
   3360 		glGenTextures(1, &tex);
   3361 		glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
   3362 		glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, m_internalFormat, m_width, m_height, m_numLayers, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
   3363 		glDeleteBuffers(1, &buf);
   3364 	}
   3365 
   3366 	const deUint32 m_internalFormat;
   3367 };
   3368 
   3369 TextureSpecificationTests::TextureSpecificationTests (Context& context)
   3370 	: TestCaseGroup(context, "specification", "Texture Specification Tests")
   3371 {
   3372 }
   3373 
   3374 TextureSpecificationTests::~TextureSpecificationTests (void)
   3375 {
   3376 }
   3377 
   3378 void TextureSpecificationTests::init (void)
   3379 {
   3380 	struct
   3381 	{
   3382 		const char*	name;
   3383 		deUint32	format;
   3384 		deUint32	dataType;
   3385 	} unsizedFormats[] =
   3386 	{
   3387 		{ "alpha_unsigned_byte",			GL_ALPHA,			GL_UNSIGNED_BYTE },
   3388 		{ "luminance_unsigned_byte",		GL_LUMINANCE,		GL_UNSIGNED_BYTE },
   3389 		{ "luminance_alpha_unsigned_byte",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
   3390 		{ "rgb_unsigned_short_5_6_5",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
   3391 		{ "rgb_unsigned_byte",				GL_RGB,				GL_UNSIGNED_BYTE },
   3392 		{ "rgba_unsigned_short_4_4_4_4",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
   3393 		{ "rgba_unsigned_short_5_5_5_1",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
   3394 		{ "rgba_unsigned_byte",				GL_RGBA,			GL_UNSIGNED_BYTE }
   3395 	};
   3396 
   3397 	struct
   3398 	{
   3399 		const char*	name;
   3400 		deUint32	internalFormat;
   3401 	} colorFormats[] =
   3402 	{
   3403 		{ "rgba32f",			GL_RGBA32F,			},
   3404 		{ "rgba32i",			GL_RGBA32I,			},
   3405 		{ "rgba32ui",			GL_RGBA32UI,		},
   3406 		{ "rgba16f",			GL_RGBA16F,			},
   3407 		{ "rgba16i",			GL_RGBA16I,			},
   3408 		{ "rgba16ui",			GL_RGBA16UI,		},
   3409 		{ "rgba8",				GL_RGBA8,			},
   3410 		{ "rgba8i",				GL_RGBA8I,			},
   3411 		{ "rgba8ui",			GL_RGBA8UI,			},
   3412 		{ "srgb8_alpha8",		GL_SRGB8_ALPHA8,	},
   3413 		{ "rgb10_a2",			GL_RGB10_A2,		},
   3414 		{ "rgb10_a2ui",			GL_RGB10_A2UI,		},
   3415 		{ "rgba4",				GL_RGBA4,			},
   3416 		{ "rgb5_a1",			GL_RGB5_A1,			},
   3417 		{ "rgba8_snorm",		GL_RGBA8_SNORM,		},
   3418 		{ "rgb8",				GL_RGB8,			},
   3419 		{ "rgb565",				GL_RGB565,			},
   3420 		{ "r11f_g11f_b10f",		GL_R11F_G11F_B10F,	},
   3421 		{ "rgb32f",				GL_RGB32F,			},
   3422 		{ "rgb32i",				GL_RGB32I,			},
   3423 		{ "rgb32ui",			GL_RGB32UI,			},
   3424 		{ "rgb16f",				GL_RGB16F,			},
   3425 		{ "rgb16i",				GL_RGB16I,			},
   3426 		{ "rgb16ui",			GL_RGB16UI,			},
   3427 		{ "rgb8_snorm",			GL_RGB8_SNORM,		},
   3428 		{ "rgb8i",				GL_RGB8I,			},
   3429 		{ "rgb8ui",				GL_RGB8UI,			},
   3430 		{ "srgb8",				GL_SRGB8,			},
   3431 		{ "rgb9_e5",			GL_RGB9_E5,			},
   3432 		{ "rg32f",				GL_RG32F,			},
   3433 		{ "rg32i",				GL_RG32I,			},
   3434 		{ "rg32ui",				GL_RG32UI,			},
   3435 		{ "rg16f",				GL_RG16F,			},
   3436 		{ "rg16i",				GL_RG16I,			},
   3437 		{ "rg16ui",				GL_RG16UI,			},
   3438 		{ "rg8",				GL_RG8,				},
   3439 		{ "rg8i",				GL_RG8I,			},
   3440 		{ "rg8ui",				GL_RG8UI,			},
   3441 		{ "rg8_snorm",			GL_RG8_SNORM,		},
   3442 		{ "r32f",				GL_R32F,			},
   3443 		{ "r32i",				GL_R32I,			},
   3444 		{ "r32ui",				GL_R32UI,			},
   3445 		{ "r16f",				GL_R16F,			},
   3446 		{ "r16i",				GL_R16I,			},
   3447 		{ "r16ui",				GL_R16UI,			},
   3448 		{ "r8",					GL_R8,				},
   3449 		{ "r8i",				GL_R8I,				},
   3450 		{ "r8ui",				GL_R8UI,			},
   3451 		{ "r8_snorm",			GL_R8_SNORM,		}
   3452 	};
   3453 
   3454 	static const struct
   3455 	{
   3456 		const char*	name;
   3457 		deUint32	internalFormat;
   3458 	} depthStencilFormats[] =
   3459 	{
   3460 		// Depth and stencil formats
   3461 		{ "depth_component32f",	GL_DEPTH_COMPONENT32F	},
   3462 		{ "depth_component24",	GL_DEPTH_COMPONENT24	},
   3463 		{ "depth_component16",	GL_DEPTH_COMPONENT16	},
   3464 		{ "depth32f_stencil8",	GL_DEPTH32F_STENCIL8	},
   3465 		{ "depth24_stencil8",	GL_DEPTH24_STENCIL8		}
   3466 	};
   3467 
   3468 	// Basic TexImage2D usage.
   3469 	{
   3470 		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
   3471 		addChild(basicTexImageGroup);
   3472 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3473 		{
   3474 			const char*	fmtName		= colorFormats[formatNdx].name;
   3475 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   3476 			const int	tex2DWidth	= 64;
   3477 			const int	tex2DHeight	= 128;
   3478 			const int	texCubeSize	= 64;
   3479 
   3480 			basicTexImageGroup->addChild(new BasicTexImage2DCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, tex2DWidth, tex2DHeight));
   3481 			basicTexImageGroup->addChild(new BasicTexImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, texCubeSize));
   3482 		}
   3483 	}
   3484 
   3485 	// Randomized TexImage2D order.
   3486 	{
   3487 		tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
   3488 		addChild(randomTexImageGroup);
   3489 
   3490 		de::Random rnd(9);
   3491 
   3492 		// 2D cases.
   3493 		for (int ndx = 0; ndx < 10; ndx++)
   3494 		{
   3495 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
   3496 			int		width		= 1 << rnd.getInt(2, 8);
   3497 			int		height		= 1 << rnd.getInt(2, 8);
   3498 
   3499 			randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, width, height));
   3500 		}
   3501 
   3502 		// Cubemap cases.
   3503 		for (int ndx = 0; ndx < 10; ndx++)
   3504 		{
   3505 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(colorFormats)-1);
   3506 			int		size		= 1 << rnd.getInt(2, 8);
   3507 
   3508 			randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", colorFormats[formatNdx].internalFormat, size));
   3509 		}
   3510 	}
   3511 
   3512 	// TexImage2D unpack alignment.
   3513 	{
   3514 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
   3515 		addChild(alignGroup);
   3516 
   3517 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_4_8",			"",	GL_R8,			 4,  8, 4, 8));
   3518 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_1",			"",	GL_R8,			63, 30, 1, 1));
   3519 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_2",			"",	GL_R8,			63, 30, 1, 2));
   3520 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_4",			"",	GL_R8,			63, 30, 1, 4));
   3521 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_r8_63_8",			"",	GL_R8,			63, 30, 1, 8));
   3522 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_1",		"",	GL_RGBA4,		51, 30, 1, 1));
   3523 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_2",		"",	GL_RGBA4,		51, 30, 1, 2));
   3524 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_4",		"",	GL_RGBA4,		51, 30, 1, 4));
   3525 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4_51_8",		"",	GL_RGBA4,		51, 30, 1, 8));
   3526 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_1",			"",	GL_RGB8,		39, 43, 1, 1));
   3527 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_2",			"",	GL_RGB8,		39, 43, 1, 2));
   3528 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_4",			"",	GL_RGB8,		39, 43, 1, 4));
   3529 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb8_39_8",			"",	GL_RGB8,		39, 43, 1, 8));
   3530 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_1",		"",	GL_RGBA8,		47, 27, 1, 1));
   3531 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_2",		"",	GL_RGBA8,		47, 27, 1, 2));
   3532 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_4",		"",	GL_RGBA8,		47, 27, 1, 4));
   3533 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8_47_8",		"",	GL_RGBA8,		47, 27, 1, 8));
   3534 
   3535 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_4_8",			"",	GL_R8,			 4, 3, 8));
   3536 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_1",			"",	GL_R8,			63, 1, 1));
   3537 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_2",			"",	GL_R8,			63, 1, 2));
   3538 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_4",			"",	GL_R8,			63, 1, 4));
   3539 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_r8_63_8",			"",	GL_R8,			63, 1, 8));
   3540 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_1",		"",	GL_RGBA4,		51, 1, 1));
   3541 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_2",		"",	GL_RGBA4,		51, 1, 2));
   3542 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_4",		"",	GL_RGBA4,		51, 1, 4));
   3543 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4_51_8",		"",	GL_RGBA4,		51, 1, 8));
   3544 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_1",		"",	GL_RGB8,		39, 1, 1));
   3545 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_2",		"",	GL_RGB8,		39, 1, 2));
   3546 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_4",		"",	GL_RGB8,		39, 1, 4));
   3547 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb8_39_8",		"",	GL_RGB8,		39, 1, 8));
   3548 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_1",		"",	GL_RGBA8,		47, 1, 1));
   3549 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_2",		"",	GL_RGBA8,		47, 1, 2));
   3550 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_4",		"",	GL_RGBA8,		47, 1, 4));
   3551 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8_47_8",		"",	GL_RGBA8,		47, 1, 8));
   3552 	}
   3553 
   3554 	// glTexImage2D() unpack parameter cases.
   3555 	{
   3556 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_unpack_params", "glTexImage2D() pixel transfer mode cases");
   3557 		addChild(paramGroup);
   3558 
   3559 		static const struct
   3560 		{
   3561 			const char*	name;
   3562 			deUint32	format;
   3563 			int			width;
   3564 			int			height;
   3565 			int			rowLength;
   3566 			int			skipRows;
   3567 			int			skipPixels;
   3568 			int			alignment;
   3569 		} cases[] =
   3570 		{
   3571 			{ "rgb8_alignment",		GL_RGB8,	31,	30,	0,	0,	0,	2 },
   3572 			{ "rgb8_row_length",	GL_RGB8,	31,	30,	50,	0,	0,	4 },
   3573 			{ "rgb8_skip_rows",		GL_RGB8,	31,	30,	0,	3,	0,	4 },
   3574 			{ "rgb8_skip_pixels",	GL_RGB8,	31,	30,	36,	0,	5,	4 },
   3575 			{ "r8_complex1",		GL_R8,		31, 30, 64, 1,	3,	1 },
   3576 			{ "r8_complex2",		GL_R8,		31, 30, 64, 1,	3,	2 },
   3577 			{ "r8_complex3",		GL_R8,		31, 30, 64, 1,	3,	4 },
   3578 			{ "r8_complex4",		GL_R8,		31, 30, 64, 1,	3,	8 },
   3579 			{ "rgba8_complex1",		GL_RGBA8,	56,	61,	69,	0,	0,	8 },
   3580 			{ "rgba8_complex2",		GL_RGBA8,	56,	61,	69,	0,	7,	8 },
   3581 			{ "rgba8_complex3",		GL_RGBA8,	56,	61,	69,	3,	0,	8 },
   3582 			{ "rgba8_complex4",		GL_RGBA8,	56,	61,	69,	3,	7,	8 },
   3583 			{ "rgba32f_complex",	GL_RGBA32F,	19,	10,	27,	1,	7,	8 }
   3584 		};
   3585 
   3586 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   3587 			paramGroup->addChild(new TexImage2DParamsCase(m_context, cases[ndx].name, "",
   3588 														  cases[ndx].format,
   3589 														  cases[ndx].width,
   3590 														  cases[ndx].height,
   3591 														  cases[ndx].rowLength,
   3592 														  cases[ndx].skipRows,
   3593 														  cases[ndx].skipPixels,
   3594 														  cases[ndx].alignment));
   3595 	}
   3596 
   3597 	// glTexImage2D() pbo cases.
   3598 	{
   3599 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_pbo", "glTexImage2D() from PBO");
   3600 		addChild(pboGroup);
   3601 
   3602 		// Parameter cases
   3603 		static const struct
   3604 		{
   3605 			const char*	name;
   3606 			deUint32	format;
   3607 			int			width;
   3608 			int			height;
   3609 			int			rowLength;
   3610 			int			skipRows;
   3611 			int			skipPixels;
   3612 			int			alignment;
   3613 			int			offset;
   3614 		} parameterCases[] =
   3615 		{
   3616 			{ "rgb8_offset",		GL_RGB8,	31,	30,	0,	0,	0,	4,	67 },
   3617 			{ "rgb8_alignment",		GL_RGB8,	31,	30,	0,	0,	0,	2,	0 },
   3618 			{ "rgb8_row_length",	GL_RGB8,	31,	30,	50,	0,	0,	4,	0 },
   3619 			{ "rgb8_skip_rows",		GL_RGB8,	31,	30,	0,	3,	0,	4,	0 },
   3620 			{ "rgb8_skip_pixels",	GL_RGB8,	31,	30,	36,	0,	5,	4,	0 }
   3621 		};
   3622 
   3623 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3624 		{
   3625 			const string	fmtName		= colorFormats[formatNdx].name;
   3626 			const deUint32	format		= colorFormats[formatNdx].internalFormat;
   3627 			const int		tex2DWidth	= 65;
   3628 			const int		tex2DHeight	= 37;
   3629 			const int		texCubeSize	= 64;
   3630 
   3631 			pboGroup->addChild(new TexImage2DBufferCase		(m_context,	(fmtName + "_2d").c_str(),		"", format, tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0));
   3632 			pboGroup->addChild(new TexImageCubeBufferCase	(m_context,	(fmtName + "_cube").c_str(),	"", format, texCubeSize, 0, 0, 0, 4, 0));
   3633 		}
   3634 
   3635 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
   3636 		{
   3637 			pboGroup->addChild(new TexImage2DBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d").c_str(), "",
   3638 														parameterCases[ndx].format,
   3639 														parameterCases[ndx].width,
   3640 														parameterCases[ndx].height,
   3641 														parameterCases[ndx].rowLength,
   3642 														parameterCases[ndx].skipRows,
   3643 														parameterCases[ndx].skipPixels,
   3644 														parameterCases[ndx].alignment,
   3645 														parameterCases[ndx].offset));
   3646 			pboGroup->addChild(new TexImageCubeBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube").c_str(), "",
   3647 														parameterCases[ndx].format,
   3648 														parameterCases[ndx].width,
   3649 														parameterCases[ndx].rowLength,
   3650 														parameterCases[ndx].skipRows,
   3651 														parameterCases[ndx].skipPixels,
   3652 														parameterCases[ndx].alignment,
   3653 														parameterCases[ndx].offset));
   3654 		}
   3655 	}
   3656 
   3657 	// glTexImage2D() depth cases.
   3658 	{
   3659 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth", "glTexImage2D() with depth or depth/stencil format");
   3660 		addChild(shadow2dGroup);
   3661 
   3662 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3663 		{
   3664 			const int tex2DWidth	= 64;
   3665 			const int tex2DHeight	= 128;
   3666 
   3667 			shadow2dGroup->addChild(new TexImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3668 		}
   3669 	}
   3670 
   3671 	// glTexImage2D() depth cases with pbo.
   3672 	{
   3673 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_depth_pbo", "glTexImage2D() with depth or depth/stencil format with pbo");
   3674 		addChild(shadow2dGroup);
   3675 
   3676 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3677 		{
   3678 			const int tex2DWidth	= 64;
   3679 			const int tex2DHeight	= 128;
   3680 
   3681 			shadow2dGroup->addChild(new TexImage2DDepthBufferCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3682 		}
   3683 	}
   3684 
   3685 	// Basic TexSubImage2D usage.
   3686 	{
   3687 		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
   3688 		addChild(basicTexSubImageGroup);
   3689 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3690 		{
   3691 			const char*	fmtName		= colorFormats[formatNdx].name;
   3692 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   3693 			const int	tex2DWidth	= 64;
   3694 			const int	tex2DHeight	= 128;
   3695 			const int	texCubeSize	= 64;
   3696 
   3697 			basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase		(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, tex2DWidth, tex2DHeight));
   3698 			basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, texCubeSize));
   3699 		}
   3700 	}
   3701 
   3702 	// TexSubImage2D to empty texture.
   3703 	{
   3704 		tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
   3705 		addChild(texSubImageEmptyTexGroup);
   3706 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(unsizedFormats); formatNdx++)
   3707 		{
   3708 			const char*	fmtName		= unsizedFormats[formatNdx].name;
   3709 			deUint32	format		= unsizedFormats[formatNdx].format;
   3710 			deUint32	dataType	= unsizedFormats[formatNdx].dataType;
   3711 			const int	tex2DWidth	= 64;
   3712 			const int	tex2DHeight	= 32;
   3713 			const int	texCubeSize	= 32;
   3714 
   3715 			texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, tex2DWidth, tex2DHeight));
   3716 			texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, texCubeSize));
   3717 		}
   3718 	}
   3719 
   3720 	// TexSubImage2D alignment cases.
   3721 	{
   3722 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
   3723 		addChild(alignGroup);
   3724 
   3725 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_1",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 1));
   3726 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_2",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 2));
   3727 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_4",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 4));
   3728 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_1_8",			"",	GL_R8,			64, 64, 13, 17,  1,  6, 8));
   3729 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_1",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 1));
   3730 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_2",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 2));
   3731 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_4",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 4));
   3732 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_r8_63_8",			"",	GL_R8,			64, 64,  1,  9, 63, 30, 8));
   3733 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_1",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 1));
   3734 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_2",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 2));
   3735 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_4",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 4));
   3736 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4_51_8",		"",	GL_RGBA4,		64, 64,  7, 29, 51, 30, 8));
   3737 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_1",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 1));
   3738 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_2",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 2));
   3739 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_4",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 4));
   3740 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb8_39_8",			"",	GL_RGB8,		64, 64, 11,  8, 39, 43, 8));
   3741 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_1",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 1));
   3742 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_2",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 2));
   3743 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_4",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 4));
   3744 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8_47_8",		"",	GL_RGBA8,		64, 64, 10,  1, 47, 27, 8));
   3745 
   3746 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_1",			"",	GL_R8,			64, 13, 17,  1,  6, 1));
   3747 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_2",			"",	GL_R8,			64, 13, 17,  1,  6, 2));
   3748 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_4",			"",	GL_R8,			64, 13, 17,  1,  6, 4));
   3749 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_1_8",			"",	GL_R8,			64, 13, 17,  1,  6, 8));
   3750 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_1",			"",	GL_R8,			64,  1,  9, 63, 30, 1));
   3751 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_2",			"",	GL_R8,			64,  1,  9, 63, 30, 2));
   3752 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_4",			"",	GL_R8,			64,  1,  9, 63, 30, 4));
   3753 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_r8_63_8",			"",	GL_R8,			64,  1,  9, 63, 30, 8));
   3754 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_1",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 1));
   3755 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_2",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 2));
   3756 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_4",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 4));
   3757 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4_51_8",		"",	GL_RGBA4,		64,  7, 29, 51, 30, 8));
   3758 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_1",		"",	GL_RGB8,		64, 11,  8, 39, 43, 1));
   3759 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_2",		"",	GL_RGB8,		64, 11,  8, 39, 43, 2));
   3760 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_4",		"",	GL_RGB8,		64, 11,  8, 39, 43, 4));
   3761 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb8_39_8",		"",	GL_RGB8,		64, 11,  8, 39, 43, 8));
   3762 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_1",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 1));
   3763 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_2",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 2));
   3764 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_4",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 4));
   3765 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8_47_8",		"",	GL_RGBA8,		64, 10,  1, 47, 27, 8));
   3766 	}
   3767 
   3768 	// glTexSubImage2D() pixel transfer mode cases.
   3769 	{
   3770 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_unpack_params", "glTexSubImage2D() pixel transfer mode cases");
   3771 		addChild(paramGroup);
   3772 
   3773 		static const struct
   3774 		{
   3775 			const char*	name;
   3776 			deUint32	format;
   3777 			int			width;
   3778 			int			height;
   3779 			int			subX;
   3780 			int			subY;
   3781 			int			subW;
   3782 			int			subH;
   3783 			int			rowLength;
   3784 			int			skipRows;
   3785 			int			skipPixels;
   3786 			int			alignment;
   3787 		} cases[] =
   3788 		{
   3789 			{ "rgb8_alignment",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	2 },
   3790 			{ "rgb8_row_length",	GL_RGB8,	54,	60,	11,	7,	31,	30,	50,	0,	0,	4 },
   3791 			{ "rgb8_skip_rows",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	3,	0,	4 },
   3792 			{ "rgb8_skip_pixels",	GL_RGB8,	54,	60,	11,	7,	31,	30,	36,	0,	5,	4 },
   3793 			{ "r8_complex1",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	1 },
   3794 			{ "r8_complex2",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	2 },
   3795 			{ "r8_complex3",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	4 },
   3796 			{ "r8_complex4",		GL_R8,		54,	60,	11,	7,	31, 30, 64, 1,	3,	8 },
   3797 			{ "rgba8_complex1",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	0,	0,	8 },
   3798 			{ "rgba8_complex2",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	0,	7,	8 },
   3799 			{ "rgba8_complex3",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	3,	0,	8 },
   3800 			{ "rgba8_complex4",		GL_RGBA8,	92,	84,	13,	19,	56,	61,	69,	3,	7,	8 },
   3801 			{ "rgba32f_complex",	GL_RGBA32F,	92,	84,	13,	19,	56,	61,	69,	3,	7,	8 }
   3802 		};
   3803 
   3804 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   3805 			paramGroup->addChild(new TexSubImage2DParamsCase(m_context, cases[ndx].name, "",
   3806 															 cases[ndx].format,
   3807 															 cases[ndx].width,
   3808 															 cases[ndx].height,
   3809 															 cases[ndx].subX,
   3810 															 cases[ndx].subY,
   3811 															 cases[ndx].subW,
   3812 															 cases[ndx].subH,
   3813 															 cases[ndx].rowLength,
   3814 															 cases[ndx].skipRows,
   3815 															 cases[ndx].skipPixels,
   3816 															 cases[ndx].alignment));
   3817 	}
   3818 
   3819 	// glTexSubImage2D() PBO cases.
   3820 	{
   3821 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_pbo", "glTexSubImage2D() pixel buffer object tests");
   3822 		addChild(pboGroup);
   3823 
   3824 		static const struct
   3825 		{
   3826 			const char*	name;
   3827 			deUint32	format;
   3828 			int			width;
   3829 			int			height;
   3830 			int			subX;
   3831 			int			subY;
   3832 			int			subW;
   3833 			int			subH;
   3834 			int			rowLength;
   3835 			int			skipRows;
   3836 			int			skipPixels;
   3837 			int			alignment;
   3838 			int			offset;
   3839 		} paramCases[] =
   3840 		{
   3841 			{ "rgb8_offset",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	4,	67 },
   3842 			{ "rgb8_alignment",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	0,	0,	2,	0 },
   3843 			{ "rgb8_row_length",	GL_RGB8,	54,	60,	11,	7,	31,	30,	50,	0,	0,	4,	0 },
   3844 			{ "rgb8_skip_rows",		GL_RGB8,	54,	60,	11,	7,	31,	30,	0,	3,	0,	4,	0 },
   3845 			{ "rgb8_skip_pixels",	GL_RGB8,	54,	60,	11,	7,	31,	30,	36,	0,	5,	4,	0 }
   3846 		};
   3847 
   3848 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   3849 		{
   3850 			pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d").c_str(), "",
   3851 														   colorFormats[ndx].internalFormat,
   3852 														   54,	// Width
   3853 														   60,	// Height
   3854 														   11,	// Sub X
   3855 														   7,	// Sub Y
   3856 														   31,	// Sub W
   3857 														   30,	// Sub H
   3858 														   0,	// Row len
   3859 														   0,	// Skip rows
   3860 														   0,	// Skip pixels
   3861 														   4,	// Alignment
   3862 														   0	/* offset */));
   3863 			pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube").c_str(), "",
   3864 														   colorFormats[ndx].internalFormat,
   3865 														   64,	// Size
   3866 														   11,	// Sub X
   3867 														   7,	// Sub Y
   3868 														   31,	// Sub W
   3869 														   30,	// Sub H
   3870 														   0,	// Row len
   3871 														   0,	// Skip rows
   3872 														   0,	// Skip pixels
   3873 														   4,	// Alignment
   3874 														   0	/* offset */));
   3875 		}
   3876 
   3877 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
   3878 		{
   3879 			pboGroup->addChild(new TexSubImage2DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d").c_str(), "",
   3880 														   paramCases[ndx].format,
   3881 														   paramCases[ndx].width,
   3882 														   paramCases[ndx].height,
   3883 														   paramCases[ndx].subX,
   3884 														   paramCases[ndx].subY,
   3885 														   paramCases[ndx].subW,
   3886 														   paramCases[ndx].subH,
   3887 														   paramCases[ndx].rowLength,
   3888 														   paramCases[ndx].skipRows,
   3889 														   paramCases[ndx].skipPixels,
   3890 														   paramCases[ndx].alignment,
   3891 														   paramCases[ndx].offset));
   3892 			pboGroup->addChild(new TexSubImageCubeBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube").c_str(), "",
   3893 														   paramCases[ndx].format,
   3894 														   paramCases[ndx].width,
   3895 														   paramCases[ndx].subX,
   3896 														   paramCases[ndx].subY,
   3897 														   paramCases[ndx].subW,
   3898 														   paramCases[ndx].subH,
   3899 														   paramCases[ndx].rowLength,
   3900 														   paramCases[ndx].skipRows,
   3901 														   paramCases[ndx].skipPixels,
   3902 														   paramCases[ndx].alignment,
   3903 														   paramCases[ndx].offset));
   3904 		}
   3905 	}
   3906 
   3907 	// glTexSubImage2D() depth cases.
   3908 	{
   3909 		tcu::TestCaseGroup* shadow2dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_depth", "glTexSubImage2D() with depth or depth/stencil format");
   3910 		addChild(shadow2dGroup);
   3911 
   3912 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   3913 		{
   3914 			const int	tex2DWidth	= 64;
   3915 			const int	tex2DHeight	= 32;
   3916 
   3917 			shadow2dGroup->addChild(new TexSubImage2DDepthCase(m_context, depthStencilFormats[ndx].name, "", depthStencilFormats[ndx].internalFormat, tex2DWidth, tex2DHeight));
   3918 		}
   3919 	}
   3920 
   3921 	// Basic glCopyTexImage2D() cases
   3922 	{
   3923 		tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
   3924 		addChild(copyTexImageGroup);
   3925 
   3926 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_alpha",				"",	GL_ALPHA,			128, 64));
   3927 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance",			"",	GL_LUMINANCE,		128, 64));
   3928 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	128, 64));
   3929 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgb",				"",	GL_RGB,				128, 64));
   3930 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgba",				"",	GL_RGBA,			128, 64));
   3931 
   3932 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			64));
   3933 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		64));
   3934 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	64));
   3935 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				64));
   3936 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			64));
   3937 	}
   3938 
   3939 	// Basic glCopyTexSubImage2D() cases
   3940 	{
   3941 		tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
   3942 		addChild(copyTexSubImageGroup);
   3943 
   3944 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_alpha",				"",	GL_ALPHA,			GL_UNSIGNED_BYTE, 128, 64));
   3945 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance",			"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, 128, 64));
   3946 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, 128, 64));
   3947 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, 128, 64));
   3948 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgba",				"",	GL_RGBA,			GL_UNSIGNED_BYTE, 128, 64));
   3949 
   3950 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			GL_UNSIGNED_BYTE, 64));
   3951 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, 64));
   3952 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, 64));
   3953 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, 64));
   3954 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			GL_UNSIGNED_BYTE, 64));
   3955 	}
   3956 
   3957 	// Basic TexImage3D usage.
   3958 	{
   3959 		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
   3960 		addChild(basicTexImageGroup);
   3961 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   3962 		{
   3963 			const char*	fmtName				= colorFormats[formatNdx].name;
   3964 			deUint32	format				= colorFormats[formatNdx].internalFormat;
   3965 			const int	tex2DArrayWidth		= 57;
   3966 			const int	tex2DArrayHeight	= 44;
   3967 			const int	tex2DArrayLevels	= 5;
   3968 			const int	tex3DWidth			= 63;
   3969 			const int	tex3DHeight			= 29;
   3970 			const int	tex3DDepth			= 11;
   3971 
   3972 			basicTexImageGroup->addChild(new BasicTexImage2DArrayCase	(m_context,	(string(fmtName) + "_2d_array").c_str(),	"",	format, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
   3973 			basicTexImageGroup->addChild(new BasicTexImage3DCase		(m_context,	(string(fmtName) + "_3d").c_str(),			"",	format, tex3DWidth, tex3DHeight, tex3DDepth));
   3974 		}
   3975 	}
   3976 
   3977 	// glTexImage3D() unpack params cases.
   3978 	{
   3979 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_unpack_params", "glTexImage3D() unpack parameters");
   3980 		addChild(paramGroup);
   3981 
   3982 		static const struct
   3983 		{
   3984 			const char*	name;
   3985 			deUint32	format;
   3986 			int			width;
   3987 			int			height;
   3988 			int			depth;
   3989 			int			imageHeight;
   3990 			int			rowLength;
   3991 			int			skipImages;
   3992 			int			skipRows;
   3993 			int			skipPixels;
   3994 			int			alignment;
   3995 		} cases[] =
   3996 		{
   3997 			{ "rgb8_image_height",	GL_RGB8,	23,	19,	8,	26,	0,	0,	0,	0,	4 },
   3998 			{ "rgb8_row_length",	GL_RGB8,	23,	19,	8,	0,	27,	0,	0,	0,	4 },
   3999 			{ "rgb8_skip_images",	GL_RGB8,	23,	19,	8,	0,	0,	3,	0,	0,	4 },
   4000 			{ "rgb8_skip_rows",		GL_RGB8,	23,	19,	8,	22,	0,	0,	3,	0,	4 },
   4001 			{ "rgb8_skip_pixels",	GL_RGB8,	23,	19,	8,	0,	25,	0,	0,	2,	4 },
   4002 			{ "r8_complex1",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	1 },
   4003 			{ "r8_complex2",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	2 },
   4004 			{ "r8_complex3",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	4 },
   4005 			{ "r8_complex4",		GL_R8,		13, 17, 11,	23,	15,	2,	3,	1,	8 },
   4006 			{ "rgba8_complex1",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	0,	0,	8 },
   4007 			{ "rgba8_complex2",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	2,	0,	8 },
   4008 			{ "rgba8_complex3",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	0,	3,	8 },
   4009 			{ "rgba8_complex4",		GL_RGBA8,	11,	20,	8,	25,	14,	0,	2,	3,	8 },
   4010 			{ "rgba32f_complex",	GL_RGBA32F,	11,	20,	8,	25,	14,	0,	2,	3,	8 }
   4011 		};
   4012 
   4013 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   4014 			paramGroup->addChild(new TexImage3DParamsCase(m_context, cases[ndx].name, "",
   4015 														  cases[ndx].format,
   4016 														  cases[ndx].width,
   4017 														  cases[ndx].height,
   4018 														  cases[ndx].depth,
   4019 														  cases[ndx].imageHeight,
   4020 														  cases[ndx].rowLength,
   4021 														  cases[ndx].skipImages,
   4022 														  cases[ndx].skipRows,
   4023 														  cases[ndx].skipPixels,
   4024 														  cases[ndx].alignment));
   4025 	}
   4026 
   4027 	// glTexImage3D() pbo cases.
   4028 	{
   4029 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
   4030 		addChild(pboGroup);
   4031 
   4032 		// Parameter cases
   4033 		static const struct
   4034 		{
   4035 			const char*	name;
   4036 			deUint32	format;
   4037 			int			width;
   4038 			int			height;
   4039 			int			depth;
   4040 			int			imageHeight;
   4041 			int			rowLength;
   4042 			int			skipImages;
   4043 			int			skipRows;
   4044 			int			skipPixels;
   4045 			int			alignment;
   4046 			int			offset;
   4047 		} parameterCases[] =
   4048 		{
   4049 			{ "rgb8_offset",		GL_RGB8,	23,	19,	8,	0,	0,	0,	0,	0,	1,	67 },
   4050 			{ "rgb8_alignment",		GL_RGB8,	23,	19,	8,	0,	0,	0,	0,	0,	2,	0 },
   4051 			{ "rgb8_image_height",	GL_RGB8,	23,	19,	8,	26,	0,	0,	0,	0,	4,	0 },
   4052 			{ "rgb8_row_length",	GL_RGB8,	23,	19,	8,	0,	27,	0,	0,	0,	4,	0 },
   4053 			{ "rgb8_skip_images",	GL_RGB8,	23,	19,	8,	0,	0,	3,	0,	0,	4,	0 },
   4054 			{ "rgb8_skip_rows",		GL_RGB8,	23,	19,	8,	22,	0,	0,	3,	0,	4,	0 },
   4055 			{ "rgb8_skip_pixels",	GL_RGB8,	23,	19,	8,	0,	25,	0,	0,	2,	4,	0 }
   4056 		};
   4057 
   4058 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4059 		{
   4060 			const string	fmtName		= colorFormats[formatNdx].name;
   4061 			const deUint32	format		= colorFormats[formatNdx].internalFormat;
   4062 			const int		tex3DWidth	= 11;
   4063 			const int		tex3DHeight	= 20;
   4064 			const int		tex3DDepth	= 8;
   4065 
   4066 			pboGroup->addChild(new TexImage2DArrayBufferCase	(m_context, (fmtName + "_2d_array").c_str(),	"", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
   4067 			pboGroup->addChild(new TexImage3DBufferCase			(m_context, (fmtName + "_3d").c_str(),			"", format, tex3DWidth, tex3DHeight, tex3DDepth, 0, 0, 0, 0, 0, 4, 0));
   4068 		}
   4069 
   4070 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
   4071 		{
   4072 			pboGroup->addChild(new TexImage2DArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_2d_array").c_str(), "",
   4073 														parameterCases[ndx].format,
   4074 														parameterCases[ndx].width,
   4075 														parameterCases[ndx].depth,
   4076 														parameterCases[ndx].height,
   4077 														parameterCases[ndx].imageHeight,
   4078 														parameterCases[ndx].rowLength,
   4079 														parameterCases[ndx].skipImages,
   4080 														parameterCases[ndx].skipRows,
   4081 														parameterCases[ndx].skipPixels,
   4082 														parameterCases[ndx].alignment,
   4083 														parameterCases[ndx].offset));
   4084 			pboGroup->addChild(new TexImage3DBufferCase(m_context, (string(parameterCases[ndx].name) + "_3d").c_str(), "",
   4085 														parameterCases[ndx].format,
   4086 														parameterCases[ndx].width,
   4087 														parameterCases[ndx].depth,
   4088 														parameterCases[ndx].height,
   4089 														parameterCases[ndx].imageHeight,
   4090 														parameterCases[ndx].rowLength,
   4091 														parameterCases[ndx].skipImages,
   4092 														parameterCases[ndx].skipRows,
   4093 														parameterCases[ndx].skipPixels,
   4094 														parameterCases[ndx].alignment,
   4095 														parameterCases[ndx].offset));
   4096 		}
   4097 	}
   4098 
   4099 	// glTexImage3D() depth cases.
   4100 	{
   4101 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
   4102 		addChild(shadow3dGroup);
   4103 
   4104 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4105 		{
   4106 			const int	tex3DWidth	= 32;
   4107 			const int	tex3DHeight	= 64;
   4108 			const int	tex3DDepth	= 8;
   4109 
   4110 			shadow3dGroup->addChild(new TexImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
   4111 		}
   4112 	}
   4113 
   4114 	// glTexImage3D() depth cases with pbo.
   4115 	{
   4116 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
   4117 		addChild(shadow3dGroup);
   4118 
   4119 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4120 		{
   4121 			const int	tex3DWidth	= 32;
   4122 			const int	tex3DHeight	= 64;
   4123 			const int	tex3DDepth	= 8;
   4124 
   4125 			shadow3dGroup->addChild(new TexImage2DArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex3DWidth, tex3DHeight, tex3DDepth));
   4126 		}
   4127 	}
   4128 
   4129 	// Basic TexSubImage3D usage.
   4130 	{
   4131 		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage3d", "Basic glTexSubImage3D() usage");
   4132 		addChild(basicTexSubImageGroup);
   4133 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4134 		{
   4135 			const char*	fmtName		= colorFormats[formatNdx].name;
   4136 			deUint32	format		= colorFormats[formatNdx].internalFormat;
   4137 			const int	tex3DWidth	= 32;
   4138 			const int	tex3DHeight	= 64;
   4139 			const int	tex3DDepth	= 8;
   4140 
   4141 			basicTexSubImageGroup->addChild(new BasicTexSubImage3DCase(m_context, (string(fmtName) + "_3d").c_str(), "", format, tex3DWidth, tex3DHeight, tex3DDepth));
   4142 		}
   4143 	}
   4144 
   4145 	// glTexSubImage3D() unpack params cases.
   4146 	{
   4147 		tcu::TestCaseGroup* paramGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_unpack_params", "glTexSubImage3D() unpack parameters");
   4148 		addChild(paramGroup);
   4149 
   4150 		static const struct
   4151 		{
   4152 			const char*	name;
   4153 			deUint32	format;
   4154 			int			width;
   4155 			int			height;
   4156 			int			depth;
   4157 			int			subX;
   4158 			int			subY;
   4159 			int			subZ;
   4160 			int			subW;
   4161 			int			subH;
   4162 			int			subD;
   4163 			int			imageHeight;
   4164 			int			rowLength;
   4165 			int			skipImages;
   4166 			int			skipRows;
   4167 			int			skipPixels;
   4168 			int			alignment;
   4169 		} cases[] =
   4170 		{
   4171 			{ "rgb8_image_height",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	26,	0,	0,	0,	0,	4 },
   4172 			{ "rgb8_row_length",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	27,	0,	0,	0,	4 },
   4173 			{ "rgb8_skip_images",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	3,	0,	0,	4 },
   4174 			{ "rgb8_skip_rows",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	22,	0,	0,	3,	0,	4 },
   4175 			{ "rgb8_skip_pixels",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	25,	0,	0,	2,	4 },
   4176 			{ "r8_complex1",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	1 },
   4177 			{ "r8_complex2",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	2 },
   4178 			{ "r8_complex3",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	4 },
   4179 			{ "r8_complex4",		GL_R8,		15,	20,	11,	1,	1,	0,	13, 17, 11,	23,	15,	2,	3,	1,	8 },
   4180 			{ "rgba8_complex1",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	0,	0,	8 },
   4181 			{ "rgba8_complex2",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	0,	8 },
   4182 			{ "rgba8_complex3",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	0,	3,	8 },
   4183 			{ "rgba8_complex4",		GL_RGBA8,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	3,	8 },
   4184 			{ "rgba32f_complex",	GL_RGBA32F,	15,	25,	10,	0,	5,	1,	11,	20,	8,	25,	14,	0,	2,	3,	8 }
   4185 		};
   4186 
   4187 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cases); ndx++)
   4188 			paramGroup->addChild(new TexSubImage3DParamsCase(m_context, cases[ndx].name, "",
   4189 															 cases[ndx].format,
   4190 															 cases[ndx].width,
   4191 															 cases[ndx].height,
   4192 															 cases[ndx].depth,
   4193 															 cases[ndx].subX,
   4194 															 cases[ndx].subY,
   4195 															 cases[ndx].subZ,
   4196 															 cases[ndx].subW,
   4197 															 cases[ndx].subH,
   4198 															 cases[ndx].subD,
   4199 															 cases[ndx].imageHeight,
   4200 															 cases[ndx].rowLength,
   4201 															 cases[ndx].skipImages,
   4202 															 cases[ndx].skipRows,
   4203 															 cases[ndx].skipPixels,
   4204 															 cases[ndx].alignment));
   4205 	}
   4206 
   4207 	// glTexSubImage3D() PBO cases.
   4208 	{
   4209 		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
   4210 		addChild(pboGroup);
   4211 
   4212 		static const struct
   4213 		{
   4214 			const char*	name;
   4215 			deUint32	format;
   4216 			int			width;
   4217 			int			height;
   4218 			int			depth;
   4219 			int			subX;
   4220 			int			subY;
   4221 			int			subZ;
   4222 			int			subW;
   4223 			int			subH;
   4224 			int			subD;
   4225 			int			imageHeight;
   4226 			int			rowLength;
   4227 			int			skipImages;
   4228 			int			skipRows;
   4229 			int			skipPixels;
   4230 			int			alignment;
   4231 			int			offset;
   4232 		} paramCases[] =
   4233 		{
   4234 			{ "rgb8_offset",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	0,	0,	0,	4,	67 },
   4235 			{ "rgb8_image_height",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	26,	0,	0,	0,	0,	4,	0 },
   4236 			{ "rgb8_row_length",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	27,	0,	0,	0,	4,	0 },
   4237 			{ "rgb8_skip_images",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	0,	3,	0,	0,	4,	0 },
   4238 			{ "rgb8_skip_rows",		GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	22,	0,	0,	3,	0,	4,	0 },
   4239 			{ "rgb8_skip_pixels",	GL_RGB8,	26, 25, 10,	1,	2,	1,	23,	19,	8,	0,	25,	0,	0,	2,	4,	0 }
   4240 		};
   4241 
   4242 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   4243 		{
   4244 			pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_2d_array").c_str(), "",
   4245 														   colorFormats[ndx].internalFormat,
   4246 														   26,	// Width
   4247 														   25,	// Height
   4248 														   10,	// Depth
   4249 														   1,	// Sub X
   4250 														   2,	// Sub Y
   4251 														   0,	// Sub Z
   4252 														   23,	// Sub W
   4253 														   19,	// Sub H
   4254 														   8,	// Sub D
   4255 														   0,	// Image height
   4256 														   0,	// Row length
   4257 														   0,	// Skip images
   4258 														   0,	// Skip rows
   4259 														   0,	// Skip pixels
   4260 														   4,	// Alignment
   4261 														   0	/* offset */));
   4262 			pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_3d").c_str(), "",
   4263 														   colorFormats[ndx].internalFormat,
   4264 														   26,	// Width
   4265 														   25,	// Height
   4266 														   10,	// Depth
   4267 														   1,	// Sub X
   4268 														   2,	// Sub Y
   4269 														   0,	// Sub Z
   4270 														   23,	// Sub W
   4271 														   19,	// Sub H
   4272 														   8,	// Sub D
   4273 														   0,	// Image height
   4274 														   0,	// Row length
   4275 														   0,	// Skip images
   4276 														   0,	// Skip rows
   4277 														   0,	// Skip pixels
   4278 														   4,	// Alignment
   4279 														   0	/* offset */));
   4280 		}
   4281 
   4282 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
   4283 		{
   4284 			pboGroup->addChild(new TexSubImage2DArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_2d_array").c_str(), "",
   4285 														   paramCases[ndx].format,
   4286 														   paramCases[ndx].width,
   4287 														   paramCases[ndx].height,
   4288 														   paramCases[ndx].depth,
   4289 														   paramCases[ndx].subX,
   4290 														   paramCases[ndx].subY,
   4291 														   paramCases[ndx].subZ,
   4292 														   paramCases[ndx].subW,
   4293 														   paramCases[ndx].subH,
   4294 														   paramCases[ndx].subD,
   4295 														   paramCases[ndx].imageHeight,
   4296 														   paramCases[ndx].rowLength,
   4297 														   paramCases[ndx].skipImages,
   4298 														   paramCases[ndx].skipRows,
   4299 														   paramCases[ndx].skipPixels,
   4300 														   paramCases[ndx].alignment,
   4301 														   paramCases[ndx].offset));
   4302 			pboGroup->addChild(new TexSubImage3DBufferCase(m_context, (std::string(paramCases[ndx].name) + "_3d").c_str(), "",
   4303 														   paramCases[ndx].format,
   4304 														   paramCases[ndx].width,
   4305 														   paramCases[ndx].height,
   4306 														   paramCases[ndx].depth,
   4307 														   paramCases[ndx].subX,
   4308 														   paramCases[ndx].subY,
   4309 														   paramCases[ndx].subZ,
   4310 														   paramCases[ndx].subW,
   4311 														   paramCases[ndx].subH,
   4312 														   paramCases[ndx].subD,
   4313 														   paramCases[ndx].imageHeight,
   4314 														   paramCases[ndx].rowLength,
   4315 														   paramCases[ndx].skipImages,
   4316 														   paramCases[ndx].skipRows,
   4317 														   paramCases[ndx].skipPixels,
   4318 														   paramCases[ndx].alignment,
   4319 														   paramCases[ndx].offset));
   4320 		}
   4321 	}
   4322 
   4323 	// glTexSubImage3D() depth cases.
   4324 	{
   4325 		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
   4326 		addChild(shadow3dGroup);
   4327 
   4328 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   4329 		{
   4330 			const int	tex2DArrayWidth		= 57;
   4331 			const int	tex2DArrayHeight	= 44;
   4332 			const int	tex2DArrayLevels	= 5;
   4333 
   4334 			shadow3dGroup->addChild(new TexSubImage2DArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_2d_array").c_str(), "", depthStencilFormats[ndx].internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels));
   4335 		}
   4336 	}
   4337 
   4338 	// glTexStorage2D() cases.
   4339 	{
   4340 		tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage2d", "Basic glTexStorage2D() usage");
   4341 		addChild(texStorageGroup);
   4342 
   4343 		// All formats.
   4344 		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage2D() with all formats");
   4345 		texStorageGroup->addChild(formatGroup);
   4346 
   4347 		// Color formats.
   4348 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4349 		{
   4350 			const char*	fmtName			= colorFormats[formatNdx].name;
   4351 			deUint32	internalFormat	= colorFormats[formatNdx].internalFormat;
   4352 			const int	tex2DWidth		= 117;
   4353 			const int	tex2DHeight		= 97;
   4354 			int			tex2DLevels		= maxLevelCount(tex2DWidth, tex2DHeight);
   4355 			const int	cubeSize		= 57;
   4356 			int			cubeLevels		= maxLevelCount(cubeSize, cubeSize);
   4357 
   4358 			formatGroup->addChild(new BasicTexStorage2DCase		(m_context, (string(fmtName) + "_2d").c_str(),		"", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
   4359 			formatGroup->addChild(new BasicTexStorageCubeCase	(m_context, (string(fmtName) + "_cube").c_str(),	"", internalFormat, cubeSize, cubeLevels));
   4360 		}
   4361 
   4362 		// Depth / stencil formats.
   4363 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
   4364 		{
   4365 			const char*	fmtName			= depthStencilFormats[formatNdx].name;
   4366 			deUint32	internalFormat	= depthStencilFormats[formatNdx].internalFormat;
   4367 			const int	tex2DWidth		= 117;
   4368 			const int	tex2DHeight		= 97;
   4369 			int			tex2DLevels		= maxLevelCount(tex2DWidth, tex2DHeight);
   4370 			const int	cubeSize		= 57;
   4371 			int			cubeLevels		= maxLevelCount(cubeSize, cubeSize);
   4372 
   4373 			formatGroup->addChild(new BasicTexStorage2DCase		(m_context, (string(fmtName) + "_2d").c_str(),		"", internalFormat, tex2DWidth, tex2DHeight, tex2DLevels));
   4374 			formatGroup->addChild(new BasicTexStorageCubeCase	(m_context, (string(fmtName) + "_cube").c_str(),	"", internalFormat, cubeSize, cubeLevels));
   4375 		}
   4376 
   4377 		// Sizes.
   4378 		static const struct
   4379 		{
   4380 			int				width;
   4381 			int				height;
   4382 			int				levels;
   4383 		} tex2DSizes[] =
   4384 		{
   4385 			//	W	H	L
   4386 			{	1,	1,	1 },
   4387 			{	2,	2,	2 },
   4388 			{	64,	32,	7 },
   4389 			{	32,	64,	4 },
   4390 			{	57,	63,	1 },
   4391 			{	57,	63,	2 },
   4392 			{	57,	63,	6 }
   4393 		};
   4394 		static const struct
   4395 		{
   4396 			int		size;
   4397 			int		levels;
   4398 		} cubeSizes[] =
   4399 		{
   4400 			//	S	L
   4401 			{	1,	1 },
   4402 			{	2,	2 },
   4403 			{	57,	1 },
   4404 			{	57,	2 },
   4405 			{	57,	6 },
   4406 			{	64,	4 },
   4407 			{	64,	7 },
   4408 		};
   4409 
   4410 		tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
   4411 		texStorageGroup->addChild(sizeGroup);
   4412 
   4413 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DSizes); ndx++)
   4414 		{
   4415 			const deUint32		format		= GL_RGBA8;
   4416 			int					width		= tex2DSizes[ndx].width;
   4417 			int					height		= tex2DSizes[ndx].height;
   4418 			int					levels		= tex2DSizes[ndx].levels;
   4419 			string				name		= string("2d_") + de::toString(width) + "x" + de::toString(height) + "_" + de::toString(levels) + "_levels";
   4420 
   4421 			sizeGroup->addChild(new BasicTexStorage2DCase(m_context, name.c_str(), "", format, width, height, levels));
   4422 		}
   4423 
   4424 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(cubeSizes); ndx++)
   4425 		{
   4426 			const deUint32		format		= GL_RGBA8;
   4427 			int					size		= cubeSizes[ndx].size;
   4428 			int					levels		= cubeSizes[ndx].levels;
   4429 			string				name		= string("cube_") + de::toString(size) + "x" + de::toString(size) + "_" + de::toString(levels) + "_levels";
   4430 
   4431 			sizeGroup->addChild(new BasicTexStorageCubeCase(m_context, name.c_str(), "", format, size, levels));
   4432 		}
   4433 	}
   4434 
   4435 	// glTexStorage3D() cases.
   4436 	{
   4437 		tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
   4438 		addChild(texStorageGroup);
   4439 
   4440 		// All formats.
   4441 		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
   4442 		texStorageGroup->addChild(formatGroup);
   4443 
   4444 		// Color formats.
   4445 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
   4446 		{
   4447 			const char*	fmtName				= colorFormats[formatNdx].name;
   4448 			deUint32	internalFormat		= colorFormats[formatNdx].internalFormat;
   4449 			const int	tex2DArrayWidth		= 57;
   4450 			const int	tex2DArrayHeight	= 13;
   4451 			const int	tex2DArrayLayers	= 7;
   4452 			int			tex2DArrayLevels	= maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
   4453 			const int	tex3DWidth			= 59;
   4454 			const int	tex3DHeight			= 37;
   4455 			const int	tex3DDepth			= 11;
   4456 			int			tex3DLevels			= maxLevelCount(tex3DWidth, tex3DHeight, tex3DDepth);
   4457 
   4458 			formatGroup->addChild(new BasicTexStorage2DArrayCase	(m_context, (string(fmtName) + "_2d_array").c_str(),	"", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
   4459 			formatGroup->addChild(new BasicTexStorage3DCase			(m_context, (string(fmtName) + "_3d").c_str(),			"", internalFormat, tex3DWidth, tex3DHeight, tex3DDepth, tex3DLevels));
   4460 		}
   4461 
   4462 		// Depth/stencil formats (only 2D texture array is supported).
   4463 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
   4464 		{
   4465 			const char*	fmtName				= depthStencilFormats[formatNdx].name;
   4466 			deUint32	internalFormat		= depthStencilFormats[formatNdx].internalFormat;
   4467 			const int	tex2DArrayWidth		= 57;
   4468 			const int	tex2DArrayHeight	= 13;
   4469 			const int	tex2DArrayLayers	= 7;
   4470 			int			tex2DArrayLevels	= maxLevelCount(tex2DArrayWidth, tex2DArrayHeight);
   4471 
   4472 			formatGroup->addChild(new BasicTexStorage2DArrayCase	(m_context, (string(fmtName) + "_2d_array").c_str(),	"", internalFormat, tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels));
   4473 		}
   4474 
   4475 		// Sizes.
   4476 		static const struct
   4477 		{
   4478 			int				width;
   4479 			int				height;
   4480 			int				layers;
   4481 			int				levels;
   4482 		} tex2DArraySizes[] =
   4483 		{
   4484 			//	W	H	La	Le
   4485 			{	1,	1,	1,	1 },
   4486 			{	2,	2,	2,	2 },
   4487 			{	64,	32,	3,	7 },
   4488 			{	32,	64,	3,	4 },
   4489 			{	57,	63,	5,	1 },
   4490 			{	57,	63,	5,	2 },
   4491 			{	57,	63,	5,	6 }
   4492 		};
   4493 		static const struct
   4494 		{
   4495 			int				width;
   4496 			int				height;
   4497 			int				depth;
   4498 			int				levels;
   4499 		} tex3DSizes[] =
   4500 		{
   4501 			//	W	H	D	L
   4502 			{	1,	1,	1,	1 },
   4503 			{	2,	2,	2,	2 },
   4504 			{	64,	32,	16,	7 },
   4505 			{	32,	64,	16,	4 },
   4506 			{	32,	16,	64,	4 },
   4507 			{	57,	63,	11,	1 },
   4508 			{	57,	63,	11,	2 },
   4509 			{	57,	63,	11,	6 }
   4510 		};
   4511 
   4512 		tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage2D() with various sizes");
   4513 		texStorageGroup->addChild(sizeGroup);
   4514 
   4515 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex2DArraySizes); ndx++)
   4516 		{
   4517 			const deUint32		format		= GL_RGBA8;
   4518 			int					width		= tex2DArraySizes[ndx].width;
   4519 			int					height		= tex2DArraySizes[ndx].height;
   4520 			int					layers		= tex2DArraySizes[ndx].layers;
   4521 			int					levels		= tex2DArraySizes[ndx].levels;
   4522 			string				name		= string("2d_array_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";
   4523 
   4524 			sizeGroup->addChild(new BasicTexStorage2DArrayCase(m_context, name.c_str(), "", format, width, height, layers, levels));
   4525 		}
   4526 
   4527 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(tex3DSizes); ndx++)
   4528 		{
   4529 			const deUint32		format		= GL_RGBA8;
   4530 			int					width		= tex3DSizes[ndx].width;
   4531 			int					height		= tex3DSizes[ndx].height;
   4532 			int					depth		= tex3DSizes[ndx].depth;
   4533 			int					levels		= tex3DSizes[ndx].levels;
   4534 			string				name		= string("3d_") + de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + de::toString(levels) + "_levels";
   4535 
   4536 			sizeGroup->addChild(new BasicTexStorage3DCase(m_context, name.c_str(), "", format, width, height, depth, levels));
   4537 		}
   4538 	}
   4539 }
   4540 
   4541 } // Functional
   4542 } // gles3
   4543 } // deqp
   4544