1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.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 State Query tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es3fTextureStateQueryTests.hpp"
25#include "es3fApiCase.hpp"
26#include "glsStateQueryUtil.hpp"
27#include "gluRenderContext.hpp"
28#include "glwEnums.hpp"
29#include "glwFunctions.hpp"
30#include "deRandom.hpp"
31#include "deMath.h"
32
33using namespace glw; // GLint and other GL types
34using namespace deqp::gls;
35using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
36
37
38namespace deqp
39{
40namespace gles3
41{
42namespace Functional
43{
44namespace TextureParamVerifiers
45{
46
47// TexParamVerifier
48
49class TexParamVerifier : protected glu::CallLogWrapper
50{
51public:
52						TexParamVerifier	(const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix);
53	virtual				~TexParamVerifier	(); // make GCC happy
54
55	const char*			getTestNamePostfix	(void) const;
56
57	virtual void		verifyInteger		(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)	= DE_NULL;
58	virtual void		verifyFloat			(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)	= DE_NULL;
59private:
60	const char*	const	m_testNamePostfix;
61};
62
63TexParamVerifier::TexParamVerifier (const glw::Functions& gl, tcu::TestLog& log, const char* testNamePostfix)
64	: glu::CallLogWrapper	(gl, log)
65	, m_testNamePostfix		(testNamePostfix)
66{
67	enableLogging(true);
68}
69TexParamVerifier::~TexParamVerifier ()
70{
71}
72
73const char* TexParamVerifier::getTestNamePostfix (void) const
74{
75	return m_testNamePostfix;
76}
77
78class GetTexParameterIVerifier : public TexParamVerifier
79{
80public:
81			GetTexParameterIVerifier	(const glw::Functions& gl, tcu::TestLog& log);
82
83	void	verifyInteger				(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
84	void	verifyFloat					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference);
85};
86
87GetTexParameterIVerifier::GetTexParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log)
88	: TexParamVerifier(gl, log, "_gettexparameteri")
89{
90}
91
92void GetTexParameterIVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
93{
94	using tcu::TestLog;
95
96	StateQueryMemoryWriteGuard<GLint> state;
97	glGetTexParameteriv(target, name, &state);
98
99	if (!state.verifyValidity(testCtx))
100		return;
101
102	if (state != reference)
103	{
104		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
105
106		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
107			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
108	}
109}
110
111void GetTexParameterIVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)
112{
113	using tcu::TestLog;
114
115	StateQueryMemoryWriteGuard<GLint> state;
116	glGetTexParameteriv(target, name, &state);
117
118	if (!state.verifyValidity(testCtx))
119		return;
120
121	const GLint expectedGLStateMax = StateQueryUtil::roundGLfloatToNearestIntegerHalfUp<GLint>(reference);
122	const GLint expectedGLStateMin = StateQueryUtil::roundGLfloatToNearestIntegerHalfDown<GLint>(reference);
123
124	if (state < expectedGLStateMin || state > expectedGLStateMax)
125	{
126		testCtx.getLog() << TestLog::Message << "// ERROR: expected in range [" << expectedGLStateMin << ", " << expectedGLStateMax << "]; got " << state << TestLog::EndMessage;
127
128		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
129			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid texture param value");
130	}
131}
132
133class GetTexParameterFVerifier : public TexParamVerifier
134{
135public:
136			GetTexParameterFVerifier	(const glw::Functions& gl, tcu::TestLog& log);
137
138	void	verifyInteger				(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
139	void	verifyFloat					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference);
140};
141
142GetTexParameterFVerifier::GetTexParameterFVerifier (const glw::Functions& gl, tcu::TestLog& log)
143	: TexParamVerifier(gl, log, "_gettexparameterf")
144{
145}
146
147void GetTexParameterFVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
148{
149	using tcu::TestLog;
150
151	const GLfloat referenceAsFloat = GLfloat(reference);
152	DE_ASSERT(reference == GLint(referenceAsFloat)); // reference integer must have 1:1 mapping to float for this to work. Reference value is always such value in these tests
153
154	StateQueryMemoryWriteGuard<GLfloat> state;
155	glGetTexParameterfv(target, name, &state);
156
157	if (!state.verifyValidity(testCtx))
158		return;
159
160	if (state != referenceAsFloat)
161	{
162		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << referenceAsFloat << "; got " << state << TestLog::EndMessage;
163
164		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
165			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
166	}
167}
168
169void GetTexParameterFVerifier::verifyFloat (tcu::TestContext& testCtx, GLenum target, GLenum name, GLfloat reference)
170{
171	using tcu::TestLog;
172
173	StateQueryMemoryWriteGuard<GLfloat> state;
174	glGetTexParameterfv(target, name, &state);
175
176	if (!state.verifyValidity(testCtx))
177		return;
178
179	if (state != reference)
180	{
181		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;
182
183		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
184			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
185	}
186}
187
188} // TextureParamVerifiers
189
190namespace
191{
192
193using namespace TextureParamVerifiers;
194
195// Tests
196
197class IsTextureCase : public ApiCase
198{
199public:
200	IsTextureCase (Context& context, const char* name, const char* description, GLenum textureTarget)
201		: ApiCase			(context, name, description)
202		, m_textureTarget	(textureTarget)
203	{
204	}
205
206	void test (void)
207	{
208		using tcu::TestLog;
209
210		GLuint textureId = 0;
211		glGenTextures(1, &textureId);
212		glBindTexture(m_textureTarget, textureId);
213		expectError(GL_NO_ERROR);
214
215		checkBooleans(glIsTexture(textureId), GL_TRUE);
216
217		glDeleteTextures(1, &textureId);
218		expectError(GL_NO_ERROR);
219
220		checkBooleans(glIsTexture(textureId), GL_FALSE);
221	}
222
223protected:
224	GLenum										m_textureTarget;
225};
226
227class TextureCase : public ApiCase
228{
229public:
230	TextureCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
231		: ApiCase			(context, name, description)
232		, m_textureTarget	(textureTarget)
233		, m_verifier		(verifier)
234	{
235	}
236
237	virtual void testTexture (void) = DE_NULL;
238
239	void test (void)
240	{
241		GLuint textureId = 0;
242		glGenTextures(1, &textureId);
243		glBindTexture(m_textureTarget, textureId);
244		expectError(GL_NO_ERROR);
245
246		testTexture();
247
248		glDeleteTextures(1, &textureId);
249		expectError(GL_NO_ERROR);
250	}
251
252protected:
253	GLenum				m_textureTarget;
254	TexParamVerifier*	m_verifier;
255};
256
257class TextureSwizzleCase : public TextureCase
258{
259public:
260	TextureSwizzleCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget, GLenum valueName, GLenum initialValue)
261		: TextureCase		(context, verifier, name, description, textureTarget)
262		, m_valueName		(valueName)
263		, m_initialValue	(initialValue)
264	{
265	}
266
267	void testTexture (void)
268	{
269		m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, m_initialValue);
270		expectError(GL_NO_ERROR);
271
272		const GLenum swizzleValues[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_ZERO, GL_ONE};
273
274		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(swizzleValues); ++ndx)
275		{
276			glTexParameteri(m_textureTarget, m_valueName, swizzleValues[ndx]);
277			expectError(GL_NO_ERROR);
278
279			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, swizzleValues[ndx]);
280			expectError(GL_NO_ERROR);
281		}
282
283		//check unit conversions with float
284
285		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(swizzleValues); ++ndx)
286		{
287			glTexParameterf(m_textureTarget, m_valueName, (GLfloat)swizzleValues[ndx]);
288			expectError(GL_NO_ERROR);
289
290			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, swizzleValues[ndx]);
291			expectError(GL_NO_ERROR);
292		}
293	}
294
295private:
296	GLenum m_valueName;
297	GLenum m_initialValue;
298};
299
300class TextureWrapCase : public TextureCase
301{
302public:
303	TextureWrapCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget, GLenum valueName)
304		: TextureCase	(context, verifier, name, description, textureTarget)
305		, m_valueName	(valueName)
306	{
307	}
308
309	void testTexture (void)
310	{
311		m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, GL_REPEAT);
312		expectError(GL_NO_ERROR);
313
314		const GLenum wrapValues[] = {GL_CLAMP_TO_EDGE, GL_REPEAT, GL_MIRRORED_REPEAT};
315
316		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
317		{
318			glTexParameteri(m_textureTarget, m_valueName, wrapValues[ndx]);
319			expectError(GL_NO_ERROR);
320
321			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
322			expectError(GL_NO_ERROR);
323		}
324
325		//check unit conversions with float
326
327		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(wrapValues); ++ndx)
328		{
329			glTexParameterf(m_textureTarget, m_valueName, (GLfloat)wrapValues[ndx]);
330			expectError(GL_NO_ERROR);
331
332			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_valueName, wrapValues[ndx]);
333			expectError(GL_NO_ERROR);
334		}
335	}
336
337private:
338	GLenum	m_valueName;
339};
340
341class TextureMagFilterCase : public TextureCase
342{
343public:
344	TextureMagFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
345		: TextureCase(context, verifier, name, description, textureTarget)
346	{
347	}
348
349	void testTexture (void)
350	{
351		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
352		expectError(GL_NO_ERROR);
353
354		const GLenum magValues[] = {GL_NEAREST, GL_LINEAR};
355
356		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
357		{
358			glTexParameteri(m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
359			expectError(GL_NO_ERROR);
360
361			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
362			expectError(GL_NO_ERROR);
363		}
364
365		//check unit conversions with float
366
367		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(magValues); ++ndx)
368		{
369			glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, (GLfloat)magValues[ndx]);
370			expectError(GL_NO_ERROR);
371
372			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MAG_FILTER, magValues[ndx]);
373			expectError(GL_NO_ERROR);
374		}
375	}
376};
377
378class TextureMinFilterCase : public TextureCase
379{
380public:
381	TextureMinFilterCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
382		: TextureCase(context, verifier, name, description, textureTarget)
383	{
384	}
385
386	void testTexture (void)
387	{
388		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
389		expectError(GL_NO_ERROR);
390
391		const GLenum minValues[] = {GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR};
392
393		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
394		{
395			glTexParameteri(m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
396			expectError(GL_NO_ERROR);
397
398			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
399			expectError(GL_NO_ERROR);
400		}
401
402		//check unit conversions with float
403
404		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(minValues); ++ndx)
405		{
406			glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, (GLfloat)minValues[ndx]);
407			expectError(GL_NO_ERROR);
408
409			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_MIN_FILTER, minValues[ndx]);
410			expectError(GL_NO_ERROR);
411		}
412	}
413};
414
415class TextureLODCase : public TextureCase
416{
417public:
418	TextureLODCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget, GLenum lodTarget, int initialValue)
419		: TextureCase		(context, verifier, name, description, textureTarget)
420		, m_lodTarget		(lodTarget)
421		, m_initialValue	(initialValue)
422	{
423	}
424
425	void testTexture (void)
426	{
427		de::Random rnd(0xabcdef);
428
429		m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_lodTarget, m_initialValue);
430		expectError(GL_NO_ERROR);
431
432		const int numIterations = 60;
433		for (int ndx = 0; ndx < numIterations; ++ndx)
434		{
435			const GLfloat ref = rnd.getFloat(-64000, 64000);
436
437			glTexParameterf(m_textureTarget, m_lodTarget, ref);
438			expectError(GL_NO_ERROR);
439
440			m_verifier->verifyFloat(m_testCtx, m_textureTarget, m_lodTarget, ref);
441			expectError(GL_NO_ERROR);
442		}
443
444		// check unit conversions with int
445
446		for (int ndx = 0; ndx < numIterations; ++ndx)
447		{
448			const GLint ref = rnd.getInt(-64000, 64000);
449
450			glTexParameteri(m_textureTarget, m_lodTarget, ref);
451			expectError(GL_NO_ERROR);
452
453			m_verifier->verifyFloat(m_testCtx, m_textureTarget, m_lodTarget, (GLfloat)ref);
454			expectError(GL_NO_ERROR);
455		}
456	}
457private:
458	GLenum	m_lodTarget;
459	int		m_initialValue;
460};
461
462class TextureLevelCase : public TextureCase
463{
464public:
465	TextureLevelCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget, GLenum levelTarget, int initialValue)
466		: TextureCase		(context, verifier, name, description, textureTarget)
467		, m_levelTarget		(levelTarget)
468		, m_initialValue	(initialValue)
469	{
470	}
471
472	void testTexture (void)
473	{
474		de::Random rnd(0xabcdef);
475
476		m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_levelTarget, m_initialValue);
477		expectError(GL_NO_ERROR);
478
479		const int numIterations = 60;
480		for (int ndx = 0; ndx < numIterations; ++ndx)
481		{
482			const GLint ref = rnd.getInt(0, 64000);
483
484			glTexParameteri(m_textureTarget, m_levelTarget, ref);
485			expectError(GL_NO_ERROR);
486
487			m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_levelTarget, ref);
488			expectError(GL_NO_ERROR);
489		}
490
491		// check unit conversions with float
492
493		const float nonSignificantOffsets[] = {-0.45f, -0.25f, 0, 0.45f}; // offsets O so that for any integers z in Z, o in O roundToClosestInt(z+o)==z
494
495		const int numConversionIterations = 30;
496		for (int ndx = 0; ndx < numConversionIterations; ++ndx)
497		{
498			const GLint ref = rnd.getInt(0, 64000);
499
500			for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(nonSignificantOffsets); ++offsetNdx)
501			{
502				glTexParameterf(m_textureTarget, m_levelTarget, ((GLfloat)ref) + nonSignificantOffsets[offsetNdx]);
503				expectError(GL_NO_ERROR);
504
505				m_verifier->verifyInteger(m_testCtx, m_textureTarget, m_levelTarget, ref);
506				expectError(GL_NO_ERROR);
507			}
508		}
509	}
510private:
511	GLenum	m_levelTarget;
512	int		m_initialValue;
513};
514
515class TextureCompareModeCase : public TextureCase
516{
517public:
518	TextureCompareModeCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
519		: TextureCase(context, verifier, name, description, textureTarget)
520	{
521	}
522
523	void testTexture (void)
524	{
525		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
526		expectError(GL_NO_ERROR);
527
528		const GLenum modes[] = {GL_COMPARE_REF_TO_TEXTURE, GL_NONE};
529		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(modes); ++ndx)
530		{
531			glTexParameteri(m_textureTarget, GL_TEXTURE_COMPARE_MODE, modes[ndx]);
532			expectError(GL_NO_ERROR);
533
534			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_MODE, modes[ndx]);
535			expectError(GL_NO_ERROR);
536		}
537
538		// with float too
539
540		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(modes); ++ndx)
541		{
542			glTexParameterf(m_textureTarget, GL_TEXTURE_COMPARE_MODE, (GLfloat)modes[ndx]);
543			expectError(GL_NO_ERROR);
544
545			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_MODE, modes[ndx]);
546			expectError(GL_NO_ERROR);
547		}
548	}
549};
550
551class TextureCompareFuncCase : public TextureCase
552{
553public:
554	TextureCompareFuncCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
555		: TextureCase(context, verifier, name, description, textureTarget)
556	{
557	}
558
559	void testTexture (void)
560	{
561		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
562		expectError(GL_NO_ERROR);
563
564		const GLenum compareFuncs[] = {GL_LEQUAL, GL_GEQUAL, GL_LESS, GL_GREATER, GL_EQUAL, GL_NOTEQUAL, GL_ALWAYS, GL_NEVER};
565		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compareFuncs); ++ndx)
566		{
567			glTexParameteri(m_textureTarget, GL_TEXTURE_COMPARE_FUNC, compareFuncs[ndx]);
568			expectError(GL_NO_ERROR);
569
570			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_FUNC, compareFuncs[ndx]);
571			expectError(GL_NO_ERROR);
572		}
573
574		// with float too
575
576		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(compareFuncs); ++ndx)
577		{
578			glTexParameterf(m_textureTarget, GL_TEXTURE_COMPARE_FUNC, (GLfloat)compareFuncs[ndx]);
579			expectError(GL_NO_ERROR);
580
581			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_COMPARE_FUNC, compareFuncs[ndx]);
582			expectError(GL_NO_ERROR);
583		}
584	}
585};
586
587class TextureImmutableLevelsCase : public TextureCase
588{
589public:
590	TextureImmutableLevelsCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
591		: TextureCase(context, verifier, name, description, textureTarget)
592	{
593	}
594
595	void testTexture (void)
596	{
597		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_IMMUTABLE_LEVELS, 0);
598		expectError(GL_NO_ERROR);
599
600		for (int level = 1; level <= 8; ++level)
601		{
602			GLuint textureID = 0;
603			glGenTextures(1, &textureID);
604			glBindTexture(m_textureTarget, textureID);
605			expectError(GL_NO_ERROR);
606
607			if (m_textureTarget == GL_TEXTURE_2D_ARRAY || m_textureTarget == GL_TEXTURE_3D)
608				glTexStorage3D(m_textureTarget, level, GL_RGB8, 256, 256, 256);
609			else
610				glTexStorage2D(m_textureTarget, level, GL_RGB8, 256, 256);
611			expectError(GL_NO_ERROR);
612
613			m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_IMMUTABLE_LEVELS, level);
614			glDeleteTextures(1, &textureID);
615			expectError(GL_NO_ERROR);
616		}
617	}
618};
619
620class TextureImmutableFormatCase : public TextureCase
621{
622public:
623	TextureImmutableFormatCase (Context& context, TexParamVerifier* verifier, const char* name, const char* description, GLenum textureTarget)
624		: TextureCase(context, verifier, name, description, textureTarget)
625	{
626	}
627
628	void testTexture (void)
629	{
630		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_IMMUTABLE_FORMAT, 0);
631		expectError(GL_NO_ERROR);
632
633		const GLenum formats[] =
634		{
635			GL_RGBA32I, GL_RGBA32UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA8, GL_RGBA8I,
636			GL_RGBA8UI, GL_SRGB8_ALPHA8, GL_RGB10_A2, GL_RGB10_A2UI, GL_RGBA4,
637			GL_RGB5_A1, GL_RGB8, GL_RGB565, GL_RG32I, GL_RG32UI, GL_RG16I, GL_RG16UI,
638			GL_RG8, GL_RG8I, GL_RG8UI, GL_R32I, GL_R32UI, GL_R16I, GL_R16UI, GL_R8,
639			GL_R8I, GL_R8UI,
640
641			GL_RGBA32F, GL_RGBA16F, GL_RGBA8_SNORM, GL_RGB32F,
642			GL_RGB32I, GL_RGB32UI, GL_RGB16F, GL_RGB16I, GL_RGB16UI, GL_RGB8_SNORM,
643			GL_RGB8I, GL_RGB8UI, GL_SRGB8, GL_R11F_G11F_B10F, GL_RGB9_E5, GL_RG32F,
644			GL_RG16F, GL_RG8_SNORM, GL_R32F, GL_R16F, GL_R8_SNORM,
645		};
646
647		const GLenum non3dFormats[] =
648		{
649			GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
650			GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8
651		};
652
653		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
654			testSingleFormat(formats[formatNdx]);
655
656		if (m_textureTarget != GL_TEXTURE_3D)
657			for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(non3dFormats); ++formatNdx)
658				testSingleFormat(non3dFormats[formatNdx]);
659	}
660
661	void testSingleFormat (GLenum format)
662	{
663		GLuint textureID = 0;
664		glGenTextures(1, &textureID);
665		glBindTexture(m_textureTarget, textureID);
666		expectError(GL_NO_ERROR);
667
668		if (m_textureTarget == GL_TEXTURE_2D_ARRAY || m_textureTarget == GL_TEXTURE_3D)
669			glTexStorage3D(m_textureTarget, 1, format, 32, 32, 32);
670		else
671			glTexStorage2D(m_textureTarget, 1, format, 32, 32);
672		expectError(GL_NO_ERROR);
673
674		m_verifier->verifyInteger(m_testCtx, m_textureTarget, GL_TEXTURE_IMMUTABLE_FORMAT, 1);
675		glDeleteTextures(1, &textureID);
676		expectError(GL_NO_ERROR);
677	}
678};
679
680
681} // anonymous
682
683#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)												\
684	for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++)	\
685	{																							\
686		TexParamVerifier* verifier = VERIFIERS[_verifierNdx];									\
687		CODE_BLOCK;																				\
688	}
689
690TextureStateQueryTests::TextureStateQueryTests (Context& context)
691	: TestCaseGroup		(context, "texture", "Texture State Query tests")
692	, m_verifierInt		(DE_NULL)
693	, m_verifierFloat	(DE_NULL)
694{
695}
696
697TextureStateQueryTests::~TextureStateQueryTests (void)
698{
699	deinit();
700}
701
702void TextureStateQueryTests::init (void)
703{
704	using namespace TextureParamVerifiers;
705
706	DE_ASSERT(m_verifierInt == DE_NULL);
707	DE_ASSERT(m_verifierFloat == DE_NULL);
708
709	m_verifierInt		= new GetTexParameterIVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
710	m_verifierFloat		= new GetTexParameterFVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
711
712	TexParamVerifier* verifiers[] = {m_verifierInt, m_verifierFloat};
713
714	const struct
715	{
716		const char*	name;
717		GLenum		textureTarget;
718	} textureTargets[] =
719	{
720		{ "texture_2d",			GL_TEXTURE_2D},
721		{ "texture_3d",			GL_TEXTURE_3D},
722		{ "texture_2d_array",	GL_TEXTURE_2D_ARRAY},
723		{ "texture_cube_map",	GL_TEXTURE_CUBE_MAP}
724	};
725
726	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(textureTargets); ++ndx)
727	{
728		addChild(new IsTextureCase(m_context, (std::string(textureTargets[ndx].name) + "_is_texture").c_str(), "IsTexture",	textureTargets[ndx].textureTarget));
729
730		FOR_EACH_VERIFIER(verifiers, addChild(new TextureSwizzleCase	(m_context, verifier, (std::string(textureTargets[ndx].name)	+ "_texture_swizzle_r"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_SWIZZLE_R",		textureTargets[ndx].textureTarget, GL_TEXTURE_SWIZZLE_R, GL_RED)));
731		FOR_EACH_VERIFIER(verifiers, addChild(new TextureSwizzleCase	(m_context, verifier, (std::string(textureTargets[ndx].name)	+ "_texture_swizzle_g"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_SWIZZLE_G",		textureTargets[ndx].textureTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN)));
732		FOR_EACH_VERIFIER(verifiers, addChild(new TextureSwizzleCase	(m_context, verifier, (std::string(textureTargets[ndx].name)	+ "_texture_swizzle_b"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_SWIZZLE_B",		textureTargets[ndx].textureTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE)));
733		FOR_EACH_VERIFIER(verifiers, addChild(new TextureSwizzleCase	(m_context, verifier, (std::string(textureTargets[ndx].name)	+ "_texture_swizzle_a"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_SWIZZLE_A",		textureTargets[ndx].textureTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA)));
734
735		FOR_EACH_VERIFIER(verifiers, addChild(new TextureWrapCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_wrap_s"			+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_WRAP_S",		textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_S)));
736		if (textureTargets[ndx].textureTarget == GL_TEXTURE_2D ||
737			textureTargets[ndx].textureTarget == GL_TEXTURE_3D ||
738			textureTargets[ndx].textureTarget == GL_TEXTURE_CUBE_MAP)
739			FOR_EACH_VERIFIER(verifiers, addChild(new TextureWrapCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_wrap_t"			+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_WRAP_T",		textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_T)));
740
741		if (textureTargets[ndx].textureTarget == GL_TEXTURE_3D)
742			FOR_EACH_VERIFIER(verifiers, addChild(new TextureWrapCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_wrap_r"			+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_WRAP_R",		textureTargets[ndx].textureTarget, GL_TEXTURE_WRAP_R)));
743
744		FOR_EACH_VERIFIER(verifiers, addChild(new TextureMagFilterCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_mag_filter"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MAG_FILTER",	textureTargets[ndx].textureTarget)));
745		FOR_EACH_VERIFIER(verifiers, addChild(new TextureMinFilterCase	(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_min_filter"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MIN_FILTER",	textureTargets[ndx].textureTarget)));
746		FOR_EACH_VERIFIER(verifiers, addChild(new TextureLODCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_min_lod"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MIN_LOD",		textureTargets[ndx].textureTarget, GL_TEXTURE_MIN_LOD, -1000)));
747		FOR_EACH_VERIFIER(verifiers, addChild(new TextureLODCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_max_lod"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MAX_LOD",		textureTargets[ndx].textureTarget, GL_TEXTURE_MAX_LOD,  1000)));
748		FOR_EACH_VERIFIER(verifiers, addChild(new TextureLevelCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_base_level"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_BASE_LEVEL",	textureTargets[ndx].textureTarget, GL_TEXTURE_BASE_LEVEL, 0)));
749		FOR_EACH_VERIFIER(verifiers, addChild(new TextureLevelCase		(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_max_level"		+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_MAX_LEVEL",		textureTargets[ndx].textureTarget, GL_TEXTURE_MAX_LEVEL, 1000)));
750
751		FOR_EACH_VERIFIER(verifiers, addChild(new TextureCompareModeCase(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_compare_mode"	+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_COMPARE_MODE",	textureTargets[ndx].textureTarget)));
752		FOR_EACH_VERIFIER(verifiers, addChild(new TextureCompareFuncCase(m_context, verifier,	(std::string(textureTargets[ndx].name)	+ "_texture_compare_func"	+ verifier->getTestNamePostfix()).c_str(), "TEXTURE_COMPARE_FUNC",	textureTargets[ndx].textureTarget)));
753
754		FOR_EACH_VERIFIER(verifiers, addChild(new TextureImmutableLevelsCase(m_context, verifier,	(std::string(textureTargets[ndx].name) + "_texture_immutable_levels" + verifier->getTestNamePostfix()).c_str(), "TEXTURE_IMMUTABLE_LEVELS",	textureTargets[ndx].textureTarget)));
755		FOR_EACH_VERIFIER(verifiers, addChild(new TextureImmutableFormatCase(m_context, verifier,	(std::string(textureTargets[ndx].name) + "_texture_immutable_format" + verifier->getTestNamePostfix()).c_str(), "TEXTURE_IMMUTABLE_FORMAT",	textureTargets[ndx].textureTarget)));
756	}
757}
758
759void TextureStateQueryTests::deinit (void)
760{
761	if (m_verifierInt)
762	{
763		delete m_verifierInt;
764		m_verifierInt = NULL;
765	}
766	if (m_verifierFloat)
767	{
768		delete m_verifierFloat;
769		m_verifierFloat = NULL;
770	}
771
772	this->TestCaseGroup::deinit();
773}
774
775} // Functional
776} // gles3
777} // deqp
778