• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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			(void) = 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 	createTexture			();
164 	renderer.renderQuad		(0, &texCoord[0], glu::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 
174 class TexCubeCompletenessCase : public tcu::TestCase
175 {
176 public:
177 							TexCubeCompletenessCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
~TexCubeCompletenessCase(void)178 							~TexCubeCompletenessCase	(void) {};
179 
180 	IterateResult			iterate						(void);
181 
182 protected:
183 	virtual void			createTexture				(void) = 0;
184 
185 	tcu::TestContext&		m_testCtx;
186 	glu::RenderContext&		m_renderCtx;
187 	RGBA					m_compareColor;
188 };
189 
TexCubeCompletenessCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description)190 TexCubeCompletenessCase::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 
iterate(void)198 TexCubeCompletenessCase::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], glu::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 
236 class Incomplete2DSizeCase : public Tex2DCompletenessCase
237 {
238 public:
239 								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)240 								~Incomplete2DSizeCase	(void) {}
241 
242 	virtual void				createTexture			(void);
243 
244 private:
245 	int							m_invalidLevelNdx;
246 	IVec2						m_invalidLevelSize;
247 	const glu::ContextInfo&		m_ctxInfo;
248 	IVec2						m_size;
249 };
250 
Incomplete2DSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx,const glu::ContextInfo & ctxInfo)251 Incomplete2DSizeCase::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 
createTexture(void)260 void 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 
312 class Incomplete2DFormatCase : public Tex2DCompletenessCase
313 {
314 public:
315 							Incomplete2DFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx);
~Incomplete2DFormatCase(void)316 							~Incomplete2DFormatCase	(void) {}
317 
318 	virtual void			createTexture			(void);
319 
320 private:
321 	int						m_invalidLevelNdx;
322 	deUint32				m_format;
323 	deUint32				m_invalidFormat;
324 	IVec2					m_size;
325 };
326 
Incomplete2DFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,deUint32 format,deUint32 invalidFormat,int invalidLevelNdx)327 Incomplete2DFormatCase::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 
createTexture(void)336 void 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 
369 class Incomplete2DMissingLevelCase : public Tex2DCompletenessCase
370 {
371 public:
372 						Incomplete2DMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx);
~Incomplete2DMissingLevelCase(void)373 						~Incomplete2DMissingLevelCase	(void) {}
374 
375 	virtual void		createTexture					(void);
376 
377 private:
378 	int					m_missingLevelNdx;
379 	IVec2				m_size;
380 };
381 
Incomplete2DMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int missingLevelNdx)382 Incomplete2DMissingLevelCase::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 
createTexture(void)389 void 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 
422 class Incomplete2DWrapModeCase : public Tex2DCompletenessCase
423 {
424 public:
425 								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)426 								~Incomplete2DWrapModeCase	(void) {}
427 
428 	virtual void				createTexture				(void);
429 
430 private:
431 	deUint32					m_wrapT;
432 	deUint32					m_wrapS;
433 	const glu::ContextInfo&		m_ctxInfo;
434 	IVec2						m_size;
435 };
436 
Incomplete2DWrapModeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,deUint32 wrapT,deUint32 wrapS,const glu::ContextInfo & ctxInfo)437 Incomplete2DWrapModeCase::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 
createTexture(void)446 void 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 
477 class Complete2DExtraLevelCase : public Tex2DCompletenessCase
478 {
479 public:
480 						Complete2DExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
~Complete2DExtraLevelCase(void)481 						~Complete2DExtraLevelCase	(void) {}
482 
483 	virtual void		createTexture				(void);
484 
485 private:
486 	IVec2				m_size;
487 };
488 
Complete2DExtraLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)489 Complete2DExtraLevelCase::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 
createTexture(void)495 void 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 
530 class Incomplete2DEmptyObjectCase : public Tex2DCompletenessCase
531 {
532 public:
533 						Incomplete2DEmptyObjectCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
~Incomplete2DEmptyObjectCase(void)534 						~Incomplete2DEmptyObjectCase	(void) {}
535 
536 	virtual void		createTexture					(void);
537 
538 private:
539 	IVec2				m_size;
540 };
541 
Incomplete2DEmptyObjectCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)542 Incomplete2DEmptyObjectCase::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 
createTexture(void)548 void 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 
565 class IncompleteCubeSizeCase : public TexCubeCompletenessCase
566 {
567 public:
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);
~IncompleteCubeSizeCase(void)570 							~IncompleteCubeSizeCase	(void) {}
571 
572 	virtual void			createTexture			(void);
573 
574 private:
575 	int						m_invalidLevelNdx;
576 	IVec2					m_invalidLevelSize;
577 	tcu::CubeFace			m_invalidCubeFace;
578 	IVec2					m_size;
579 };
580 
IncompleteCubeSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx)581 IncompleteCubeSizeCase::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 
IncompleteCubeSizeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,IVec2 invalidLevelSize,int invalidLevelNdx,tcu::CubeFace invalidCubeFace)590 IncompleteCubeSizeCase::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 
createTexture(void)599 void 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 
637 class IncompleteCubeFormatCase : public TexCubeCompletenessCase
638 {
639 public:
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);
~IncompleteCubeFormatCase(void)642 							~IncompleteCubeFormatCase	(void) {}
643 
644 	virtual void			createTexture				(void);
645 
646 private:
647 	deUint32				m_format;
648 	deUint32				m_invalidFormat;
649 	tcu::CubeFace			m_invalidCubeFace;
650 	IVec2					m_size;
651 };
652 
IncompleteCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,deUint32 format,deUint32 invalidFormat)653 IncompleteCubeFormatCase::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 
IncompleteCubeFormatCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,deUint32 format,deUint32 invalidFormat,tcu::CubeFace invalidCubeFace)662 IncompleteCubeFormatCase::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 
createTexture(void)671 void 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 
709 class IncompleteCubeMissingLevelCase : public TexCubeCompletenessCase
710 {
711 public:
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);
~IncompleteCubeMissingLevelCase(void)714 							~IncompleteCubeMissingLevelCase	(void) {}
715 
716 	virtual void			createTexture					(void);
717 
718 private:
719 	int						m_invalidLevelNdx;
720 	tcu::CubeFace			m_invalidCubeFace;
721 	IVec2					m_size;
722 };
723 
IncompleteCubeMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int invalidLevelNdx)724 IncompleteCubeMissingLevelCase::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 
IncompleteCubeMissingLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,int invalidLevelNdx,tcu::CubeFace invalidCubeFace)732 IncompleteCubeMissingLevelCase::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 
createTexture(void)740 void 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 
779 class IncompleteCubeWrapModeCase : public TexCubeCompletenessCase
780 {
781 public:
782 								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)783 								~IncompleteCubeWrapModeCase	(void) {}
784 
785 	virtual void				createTexture				(void);
786 
787 private:
788 	deUint32					m_wrapT;
789 	deUint32					m_wrapS;
790 	const glu::ContextInfo&		m_ctxInfo;
791 	IVec2						m_size;
792 };
793 
IncompleteCubeWrapModeCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size,deUint32 wrapT,deUint32 wrapS,const glu::ContextInfo & ctxInfo)794 IncompleteCubeWrapModeCase::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 
createTexture(void)803 void 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 
835 class CompleteCubeExtraLevelCase : public TexCubeCompletenessCase
836 {
837 public:
838 						CompleteCubeExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
~CompleteCubeExtraLevelCase(void)839 						~CompleteCubeExtraLevelCase	(void) {}
840 
841 	virtual void		createTexture				(void);
842 
843 private:
844 	IVec2				m_size;
845 };
846 
CompleteCubeExtraLevelCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)847 CompleteCubeExtraLevelCase::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 
createTexture(void)853 void 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 
891 class IncompleteCubeEmptyObjectCase : public TexCubeCompletenessCase
892 {
893 public:
894 							IncompleteCubeEmptyObjectCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
~IncompleteCubeEmptyObjectCase(void)895 							~IncompleteCubeEmptyObjectCase	(void) {}
896 
897 	virtual void			createTexture				(void);
898 
899 private:
900 	IVec2					m_size;
901 };
902 
IncompleteCubeEmptyObjectCase(tcu::TestContext & testCtx,glu::RenderContext & renderCtx,const char * name,const char * description,IVec2 size)903 IncompleteCubeEmptyObjectCase::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 
createTexture(void)909 void 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 
TextureCompletenessTests(Context & context)926 TextureCompletenessTests::TextureCompletenessTests (Context& context)
927 	: TestCaseGroup(context, "completeness", "Completeness tests")
928 {
929 }
930 
init(void)931 void 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