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 completeness tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es2fTextureCompletenessTests.hpp"
25#include "glsTextureTestUtil.hpp"
26
27#include "tcuTestLog.hpp"
28#include "tcuSurface.hpp"
29#include "tcuImageCompare.hpp"
30#include "tcuVector.hpp"
31#include "tcuTextureUtil.hpp"
32#include "tcuRenderTarget.hpp"
33
34#include "deRandom.hpp"
35#include "deMath.h"
36#include "deInt32.h"
37#include "deString.h"
38
39#include "gluTextureUtil.hpp"
40#include "gluPixelTransfer.hpp"
41#include "gluContextInfo.hpp"
42#include "gluRenderContext.hpp"
43
44#include "glw.h"
45
46namespace deqp
47{
48namespace gles2
49{
50namespace Functional
51{
52
53using std::vector;
54using std::string;
55using tcu::TestLog;
56using tcu::TextureFormat;
57using tcu::Sampler;
58using tcu::IVec2;
59using tcu::RGBA;
60using gls::TextureTestUtil::TextureRenderer;
61using gls::TextureTestUtil::computeQuadTexCoord2D;
62using gls::TextureTestUtil::computeQuadTexCoordCube;
63
64static const GLenum s_cubeTargets[] =
65{
66	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
67	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
68	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
69	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
70	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
71	GL_TEXTURE_CUBE_MAP_POSITIVE_Z
72};
73
74static bool isExtensionSupported (const glu::ContextInfo& ctxInfo, const char* extension)
75{
76	vector<string> extensions = ctxInfo.getExtensions();
77
78	for (vector<string>::iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
79		if (iter->compare(extension) == 0)
80			return true;
81
82	return false;
83}
84
85static bool compareToConstantColor (TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& result, tcu::CompareLogMode logMode, RGBA color)
86{
87	bool isOk = true;
88
89	for (int y = 0; y < result.getHeight(); y++)
90	{
91		for (int x = 0; x < result.getWidth(); x++)
92		{
93			if (result.getPixel(x, y).getRed()		!= color.getRed()	||
94				result.getPixel(x, y).getGreen()	!= color.getGreen() ||
95				result.getPixel(x, y).getBlue()		!= color.getBlue()	||
96				result.getPixel(x, y).getAlpha()	!= color.getAlpha())
97			{
98				isOk = false;
99			}
100		}
101	}
102
103	if (!isOk || logMode == tcu::COMPARE_LOG_EVERYTHING)
104	{
105		if (!isOk)
106			log << TestLog::Message << "Image comparison failed" << TestLog::EndMessage;
107
108		log << TestLog::ImageSet(imageSetName, imageSetDesc)
109			<< TestLog::Image("Result",		"Result",		result)
110			<< TestLog::EndImageSet;
111	}
112	else if (logMode == tcu::COMPARE_LOG_RESULT)
113		log << TestLog::ImageSet(imageSetName, imageSetDesc)
114			<< TestLog::Image("Result",		"Result",		result)
115			<< TestLog::EndImageSet;
116
117	return isOk;
118}
119
120// Base classes.
121
122class Tex2DCompletenessCase : public tcu::TestCase
123{
124public:
125							Tex2DCompletenessCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
126							~Tex2DCompletenessCase	(void) {};
127
128	IterateResult			iterate					(void);
129
130protected:
131	virtual void			createTexture			(void) = 0;
132
133	tcu::TestContext&		m_testCtx;
134	glu::RenderContext&		m_renderCtx;
135	RGBA					m_compareColor;
136};
137
138Tex2DCompletenessCase::Tex2DCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
139	: TestCase			(testCtx, name, description)
140	, m_testCtx			(testCtx)
141	, m_renderCtx		(renderCtx)
142	, m_compareColor	(RGBA(0,0,0,255))
143{
144}
145
146Tex2DCompletenessCase::IterateResult Tex2DCompletenessCase::iterate (void)
147{
148	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
149	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
150	TestLog&			log				= m_testCtx.getLog();
151	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
152	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
153	vector<float>		texCoord;
154
155	de::Random			random			(deStringHash(getName()));
156	int					offsetX			= random.getInt(0, m_renderCtx.getRenderTarget().getWidth()		- viewportWidth	);
157	int					offsetY			= random.getInt(0, m_renderCtx.getRenderTarget().getHeight()	- viewportHeight);
158
159	computeQuadTexCoord2D	(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
160
161	glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);
162
163	createTexture			();
164	renderer.renderQuad		(0, &texCoord[0], gls::TextureTestUtil::TEXTURETYPE_2D);
165	glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
166
167	bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);
168
169	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
170							isOk ? "Pass"				: "Image comparison failed");
171	return STOP;
172}
173
174class TexCubeCompletenessCase : public tcu::TestCase
175{
176public:
177							TexCubeCompletenessCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
178							~TexCubeCompletenessCase	(void) {};
179
180	IterateResult			iterate						(void);
181
182protected:
183	virtual void			createTexture				(void) = 0;
184
185	tcu::TestContext&		m_testCtx;
186	glu::RenderContext&		m_renderCtx;
187	RGBA					m_compareColor;
188};
189
190TexCubeCompletenessCase::TexCubeCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
191	: TestCase			(testCtx, name, description)
192	, m_testCtx			(testCtx)
193	, m_renderCtx		(renderCtx)
194	, m_compareColor	(RGBA(0,0,0,255))
195{
196}
197
198TexCubeCompletenessCase::IterateResult TexCubeCompletenessCase::iterate (void)
199{
200	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
201	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
202	bool				allFacesOk		= true;
203	TestLog&			log				= m_testCtx.getLog();
204	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
205	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
206	vector<float>		texCoord;
207
208	de::Random			random			(deStringHash(getName()));
209	int					offsetX			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getWidth()	- 64));
210	int					offsetY			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getHeight()	- 64));
211
212	createTexture();
213
214	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
215	{
216		computeQuadTexCoordCube	(texCoord, (tcu::CubeFace)face);
217
218		glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);
219
220		renderer.renderQuad		(0, &texCoord[0], gls::TextureTestUtil::TEXTURETYPE_CUBE);
221		glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
222
223		bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);
224
225		if (!isOk)
226			allFacesOk = false;
227	}
228
229	m_testCtx.setTestResult(allFacesOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
230							allFacesOk ? "Pass"					: "Image comparison failed");
231	return STOP;
232}
233
234// Texture 2D tests.
235
236class Incomplete2DSizeCase : public Tex2DCompletenessCase
237{
238public:
239								Incomplete2DSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo);
240								~Incomplete2DSizeCase	(void) {}
241
242	virtual void				createTexture			(void);
243
244private:
245	int							m_invalidLevelNdx;
246	IVec2						m_invalidLevelSize;
247	const glu::ContextInfo&		m_ctxInfo;
248	IVec2						m_size;
249};
250
251Incomplete2DSizeCase::Incomplete2DSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo)
252	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
253	, m_invalidLevelNdx			(invalidLevelNdx)
254	, m_invalidLevelSize		(invalidLevelSize)
255	, m_ctxInfo					(ctxInfo)
256	, m_size					(size)
257{
258}
259
260void Incomplete2DSizeCase::createTexture (void)
261{
262	static const char* const s_relaxingExtensions[] =
263	{
264		"GL_OES_texture_npot",
265		"GL_NV_texture_npot_2D_mipmap",
266	};
267
268	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
269	tcu::TextureLevel		levelData		(fmt);
270	TestLog&				log				= m_testCtx.getLog();
271
272	GLuint texture;
273	glGenTextures	(1, &texture);
274	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
275	glBindTexture	(GL_TEXTURE_2D, texture);
276
277	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
278	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
279	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
280	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
281
282	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
283
284	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
285	{
286		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.x() : de::max(1, m_size.x() >> levelNdx);
287		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.y() : de::max(1, m_size.y() >> levelNdx);
288
289		levelData.setSize(m_size.x(), m_size.y());
290		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
291
292		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
293	}
294
295	GLU_CHECK_MSG("Set texturing state");
296
297	// If size not allowed in core, search for relaxing extensions
298	if (!deIsPowerOfTwo32(m_size.x()) && !deIsPowerOfTwo32(m_size.y()))
299	{
300		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_relaxingExtensions); ++ndx)
301		{
302			if (isExtensionSupported(m_ctxInfo, s_relaxingExtensions[ndx]))
303			{
304				log << TestLog::Message << s_relaxingExtensions[ndx] << " supported, assuming completeness test to pass." << TestLog::EndMessage;
305				m_compareColor = RGBA(0,0,255,255);
306				break;
307			}
308		}
309	}
310}
311
312class Incomplete2DFormatCase : public Tex2DCompletenessCase
313{
314public:
315							Incomplete2DFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx);
316							~Incomplete2DFormatCase	(void) {}
317
318	virtual void			createTexture			(void);
319
320private:
321	int						m_invalidLevelNdx;
322	deUint32				m_format;
323	deUint32				m_invalidFormat;
324	IVec2					m_size;
325};
326
327Incomplete2DFormatCase::Incomplete2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx)
328	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
329	, m_invalidLevelNdx			(invalidLevelNdx)
330	, m_format					(format)
331	, m_invalidFormat			(invalidFormat)
332	, m_size					(size)
333{
334}
335
336void Incomplete2DFormatCase::createTexture (void)
337{
338	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(m_format, GL_UNSIGNED_BYTE);
339	tcu::TextureLevel	levelData	(fmt);
340
341	GLuint texture;
342	glGenTextures	(1, &texture);
343	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
344	glBindTexture	(GL_TEXTURE_2D, texture);
345
346	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
347	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
348	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
349	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
350
351	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
352
353	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
354	{
355		int	levelW = de::max(1, m_size.x() >> levelNdx);
356		int	levelH = de::max(1, m_size.y() >> levelNdx);
357
358		levelData.setSize(m_size.x(), m_size.y());
359		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
360
361		deUint32 format = levelNdx == m_invalidLevelNdx ? m_invalidFormat : m_format;
362
363		glTexImage2D(GL_TEXTURE_2D, levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
364	}
365
366	GLU_CHECK_MSG("Set texturing state");
367}
368
369class Incomplete2DMissingLevelCase : public Tex2DCompletenessCase
370{
371public:
372						Incomplete2DMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx);
373						~Incomplete2DMissingLevelCase	(void) {}
374
375	virtual void		createTexture					(void);
376
377private:
378	int					m_missingLevelNdx;
379	IVec2				m_size;
380};
381
382Incomplete2DMissingLevelCase::Incomplete2DMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx)
383	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
384	, m_missingLevelNdx			(missingLevelNdx)
385	, m_size					(size)
386{
387}
388
389void Incomplete2DMissingLevelCase::createTexture (void)
390{
391	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
392	tcu::TextureLevel	levelData	(fmt);
393
394	GLuint texture;
395	glGenTextures	(1, &texture);
396	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
397	glBindTexture	(GL_TEXTURE_2D, texture);
398
399	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
400	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
401	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
402	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
403
404	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
405
406	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
407	{
408		levelData.setSize(m_size.x(), m_size.y());
409		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
410
411		int	levelW = de::max(1, m_size.x() >> levelNdx);
412		int	levelH = de::max(1, m_size.y() >> levelNdx);
413
414		// Skip specified level.
415		if (levelNdx != m_missingLevelNdx)
416			glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
417	}
418
419	GLU_CHECK_MSG("Set texturing state");
420}
421
422class Incomplete2DWrapModeCase : public Tex2DCompletenessCase
423{
424public:
425								Incomplete2DWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
426								~Incomplete2DWrapModeCase	(void) {}
427
428	virtual void				createTexture				(void);
429
430private:
431	deUint32					m_wrapT;
432	deUint32					m_wrapS;
433	const glu::ContextInfo&		m_ctxInfo;
434	IVec2						m_size;
435};
436
437Incomplete2DWrapModeCase::Incomplete2DWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
438	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
439	, m_wrapT					(wrapT)
440	, m_wrapS					(wrapS)
441	, m_ctxInfo					(ctxInfo)
442	, m_size					(size)
443{
444}
445
446void Incomplete2DWrapModeCase::createTexture (void)
447{
448	TestLog&			log			= m_testCtx.getLog();
449	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
450	tcu::TextureLevel	levelData	(fmt);
451
452	GLuint texture;
453	glGenTextures(1, &texture);
454	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
455	glBindTexture(GL_TEXTURE_2D, texture);
456
457	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
458	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
459	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
460	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
461
462	levelData.setSize(m_size.x(), m_size.y());
463	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
464
465	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
466
467	GLU_CHECK_MSG("Set texturing state");
468
469	const char* extension = "GL_OES_texture_npot";
470	if (isExtensionSupported(m_ctxInfo, extension))
471	{
472		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
473		m_compareColor = RGBA(0,0,255,255);
474	}
475}
476
477class Complete2DExtraLevelCase : public Tex2DCompletenessCase
478{
479public:
480						Complete2DExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
481						~Complete2DExtraLevelCase	(void) {}
482
483	virtual void		createTexture				(void);
484
485private:
486	IVec2				m_size;
487};
488
489Complete2DExtraLevelCase::Complete2DExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
490	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
491	, m_size					(size)
492{
493}
494
495void Complete2DExtraLevelCase::createTexture (void)
496{
497	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
498	tcu::TextureLevel	levelData	(fmt);
499
500	GLuint texture;
501	glGenTextures	(1, &texture);
502	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
503	glBindTexture	(GL_TEXTURE_2D, texture);
504
505	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
506	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
507	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
508	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
509
510	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
511
512	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
513	{
514		int	levelW = de::max(1, m_size.x() >> levelNdx);
515		int	levelH = de::max(1, m_size.y() >> levelNdx);
516
517		levelData.setSize(m_size.x(), m_size.y());
518		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
519
520		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
521	}
522
523	// Specify extra level.
524	glTexImage2D(GL_TEXTURE_2D, numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
525	m_compareColor = RGBA(0,0,255,255);
526
527	GLU_CHECK_MSG("Set texturing state");
528}
529
530class Incomplete2DEmptyObjectCase : public Tex2DCompletenessCase
531{
532public:
533						Incomplete2DEmptyObjectCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
534						~Incomplete2DEmptyObjectCase	(void) {}
535
536	virtual void		createTexture					(void);
537
538private:
539	IVec2				m_size;
540};
541
542Incomplete2DEmptyObjectCase::Incomplete2DEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
543	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
544	, m_size					(size)
545{
546}
547
548void Incomplete2DEmptyObjectCase::createTexture (void)
549{
550	GLuint texture;
551	glGenTextures	(1, &texture);
552	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
553	glBindTexture	(GL_TEXTURE_2D, texture);
554
555	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
556	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
557	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
558	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
559
560	GLU_CHECK_MSG("Set texturing state");
561}
562
563// Cube texture tests.
564
565class IncompleteCubeSizeCase : public TexCubeCompletenessCase
566{
567public:
568							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx);
569							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
570							~IncompleteCubeSizeCase	(void) {}
571
572	virtual void			createTexture			(void);
573
574private:
575	int						m_invalidLevelNdx;
576	IVec2					m_invalidLevelSize;
577	tcu::CubeFace			m_invalidCubeFace;
578	IVec2					m_size;
579};
580
581IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx)
582	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
583	, m_invalidLevelNdx				(invalidLevelNdx)
584	, m_invalidLevelSize			(invalidLevelSize)
585	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
586	, m_size						(size)
587{
588}
589
590IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
591	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
592	, m_invalidLevelNdx				(invalidLevelNdx)
593	, m_invalidLevelSize			(invalidLevelSize)
594	, m_invalidCubeFace				(invalidCubeFace)
595	, m_size						(size)
596{
597}
598
599void IncompleteCubeSizeCase::createTexture (void)
600{
601	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
602	tcu::TextureLevel	levelData	(fmt);
603
604	GLuint texture;
605	glGenTextures	(1, &texture);
606	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
607	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
608
609	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
610	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
611	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
612	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
613
614	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
615
616	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
617	{
618		levelData.setSize(m_size.x(), m_size.y());
619		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
620
621		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
622		{
623			int levelW = de::max(1, m_size.x() >> levelNdx);
624			int levelH = de::max(1, m_size.y() >> levelNdx);
625			if (levelNdx == m_invalidLevelNdx && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
626			{
627				levelW =  m_invalidLevelSize.x();
628				levelH =  m_invalidLevelSize.y();
629			}
630			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
631		}
632	}
633
634	GLU_CHECK_MSG("Set texturing state");
635}
636
637class IncompleteCubeFormatCase : public TexCubeCompletenessCase
638{
639public:
640							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat);
641							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace);
642							~IncompleteCubeFormatCase	(void) {}
643
644	virtual void			createTexture				(void);
645
646private:
647	deUint32				m_format;
648	deUint32				m_invalidFormat;
649	tcu::CubeFace			m_invalidCubeFace;
650	IVec2					m_size;
651};
652
653IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat)
654	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
655	, m_format						(format)
656	, m_invalidFormat				(invalidFormat)
657	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
658	, m_size						(size)
659{
660}
661
662IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace)
663	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
664	, m_format						(format)
665	, m_invalidFormat				(invalidFormat)
666	, m_invalidCubeFace				(invalidCubeFace)
667	, m_size						(size)
668{
669}
670
671void IncompleteCubeFormatCase::createTexture (void)
672{
673	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
674	tcu::TextureLevel	levelData	(fmt);
675
676	GLuint texture;
677	glGenTextures	(1, &texture);
678	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
679	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
680
681	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
682	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
683	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
684	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
685
686	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
687
688	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
689	{
690		levelData.setSize(m_size.x(), m_size.y());
691		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
692
693		int	levelW = de::max(1, m_size.x() >> levelNdx);
694		int	levelH = de::max(1, m_size.y() >> levelNdx);
695
696		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
697		{
698			deUint32 format = m_format;
699			if (levelNdx == 0 && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
700				format = m_invalidFormat;
701
702			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
703		}
704	}
705
706	GLU_CHECK_MSG("Set texturing state");
707}
708
709class IncompleteCubeMissingLevelCase : public TexCubeCompletenessCase
710{
711public:
712							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx);
713							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
714							~IncompleteCubeMissingLevelCase	(void) {}
715
716	virtual void			createTexture					(void);
717
718private:
719	int						m_invalidLevelNdx;
720	tcu::CubeFace			m_invalidCubeFace;
721	IVec2					m_size;
722};
723
724IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx)
725	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
726	, m_invalidLevelNdx				(invalidLevelNdx)
727	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
728	, m_size						(size)
729{
730}
731
732IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
733	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
734	, m_invalidLevelNdx				(invalidLevelNdx)
735	, m_invalidCubeFace				(invalidCubeFace)
736	, m_size						(size)
737{
738}
739
740void IncompleteCubeMissingLevelCase::createTexture (void)
741{
742	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
743	tcu::TextureLevel	levelData	(fmt);
744
745	GLuint texture;
746	glGenTextures	(1, &texture);
747	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
748	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
749
750	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
751	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
752	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
753	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
754
755	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
756
757	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
758	{
759		levelData.setSize(m_size.x(), m_size.y());
760		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
761
762		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_size.x() : de::max(1, m_size.x() >> levelNdx);
763		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_size.y() : de::max(1, m_size.y() >> levelNdx);
764
765		if (levelNdx != m_invalidLevelNdx || m_invalidCubeFace != tcu::CUBEFACE_LAST)
766		{
767			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
768			{
769				// If single cubeface is specified then skip only that one.
770				if (m_invalidCubeFace != targetNdx)
771					glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
772			}
773		}
774	}
775
776	GLU_CHECK_MSG("Set texturing state");
777}
778
779class IncompleteCubeWrapModeCase : public TexCubeCompletenessCase
780{
781public:
782								IncompleteCubeWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
783								~IncompleteCubeWrapModeCase	(void) {}
784
785	virtual void				createTexture				(void);
786
787private:
788	deUint32					m_wrapT;
789	deUint32					m_wrapS;
790	const glu::ContextInfo&		m_ctxInfo;
791	IVec2						m_size;
792};
793
794IncompleteCubeWrapModeCase::IncompleteCubeWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
795	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
796	, m_wrapT					(wrapT)
797	, m_wrapS					(wrapS)
798	, m_ctxInfo					(ctxInfo)
799	, m_size					(size)
800{
801}
802
803void IncompleteCubeWrapModeCase::createTexture (void)
804{
805	TestLog&			log			= m_testCtx.getLog();
806	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
807	tcu::TextureLevel	levelData	(fmt);
808
809	GLuint texture;
810	glGenTextures(1, &texture);
811	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
812	glBindTexture(GL_TEXTURE_2D, texture);
813
814	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
815	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
816	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
817	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
818
819	levelData.setSize(m_size.x(), m_size.y());
820	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
821
822	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
823		glTexImage2D(s_cubeTargets[targetNdx], 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
824
825	GLU_CHECK_MSG("Set texturing state");
826
827	const char* extension = "GL_OES_texture_npot";
828	if (isExtensionSupported(m_ctxInfo, extension))
829	{
830		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
831		m_compareColor = RGBA(0,0,255,255);
832	}
833}
834
835class CompleteCubeExtraLevelCase : public TexCubeCompletenessCase
836{
837public:
838						CompleteCubeExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
839						~CompleteCubeExtraLevelCase	(void) {}
840
841	virtual void		createTexture				(void);
842
843private:
844	IVec2				m_size;
845};
846
847CompleteCubeExtraLevelCase::CompleteCubeExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
848	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
849	, m_size					(size)
850{
851}
852
853void CompleteCubeExtraLevelCase::createTexture (void)
854{
855	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
856	tcu::TextureLevel		levelData		(fmt);
857
858	GLuint texture;
859	glGenTextures	(1, &texture);
860	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
861	glBindTexture	(GL_TEXTURE_2D, texture);
862
863	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
864	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
865	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
866	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
867
868	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
869
870	levelData.setSize(m_size.x(), m_size.y());
871	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
872
873	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
874	{
875		int	levelW = de::max(1, m_size.x() >> levelNdx);
876		int	levelH = de::max(1, m_size.y() >> levelNdx);
877
878		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
879			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
880	}
881
882	// Specify extra level.
883	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
884		glTexImage2D(s_cubeTargets[targetNdx], numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
885
886	m_compareColor = RGBA(0,0,255,255);
887
888	GLU_CHECK_MSG("Set texturing state");
889}
890
891class IncompleteCubeEmptyObjectCase : public TexCubeCompletenessCase
892{
893public:
894							IncompleteCubeEmptyObjectCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
895							~IncompleteCubeEmptyObjectCase	(void) {}
896
897	virtual void			createTexture				(void);
898
899private:
900	IVec2					m_size;
901};
902
903IncompleteCubeEmptyObjectCase::IncompleteCubeEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
904	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
905	, m_size					(size)
906{
907}
908
909void IncompleteCubeEmptyObjectCase::createTexture (void)
910{
911	GLuint texture;
912	glGenTextures	(1, &texture);
913	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
914	glBindTexture	(GL_TEXTURE_2D, texture);
915
916	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
917	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
918	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
919	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
920
921	GLU_CHECK_MSG("Set texturing state");
922}
923
924// Texture completeness group.
925
926TextureCompletenessTests::TextureCompletenessTests (Context& context)
927	: TestCaseGroup(context, "completeness", "Completeness tests")
928{
929}
930
931void TextureCompletenessTests::init (void)
932{
933	tcu::TestCaseGroup* tex2d = new tcu::TestCaseGroup(m_testCtx, "2d", "2D completeness");
934	addChild(tex2d);
935	tcu::TestCaseGroup* cube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cubemap completeness");
936	addChild(cube);
937
938	// Texture 2D size.
939	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size",				"", IVec2(255, 255), IVec2(255, 255), 0, m_context.getContextInfo()));
940	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",		"", IVec2(256, 256), IVec2(255, 255), 0, m_context.getContextInfo()));
941	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",		"", IVec2(256, 256), IVec2(127, 127), 1, m_context.getContextInfo()));
942	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",	"", IVec2(256, 256), IVec2(0, 0),	  0, m_context.getContextInfo()));
943	// Texture 2D format.
944	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba",						"", IVec2(128, 128), GL_RGB,				GL_RGBA,			1));
945	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb",						"", IVec2(128, 128), GL_RGBA,				GL_RGB,				1));
946	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha",	"", IVec2(128, 128), GL_LUMINANCE,			GL_LUMINANCE_ALPHA,	1));
947	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance",	"", IVec2(128, 128), GL_LUMINANCE_ALPHA,	GL_LUMINANCE,		1));
948	// Texture 2D missing level.
949	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",			"", IVec2(128, 128),	1));
950	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",			"", IVec2(128, 128),	3));
951	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "last_level_missing",			"", IVec2(128, 64),		de::max(deLog2Floor32(128), deLog2Floor32(64))));
952	// Texture 2D wrap modes.
953	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
954	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
955	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
956	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
957	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_width_npot",		"", IVec2(127, 128), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
958	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_height_npot",		"", IVec2(128, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
959	// Texture 2D extra level.
960	tex2d->addChild(new Complete2DExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
961	// Texture 2D empty object.
962	tex2d->addChild(new Incomplete2DEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
963
964	// Cube size.
965	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",			"", IVec2(64, 64), IVec2(63, 63), 0));
966	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",			"", IVec2(64, 64), IVec2(31, 31), 1));
967	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0_pos_x",	"", IVec2(64, 64), IVec2(63, 63), 0, tcu::CUBEFACE_POSITIVE_X));
968	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1_neg_x",	"", IVec2(64, 64), IVec2(31, 31), 1, tcu::CUBEFACE_NEGATIVE_X));
969	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",		"", IVec2(64, 64), IVec2(0,0)	, 0));
970	// Cube format.
971	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba_level_0",					"", IVec2(64, 64), GL_RGB,				GL_RGBA));
972	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb_level_0",					"", IVec2(64, 64), GL_RGBA,				GL_RGB));
973	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha_level_0",	"", IVec2(64, 64), GL_LUMINANCE,		GL_LUMINANCE_ALPHA));
974	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance_level_0",	"", IVec2(64, 64), GL_LUMINANCE_ALPHA,	GL_LUMINANCE));
975	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba_level_0_pos_z",				"", IVec2(64, 64), GL_RGB,				GL_RGBA,	tcu::CUBEFACE_POSITIVE_Z));
976	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb_level_0_neg_z",				"", IVec2(64, 64), GL_RGBA,				GL_RGB,		tcu::CUBEFACE_NEGATIVE_Z));
977	// Cube missing level.
978	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",		"", IVec2(64, 64), 1));
979	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",		"", IVec2(64, 64), 3));
980	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1_pos_y",	"", IVec2(64, 64), 1, tcu::CUBEFACE_POSITIVE_Y));
981	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3_neg_y",	"", IVec2(64, 64), 3, tcu::CUBEFACE_NEGATIVE_Y));
982	// Cube wrap modes.
983	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
984	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
985	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
986	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
987	// Cube extra level.
988	cube->addChild(new CompleteCubeExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
989	// Cube extra level.
990	cube->addChild(new IncompleteCubeEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
991}
992
993} // Functional
994} // gles2
995} // deqp
996