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