Home | History | Annotate | Download | only in functional
      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 Base class for FBO tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fFboTestCase.hpp"
     25 #include "es3fFboTestUtil.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 gles3
     42 {
     43 namespace Functional
     44 {
     45 
     46 using tcu::TestLog;
     47 using std::string;
     48 
     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 
     56 FboTestCase::~FboTestCase (void)
     57 {
     58 }
     59 
     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 	// Render using GLES3.
     81 	try
     82 	{
     83 		sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
     84 		setContext(&context);
     85 		render(result);
     86 
     87 		// Check error.
     88 		deUint32 err = glGetError();
     89 		if (err != GL_NO_ERROR)
     90 			throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), DE_NULL, __FILE__, __LINE__);
     91 
     92 		setContext(DE_NULL);
     93 	}
     94 	catch (const FboTestUtil::FboIncompleteException& e)
     95 	{
     96 		if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
     97 		{
     98 			log << e;
     99 			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
    100 			return STOP;
    101 		}
    102 		else
    103 			throw;
    104 	}
    105 
    106 	// Render reference.
    107 	{
    108 		sglr::ReferenceContextBuffers	buffers	(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height);
    109 		sglr::ReferenceContext			context	(sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());
    110 
    111 		setContext(&context);
    112 		render(reference);
    113 		setContext(DE_NULL);
    114 	}
    115 
    116 	bool isOk = compare(reference, result);
    117 	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    118 							isOk ? "Pass"				: "Image comparison failed");
    119 	return STOP;
    120 }
    121 
    122 bool FboTestCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
    123 {
    124 	return tcu::fuzzyCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference, result, 0.05f, tcu::COMPARE_LOG_RESULT);
    125 }
    126 
    127 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)
    128 {
    129 	FboTestUtil::readPixels(*getCurrentContext(), dst, x, y, width, height, format, scale, bias);
    130 }
    131 
    132 void FboTestCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
    133 {
    134 	getCurrentContext()->readPixels(dst, x, y, width, height);
    135 }
    136 
    137 void FboTestCase::checkFramebufferStatus (deUint32 target)
    138 {
    139 	deUint32 status = glCheckFramebufferStatus(target);
    140 	if (status != GL_FRAMEBUFFER_COMPLETE)
    141 		throw FboTestUtil::FboIncompleteException(status, __FILE__, __LINE__);
    142 }
    143 
    144 void FboTestCase::checkError (void)
    145 {
    146 	deUint32 err = glGetError();
    147 	if (err != GL_NO_ERROR)
    148 		throw glu::Error((int)err, (string("Got ") + glu::getErrorStr(err).toString()).c_str(), DE_NULL, __FILE__, __LINE__);
    149 }
    150 
    151 static bool isRequiredFormat (deUint32 format)
    152 {
    153 	switch (format)
    154 	{
    155 		// Color-renderable formats
    156 		case GL_RGBA32I:
    157 		case GL_RGBA32UI:
    158 		case GL_RGBA16I:
    159 		case GL_RGBA16UI:
    160 		case GL_RGBA8:
    161 		case GL_RGBA8I:
    162 		case GL_RGBA8UI:
    163 		case GL_SRGB8_ALPHA8:
    164 		case GL_RGB10_A2:
    165 		case GL_RGB10_A2UI:
    166 		case GL_RGBA4:
    167 		case GL_RGB5_A1:
    168 		case GL_RGB8:
    169 		case GL_RGB565:
    170 		case GL_RG32I:
    171 		case GL_RG32UI:
    172 		case GL_RG16I:
    173 		case GL_RG16UI:
    174 		case GL_RG8:
    175 		case GL_RG8I:
    176 		case GL_RG8UI:
    177 		case GL_R32I:
    178 		case GL_R32UI:
    179 		case GL_R16I:
    180 		case GL_R16UI:
    181 		case GL_R8:
    182 		case GL_R8I:
    183 		case GL_R8UI:
    184 			return true;
    185 
    186 		// Depth formats
    187 		case GL_DEPTH_COMPONENT32F:
    188 		case GL_DEPTH_COMPONENT24:
    189 		case GL_DEPTH_COMPONENT16:
    190 			return true;
    191 
    192 		// Depth+stencil formats
    193 		case GL_DEPTH32F_STENCIL8:
    194 		case GL_DEPTH24_STENCIL8:
    195 			return true;
    196 
    197 		// Stencil formats
    198 		case GL_STENCIL_INDEX8:
    199 			return true;
    200 
    201 		default:
    202 			return false;
    203 	}
    204 }
    205 
    206 static std::vector<std::string> getEnablingExtensions (deUint32 format)
    207 {
    208 	std::vector<std::string> out;
    209 
    210 	DE_ASSERT(!isRequiredFormat(format));
    211 
    212 	switch (format)
    213 	{
    214 		case GL_RGB16F:
    215 			out.push_back("GL_EXT_color_buffer_half_float");
    216 			break;
    217 
    218 		case GL_RGBA16F:
    219 		case GL_RG16F:
    220 		case GL_R16F:
    221 			out.push_back("GL_EXT_color_buffer_half_float");
    222 
    223 		case GL_RGBA32F:
    224 		case GL_RGB32F:
    225 		case GL_R11F_G11F_B10F:
    226 		case GL_RG32F:
    227 		case GL_R32F:
    228 			out.push_back("GL_EXT_color_buffer_float");
    229 
    230 		default:
    231 			break;
    232 	}
    233 
    234 	return out;
    235 }
    236 
    237 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
    238 {
    239 	for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
    240 	{
    241 		const std::string& extension = *iter;
    242 
    243 		if (context.getContextInfo().isExtensionSupported(extension.c_str()))
    244 			return true;
    245 	}
    246 
    247 	return false;
    248 }
    249 
    250 void FboTestCase::checkFormatSupport (deUint32 sizedFormat)
    251 {
    252 	const bool						isCoreFormat	= isRequiredFormat(sizedFormat);
    253 	const std::vector<std::string>	requiredExts	= (!isCoreFormat) ? getEnablingExtensions(sizedFormat) : std::vector<std::string>();
    254 
    255 	// Check that we don't try to use invalid formats.
    256 	DE_ASSERT(isCoreFormat || !requiredExts.empty());
    257 
    258 	if (!requiredExts.empty() && !isAnyExtensionSupported(m_context, requiredExts))
    259 		throw tcu::NotSupportedError("Format not supported");
    260 }
    261 
    262 static int getMinimumSampleCount (deUint32 format)
    263 {
    264 	switch (format)
    265 	{
    266 		// Core formats
    267 		case GL_RGBA32I:
    268 		case GL_RGBA32UI:
    269 		case GL_RGBA16I:
    270 		case GL_RGBA16UI:
    271 		case GL_RGBA8:
    272 		case GL_RGBA8I:
    273 		case GL_RGBA8UI:
    274 		case GL_SRGB8_ALPHA8:
    275 		case GL_RGB10_A2:
    276 		case GL_RGB10_A2UI:
    277 		case GL_RGBA4:
    278 		case GL_RGB5_A1:
    279 		case GL_RGB8:
    280 		case GL_RGB565:
    281 		case GL_RG32I:
    282 		case GL_RG32UI:
    283 		case GL_RG16I:
    284 		case GL_RG16UI:
    285 		case GL_RG8:
    286 		case GL_RG8I:
    287 		case GL_RG8UI:
    288 		case GL_R32I:
    289 		case GL_R32UI:
    290 		case GL_R16I:
    291 		case GL_R16UI:
    292 		case GL_R8:
    293 		case GL_R8I:
    294 		case GL_R8UI:
    295 		case GL_DEPTH_COMPONENT32F:
    296 		case GL_DEPTH_COMPONENT24:
    297 		case GL_DEPTH_COMPONENT16:
    298 		case GL_DEPTH32F_STENCIL8:
    299 		case GL_DEPTH24_STENCIL8:
    300 		case GL_STENCIL_INDEX8:
    301 			return 4;
    302 
    303 		// GL_EXT_color_buffer_float
    304 		case GL_R11F_G11F_B10F:
    305 		case GL_RG16F:
    306 		case GL_R16F:
    307 			return 4;
    308 
    309 		case GL_RGBA32F:
    310 		case GL_RGBA16F:
    311 		case GL_RG32F:
    312 		case GL_R32F:
    313 			return 0;
    314 
    315 		// GL_EXT_color_buffer_half_float
    316 		case GL_RGB16F:
    317 			return 0;
    318 
    319 		default:
    320 			DE_ASSERT(!"Unknown format");
    321 			return 0;
    322 	}
    323 }
    324 
    325 static std::vector<int> querySampleCounts (const glw::Functions& gl, deUint32 format)
    326 {
    327 	int					numSampleCounts		= 0;
    328 	std::vector<int>	sampleCounts;
    329 
    330 	gl.getInternalformativ(GL_RENDERBUFFER, format, GL_NUM_SAMPLE_COUNTS, 1, &numSampleCounts);
    331 
    332 	if (numSampleCounts > 0)
    333 	{
    334 		sampleCounts.resize(numSampleCounts);
    335 		gl.getInternalformativ(GL_RENDERBUFFER, format, GL_SAMPLES, (glw::GLsizei)sampleCounts.size(), &sampleCounts[0]);
    336 	}
    337 
    338 	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to query sample counts for format");
    339 
    340 	return sampleCounts;
    341 }
    342 
    343 void FboTestCase::checkSampleCount (deUint32 sizedFormat, int numSamples)
    344 {
    345 	const int minSampleCount = getMinimumSampleCount(sizedFormat);
    346 
    347 	if (numSamples > minSampleCount)
    348 	{
    349 		// Exceeds spec-mandated minimum - need to check.
    350 		const std::vector<int> supportedSampleCounts = querySampleCounts(m_context.getRenderContext().getFunctions(), sizedFormat);
    351 
    352 		if (std::find(supportedSampleCounts.begin(), supportedSampleCounts.end(), numSamples) == supportedSampleCounts.end())
    353 			throw tcu::NotSupportedError("Sample count not supported");
    354 	}
    355 }
    356 
    357 void FboTestCase::clearColorBuffer (const tcu::TextureFormat& format, const tcu::Vec4& value)
    358 {
    359 	FboTestUtil::clearColorBuffer(*getCurrentContext(), format, value);
    360 }
    361 
    362 } // Functional
    363 } // gles3
    364 } // deqp
    365