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