es31fInternalFormatQueryTests.cpp revision 3c827367444ee418f129b2c238299f49d3264554
1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 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 Internal format query tests
22 *//*--------------------------------------------------------------------*/
23
24#include "es31fInternalFormatQueryTests.hpp"
25#include "tcuTestLog.hpp"
26#include "gluRenderContext.hpp"
27#include "gluStrUtil.hpp"
28#include "gluContextInfo.hpp"
29#include "glwFunctions.hpp"
30#include "glwEnums.hpp"
31
32namespace deqp
33{
34namespace gles31
35{
36namespace Functional
37{
38namespace
39{
40
41class FormatSamplesCase : public TestCase
42{
43public:
44	enum FormatType
45	{
46		FORMAT_COLOR,
47		FORMAT_INT,
48		FORMAT_DEPTH_STENCIL
49	};
50
51						FormatSamplesCase	(Context& ctx, const char* name, const char* desc, glw::GLenum texTarget, glw::GLenum internalFormat, FormatType type);
52private:
53	void				init				(void);
54	IterateResult		iterate				(void);
55
56	void				testMultisample		(void);
57	void				testSinglesample	(void);
58
59	const glw::GLenum	m_texTarget;
60	const glw::GLenum	m_internalFormat;
61	const FormatType	m_type;
62};
63
64FormatSamplesCase::FormatSamplesCase (Context& ctx, const char* name, const char* desc, glw::GLenum texTarget, glw::GLenum internalFormat, FormatType type)
65	: TestCase			(ctx, name, desc)
66	, m_texTarget		(texTarget)
67	, m_internalFormat	(internalFormat)
68	, m_type			(type)
69{
70}
71
72void FormatSamplesCase::init (void)
73{
74	if (m_texTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY && !m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
75		throw tcu::NotSupportedError("Test requires OES_texture_storage_multisample_2d_array extension");
76}
77
78FormatSamplesCase::IterateResult FormatSamplesCase::iterate (void)
79{
80	if (m_texTarget == GL_TEXTURE_2D_MULTISAMPLE || m_texTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY || m_texTarget == GL_RENDERBUFFER)
81		testMultisample();
82	else
83		testSinglesample();
84
85	return STOP;
86}
87
88void FormatSamplesCase::testMultisample (void)
89{
90	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
91	bool					error			= false;
92	glw::GLint				maxSamples		= 0;
93	glw::GLint				numSampleCounts	= 0;
94
95	// Lowest limit
96	{
97		const glw::GLenum samplesEnum = (m_type == FORMAT_COLOR) ? (GL_MAX_COLOR_TEXTURE_SAMPLES) : (m_type == FORMAT_INT) ? (GL_MAX_INTEGER_SAMPLES) : (GL_MAX_DEPTH_TEXTURE_SAMPLES);
98		m_testCtx.getLog() << tcu::TestLog::Message << "Format must support sample count of " << glu::getGettableStateStr(samplesEnum) << tcu::TestLog::EndMessage;
99
100		gl.getIntegerv(samplesEnum, &maxSamples);
101		GLU_EXPECT_NO_ERROR(gl.getError(), "get MAX_*_SAMPLES");
102
103		m_testCtx.getLog() << tcu::TestLog::Message << glu::getGettableStateStr(samplesEnum) << " = " << maxSamples << tcu::TestLog::EndMessage;
104
105		if (maxSamples < 1)
106		{
107			m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: minimum value of "  << glu::getGettableStateStr(samplesEnum) << " is 1" << tcu::TestLog::EndMessage;
108			error = true;
109		}
110	}
111
112	// Number of sample counts
113	{
114		gl.getInternalformativ(m_texTarget, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
115		GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
116
117		m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
118
119		if (numSampleCounts < 1)
120		{
121			m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Format MUST support some multisample configuration, got GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
122			error = true;
123		}
124	}
125
126	// Sample counts
127	{
128		tcu::MessageBuilder		samplesMsg(&m_testCtx.getLog());
129		std::vector<glw::GLint>	samples;
130
131		if (numSampleCounts > 0)
132		{
133			samples.resize(numSampleCounts, -1);
134
135			gl.getInternalformativ(m_texTarget, m_internalFormat, GL_SAMPLES, numSampleCounts, &samples[0]);
136			GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_SAMPLES");
137		}
138		else
139			TCU_FAIL("glGetInternalFormativ() reported 0 supported sample counts");
140
141		// make a pretty log
142
143		samplesMsg << "GL_SAMPLES = [";
144		for (int ndx = 0; ndx < numSampleCounts; ++ndx)
145		{
146			if (ndx)
147				samplesMsg << ", ";
148			samplesMsg << samples[ndx];
149		}
150		samplesMsg << "]" << tcu::TestLog::EndMessage;
151
152		// Samples are in order
153		for (int ndx = 1; ndx < numSampleCounts; ++ndx)
154		{
155			if (samples[ndx-1] <= samples[ndx])
156			{
157				m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Samples must be ordered descending." << tcu::TestLog::EndMessage;
158				error = true;
159				break;
160			}
161		}
162
163		// samples are positive
164		for (int ndx = 1; ndx < numSampleCounts; ++ndx)
165		{
166			if (samples[ndx-1] <= 0)
167			{
168				m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: Only positive SAMPLES allowed." << tcu::TestLog::EndMessage;
169				error = true;
170				break;
171			}
172		}
173
174		// maxSamples must be supported
175		if (samples[0] < maxSamples)
176		{
177			m_testCtx.getLog() << tcu::TestLog::Message << "ERROR: MAX_*_SAMPLES must be supported." << tcu::TestLog::EndMessage;
178			error = true;
179		}
180	}
181
182	// Result
183	if (!error)
184		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
185	else
186		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
187}
188
189void FormatSamplesCase::testSinglesample (void)
190{
191	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
192	const int				defValue		= -123;
193	glw::GLint				numSampleCounts	= defValue;
194
195	m_testCtx.getLog()
196		<< tcu::TestLog::Message
197		<< "Quering GL_NUM_SAMPLE_COUNTS with target = " << glu::getInternalFormatTargetName(m_texTarget) << ", internal format = " << glu::getPixelFormatName(m_internalFormat) << "\n"
198		<< "Expecting 0."
199		<< tcu::TestLog::EndMessage;
200
201	gl.getInternalformativ(m_texTarget, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
202	GLU_EXPECT_NO_ERROR(gl.getError(), "get GL_NUM_SAMPLE_COUNTS");
203
204	if (numSampleCounts == 0)
205	{
206		m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << tcu::TestLog::EndMessage;
207		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
208	}
209	else if (numSampleCounts == defValue)
210	{
211		m_testCtx.getLog() << tcu::TestLog::Message << "getInternalformativ did not return a value." << tcu::TestLog::EndMessage;
212		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No value");
213	}
214	else
215	{
216		m_testCtx.getLog() << tcu::TestLog::Message << "GL_NUM_SAMPLE_COUNTS = " << numSampleCounts << ", expected 0" << tcu::TestLog::EndMessage;
217		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid value");
218	}
219}
220
221} // anonymous
222
223InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
224	: TestCaseGroup(context, "internal_format", "Internal format queries")
225{
226}
227
228InternalFormatQueryTests::~InternalFormatQueryTests (void)
229{
230}
231
232void InternalFormatQueryTests::init (void)
233{
234	static const struct InternalFormat
235	{
236		const char*						name;
237		glw::GLenum						format;
238		FormatSamplesCase::FormatType	type;
239	} internalFormats[] =
240	{
241		// color renderable
242		{ "r8",						GL_R8,					FormatSamplesCase::FORMAT_COLOR			},
243		{ "rg8",					GL_RG8,					FormatSamplesCase::FORMAT_COLOR			},
244		{ "rgb8",					GL_RGB8,				FormatSamplesCase::FORMAT_COLOR			},
245		{ "rgb565",					GL_RGB565,				FormatSamplesCase::FORMAT_COLOR			},
246		{ "rgba4",					GL_RGBA4,				FormatSamplesCase::FORMAT_COLOR			},
247		{ "rgb5_a1",				GL_RGB5_A1,				FormatSamplesCase::FORMAT_COLOR			},
248		{ "rgba8",					GL_RGBA8,				FormatSamplesCase::FORMAT_COLOR			},
249		{ "rgb10_a2",				GL_RGB10_A2,			FormatSamplesCase::FORMAT_COLOR			},
250		{ "rgb10_a2ui",				GL_RGB10_A2UI,			FormatSamplesCase::FORMAT_INT			},
251		{ "srgb8_alpha8",			GL_SRGB8_ALPHA8,		FormatSamplesCase::FORMAT_COLOR			},
252		{ "r8i",					GL_R8I,					FormatSamplesCase::FORMAT_INT			},
253		{ "r8ui",					GL_R8UI,				FormatSamplesCase::FORMAT_INT			},
254		{ "r16i",					GL_R16I,				FormatSamplesCase::FORMAT_INT			},
255		{ "r16ui",					GL_R16UI,				FormatSamplesCase::FORMAT_INT			},
256		{ "r32i",					GL_R32I,				FormatSamplesCase::FORMAT_INT			},
257		{ "r32ui",					GL_R32UI,				FormatSamplesCase::FORMAT_INT			},
258		{ "rg8i",					GL_RG8I,				FormatSamplesCase::FORMAT_INT			},
259		{ "rg8ui",					GL_RG8UI,				FormatSamplesCase::FORMAT_INT			},
260		{ "rg16i",					GL_RG16I,				FormatSamplesCase::FORMAT_INT			},
261		{ "rg16ui",					GL_RG16UI,				FormatSamplesCase::FORMAT_INT			},
262		{ "rg32i",					GL_RG32I,				FormatSamplesCase::FORMAT_INT			},
263		{ "rg32ui",					GL_RG32UI,				FormatSamplesCase::FORMAT_INT			},
264		{ "rgba8i",					GL_RGBA8I,				FormatSamplesCase::FORMAT_INT			},
265		{ "rgba8ui",				GL_RGBA8UI,				FormatSamplesCase::FORMAT_INT			},
266		{ "rgba16i",				GL_RGBA16I,				FormatSamplesCase::FORMAT_INT			},
267		{ "rgba16ui",				GL_RGBA16UI,			FormatSamplesCase::FORMAT_INT			},
268		{ "rgba32i",				GL_RGBA32I,				FormatSamplesCase::FORMAT_INT			},
269		{ "rgba32ui",				GL_RGBA32UI,			FormatSamplesCase::FORMAT_INT			},
270
271		// depth renderable
272		{ "depth_component16",		GL_DEPTH_COMPONENT16,	FormatSamplesCase::FORMAT_DEPTH_STENCIL	},
273		{ "depth_component24",		GL_DEPTH_COMPONENT24,	FormatSamplesCase::FORMAT_DEPTH_STENCIL	},
274		{ "depth_component32f",		GL_DEPTH_COMPONENT32F,	FormatSamplesCase::FORMAT_DEPTH_STENCIL	},
275		{ "depth24_stencil8",		GL_DEPTH24_STENCIL8,	FormatSamplesCase::FORMAT_DEPTH_STENCIL	},
276		{ "depth32f_stencil8",		GL_DEPTH32F_STENCIL8,	FormatSamplesCase::FORMAT_DEPTH_STENCIL	},
277
278		// stencil renderable
279		{ "stencil_index8",			GL_STENCIL_INDEX8,		FormatSamplesCase::FORMAT_DEPTH_STENCIL	}
280		// DEPTH24_STENCIL8,  duplicate
281		// DEPTH32F_STENCIL8  duplicate
282	};
283
284	static const struct
285	{
286		const char*	name;
287		deUint32	target;
288	} textureTargets[] =
289	{
290		{ "texture_2d_multisample",			GL_TEXTURE_2D_MULTISAMPLE		},
291		{ "texture_2d_multisample_array",	GL_TEXTURE_2D_MULTISAMPLE_ARRAY	},
292	};
293
294	for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(textureTargets); ++groupNdx)
295	{
296		tcu::TestCaseGroup* const	group		= new tcu::TestCaseGroup(m_testCtx, textureTargets[groupNdx].name, glu::getInternalFormatTargetName(textureTargets[groupNdx].target));
297		const glw::GLenum			texTarget	= textureTargets[groupNdx].target;
298
299		addChild(group);
300
301		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(internalFormats); ++caseNdx)
302		{
303			const std::string name = std::string(internalFormats[caseNdx].name) + "_samples";
304			const std::string desc = std::string("Verify GL_SAMPLES of ") + internalFormats[caseNdx].name;
305
306			group->addChild(new FormatSamplesCase(m_context, name.c_str(), desc.c_str(), texTarget, internalFormats[caseNdx].format, internalFormats[caseNdx].type));
307		}
308	}
309}
310
311} // Functional
312} // gles31
313} // deqp
314