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