• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
mapGLUnsizedInternalFormat(deUint32 internalFormat)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 
maxLevelCount(int width,int height)87 static inline int maxLevelCount (int width, int height)
88 {
89 	return (int)deLog2Floor32(de::max(width, height))+1;
90 }
91 
maxLevelCount(int width,int height,int depth)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 
getPixelFormatCompareDepth(const tcu::PixelFormat & pixelFormat,tcu::TextureFormat textureFormat)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 
getEffectiveTextureFormatBitDepth(tcu::TextureFormat textureFormat)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 
computeCompareThreshold(const tcu::PixelFormat & pixelFormat,tcu::TextureFormat textureFormat)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 
TextureSpecCase(Context & context,const char * name,const char * desc)171 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
172 	: TestCase(context, name, desc)
173 {
174 }
175 
~TextureSpecCase(void)176 TextureSpecCase::~TextureSpecCase (void)
177 {
178 }
179 
iterate(void)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 
renderTex(tcu::Surface & dst,deUint32 program,int width,int height)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 
readPixels(tcu::Surface & dst,int x,int y,int width,int height)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 
Texture2DSpecCase(Context & context,const char * name,const char * desc,const tcu::TextureFormat & format,int width,int height,int numLevels)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 
~Texture2DSpecCase(void)275 Texture2DSpecCase::~Texture2DSpecCase (void)
276 {
277 }
278 
verifyTexture(sglr::GLContext & gles3Context,sglr::ReferenceContext & refContext)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 
TextureCubeSpecCase(Context & context,const char * name,const char * desc,const tcu::TextureFormat & format,int size,int numLevels)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 
~TextureCubeSpecCase(void)358 TextureCubeSpecCase::~TextureCubeSpecCase (void)
359 {
360 }
361 
verifyTexture(sglr::GLContext & gles3Context,sglr::ReferenceContext & refContext)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 
Texture2DArraySpecCase(Context & context,const char * name,const char * desc,const tcu::TextureFormat & format,int width,int height,int numLayers,int numLevels)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 
~Texture2DArraySpecCase(void)459 Texture2DArraySpecCase::~Texture2DArraySpecCase (void)
460 {
461 }
462 
verifyTexture(sglr::GLContext & gles3Context,sglr::ReferenceContext & refContext)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 
Texture3DSpecCase(Context & context,const char * name,const char * desc,const tcu::TextureFormat & format,int width,int height,int depth,int numLevels)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 
~Texture3DSpecCase(void)559 Texture3DSpecCase::~Texture3DSpecCase (void)
560 {
561 }
562 
verifyTexture(sglr::GLContext & gles3Context,sglr::ReferenceContext & refContext)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.
BasicTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height)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.
BasicTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height)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:
createTexture(void)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.
BasicTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size)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.
BasicTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size)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:
createTexture(void)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:
BasicTexImage2DArrayCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int numLayers)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:
createTexture(void)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:
BasicTexImage3DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth)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:
createTexture(void)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:
RandomOrderTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height)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 
RandomOrderTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height)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:
createTexture(void)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:
RandomOrderTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size)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 
RandomOrderTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size)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:
createTexture(void)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:
TexImage2DAlignCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height,int numLevels,int alignment)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 
TexImage2DAlignCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int numLevels,int alignment)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:
createTexture(void)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:
TexImageCubeAlignCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size,int numLevels,int alignment)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 
TexImageCubeAlignCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size,int numLevels,int alignment)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:
createTexture(void)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:
TexImage2DParamsCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int rowLength,int skipRows,int skipPixels,int alignment)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:
createTexture(void)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:
TexImage3DParamsCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment)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:
createTexture(void)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:
BasicTexSubImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height)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 
BasicTexSubImage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height)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:
createTexture(void)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:
BasicTexSubImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size)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 
BasicTexSubImageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size)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:
createTexture(void)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:
TexSubImage2DParamsCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int subX,int subY,int subW,int subH,int rowLength,int skipRows,int skipPixels,int alignment)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:
createTexture(void)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:
BasicTexSubImage3DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth)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:
createTexture(void)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:
TexSubImage2DEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height)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 
TexSubImage2DEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height)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:
createTexture(void)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:
TexSubImageCubeEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size)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 
TexSubImageCubeEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size)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:
createTexture(void)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:
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)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 
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)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:
createTexture(void)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:
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)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 
TexSubImageCubeAlignCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size,int subX,int subY,int subW,int subH,int alignment)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:
createTexture(void)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:
TexSubImage3DParamsCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int subX,int subY,int subZ,int subW,int subH,int subD,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment)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:
createTexture(void)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:
BasicCopyTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height)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:
createTexture(void)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:
BasicCopyTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size)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:
createTexture(void)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:
BasicCopyTexSubImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int width,int height)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:
createTexture(void)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:
BasicCopyTexSubImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,int size)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:
createTexture(void)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:
BasicTexStorage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int numLevels)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:
createTexture(void)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:
BasicTexStorageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size,int numLevels)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:
createTexture(void)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:
BasicTexStorage2DArrayCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int numLayers,int numLevels)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:
createTexture(void)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:
BasicTexStorage3DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int numLevels)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:
createTexture(void)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:
TexImage2DBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int rowLength,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexImageCubeBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size,int rowLength,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexImage2DArrayBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexImage3DBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexSubImage2DBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int subX,int subY,int subW,int subH,int rowLength,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexSubImageCubeBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int size,int subX,int subY,int subW,int subH,int rowLength,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexSubImage2DArrayBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int subX,int subY,int subZ,int subW,int subH,int subD,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexSubImage3DBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int width,int height,int depth,int subX,int subY,int subZ,int subW,int subH,int subD,int imageHeight,int rowLength,int skipImages,int skipRows,int skipPixels,int alignment,int offset)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:
createTexture(void)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:
TexImage2DDepthCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight)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 
createTexture(void)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:
TexImage2DArrayDepthCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight,int numLayers)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 
createTexture(void)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:
TexSubImage2DDepthCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight)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 
createTexture(void)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:
TexSubImage2DArrayDepthCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight,int numLayers)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 
createTexture(void)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:
TexImage2DDepthBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight)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 
createTexture(void)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:
TexImage2DArrayDepthBufferCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,int imageWidth,int imageHeight,int numLayers)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 
createTexture(void)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 
TextureSpecificationTests(Context & context)3369 TextureSpecificationTests::TextureSpecificationTests (Context& context)
3370 	: TestCaseGroup(context, "specification", "Texture Specification Tests")
3371 {
3372 }
3373 
~TextureSpecificationTests(void)3374 TextureSpecificationTests::~TextureSpecificationTests (void)
3375 {
3376 }
3377 
init(void)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