• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Internal Format Query tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fInternalFormatQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "es3fApiCase.hpp"
27 #include "gluRenderContext.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "deMath.h"
31 
32 using namespace glw; // GLint and other GL types
33 using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;
34 
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41 namespace
42 {
43 
44 class SamplesCase : public ApiCase
45 {
46 public:
SamplesCase(Context & context,const char * name,const char * description,GLenum internalFormat,bool isIntegerInternalFormat)47 	SamplesCase(Context& context, const char* name, const char* description, GLenum internalFormat, bool isIntegerInternalFormat)
48 		: ApiCase					(context, name, description)
49 		, m_internalFormat			(internalFormat)
50 		, m_isIntegerInternalFormat	(isIntegerInternalFormat)
51 	{
52 	}
53 
test(void)54 	void test (void)
55 	{
56 		using tcu::TestLog;
57 
58 		StateQueryMemoryWriteGuard<GLint> sampleCounts;
59 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts);
60 		expectError(GL_NO_ERROR);
61 
62 		if (!sampleCounts.verifyValidity(m_testCtx))
63 			return;
64 
65 		m_testCtx.getLog() << TestLog::Message << "// sample counts is " << sampleCounts << TestLog::EndMessage;
66 
67 		if (m_isIntegerInternalFormat && sampleCounts != 0)
68 		{
69 			// Since multisampling is not supported for signed and unsigned integer internal
70 			// formats, the value of NUM_SAMPLE_COUNTS will be zero for such formats.
71 			m_testCtx.getLog() << TestLog::Message << "// ERROR: integer internal formats should have NUM_SAMPLE_COUNTS = 0; got " << sampleCounts << TestLog::EndMessage;
72 			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
73 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
74 		}
75 
76 		if (sampleCounts == 0)
77 			return;
78 
79 		std::vector<GLint> samples;
80 		samples.resize(sampleCounts, -1);
81 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_SAMPLES, sampleCounts, &samples[0]);
82 		expectError(GL_NO_ERROR);
83 
84 		GLint prevSampleCount = 0;
85 		GLint sampleCount = 0;
86 		for (size_t ndx = 0; ndx < samples.size(); ++ndx, prevSampleCount = sampleCount)
87 		{
88 			sampleCount = samples[ndx];
89 
90 			// sample count must be > 0
91 			if (sampleCount <= 0)
92 			{
93 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected sample count to be at least one; got " << sampleCount << TestLog::EndMessage;
94 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
95 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
96 			}
97 
98 			// samples must be ordered descending
99 			if (ndx != 0 && !(sampleCount < prevSampleCount))
100 			{
101 				m_testCtx.getLog() << TestLog::Message
102 					<< "// ERROR: Expected sample count to be ordered in descending order;"
103 					<< "got " << prevSampleCount << " at index " << (ndx - 1) << ", and " << sampleCount << " at index " << ndx << TestLog::EndMessage;
104 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
105 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid order");
106 			}
107 		}
108 
109 		// the maximum value in SAMPLES is guaranteed to be at least the value of MAX_SAMPLES
110 		StateQueryMemoryWriteGuard<GLint> maxSamples;
111 		glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
112 		expectError(GL_NO_ERROR);
113 
114 		if (maxSamples.verifyValidity(m_testCtx))
115 		{
116 			const GLint maximumFormatSampleCount = samples[0];
117 			if (!(maximumFormatSampleCount >= maxSamples))
118 			{
119 				m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected maximum value in SAMPLES (" << maximumFormatSampleCount << ") to be at least the value of MAX_SAMPLES (" << maxSamples << ")" << TestLog::EndMessage;
120 				if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
121 					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid maximum sample count");
122 			}
123 		}
124 	}
125 
126 private:
127 	GLenum	m_internalFormat;
128 	bool	m_isIntegerInternalFormat;
129 };
130 
131 class SamplesBufferSizeCase : public ApiCase
132 {
133 public:
SamplesBufferSizeCase(Context & context,const char * name,const char * description,GLenum internalFormat)134 	SamplesBufferSizeCase(Context& context, const char* name, const char* description, GLenum internalFormat)
135 		: ApiCase			(context, name, description)
136 		, m_internalFormat	(internalFormat)
137 	{
138 	}
139 
test(void)140 	void test (void)
141 	{
142 		using tcu::TestLog;
143 
144 		StateQueryMemoryWriteGuard<GLint> sampleCounts;
145 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCounts);
146 		expectError(GL_NO_ERROR);
147 
148 		if (!sampleCounts.verifyValidity(m_testCtx))
149 			return;
150 
151 		// test with bufSize = 0
152 		GLint queryTargetValue = -1;
153 		glGetInternalformativ(GL_RENDERBUFFER, m_internalFormat, GL_NUM_SAMPLE_COUNTS, 0, &queryTargetValue);
154 		expectError(GL_NO_ERROR);
155 
156 		if (queryTargetValue != -1)
157 		{
158 			m_testCtx.getLog() << TestLog::Message << "// ERROR: Expected output variable not to be written to." << TestLog::EndMessage;
159 			if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
160 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid write");
161 		}
162 	}
163 
164 private:
165 	GLenum m_internalFormat;
166 };
167 
168 } // anonymous
169 
170 
InternalFormatQueryTests(Context & context)171 InternalFormatQueryTests::InternalFormatQueryTests (Context& context)
172 	: TestCaseGroup(context, "internal_format", "Internal Format Query tests.")
173 {
174 }
175 
init(void)176 void InternalFormatQueryTests::init (void)
177 {
178 	const struct InternalFormat
179 	{
180 		const char*	name;
181 		GLenum		format;
182 		bool		isIntegerFormat;
183 	} internalFormats[] =
184 	{
185 		// color renderable and unsized
186 		// \note These unsized formats seem to allowed by the spec, but they are not useful in any way. (You can't create a renderbuffer with such internalFormat)
187 		{ "rgba",					GL_RGBA,				false	},
188 		{ "rgb",					GL_RGB,					false	},
189 
190 		// color renderable
191 		{ "r8",						GL_R8,					false	},
192 		{ "rg8",					GL_RG8,					false	},
193 		{ "rgb8",					GL_RGB8,				false	},
194 		{ "rgb565",					GL_RGB565,				false	},
195 		{ "rgba4",					GL_RGBA4,				false	},
196 		{ "rgb5_a1",				GL_RGB5_A1,				false	},
197 		{ "rgba8",					GL_RGBA8,				false	},
198 		{ "rgb10_a2",				GL_RGB10_A2,			false	},
199 		{ "rgb10_a2ui",				GL_RGB10_A2UI,			true	},
200 		{ "srgb8_alpha8",			GL_SRGB8_ALPHA8,		false	},
201 		{ "r8i",					GL_R8I,					true	},
202 		{ "r8ui",					GL_R8UI,				true	},
203 		{ "r16i",					GL_R16I,				true	},
204 		{ "r16ui",					GL_R16UI,				true	},
205 		{ "r32i",					GL_R32I,				true	},
206 		{ "r32ui",					GL_R32UI,				true	},
207 		{ "rg8i",					GL_RG8I,				true	},
208 		{ "rg8ui",					GL_RG8UI,				true	},
209 		{ "rg16i",					GL_RG16I,				true	},
210 		{ "rg16ui",					GL_RG16UI,				true	},
211 		{ "rg32i",					GL_RG32I,				true	},
212 		{ "rg32ui",					GL_RG32UI,				true	},
213 		{ "rgba8i",					GL_RGBA8I,				true	},
214 		{ "rgba8ui",				GL_RGBA8UI,				true	},
215 		{ "rgba16i",				GL_RGBA16I,				true	},
216 		{ "rgba16ui",				GL_RGBA16UI,			true	},
217 		{ "rgba32i",				GL_RGBA32I,				true	},
218 		{ "rgba32ui",				GL_RGBA32UI,			true	},
219 
220 		// depth renderable
221 		{ "depth_component16",		GL_DEPTH_COMPONENT16,	false	},
222 		{ "depth_component24",		GL_DEPTH_COMPONENT24,	false	},
223 		{ "depth_component32f",		GL_DEPTH_COMPONENT32F,	false	},
224 		{ "depth24_stencil8",		GL_DEPTH24_STENCIL8,	false	},
225 		{ "depth32f_stencil8",		GL_DEPTH32F_STENCIL8,	false	},
226 
227 		// stencil renderable
228 		{ "stencil_index8",			GL_STENCIL_INDEX8,		false	}
229 		// DEPTH24_STENCIL8,  duplicate
230 		// DEPTH32F_STENCIL8  duplicate
231 	};
232 
233 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(internalFormats); ++ndx)
234 	{
235 		const InternalFormat internalFormat = internalFormats[ndx];
236 
237 		addChild(new SamplesCase(m_context, (std::string(internalFormat.name) + "_samples").c_str(), "SAMPLES and NUM_SAMPLE_COUNTS", internalFormat.format, internalFormat.isIntegerFormat));
238 	}
239 
240 	addChild(new SamplesBufferSizeCase(m_context, "rgba8_samples_buffer", "SAMPLES bufSize parameter", GL_RGBA8));
241 }
242 
243 } // Functional
244 } // gles3
245 } // deqp
246