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