1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 2.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 "es2fTextureSpecificationTests.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuImageCompare.hpp"
32 #include "gluTextureUtil.hpp"
33 #include "sglrContextUtil.hpp"
34 #include "sglrContextWrapper.hpp"
35 #include "sglrGLContext.hpp"
36 #include "sglrReferenceContext.hpp"
37 #include "glsTextureTestUtil.hpp"
38 #include "tcuTextureUtil.hpp"
39 #include "tcuFormatUtil.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "deRandom.hpp"
42 #include "deStringUtil.hpp"
43 
44 #include "glwEnums.hpp"
45 #include "glwFunctions.hpp"
46 
47 namespace deqp
48 {
49 namespace gles2
50 {
51 namespace Functional
52 {
53 
54 using std::string;
55 using std::vector;
56 using std::pair;
57 using tcu::TestLog;
58 using tcu::Vec4;
59 using tcu::IVec4;
60 using tcu::UVec4;
61 
mapGLUnsizedInternalFormat(deUint32 internalFormat)62 tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat)
63 {
64 	using tcu::TextureFormat;
65 	switch (internalFormat)
66 	{
67 		case GL_ALPHA:				return TextureFormat(TextureFormat::A,		TextureFormat::UNORM_INT8);
68 		case GL_LUMINANCE:			return TextureFormat(TextureFormat::L,		TextureFormat::UNORM_INT8);
69 		case GL_LUMINANCE_ALPHA:	return TextureFormat(TextureFormat::LA,		TextureFormat::UNORM_INT8);
70 		case GL_RGB:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
71 		case GL_RGBA:				return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
72 		default:
73 			throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format");
74 	}
75 }
76 
77 template <int Size>
78 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))
79 {
80 	tcu::Vector<float, Size> res;
81 	for (int ndx = 0; ndx < Size; ndx++)
82 		res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
83 	return res;
84 }
85 
getPixelFormatCompareDepth(const tcu::PixelFormat & pixelFormat,tcu::TextureFormat textureFormat)86 static tcu::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
87 {
88 	switch (textureFormat.order)
89 	{
90 		case tcu::TextureFormat::L:
91 		case tcu::TextureFormat::LA:
92 			return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits);
93 		default:
94 			return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
95 	}
96 }
97 
computeCompareThreshold(const tcu::PixelFormat & pixelFormat,tcu::TextureFormat textureFormat)98 static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
99 {
100 	const IVec4		texFormatBits		= tcu::getTextureFormatBitDepth(textureFormat);
101 	const IVec4		pixelFormatBits		= getPixelFormatCompareDepth(pixelFormat, textureFormat);
102 	const IVec4		accurateFmtBits		= min(pixelFormatBits, texFormatBits);
103 	const IVec4		compareBits			= select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1;
104 
105 	return (IVec4(1) << (8-compareBits)).asUint();
106 }
107 
108 class GradientShader : public sglr::ShaderProgram
109 {
110 public:
GradientShader(void)111 	GradientShader (void)
112 		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
113 					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
114 					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
115 					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
116 					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
117 					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
118 												"attribute mediump vec2 a_coord;\n"
119 												"varying mediump vec2 v_coord;\n"
120 												"void main (void)\n"
121 												"{\n"
122 												"	gl_Position = a_position;\n"
123 												"	v_coord = a_coord;\n"
124 												"}\n")
125 					<< sglr::pdec::FragmentSource("varying mediump vec2 v_coord;\n"
126 												  "void main (void)\n"
127 												  "{\n"
128 												  "	mediump float x = v_coord.x;\n"
129 												  "	mediump float y = v_coord.y;\n"
130 												  "	mediump float f0 = (x + y) * 0.5;\n"
131 												  "	mediump float f1 = 0.5 + (x - y) * 0.5;\n"
132 												  "	gl_FragColor = vec4(f0, f1, 1.0-f0, 1.0-f1);\n"
133 												  "}\n"))
134 	{
135 	}
136 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const137 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
138 	{
139 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
140 		{
141 			rr::VertexPacket& packet = *packets[packetNdx];
142 
143 			packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
144 			packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
145 		}
146 	}
147 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const148 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
149 	{
150 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
151 		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
152 		{
153 			const tcu::Vec4		coord	= rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
154 			const float			x		= coord.x();
155 			const float			y		= coord.y();
156 			const float			f0		= (x + y) * 0.5f;
157 			const float			f1		= 0.5f + (x - y) * 0.5f;
158 
159 			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(f0, f1, 1.0f-f0, 1.0f-f1));
160 		}
161 	}
162 };
163 
164 class Tex2DShader : public sglr::ShaderProgram
165 {
166 public:
Tex2DShader(void)167 	Tex2DShader (void)
168 		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
169 					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
170 					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
171 					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
172 					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
173 					<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D)
174 					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
175 												"attribute mediump vec2 a_coord;\n"
176 												"varying mediump vec2 v_coord;\n"
177 												"void main (void)\n"
178 												"{\n"
179 												"	gl_Position = a_position;\n"
180 												"	v_coord = a_coord;\n"
181 												"}\n")
182 					<< sglr::pdec::FragmentSource("uniform sampler2D u_sampler0;\n"
183 												  "varying mediump vec2 v_coord;\n"
184 												  "void main (void)\n"
185 												  "{\n"
186 												  "	gl_FragColor = texture2D(u_sampler0, v_coord);\n"
187 												  "}\n"))
188 	{
189 	}
190 
setUniforms(sglr::Context & ctx,deUint32 program) const191 	void setUniforms (sglr::Context& ctx, deUint32 program) const
192 	{
193 		ctx.useProgram(program);
194 		ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
195 	}
196 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const197 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
198 	{
199 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
200 		{
201 			rr::VertexPacket& packet = *packets[packetNdx];
202 
203 			packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
204 			packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
205 		}
206 	}
207 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const208 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
209 	{
210 		tcu::Vec2 texCoords[4];
211 		tcu::Vec4 colors[4];
212 
213 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
214 		{
215 			// setup tex coords
216 			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
217 			{
218 				const tcu::Vec4	coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
219 				texCoords[fragNdx] = tcu::Vec2(coord.x(), coord.y());
220 			}
221 
222 			// Sample
223 			m_uniforms[0].sampler.tex2D->sample4(colors, texCoords);
224 
225 			// Write out
226 			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
227 				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, colors[fragNdx]);
228 		}
229 	}
230 };
231 
232 static const char* s_cubeSwizzles[] =
233 {
234 	"vec3(-1, -y, +x)",
235 	"vec3(+1, -y, -x)",
236 	"vec3(+x, -1, -y)",
237 	"vec3(+x, +1, +y)",
238 	"vec3(-x, -y, -1)",
239 	"vec3(+x, -y, +1)"
240 };
241 
242 class TexCubeShader : public sglr::ShaderProgram
243 {
244 public:
TexCubeShader(tcu::CubeFace face)245 	TexCubeShader (tcu::CubeFace face)
246 		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
247 					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
248 					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
249 					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
250 					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
251 					<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_CUBE)
252 					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
253 												"attribute mediump vec2 a_coord;\n"
254 												"varying mediump vec2 v_coord;\n"
255 												"void main (void)\n"
256 												"{\n"
257 												"	gl_Position = a_position;\n"
258 												"	v_coord = a_coord;\n"
259 												"}\n")
260 					<< sglr::pdec::FragmentSource(string("") +
261 												  "uniform samplerCube u_sampler0;\n"
262 												  "varying mediump vec2 v_coord;\n"
263 												  "void main (void)\n"
264 												  "{\n"
265 												  "	mediump float x = v_coord.x*2.0 - 1.0;\n"
266 												  "	mediump float y = v_coord.y*2.0 - 1.0;\n"
267 												  "	gl_FragColor = textureCube(u_sampler0, " + s_cubeSwizzles[face] + ");\n"
268 												  "}\n"))
269 		, m_face(face)
270 	{
271 	}
272 
setUniforms(sglr::Context & ctx,deUint32 program) const273 	void setUniforms (sglr::Context& ctx, deUint32 program) const
274 	{
275 		ctx.useProgram(program);
276 		ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
277 	}
278 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const279 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
280 	{
281 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
282 		{
283 			rr::VertexPacket& packet = *packets[packetNdx];
284 
285 			packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
286 			packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
287 		}
288 	}
289 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const290 	void shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
291 	{
292 		tcu::Vec3 texCoords[4];
293 		tcu::Vec4 colors[4];
294 
295 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
296 		{
297 			// setup tex coords
298 			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
299 			{
300 				const tcu::Vec4	coord	= rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
301 				const float		x		= coord.x()*2.0f - 1.0f;
302 				const float		y		= coord.y()*2.0f - 1.0f;
303 
304 				// Swizzle tex coords
305 				switch (m_face)
306 				{
307 					case tcu::CUBEFACE_NEGATIVE_X:	texCoords[fragNdx] = tcu::Vec3(-1.0f,    -y,    +x);		break;
308 					case tcu::CUBEFACE_POSITIVE_X:	texCoords[fragNdx] = tcu::Vec3(+1.0f,    -y,    -x);		break;
309 					case tcu::CUBEFACE_NEGATIVE_Y:	texCoords[fragNdx] = tcu::Vec3(   +x, -1.0f,    -y);		break;
310 					case tcu::CUBEFACE_POSITIVE_Y:	texCoords[fragNdx] = tcu::Vec3(   +x, +1.0f,    +y);		break;
311 					case tcu::CUBEFACE_NEGATIVE_Z:	texCoords[fragNdx] = tcu::Vec3(   -x,    -y, -1.0f);		break;
312 					case tcu::CUBEFACE_POSITIVE_Z:	texCoords[fragNdx] = tcu::Vec3(   +x,    -y, +1.0f);		break;
313 					default:
314 						DE_ASSERT(false);
315 				}
316 			}
317 
318 			// Sample
319 			m_uniforms[0].sampler.texCube->sample4(colors, texCoords);
320 
321 			// Write out
322 			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
323 				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, colors[fragNdx]);
324 		}
325 	}
326 private:
327 	tcu::CubeFace m_face;
328 };
329 
330 enum TextureType
331 {
332 	TEXTURETYPE_2D = 0,
333 	TEXTURETYPE_CUBE,
334 
335 	TEXTURETYPE_LAST
336 };
337 
338 enum Flags
339 {
340 	MIPMAPS		= (1<<0)
341 };
342 
343 static const deUint32 s_cubeMapFaces[] =
344 {
345 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
346 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
347 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
348 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
349 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
350 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
351 };
352 
353 class TextureSpecCase : public TestCase, public sglr::ContextWrapper
354 {
355 public:
356 								TextureSpecCase		(Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height);
357 								~TextureSpecCase	(void);
358 
359 	IterateResult				iterate				(void);
360 
361 protected:
362 	virtual void				createTexture		(void) = DE_NULL;
363 
364 	const TextureType			m_texType;
365 	const tcu::TextureFormat	m_texFormat;
366 	const deUint32				m_flags;
367 	const int					m_width;
368 	const int					m_height;
369 
370 private:
371 								TextureSpecCase		(const TextureSpecCase& other);
372 	TextureSpecCase&			operator=			(const TextureSpecCase& other);
373 
374 	void						verifyTex2D			(sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);
375 	void						verifyTexCube		(sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);
376 
377 	void						renderTex2D			(tcu::Surface& dst, int width, int height);
378 	void						renderTexCube		(tcu::Surface& dst, int width, int height, tcu::CubeFace face);
379 
380 	void						readPixels			(tcu::Surface& dst, int x, int y, int width, int height);
381 
382 	// \todo [2012-03-27 pyry] Renderer should be extended to allow custom attributes, that would clean up this cubemap mess.
383 	Tex2DShader					m_tex2DShader;
384 	TexCubeShader				m_texCubeNegXShader;
385 	TexCubeShader				m_texCubePosXShader;
386 	TexCubeShader				m_texCubeNegYShader;
387 	TexCubeShader				m_texCubePosYShader;
388 	TexCubeShader				m_texCubeNegZShader;
389 	TexCubeShader				m_texCubePosZShader;
390 };
391 
TextureSpecCase(Context & context,const char * name,const char * desc,const TextureType type,const tcu::TextureFormat format,const deUint32 flags,int width,int height)392 TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height)
393 	: TestCase				(context, name, desc)
394 	, m_texType				(type)
395 	, m_texFormat			(format)
396 	, m_flags				(flags)
397 	, m_width				(width)
398 	, m_height				(height)
399 	, m_texCubeNegXShader	(tcu::CUBEFACE_NEGATIVE_X)
400 	, m_texCubePosXShader	(tcu::CUBEFACE_POSITIVE_X)
401 	, m_texCubeNegYShader	(tcu::CUBEFACE_NEGATIVE_Y)
402 	, m_texCubePosYShader	(tcu::CUBEFACE_POSITIVE_Y)
403 	, m_texCubeNegZShader	(tcu::CUBEFACE_NEGATIVE_Z)
404 	, m_texCubePosZShader	(tcu::CUBEFACE_POSITIVE_Z)
405 {
406 }
407 
~TextureSpecCase(void)408 TextureSpecCase::~TextureSpecCase (void)
409 {
410 }
411 
iterate(void)412 TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
413 {
414 	glu::RenderContext&			renderCtx				= TestCase::m_context.getRenderContext();
415 	const tcu::RenderTarget&	renderTarget			= renderCtx.getRenderTarget();
416 	tcu::TestLog&				log						= m_testCtx.getLog();
417 
418 	DE_ASSERT(m_width <= 256 && m_height <= 256);
419 	if (renderTarget.getWidth() < m_width || renderTarget.getHeight() < m_height)
420 		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);
421 
422 	// Context size, and viewport for GLES2
423 	de::Random		rnd			(deStringHash(getName()));
424 	int				width		= deMin32(renderTarget.getWidth(),	256);
425 	int				height		= deMin32(renderTarget.getHeight(),	256);
426 	int				x			= rnd.getInt(0, renderTarget.getWidth()		- width);
427 	int				y			= rnd.getInt(0, renderTarget.getHeight()	- height);
428 
429 	// Contexts.
430 	sglr::GLContext					gles2Context	(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
431 	sglr::ReferenceContextBuffers	refBuffers		(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
432 	sglr::ReferenceContext			refContext		(sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());
433 
434 	// Clear color buffer.
435 	for (int ndx = 0; ndx < 2; ndx++)
436 	{
437 		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
438 		glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
439 		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
440 	}
441 
442 	// Construct texture using both GLES2 and reference contexts.
443 	for (int ndx = 0; ndx < 2; ndx++)
444 	{
445 		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
446 		createTexture();
447 		TCU_CHECK(glGetError() == GL_NO_ERROR);
448 	}
449 
450 	// Setup texture filtering state.
451 	for (int ndx = 0; ndx < 2; ndx++)
452 	{
453 		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
454 
455 		deUint32 texTarget = m_texType == TEXTURETYPE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
456 		glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER,	(m_flags & MIPMAPS) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
457 		glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
458 		glTexParameteri(texTarget, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
459 		glTexParameteri(texTarget, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
460 	}
461 
462 	// Initialize case result to pass.
463 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
464 
465 	// Disable logging.
466 	gles2Context.enableLogging(0);
467 
468 	// Verify results.
469 	switch (m_texType)
470 	{
471 		case TEXTURETYPE_2D:	verifyTex2D		(gles2Context, refContext);	break;
472 		case TEXTURETYPE_CUBE:	verifyTexCube	(gles2Context, refContext);	break;
473 		default:
474 			DE_ASSERT(false);
475 	}
476 
477 	return STOP;
478 }
479 
verifyTex2D(sglr::GLContext & gles2Context,sglr::ReferenceContext & refContext)480 void TextureSpecCase::verifyTex2D (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
481 {
482 	int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
483 
484 	DE_ASSERT(m_texType == TEXTURETYPE_2D);
485 
486 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
487 	{
488 		int				levelW		= de::max(1, m_width >> levelNdx);
489 		int				levelH		= de::max(1, m_height >> levelNdx);
490 		tcu::Surface	reference;
491 		tcu::Surface	result;
492 
493 		if (levelW <= 2 || levelH <= 2)
494 			continue; // Don't bother checking.
495 
496 		// Render with GLES2
497 		setContext(&gles2Context);
498 		renderTex2D(result, levelW, levelH);
499 
500 		// Render reference.
501 		setContext(&refContext);
502 		renderTex2D(reference, levelW, levelH);
503 
504 		{
505 			tcu::UVec4	threshold	= computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
506 			bool		isOk		= tcu::intThresholdCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold,
507 															   levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
508 
509 			if (!isOk)
510 			{
511 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
512 				break;
513 			}
514 		}
515 	}
516 }
517 
verifyTexCube(sglr::GLContext & gles2Context,sglr::ReferenceContext & refContext)518 void TextureSpecCase::verifyTexCube (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
519 {
520 	int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
521 
522 	DE_ASSERT(m_texType == TEXTURETYPE_CUBE);
523 
524 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
525 	{
526 		int		levelW	= de::max(1, m_width >> levelNdx);
527 		int		levelH	= de::max(1, m_height >> levelNdx);
528 		bool	isOk	= true;
529 
530 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
531 		{
532 			tcu::Surface	reference;
533 			tcu::Surface	result;
534 
535 			if (levelW <= 2 || levelH <= 2)
536 				continue; // Don't bother checking.
537 
538 			// Render with GLES2
539 			setContext(&gles2Context);
540 			renderTexCube(result, levelW, levelH, (tcu::CubeFace)face);
541 
542 			// Render reference.
543 			setContext(&refContext);
544 			renderTexCube(reference, levelW, levelH, (tcu::CubeFace)face);
545 
546 			const float	threshold	= 0.02f;
547 			isOk = tcu::fuzzyCompare(m_testCtx.getLog(), "Result", (string("Image comparison result: ") + de::toString((tcu::CubeFace)face)).c_str(), reference, result, threshold,
548 									 levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);
549 
550 			if (!isOk)
551 			{
552 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
553 				break;
554 			}
555 		}
556 
557 		if (!isOk)
558 			break;
559 	}
560 }
561 
renderTex2D(tcu::Surface & dst,int width,int height)562 void TextureSpecCase::renderTex2D (tcu::Surface& dst, int width, int height)
563 {
564 	int			targetW		= getWidth();
565 	int			targetH		= getHeight();
566 
567 	float		w			= (float)width	/ (float)targetW;
568 	float		h			= (float)height	/ (float)targetH;
569 
570 	deUint32	shaderID	= getCurrentContext()->createProgram(&m_tex2DShader);
571 
572 	m_tex2DShader.setUniforms(*getCurrentContext(), shaderID);
573 	sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
574 
575 	// Read pixels back.
576 	readPixels(dst, 0, 0, width, height);
577 }
578 
renderTexCube(tcu::Surface & dst,int width,int height,tcu::CubeFace face)579 void TextureSpecCase::renderTexCube (tcu::Surface& dst, int width, int height, tcu::CubeFace face)
580 {
581 	int		targetW		= getWidth();
582 	int		targetH		= getHeight();
583 
584 	float	w			= (float)width	/ (float)targetW;
585 	float	h			= (float)height	/ (float)targetH;
586 
587 	TexCubeShader* shaders[] =
588 	{
589 		&m_texCubeNegXShader,
590 		&m_texCubePosXShader,
591 		&m_texCubeNegYShader,
592 		&m_texCubePosYShader,
593 		&m_texCubeNegZShader,
594 		&m_texCubePosZShader
595 	};
596 
597 	deUint32	shaderID	= getCurrentContext()->createProgram(shaders[face]);
598 
599 	shaders[face]->setUniforms(*getCurrentContext(), shaderID);
600 	sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));
601 
602 	// Read pixels back.
603 	readPixels(dst, 0, 0, width, height);
604 }
605 
readPixels(tcu::Surface & dst,int x,int y,int width,int height)606 void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
607 {
608 	dst.setSize(width, height);
609 	glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
610 }
611 
612 // Basic TexImage2D() with 2D texture usage
613 class BasicTexImage2DCase : public TextureSpecCase
614 {
615 public:
BasicTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)616 	BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
617 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
618 		, m_format			(format)
619 		, m_dataType		(dataType)
620 	{
621 	}
622 
623 protected:
createTexture(void)624 	void createTexture (void)
625 	{
626 		tcu::TextureFormat	fmt			= m_texFormat;
627 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
628 		deUint32			tex			= 0;
629 		tcu::TextureLevel	levelData	(fmt);
630 		de::Random			rnd			(deStringHash(getName()));
631 
632 		glGenTextures(1, &tex);
633 		glBindTexture(GL_TEXTURE_2D, tex);
634 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
635 
636 		for (int ndx = 0; ndx < numLevels; ndx++)
637 		{
638 			int		levelW		= de::max(1, m_width >> ndx);
639 			int		levelH		= de::max(1, m_height >> ndx);
640 			Vec4	gMin		= randomVector<4>(rnd);
641 			Vec4	gMax		= randomVector<4>(rnd);
642 
643 			levelData.setSize(levelW, levelH);
644 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
645 
646 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
647 		}
648 	}
649 
650 	deUint32	m_format;
651 	deUint32	m_dataType;
652 };
653 
654 // Basic TexImage2D() with cubemap usage
655 class BasicTexImageCubeCase : public TextureSpecCase
656 {
657 public:
BasicTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)658 	BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
659 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
660 		, m_format			(format)
661 		, m_dataType		(dataType)
662 	{
663 	}
664 
665 protected:
createTexture(void)666 	void createTexture (void)
667 	{
668 		tcu::TextureFormat	fmt			= m_texFormat;
669 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
670 		deUint32			tex			= 0;
671 		tcu::TextureLevel	levelData	(fmt);
672 		de::Random			rnd			(deStringHash(getName()));
673 
674 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
675 
676 		glGenTextures(1, &tex);
677 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
678 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
679 
680 		for (int ndx = 0; ndx < numLevels; ndx++)
681 		{
682 			int		levelW		= de::max(1, m_width >> ndx);
683 			int		levelH		= de::max(1, m_height >> ndx);
684 
685 			levelData.setSize(levelW, levelH);
686 
687 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
688 			{
689 				Vec4 gMin = randomVector<4>(rnd);
690 				Vec4 gMax = randomVector<4>(rnd);
691 
692 				tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
693 
694 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
695 			}
696 		}
697 	}
698 
699 	deUint32	m_format;
700 	deUint32	m_dataType;
701 };
702 
703 // Randomized 2D texture specification using TexImage2D
704 class RandomOrderTexImage2DCase : public TextureSpecCase
705 {
706 public:
RandomOrderTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)707 	RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
708 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
709 		, m_format			(format)
710 		, m_dataType		(dataType)
711 	{
712 	}
713 
714 protected:
createTexture(void)715 	void createTexture (void)
716 	{
717 		tcu::TextureFormat	fmt			= m_texFormat;
718 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
719 		deUint32			tex			= 0;
720 		tcu::TextureLevel	levelData	(fmt);
721 		de::Random			rnd			(deStringHash(getName()));
722 
723 		glGenTextures(1, &tex);
724 		glBindTexture(GL_TEXTURE_2D, tex);
725 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
726 
727 		vector<int>			levels		(numLevels);
728 
729 		for (int i = 0; i < numLevels; i++)
730 			levels[i] = i;
731 		rnd.shuffle(levels.begin(), levels.end());
732 
733 		for (int ndx = 0; ndx < numLevels; ndx++)
734 		{
735 			int		levelNdx	= levels[ndx];
736 			int		levelW		= de::max(1, m_width	>> levelNdx);
737 			int		levelH		= de::max(1, m_height	>> levelNdx);
738 			Vec4	gMin		= randomVector<4>(rnd);
739 			Vec4	gMax		= randomVector<4>(rnd);
740 
741 			levelData.setSize(levelW, levelH);
742 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
743 
744 			glTexImage2D(GL_TEXTURE_2D, levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
745 		}
746 	}
747 
748 	deUint32	m_format;
749 	deUint32	m_dataType;
750 };
751 
752 // Randomized cubemap texture specification using TexImage2D
753 class RandomOrderTexImageCubeCase : public TextureSpecCase
754 {
755 public:
RandomOrderTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)756 	RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
757 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
758 		, m_format			(format)
759 		, m_dataType		(dataType)
760 	{
761 	}
762 
763 protected:
createTexture(void)764 	void createTexture (void)
765 	{
766 		tcu::TextureFormat	fmt			= m_texFormat;
767 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
768 		deUint32			tex			= 0;
769 		tcu::TextureLevel	levelData	(fmt);
770 		de::Random			rnd			(deStringHash(getName()));
771 
772 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
773 
774 		glGenTextures(1, &tex);
775 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
776 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
777 
778 		// Level-face pairs.
779 		vector<pair<int, tcu::CubeFace> >	images	(numLevels*6);
780 
781 		for (int ndx = 0; ndx < numLevels; ndx++)
782 			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
783 				images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face);
784 
785 		rnd.shuffle(images.begin(), images.end());
786 
787 		for (int ndx = 0; ndx < (int)images.size(); ndx++)
788 		{
789 			int				levelNdx	= images[ndx].first;
790 			tcu::CubeFace	face		= images[ndx].second;
791 			int				levelW		= de::max(1, m_width >> levelNdx);
792 			int				levelH		= de::max(1, m_height >> levelNdx);
793 			Vec4			gMin		= randomVector<4>(rnd);
794 			Vec4			gMax		= randomVector<4>(rnd);
795 
796 			levelData.setSize(levelW, levelH);
797 			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);
798 
799 			glTexImage2D(s_cubeMapFaces[face], levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
800 		}
801 	}
802 
803 	deUint32	m_format;
804 	deUint32	m_dataType;
805 };
806 
getRowPitch(const tcu::TextureFormat & transferFmt,int rowLen,int alignment)807 static inline int getRowPitch (const tcu::TextureFormat& transferFmt, int rowLen, int alignment)
808 {
809 	int basePitch = transferFmt.getPixelSize()*rowLen;
810 	return alignment*(basePitch/alignment + ((basePitch % alignment) ? 1 : 0));
811 }
812 
813 // TexImage2D() unpack alignment case.
814 class TexImage2DAlignCase : public TextureSpecCase
815 {
816 public:
TexImage2DAlignCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height,int alignment)817 	TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
818 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
819 		, m_format			(format)
820 		, m_dataType		(dataType)
821 		, m_alignment		(alignment)
822 	{
823 	}
824 
825 protected:
createTexture(void)826 	void createTexture (void)
827 	{
828 		tcu::TextureFormat	fmt			= m_texFormat;
829 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
830 		deUint32			tex			= 0;
831 		vector<deUint8>		data;
832 
833 		glGenTextures(1, &tex);
834 		glBindTexture(GL_TEXTURE_2D, tex);
835 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
836 
837 		for (int ndx = 0; ndx < numLevels; ndx++)
838 		{
839 			int		levelW		= de::max(1, m_width >> ndx);
840 			int		levelH		= de::max(1, m_height >> ndx);
841 			Vec4	colorA		(1.0f, 0.0f, 0.0f, 1.0f);
842 			Vec4	colorB		(0.0f, 1.0f, 0.0f, 1.0f);
843 			int		rowPitch	= getRowPitch(fmt, levelW, m_alignment);
844 			int		cellSize	= de::max(1, de::min(levelW >> 2, levelH >> 2));
845 
846 			data.resize(rowPitch*levelH);
847 			tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
848 
849 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
850 		}
851 	}
852 
853 	deUint32	m_format;
854 	deUint32	m_dataType;
855 	int			m_alignment;
856 };
857 
858 // TexImage2D() unpack alignment case.
859 class TexImageCubeAlignCase : public TextureSpecCase
860 {
861 public:
TexImageCubeAlignCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height,int alignment)862 	TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
863 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
864 		, m_format			(format)
865 		, m_dataType		(dataType)
866 		, m_alignment		(alignment)
867 	{
868 	}
869 
870 protected:
createTexture(void)871 	void createTexture (void)
872 	{
873 		tcu::TextureFormat	fmt			= m_texFormat;
874 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
875 		deUint32			tex			= 0;
876 		vector<deUint8>		data;
877 
878 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
879 
880 		glGenTextures(1, &tex);
881 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
882 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
883 
884 		for (int ndx = 0; ndx < numLevels; ndx++)
885 		{
886 			int		levelW		= de::max(1, m_width >> ndx);
887 			int		levelH		= de::max(1, m_height >> ndx);
888 			int		rowPitch	= getRowPitch(fmt, levelW, m_alignment);
889 			Vec4	colorA		(1.0f, 0.0f, 0.0f, 1.0f);
890 			Vec4	colorB		(0.0f, 1.0f, 0.0f, 1.0f);
891 			int		cellSize	= de::max(1, de::min(levelW >> 2, levelH >> 2));
892 
893 			data.resize(rowPitch*levelH);
894 			tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);
895 
896 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
897 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
898 		}
899 	}
900 
901 	deUint32	m_format;
902 	deUint32	m_dataType;
903 	int			m_alignment;
904 };
905 
906 // Basic TexSubImage2D() with 2D texture usage
907 class BasicTexSubImage2DCase : public TextureSpecCase
908 {
909 public:
BasicTexSubImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)910 	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
911 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
912 		, m_format			(format)
913 		, m_dataType		(dataType)
914 	{
915 	}
916 
917 protected:
createTexture(void)918 	void createTexture (void)
919 	{
920 		tcu::TextureFormat	fmt			= m_texFormat;
921 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
922 		deUint32			tex			= 0;
923 		tcu::TextureLevel	data		(fmt);
924 		de::Random			rnd			(deStringHash(getName()));
925 
926 		glGenTextures(1, &tex);
927 		glBindTexture(GL_TEXTURE_2D, tex);
928 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
929 
930 		// First specify full texture.
931 		for (int ndx = 0; ndx < numLevels; ndx++)
932 		{
933 			int		levelW		= de::max(1, m_width >> ndx);
934 			int		levelH		= de::max(1, m_height >> ndx);
935 			Vec4	gMin		= randomVector<4>(rnd);
936 			Vec4	gMax		= randomVector<4>(rnd);
937 
938 			data.setSize(levelW, levelH);
939 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
940 
941 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
942 		}
943 
944 		// Re-specify parts of each level.
945 		for (int ndx = 0; ndx < numLevels; ndx++)
946 		{
947 			int		levelW		= de::max(1, m_width >> ndx);
948 			int		levelH		= de::max(1, m_height >> ndx);
949 
950 			int		w			= rnd.getInt(1, levelW);
951 			int		h			= rnd.getInt(1, levelH);
952 			int		x			= rnd.getInt(0, levelW-w);
953 			int		y			= rnd.getInt(0, levelH-h);
954 
955 			Vec4	colorA		= randomVector<4>(rnd);
956 			Vec4	colorB		= randomVector<4>(rnd);
957 			int		cellSize	= rnd.getInt(2, 16);
958 
959 			data.setSize(w, h);
960 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
961 
962 			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
963 		}
964 	}
965 
966 	deUint32	m_format;
967 	deUint32	m_dataType;
968 };
969 
970 // Basic TexSubImage2D() with cubemap usage
971 class BasicTexSubImageCubeCase : public TextureSpecCase
972 {
973 public:
BasicTexSubImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)974 	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
975 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
976 		, m_format			(format)
977 		, m_dataType		(dataType)
978 	{
979 	}
980 
981 protected:
createTexture(void)982 	void createTexture (void)
983 	{
984 		tcu::TextureFormat	fmt			= m_texFormat;
985 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
986 		deUint32			tex			= 0;
987 		tcu::TextureLevel	data		(fmt);
988 		de::Random			rnd			(deStringHash(getName()));
989 
990 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
991 
992 		glGenTextures(1, &tex);
993 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
994 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
995 
996 		for (int ndx = 0; ndx < numLevels; ndx++)
997 		{
998 			int		levelW		= de::max(1, m_width >> ndx);
999 			int		levelH		= de::max(1, m_height >> ndx);
1000 
1001 			data.setSize(levelW, levelH);
1002 
1003 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1004 			{
1005 				Vec4 gMin = randomVector<4>(rnd);
1006 				Vec4 gMax = randomVector<4>(rnd);
1007 
1008 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1009 
1010 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1011 			}
1012 		}
1013 
1014 		// Re-specify parts of each face and level.
1015 		for (int ndx = 0; ndx < numLevels; ndx++)
1016 		{
1017 			int		levelW		= de::max(1, m_width >> ndx);
1018 			int		levelH		= de::max(1, m_height >> ndx);
1019 
1020 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1021 			{
1022 				int		w			= rnd.getInt(1, levelW);
1023 				int		h			= rnd.getInt(1, levelH);
1024 				int		x			= rnd.getInt(0, levelW-w);
1025 				int		y			= rnd.getInt(0, levelH-h);
1026 
1027 				Vec4	colorA		= randomVector<4>(rnd);
1028 				Vec4	colorB		= randomVector<4>(rnd);
1029 				int		cellSize	= rnd.getInt(2, 16);
1030 
1031 				data.setSize(w, h);
1032 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1033 
1034 				glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
1035 			}
1036 		}
1037 	}
1038 
1039 	deUint32	m_format;
1040 	deUint32	m_dataType;
1041 };
1042 
1043 // TexSubImage2D() to texture initialized with empty data
1044 class TexSubImage2DEmptyTexCase : public TextureSpecCase
1045 {
1046 public:
TexSubImage2DEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)1047 	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1048 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1049 		, m_format			(format)
1050 		, m_dataType		(dataType)
1051 	{
1052 	}
1053 
1054 protected:
createTexture(void)1055 	void createTexture (void)
1056 	{
1057 		tcu::TextureFormat	fmt			= m_texFormat;
1058 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1059 		deUint32			tex			= 0;
1060 		tcu::TextureLevel	data		(fmt);
1061 		de::Random			rnd			(deStringHash(getName()));
1062 
1063 		glGenTextures(1, &tex);
1064 		glBindTexture(GL_TEXTURE_2D, tex);
1065 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1066 
1067 		// First allocate storage for each level.
1068 		for (int ndx = 0; ndx < numLevels; ndx++)
1069 		{
1070 			int		levelW		= de::max(1, m_width >> ndx);
1071 			int		levelH		= de::max(1, m_height >> ndx);
1072 
1073 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1074 		}
1075 
1076 		// Specify pixel data to all levels using glTexSubImage2D()
1077 		for (int ndx = 0; ndx < numLevels; ndx++)
1078 		{
1079 			int		levelW		= de::max(1, m_width >> ndx);
1080 			int		levelH		= de::max(1, m_height >> ndx);
1081 			Vec4	gMin		= randomVector<4>(rnd);
1082 			Vec4	gMax		= randomVector<4>(rnd);
1083 
1084 			data.setSize(levelW, levelH);
1085 			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1086 
1087 			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1088 		}
1089 	}
1090 
1091 	deUint32	m_format;
1092 	deUint32	m_dataType;
1093 };
1094 
1095 // TexSubImage2D() to empty cubemap texture
1096 class TexSubImageCubeEmptyTexCase : public TextureSpecCase
1097 {
1098 public:
TexSubImageCubeEmptyTexCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)1099 	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1100 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1101 		, m_format			(format)
1102 		, m_dataType		(dataType)
1103 	{
1104 	}
1105 
1106 protected:
createTexture(void)1107 	void createTexture (void)
1108 	{
1109 		tcu::TextureFormat	fmt			= m_texFormat;
1110 		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1111 		deUint32			tex			= 0;
1112 		tcu::TextureLevel	data		(fmt);
1113 		de::Random			rnd			(deStringHash(getName()));
1114 
1115 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1116 
1117 		glGenTextures(1, &tex);
1118 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1119 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1120 
1121 		// Specify storage for each level.
1122 		for (int ndx = 0; ndx < numLevels; ndx++)
1123 		{
1124 			int		levelW		= de::max(1, m_width >> ndx);
1125 			int		levelH		= de::max(1, m_height >> ndx);
1126 
1127 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1128 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
1129 		}
1130 
1131 		// Specify data using glTexSubImage2D()
1132 		for (int ndx = 0; ndx < numLevels; ndx++)
1133 		{
1134 			int		levelW		= de::max(1, m_width >> ndx);
1135 			int		levelH		= de::max(1, m_height >> ndx);
1136 
1137 			data.setSize(levelW, levelH);
1138 
1139 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1140 			{
1141 				Vec4 gMin = randomVector<4>(rnd);
1142 				Vec4 gMax = randomVector<4>(rnd);
1143 
1144 				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);
1145 
1146 				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
1147 			}
1148 		}
1149 	}
1150 
1151 	deUint32	m_format;
1152 	deUint32	m_dataType;
1153 };
1154 
1155 // TexSubImage2D() unpack alignment with 2D texture
1156 class TexSubImage2DAlignCase : public TextureSpecCase
1157 {
1158 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)1159 	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)
1160 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
1161 		, m_format			(format)
1162 		, m_dataType		(dataType)
1163 		, m_subX			(subX)
1164 		, m_subY			(subY)
1165 		, m_subW			(subW)
1166 		, m_subH			(subH)
1167 		, m_alignment		(alignment)
1168 	{
1169 	}
1170 
1171 protected:
createTexture(void)1172 	void createTexture (void)
1173 	{
1174 		tcu::TextureFormat	fmt			= m_texFormat;
1175 		deUint32			tex			= 0;
1176 		vector<deUint8>		data;
1177 
1178 		glGenTextures(1, &tex);
1179 		glBindTexture(GL_TEXTURE_2D, tex);
1180 
1181 		// Specify base level.
1182 		data.resize(fmt.getPixelSize()*m_width*m_height);
1183 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1184 
1185 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1186 		glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1187 
1188 		// Re-specify subrectangle.
1189 		int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
1190 		data.resize(rowPitch*m_subH);
1191 		tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, 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));
1192 
1193 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1194 		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1195 	}
1196 
1197 	deUint32	m_format;
1198 	deUint32	m_dataType;
1199 	int			m_subX;
1200 	int			m_subY;
1201 	int			m_subW;
1202 	int			m_subH;
1203 	int			m_alignment;
1204 };
1205 
1206 // TexSubImage2D() unpack alignment with cubemap texture
1207 class TexSubImageCubeAlignCase : public TextureSpecCase
1208 {
1209 public:
TexSubImageCubeAlignCase(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)1210 	TexSubImageCubeAlignCase (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)
1211 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
1212 		, m_format			(format)
1213 		, m_dataType		(dataType)
1214 		, m_subX			(subX)
1215 		, m_subY			(subY)
1216 		, m_subW			(subW)
1217 		, m_subH			(subH)
1218 		, m_alignment		(alignment)
1219 	{
1220 	}
1221 
1222 protected:
createTexture(void)1223 	void createTexture (void)
1224 	{
1225 		tcu::TextureFormat	fmt			= m_texFormat;
1226 		deUint32			tex			= 0;
1227 		vector<deUint8>		data;
1228 
1229 		DE_ASSERT(m_width == m_height);
1230 
1231 		glGenTextures(1, &tex);
1232 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1233 
1234 		// Specify base level.
1235 		data.resize(fmt.getPixelSize()*m_width*m_height);
1236 		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));
1237 
1238 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1239 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1240 			glTexImage2D(s_cubeMapFaces[face], 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);
1241 
1242 		// Re-specify subrectangle.
1243 		int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
1244 		data.resize(rowPitch*m_subH);
1245 		tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, 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));
1246 
1247 		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
1248 		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
1249 			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
1250 	}
1251 
1252 	deUint32	m_format;
1253 	deUint32	m_dataType;
1254 	int			m_subX;
1255 	int			m_subY;
1256 	int			m_subW;
1257 	int			m_subH;
1258 	int			m_alignment;
1259 };
1260 
1261 
1262 
1263 // Basic CopyTexImage2D() with 2D texture usage
1264 class BasicCopyTexImage2DCase : public TextureSpecCase
1265 {
1266 public:
BasicCopyTexImage2DCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,deUint32 flags,int width,int height)1267 	BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
1268 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
1269 		, m_internalFormat	(internalFormat)
1270 	{
1271 	}
1272 
1273 protected:
createTexture(void)1274 	void createTexture (void)
1275 	{
1276 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
1277 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1278 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
1279 		tcu::TextureFormat			fmt				= m_texFormat;
1280 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
1281 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1282 		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1283 		deUint32					tex				= 0;
1284 		de::Random					rnd				(deStringHash(getName()));
1285 		GradientShader				shader;
1286 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
1287 
1288 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1289 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1290 
1291 		// Fill render target with gradient.
1292 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1293 
1294 		glGenTextures(1, &tex);
1295 		glBindTexture(GL_TEXTURE_2D, tex);
1296 
1297 		for (int ndx = 0; ndx < numLevels; ndx++)
1298 		{
1299 			int		levelW		= de::max(1, m_width >> ndx);
1300 			int		levelH		= de::max(1, m_height >> ndx);
1301 			int		x			= rnd.getInt(0, getWidth()	- levelW);
1302 			int		y			= rnd.getInt(0, getHeight()	- levelH);
1303 
1304 			glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
1305 		}
1306 	}
1307 
1308 	deUint32 m_internalFormat;
1309 };
1310 
1311 // Basic CopyTexImage2D() with cubemap usage
1312 class BasicCopyTexImageCubeCase : public TextureSpecCase
1313 {
1314 public:
BasicCopyTexImageCubeCase(Context & context,const char * name,const char * desc,deUint32 internalFormat,deUint32 flags,int width,int height)1315 	BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
1316 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
1317 		, m_internalFormat	(internalFormat)
1318 	{
1319 	}
1320 
1321 protected:
createTexture(void)1322 	void createTexture (void)
1323 	{
1324 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
1325 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1326 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
1327 		tcu::TextureFormat			fmt				= m_texFormat;
1328 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
1329 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1330 		int							numLevels		= (m_flags & MIPMAPS) ? deLog2Floor32(m_width)+1 : 1;
1331 		deUint32					tex				= 0;
1332 		de::Random					rnd				(deStringHash(getName()));
1333 		GradientShader				shader;
1334 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
1335 
1336 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1337 
1338 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1339 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1340 
1341 		// Fill render target with gradient.
1342 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1343 
1344 		glGenTextures(1, &tex);
1345 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1346 
1347 		for (int ndx = 0; ndx < numLevels; ndx++)
1348 		{
1349 			int levelW = de::max(1, m_width >> ndx);
1350 			int levelH = de::max(1, m_height >> ndx);
1351 
1352 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1353 			{
1354 				int x = rnd.getInt(0, getWidth()	- levelW);
1355 				int y = rnd.getInt(0, getHeight()	- levelH);
1356 
1357 				glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelW, levelH, 0);
1358 			}
1359 		}
1360 	}
1361 
1362 	deUint32 m_internalFormat;
1363 };
1364 
1365 
1366 
1367 // Basic CopyTexSubImage2D() with 2D texture usage
1368 class BasicCopyTexSubImage2DCase : public TextureSpecCase
1369 {
1370 public:
BasicCopyTexSubImage2DCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)1371 	BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1372 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1373 		, m_format			(format)
1374 		, m_dataType		(dataType)
1375 	{
1376 	}
1377 
1378 protected:
createTexture(void)1379 	void createTexture (void)
1380 	{
1381 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
1382 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1383 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
1384 		tcu::TextureFormat			fmt				= m_texFormat;
1385 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
1386 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1387 		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1388 		deUint32					tex				= 0;
1389 		tcu::TextureLevel			data			(fmt);
1390 		de::Random					rnd				(deStringHash(getName()));
1391 		GradientShader				shader;
1392 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
1393 
1394 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1395 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1396 
1397 		glGenTextures(1, &tex);
1398 		glBindTexture(GL_TEXTURE_2D, tex);
1399 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1400 
1401 		// First specify full texture.
1402 		for (int ndx = 0; ndx < numLevels; ndx++)
1403 		{
1404 			int		levelW		= de::max(1, m_width >> ndx);
1405 			int		levelH		= de::max(1, m_height >> ndx);
1406 
1407 			Vec4	colorA		= randomVector<4>(rnd);
1408 			Vec4	colorB		= randomVector<4>(rnd);
1409 			int		cellSize	= rnd.getInt(2, 16);
1410 
1411 			data.setSize(levelW, levelH);
1412 			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1413 
1414 			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1415 		}
1416 
1417 		// Fill render target with gradient.
1418 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1419 
1420 		// Re-specify parts of each level.
1421 		for (int ndx = 0; ndx < numLevels; ndx++)
1422 		{
1423 			int		levelW		= de::max(1, m_width >> ndx);
1424 			int		levelH		= de::max(1, m_height >> ndx);
1425 
1426 			int		w			= rnd.getInt(1, levelW);
1427 			int		h			= rnd.getInt(1, levelH);
1428 			int		xo			= rnd.getInt(0, levelW-w);
1429 			int		yo			= rnd.getInt(0, levelH-h);
1430 
1431 			int		x			= rnd.getInt(0, getWidth() - w);
1432 			int		y			= rnd.getInt(0, getHeight() - h);
1433 
1434 			glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
1435 		}
1436 	}
1437 
1438 	deUint32	m_format;
1439 	deUint32	m_dataType;
1440 };
1441 
1442 // Basic CopyTexSubImage2D() with cubemap usage
1443 class BasicCopyTexSubImageCubeCase : public TextureSpecCase
1444 {
1445 public:
BasicCopyTexSubImageCubeCase(Context & context,const char * name,const char * desc,deUint32 format,deUint32 dataType,deUint32 flags,int width,int height)1446 	BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
1447 		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
1448 		, m_format			(format)
1449 		, m_dataType		(dataType)
1450 	{
1451 	}
1452 
1453 protected:
createTexture(void)1454 	void createTexture (void)
1455 	{
1456 		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
1457 		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
1458 		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
1459 		tcu::TextureFormat			fmt				= m_texFormat;
1460 		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
1461 		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
1462 		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
1463 		deUint32					tex				= 0;
1464 		tcu::TextureLevel			data			(fmt);
1465 		de::Random					rnd				(deStringHash(getName()));
1466 		GradientShader				shader;
1467 		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);
1468 
1469 		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.
1470 
1471 		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
1472 			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);
1473 
1474 		glGenTextures(1, &tex);
1475 		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
1476 		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1477 
1478 		for (int ndx = 0; ndx < numLevels; ndx++)
1479 		{
1480 			int		levelW		= de::max(1, m_width >> ndx);
1481 			int		levelH		= de::max(1, m_height >> ndx);
1482 
1483 			data.setSize(levelW, levelH);
1484 
1485 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1486 			{
1487 				Vec4	colorA		= randomVector<4>(rnd);
1488 				Vec4	colorB		= randomVector<4>(rnd);
1489 				int		cellSize	= rnd.getInt(2, 16);
1490 
1491 				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
1492 				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
1493 			}
1494 		}
1495 
1496 		// Fill render target with gradient.
1497 		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));
1498 
1499 		// Re-specify parts of each face and level.
1500 		for (int ndx = 0; ndx < numLevels; ndx++)
1501 		{
1502 			int		levelW		= de::max(1, m_width >> ndx);
1503 			int		levelH		= de::max(1, m_height >> ndx);
1504 
1505 			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
1506 			{
1507 				int		w			= rnd.getInt(1, levelW);
1508 				int		h			= rnd.getInt(1, levelH);
1509 				int		xo			= rnd.getInt(0, levelW-w);
1510 				int		yo			= rnd.getInt(0, levelH-h);
1511 
1512 				int		x			= rnd.getInt(0, getWidth() - w);
1513 				int		y			= rnd.getInt(0, getHeight() - h);
1514 
1515 				glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
1516 			}
1517 		}
1518 	}
1519 
1520 	deUint32	m_format;
1521 	deUint32	m_dataType;
1522 };
1523 
TextureSpecificationTests(Context & context)1524 TextureSpecificationTests::TextureSpecificationTests (Context& context)
1525 	: TestCaseGroup(context, "specification", "Texture Specification Tests")
1526 {
1527 }
1528 
~TextureSpecificationTests(void)1529 TextureSpecificationTests::~TextureSpecificationTests (void)
1530 {
1531 }
1532 
init(void)1533 void TextureSpecificationTests::init (void)
1534 {
1535 	struct
1536 	{
1537 		const char*	name;
1538 		deUint32	format;
1539 		deUint32	dataType;
1540 	} texFormats[] =
1541 	{
1542 		{ "a8",			GL_ALPHA,			GL_UNSIGNED_BYTE },
1543 		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
1544 		{ "la88",		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
1545 		{ "rgb565",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
1546 		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
1547 		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
1548 		{ "rgba5551",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
1549 		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE }
1550 	};
1551 
1552 	// Basic TexImage2D usage.
1553 	{
1554 		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
1555 		addChild(basicTexImageGroup);
1556 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1557 		{
1558 			const char*	fmtName		= texFormats[formatNdx].name;
1559 			deUint32	format		= texFormats[formatNdx].format;
1560 			deUint32	dataType	= texFormats[formatNdx].dataType;
1561 			const int	tex2DWidth	= 64;
1562 			const int	tex2DHeight	= 128;
1563 			const int	texCubeSize	= 64;
1564 
1565 			basicTexImageGroup->addChild(new BasicTexImage2DCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1566 			basicTexImageGroup->addChild(new BasicTexImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1567 		}
1568 	}
1569 
1570 	// Randomized TexImage2D order.
1571 	{
1572 		tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
1573 		addChild(randomTexImageGroup);
1574 
1575 		de::Random rnd(9);
1576 
1577 		// 2D cases.
1578 		for (int ndx = 0; ndx < 10; ndx++)
1579 		{
1580 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
1581 			int		width		= 1 << rnd.getInt(2, 8);
1582 			int		height		= 1 << rnd.getInt(2, 8);
1583 
1584 			randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, width, height));
1585 		}
1586 
1587 		// Cubemap cases.
1588 		for (int ndx = 0; ndx < 10; ndx++)
1589 		{
1590 			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
1591 			int		size		= 1 << rnd.getInt(2, 8);
1592 
1593 			randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, size, size));
1594 		}
1595 	}
1596 
1597 	// TexImage2D unpack alignment.
1598 	{
1599 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
1600 		addChild(alignGroup);
1601 
1602 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_4_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			MIPMAPS,	 4, 8, 8));
1603 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 1));
1604 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 2));
1605 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 4));
1606 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 8));
1607 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_1",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 1));
1608 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_2",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 2));
1609 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_4",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 4));
1610 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_8",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 8));
1611 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 1));
1612 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 2));
1613 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 4));
1614 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 8));
1615 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_1",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 1));
1616 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_2",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 2));
1617 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_4",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 4));
1618 		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_8",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 8));
1619 
1620 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_4_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			MIPMAPS,	 4, 4, 8));
1621 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 1));
1622 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 2));
1623 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 4));
1624 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 8));
1625 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_1",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 1));
1626 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_2",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 2));
1627 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_4",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 4));
1628 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_8",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 8));
1629 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 1));
1630 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 2));
1631 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 4));
1632 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 8));
1633 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_1",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 1));
1634 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_2",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 2));
1635 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_4",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 4));
1636 		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_8",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 8));
1637 	}
1638 
1639 	// Basic TexSubImage2D usage.
1640 	{
1641 		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
1642 		addChild(basicTexSubImageGroup);
1643 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1644 		{
1645 			const char*	fmtName		= texFormats[formatNdx].name;
1646 			deUint32	format		= texFormats[formatNdx].format;
1647 			deUint32	dataType	= texFormats[formatNdx].dataType;
1648 			const int	tex2DWidth	= 64;
1649 			const int	tex2DHeight	= 128;
1650 			const int	texCubeSize	= 64;
1651 
1652 			basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase		(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1653 			basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1654 		}
1655 	}
1656 
1657 	// TexSubImage2D to empty texture.
1658 	{
1659 		tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
1660 		addChild(texSubImageEmptyTexGroup);
1661 		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
1662 		{
1663 			const char*	fmtName		= texFormats[formatNdx].name;
1664 			deUint32	format		= texFormats[formatNdx].format;
1665 			deUint32	dataType	= texFormats[formatNdx].dataType;
1666 			const int	tex2DWidth	= 64;
1667 			const int	tex2DHeight	= 32;
1668 			const int	texCubeSize	= 32;
1669 
1670 			texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
1671 			texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
1672 		}
1673 	}
1674 
1675 	// TexSubImage2D alignment cases.
1676 	{
1677 		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
1678 		addChild(alignGroup);
1679 
1680 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 1));
1681 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 2));
1682 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 4));
1683 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 8));
1684 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 1));
1685 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 2));
1686 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 4));
1687 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 8));
1688 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_1",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 1));
1689 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_2",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 2));
1690 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_4",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 4));
1691 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_8",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 8));
1692 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 1));
1693 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 2));
1694 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 4));
1695 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 8));
1696 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_1",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 1));
1697 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_2",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 2));
1698 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_4",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 4));
1699 		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_8",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 8));
1700 
1701 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 1));
1702 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 2));
1703 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 4));
1704 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 8));
1705 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 1));
1706 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 2));
1707 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 4));
1708 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 8));
1709 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_1",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 1));
1710 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_2",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 2));
1711 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_4",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 4));
1712 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_8",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 8));
1713 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 1));
1714 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 2));
1715 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 4));
1716 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 8));
1717 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_1",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 1));
1718 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_2",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 2));
1719 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_4",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 4));
1720 		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_8",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 8));
1721 	}
1722 
1723 	// Basic glCopyTexImage2D() cases
1724 	{
1725 		tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
1726 		addChild(copyTexImageGroup);
1727 
1728 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_alpha",				"",	GL_ALPHA,			MIPMAPS,	128, 64));
1729 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance",			"",	GL_LUMINANCE,		MIPMAPS,	128, 64));
1730 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	MIPMAPS,	128, 64));
1731 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgb",				"",	GL_RGB,				MIPMAPS,	128, 64));
1732 		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgba",				"",	GL_RGBA,			MIPMAPS,	128, 64));
1733 
1734 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			MIPMAPS,	64, 64));
1735 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		MIPMAPS,	64, 64));
1736 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	MIPMAPS,	64, 64));
1737 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				MIPMAPS,	64, 64));
1738 		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			MIPMAPS,	64, 64));
1739 	}
1740 
1741 	// Basic glCopyTexSubImage2D() cases
1742 	{
1743 		tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
1744 		addChild(copyTexSubImageGroup);
1745 
1746 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_alpha",				"",	GL_ALPHA,			GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1747 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance",			"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1748 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1749 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1750 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgba",				"",	GL_RGBA,			GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
1751 
1752 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1753 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1754 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1755 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1756 		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
1757 	}
1758 }
1759 
1760 } // Functional
1761 } // gles2
1762 } // deqp
1763