• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Base class for FBO tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fFboTestCase.hpp"
25 #include "es31fFboTestUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "tcuImageCompare.hpp"
28 #include "tcuRenderTarget.hpp"
29 #include "sglrGLContext.hpp"
30 #include "sglrReferenceContext.hpp"
31 #include "gluStrUtil.hpp"
32 #include "gluContextInfo.hpp"
33 #include "deRandom.hpp"
34 #include "glwEnums.hpp"
35 #include "glwFunctions.hpp"
36 
37 #include <algorithm>
38 
39 namespace deqp
40 {
41 namespace gles31
42 {
43 namespace Functional
44 {
45 
46 using tcu::TestLog;
47 using std::string;
48 
FboTestCase(Context & context,const char * name,const char * description,bool useScreenSizedViewport)49 FboTestCase::FboTestCase (Context& context, const char* name, const char* description, bool useScreenSizedViewport)
50 	: TestCase			(context, name, description)
51 	, m_viewportWidth	(useScreenSizedViewport ? context.getRenderTarget().getWidth() : 128)
52 	, m_viewportHeight	(useScreenSizedViewport ? context.getRenderTarget().getHeight() : 128)
53 {
54 }
55 
~FboTestCase(void)56 FboTestCase::~FboTestCase (void)
57 {
58 }
59 
iterate(void)60 FboTestCase::IterateResult FboTestCase::iterate (void)
61 {
62 	glu::RenderContext&			renderCtx		= TestCase::m_context.getRenderContext();
63 	const tcu::RenderTarget&	renderTarget	= renderCtx.getRenderTarget();
64 	TestLog&					log				= m_testCtx.getLog();
65 
66 	// Viewport.
67 	de::Random					rnd				(deStringHash(getName()));
68 	int							width			= deMin32(renderTarget.getWidth(),	m_viewportWidth);
69 	int							height			= deMin32(renderTarget.getHeight(),	m_viewportHeight);
70 	int							x				= rnd.getInt(0, renderTarget.getWidth()		- width);
71 	int							y				= rnd.getInt(0, renderTarget.getHeight()	- height);
72 
73 	// Surface format and storage is choosen by render().
74 	tcu::Surface				reference;
75 	tcu::Surface				result;
76 
77 	// Call preCheck() that can throw exception if some requirement is not met.
78 	preCheck();
79 
80 	log << TestLog::Message << "Rendering with GL driver" << TestLog::EndMessage;
81 
82 	// Render using GLES3.1
83 	try
84 	{
85 		sglr::GLContext context(renderCtx, log, 0, tcu::IVec4(x, y, width, height));
86 		setContext(&context);
87 		render(result);
88 
89 		// Check error.
90 		deUint32 err = glGetError();
91 		if (err != GL_NO_ERROR)
92 			throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), DE_NULL, __FILE__, __LINE__);
93 
94 		setContext(DE_NULL);
95 	}
96 	catch (const FboTestUtil::FboIncompleteException& e)
97 	{
98 		if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
99 		{
100 			log << e;
101 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
102 			return STOP;
103 		}
104 		else
105 			throw;
106 	}
107 
108 	log << TestLog::Message << "Rendering reference image" << TestLog::EndMessage;
109 
110 	// Render reference.
111 	{
112 		sglr::ReferenceContextBuffers	buffers	(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
113 		sglr::ReferenceContext			context	(sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
114 
115 		setContext(&context);
116 		render(reference);
117 		setContext(DE_NULL);
118 	}
119 
120 	bool isOk = compare(reference, result);
121 	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
122 							isOk ? "Pass"				: "Image comparison failed");
123 	return STOP;
124 }
125 
compare(const tcu::Surface & reference,const tcu::Surface & result)126 bool FboTestCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
127 {
128 	return tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, 0.05f, tcu::COMPARE_LOG_RESULT);
129 }
130 
readPixels(tcu::Surface & dst,int x,int y,int width,int height,const tcu::TextureFormat & format,const tcu::Vec4 & scale,const tcu::Vec4 & bias)131 void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height, const tcu::TextureFormat& format, const tcu::Vec4& scale, const tcu::Vec4& bias)
132 {
133 	FboTestUtil::readPixels(*getCurrentContext(), dst, x, y, width, height, format, scale, bias);
134 }
135 
readPixels(tcu::Surface & dst,int x,int y,int width,int height)136 void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
137 {
138 	getCurrentContext()->readPixels(dst, x, y, width, height);
139 }
140 
checkFramebufferStatus(deUint32 target)141 void FboTestCase::checkFramebufferStatus (deUint32 target)
142 {
143 	deUint32 status = glCheckFramebufferStatus(target);
144 	if (status != GL_FRAMEBUFFER_COMPLETE)
145 		throw FboTestUtil::FboIncompleteException(status, __FILE__, __LINE__);
146 }
147 
checkError(void)148 void FboTestCase::checkError (void)
149 {
150 	deUint32 err = glGetError();
151 	if (err != GL_NO_ERROR)
152 		throw glu::Error((int)err, (string("Got ") + glu::getErrorStr(err).toString()).c_str(), DE_NULL, __FILE__, __LINE__);
153 }
154 
isRequiredFormat(deUint32 format,glu::RenderContext & renderContext)155 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
156 {
157 	const bool supportsES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
158 	switch (format)
159 	{
160 		// Color-renderable formats
161 		case GL_RGBA32I:
162 		case GL_RGBA32UI:
163 		case GL_RGBA16I:
164 		case GL_RGBA16UI:
165 		case GL_RGBA8:
166 		case GL_RGBA8I:
167 		case GL_RGBA8UI:
168 		case GL_SRGB8_ALPHA8:
169 		case GL_RGB10_A2:
170 		case GL_RGB10_A2UI:
171 		case GL_RGBA4:
172 		case GL_RGB5_A1:
173 		case GL_RGB8:
174 		case GL_RGB565:
175 		case GL_RG32I:
176 		case GL_RG32UI:
177 		case GL_RG16I:
178 		case GL_RG16UI:
179 		case GL_RG8:
180 		case GL_RG8I:
181 		case GL_RG8UI:
182 		case GL_R32I:
183 		case GL_R32UI:
184 		case GL_R16I:
185 		case GL_R16UI:
186 		case GL_R8:
187 		case GL_R8I:
188 		case GL_R8UI:
189 			return true;
190 
191 		// Depth formats
192 		case GL_DEPTH_COMPONENT32F:
193 		case GL_DEPTH_COMPONENT24:
194 		case GL_DEPTH_COMPONENT16:
195 			return true;
196 
197 		// Depth+stencil formats
198 		case GL_DEPTH32F_STENCIL8:
199 		case GL_DEPTH24_STENCIL8:
200 			return true;
201 
202 		// Stencil formats
203 		case GL_STENCIL_INDEX8:
204 			return true;
205 
206 		// Float format
207 		case GL_RGBA32F:
208 		case GL_R11F_G11F_B10F:
209 		case GL_RG32F:
210 		case GL_R32F:
211 		case GL_RGBA16F:
212 		case GL_RG16F:
213 		case GL_R16F:
214 			return supportsES32;
215 
216 		default:
217 			return false;
218 	}
219 }
220 
getEnablingExtensions(deUint32 format,glu::RenderContext & renderContext)221 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
222 {
223 	const bool					supportsES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
224 	std::vector<std::string>	out;
225 
226 	DE_ASSERT(!isRequiredFormat(format, renderContext));
227 
228 	switch (format)
229 	{
230 		case GL_RGB16F:
231 			out.push_back("GL_EXT_color_buffer_half_float");
232 			break;
233 
234 		case GL_RGB32F:
235 			out.push_back("GL_EXT_color_buffer_float");
236 			break;
237 
238 		case GL_RGBA16F:
239 		case GL_RG16F:
240 		case GL_R16F:
241 			if (!supportsES32)
242 				out.push_back("GL_EXT_color_buffer_half_float");
243 			break;
244 
245 		case GL_RGBA32F:
246 		case GL_R11F_G11F_B10F:
247 		case GL_RG32F:
248 		case GL_R32F:
249 			if (!supportsES32)
250 				out.push_back("GL_EXT_color_buffer_float");
251 			break;
252 
253 		default:
254 			break;
255 	}
256 
257 	return out;
258 }
259 
isAnyExtensionSupported(Context & context,const std::vector<std::string> & requiredExts)260 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
261 {
262 	for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
263 	{
264 		const std::string& extension = *iter;
265 
266 		if (context.getContextInfo().isExtensionSupported(extension.c_str()))
267 			return true;
268 	}
269 
270 	return false;
271 }
272 
checkFormatSupport(deUint32 sizedFormat)273 void FboTestCase::checkFormatSupport (deUint32 sizedFormat)
274 {
275 	const bool						isCoreFormat	= isRequiredFormat(sizedFormat, m_context.getRenderContext());
276 	const std::vector<std::string>	requiredExts	= (!isCoreFormat) ? getEnablingExtensions(sizedFormat, m_context.getRenderContext()) : std::vector<std::string>();
277 
278 	// Check that we don't try to use invalid formats.
279 	DE_ASSERT(isCoreFormat || !requiredExts.empty());
280 
281 	if (!requiredExts.empty() && !isAnyExtensionSupported(m_context, requiredExts))
282 		throw tcu::NotSupportedError("Format not supported");
283 }
284 
getMinimumSampleCount(deUint32 format)285 static int getMinimumSampleCount (deUint32 format)
286 {
287 	switch (format)
288 	{
289 		// Core formats
290 		case GL_RGBA32I:
291 		case GL_RGBA32UI:
292 		case GL_RGBA16I:
293 		case GL_RGBA16UI:
294 		case GL_RGBA8:
295 		case GL_RGBA8I:
296 		case GL_RGBA8UI:
297 		case GL_SRGB8_ALPHA8:
298 		case GL_RGB10_A2:
299 		case GL_RGB10_A2UI:
300 		case GL_RGBA4:
301 		case GL_RGB5_A1:
302 		case GL_RGB8:
303 		case GL_RGB565:
304 		case GL_RG32I:
305 		case GL_RG32UI:
306 		case GL_RG16I:
307 		case GL_RG16UI:
308 		case GL_RG8:
309 		case GL_RG8I:
310 		case GL_RG8UI:
311 		case GL_R32I:
312 		case GL_R32UI:
313 		case GL_R16I:
314 		case GL_R16UI:
315 		case GL_R8:
316 		case GL_R8I:
317 		case GL_R8UI:
318 		case GL_DEPTH_COMPONENT32F:
319 		case GL_DEPTH_COMPONENT24:
320 		case GL_DEPTH_COMPONENT16:
321 		case GL_DEPTH32F_STENCIL8:
322 		case GL_DEPTH24_STENCIL8:
323 		case GL_STENCIL_INDEX8:
324 			return 4;
325 
326 		// GL_EXT_color_buffer_float
327 		case GL_R11F_G11F_B10F:
328 		case GL_RG16F:
329 		case GL_R16F:
330 			return 4;
331 
332 		case GL_RGBA32F:
333 		case GL_RGBA16F:
334 		case GL_RG32F:
335 		case GL_R32F:
336 			return 0;
337 
338 		// GL_EXT_color_buffer_half_float
339 		case GL_RGB16F:
340 			return 0;
341 
342 		default:
343 			DE_FATAL("Unknown format");
344 			return 0;
345 	}
346 }
347 
querySampleCounts(const glw::Functions & gl,deUint32 format)348 static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format)
349 {
350 	int					numSampleCounts		= 0;
351 	std::vector<int>	sampleCounts;
352 
353 	gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
354 
355 	if (numSampleCounts > 0)
356 	{
357 		sampleCounts.resize(numSampleCounts);
358 		gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]);
359 	}
360 
361 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format");
362 
363 	return sampleCounts;
364 }
365 
checkSampleCount(deUint32 sizedFormat,int numSamples)366 void FboTestCase::checkSampleCount (deUint32 sizedFormat, int numSamples)
367 {
368 	const int minSampleCount = getMinimumSampleCount(sizedFormat);
369 
370 	if (numSamples > minSampleCount)
371 	{
372 		// Exceeds spec-mandated minimum - need to check.
373 		const std::vector<int> supportedSampleCounts = querySampleCounts(m_context.getRenderContext().getFunctions(), sizedFormat);
374 
375 		if (std::find(supportedSampleCounts.begin(), supportedSampleCounts.end(), numSamples) == supportedSampleCounts.end())
376 			throw tcu::NotSupportedError("Sample count not supported");
377 	}
378 }
379 
clearColorBuffer(const tcu::TextureFormat & format,const tcu::Vec4 & value)380 void FboTestCase::clearColorBuffer (const tcu::TextureFormat& format, const tcu::Vec4& value)
381 {
382 	FboTestUtil::clearColorBuffer(*getCurrentContext(), format, value);
383 }
384 
385 } // Functional
386 } // gles31
387 } // deqp
388