Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL (ES) 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 Framebuffer completeness tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es2fFboCompletenessTests.hpp"
     25 
     26 #include "glsFboCompletenessTests.hpp"
     27 #include "gluObjectWrapper.hpp"
     28 
     29 using namespace glw;
     30 using deqp::gls::Range;
     31 using namespace deqp::gls::FboUtil;
     32 using namespace deqp::gls::FboUtil::config;
     33 namespace fboc = deqp::gls::fboc;
     34 typedef tcu::TestCase::IterateResult IterateResult;
     35 
     36 namespace deqp
     37 {
     38 namespace gles2
     39 {
     40 namespace Functional
     41 {
     42 
     43 static const FormatKey s_es2ColorRenderables[] =
     44 {
     45 	GL_RGBA4, GL_RGB5_A1, GL_RGB565,
     46 };
     47 
     48 // GLES2 does not strictly allow these, but this seems to be a bug in the
     49 // specification. For now, let's assume the unsized formats corresponding to
     50 // the color-renderable sized formats are allowed.
     51 // See https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7333
     52 
     53 static const FormatKey s_es2UnsizedColorRenderables[] =
     54 {
     55 	GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4),
     56 	GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1),
     57 	GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_SHORT_5_6_5)
     58 };
     59 
     60 static const FormatKey s_es2DepthRenderables[] =
     61 {
     62 	GL_DEPTH_COMPONENT16,
     63 };
     64 
     65 static const FormatKey s_es2StencilRenderables[] =
     66 {
     67 	GL_STENCIL_INDEX8,
     68 };
     69 
     70 static const FormatEntry s_es2Formats[] =
     71 {
     72 	{ COLOR_RENDERABLE | TEXTURE_VALID,
     73 	  GLS_ARRAY_RANGE(s_es2UnsizedColorRenderables) },
     74 	{ REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
     75 	  GLS_ARRAY_RANGE(s_es2ColorRenderables) },
     76 	{ REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID,
     77 	  GLS_ARRAY_RANGE(s_es2DepthRenderables) },
     78 	{ REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID,
     79 	  GLS_ARRAY_RANGE(s_es2StencilRenderables) },
     80 };
     81 
     82 // We have here only the extensions that are redundant in vanilla GLES3. Those
     83 // that are applicable both to GLES2 and GLES3 are in glsFboCompletenessTests.cpp.
     84 
     85 // GL_OES_texture_float
     86 static const FormatKey s_oesTextureFloatFormats[] =
     87 {
     88 	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_FLOAT),
     89 	GLS_UNSIZED_FORMATKEY(GL_RGB,	GL_FLOAT),
     90 };
     91 
     92 // GL_OES_texture_half_float
     93 static const FormatKey s_oesTextureHalfFloatFormats[] =
     94 {
     95 	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_HALF_FLOAT_OES),
     96 	GLS_UNSIZED_FORMATKEY(GL_RGB,	GL_HALF_FLOAT_OES),
     97 };
     98 
     99 // GL_EXT_sRGB_write_control
    100 static const FormatKey s_extSrgbWriteControlFormats[] =
    101 {
    102 	GL_SRGB8_ALPHA8
    103 };
    104 
    105 // DEQP_gles3_core_no_extension_features
    106 static const FormatKey s_es3NoExtRboFormats[] =
    107 {
    108 	GL_RGB10_A2,
    109 };
    110 static const FormatKey s_es3NoExtTextureFormats[] =
    111 {
    112 	GL_R16F,
    113 	GL_RG16F,
    114 	GL_RGB16F,
    115 	GL_RGBA16F,
    116 	GL_R11F_G11F_B10F,
    117 };
    118 static const FormatKey s_es3NoExtTextureColorRenderableFormats[] =
    119 {
    120 	GL_R8,
    121 	GL_RG8,
    122 };
    123 
    124 // with ES3 core and GL_EXT_color_buffer_float
    125 static const FormatKey s_es3NoExtExtColorBufferFloatFormats[] =
    126 {
    127 	// \note Only the GLES2+exts subset of formats
    128 	GL_R11F_G11F_B10F, GL_RGBA16F, GL_RG16F, GL_R16F,
    129 };
    130 
    131 // with ES3 core with OES_texture_stencil8
    132 static const FormatKey s_es3NoExtOesTextureStencil8Formats[] =
    133 {
    134 	GL_STENCIL_INDEX8,
    135 };
    136 
    137 static const FormatExtEntry s_es2ExtFormats[] =
    138 {
    139 	// The extension does not specify these to be color-renderable.
    140 	{
    141 		"GL_OES_texture_float",
    142 		(deUint32)TEXTURE_VALID,
    143 		GLS_ARRAY_RANGE(s_oesTextureFloatFormats)
    144 	},
    145 	{
    146 		"GL_OES_texture_half_float",
    147 		(deUint32)TEXTURE_VALID,
    148 		GLS_ARRAY_RANGE(s_oesTextureHalfFloatFormats)
    149 	},
    150 
    151 	// GL_EXT_sRGB_write_control makes SRGB8_ALPHA8 color-renderable
    152 	{
    153 		"GL_EXT_sRGB_write_control",
    154 		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID),
    155 		GLS_ARRAY_RANGE(s_extSrgbWriteControlFormats)
    156 	},
    157 
    158 	// Since GLES3 is "backwards compatible" to GLES2, we might actually be running on a GLES3
    159 	// context. Since GLES3 added some features to core with no corresponding GLES2 extension,
    160 	// some tests might produce wrong results (since they are using rules of GLES2 & extensions)
    161 	//
    162 	// To avoid this, require new features of GLES3 that have no matching GLES2 extension if
    163 	// context is GLES3. This can be done with a DEQP_* extensions.
    164 	//
    165 	// \note Not all feature changes are listed here but only those that alter GLES2 subset of
    166 	//       the formats
    167 	{
    168 		"DEQP_gles3_core_compatible",
    169 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
    170 		GLS_ARRAY_RANGE(s_es3NoExtRboFormats)
    171 	},
    172 	{
    173 		"DEQP_gles3_core_compatible",
    174 		(deUint32)TEXTURE_VALID,
    175 		GLS_ARRAY_RANGE(s_es3NoExtTextureFormats)
    176 	},
    177 	{
    178 		"DEQP_gles3_core_compatible",
    179 		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID),
    180 		GLS_ARRAY_RANGE(s_es3NoExtTextureColorRenderableFormats)
    181 	},
    182 	{
    183 		"DEQP_gles3_core_compatible GL_EXT_color_buffer_float",
    184 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
    185 		GLS_ARRAY_RANGE(s_es3NoExtExtColorBufferFloatFormats)
    186 	},
    187 	{
    188 		"DEQP_gles3_core_compatible GL_OES_texture_stencil8",
    189 		(deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID),
    190 		GLS_ARRAY_RANGE(s_es3NoExtOesTextureStencil8Formats)
    191 	},
    192 };
    193 
    194 class ES2Checker : public Checker
    195 {
    196 public:
    197 			ES2Checker				(const glu::RenderContext& ctx);
    198 	void	check					(GLenum attPoint, const Attachment& att,
    199 									 const Image* image);
    200 private:
    201 	GLsizei	m_width;	//< The common width of images
    202 	GLsizei	m_height;	//< The common height of images
    203 };
    204 
    205 ES2Checker::ES2Checker (const glu::RenderContext& ctx)\
    206 	: Checker		(ctx)
    207 	, m_width		(-1)
    208 	, m_height		(-1)
    209 {
    210 }
    211 
    212 void ES2Checker::check (GLenum attPoint, const Attachment& att, const Image* image)
    213 {
    214 	DE_UNREF(attPoint);
    215 	DE_UNREF(att);
    216 	// GLES2: "All attached images have the same width and height."
    217 	if (m_width == -1)
    218 	{
    219 		m_width = image->width;
    220 		m_height = image->height;
    221 	}
    222 	else if (image->width != m_width || image->height != m_height)
    223 	{
    224 		// Since GLES3 is "backwards compatible" to GLES2, we might actually be running
    225 		// on a GLES3 context. On GLES3, FRAMEBUFFER_INCOMPLETE_DIMENSIONS is not generated
    226 		// if attachments have different sizes.
    227 		if (!gls::FboUtil::checkExtensionSupport(m_renderCtx, "DEQP_gles3_core_compatible"))
    228 		{
    229 			// running on GLES2
    230 			addFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "Sizes of attachments differ");
    231 		}
    232 	}
    233 	// GLES2, 4.4.5: "some implementations may not support rendering to
    234 	// particular combinations of internal formats. If the combination of
    235 	// formats of the images attached to a framebuffer object are not
    236 	// supported by the implementation, then the framebuffer is not complete
    237 	// under the clause labeled FRAMEBUFFER_UNSUPPORTED."
    238 	//
    239 	// Hence it is _always_ allowed to report FRAMEBUFFER_UNSUPPORTED.
    240 	addPotentialFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Particular format combinations need not to be supported");
    241 }
    242 
    243 struct FormatCombination
    244 {
    245 	GLenum			colorKind;
    246 	ImageFormat		colorFmt;
    247 	GLenum			depthKind;
    248 	ImageFormat		depthFmt;
    249 	GLenum			stencilKind;
    250 	ImageFormat		stencilFmt;
    251 };
    252 
    253 class SupportedCombinationTest : public fboc::TestBase
    254 {
    255 public:
    256 					SupportedCombinationTest	(fboc::Context& ctx,
    257 												 const char* name, const char* desc)
    258 						: TestBase		(ctx, name, desc) {}
    259 
    260 	IterateResult	iterate						(void);
    261 	bool			tryCombination				(const FormatCombination& comb);
    262 	GLenum			formatKind					(ImageFormat fmt);
    263 };
    264 
    265 bool SupportedCombinationTest::tryCombination (const FormatCombination& comb)
    266 {
    267 	glu::Framebuffer fbo(m_ctx.getRenderContext());
    268 	FboBuilder builder(*fbo, GL_FRAMEBUFFER, fboc::gl(*this));
    269 
    270 	attachTargetToNew(GL_COLOR_ATTACHMENT0,		comb.colorKind,		comb.colorFmt,
    271 					  64,						64,					builder);
    272 	attachTargetToNew(GL_DEPTH_ATTACHMENT,		comb.depthKind,		comb.depthFmt,
    273 					  64,						64,					builder);
    274 	attachTargetToNew(GL_STENCIL_ATTACHMENT,	comb.stencilKind,	comb.stencilFmt,
    275 					  64,						64,					builder);
    276 
    277 	const GLenum glStatus = fboc::gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER);
    278 
    279 	return (glStatus == GL_FRAMEBUFFER_COMPLETE);
    280 }
    281 
    282 GLenum SupportedCombinationTest::formatKind (ImageFormat fmt)
    283 {
    284 	if (fmt.format == GL_NONE)
    285 		return GL_NONE;
    286 
    287 	const FormatFlags flags = m_ctx.getCoreFormats().getFormatInfo(fmt);
    288 	const bool rbo = (flags & RENDERBUFFER_VALID) != 0;
    289 	// exactly one of renderbuffer and texture is supported by vanilla GLES2 formats
    290 	DE_ASSERT(rbo != ((flags & TEXTURE_VALID) != 0));
    291 
    292 	return rbo ? GL_RENDERBUFFER : GL_TEXTURE;
    293 }
    294 
    295 IterateResult SupportedCombinationTest::iterate (void)
    296 {
    297 	const FormatDB& db		= m_ctx.getCoreFormats();
    298 	const ImageFormat none	= ImageFormat::none();
    299 	Formats colorFmts		= db.getFormats(COLOR_RENDERABLE);
    300 	Formats depthFmts		= db.getFormats(DEPTH_RENDERABLE);
    301 	Formats stencilFmts		= db.getFormats(STENCIL_RENDERABLE);
    302 	FormatCombination comb;
    303 	bool succ = false;
    304 
    305 	colorFmts.insert(none);
    306 	depthFmts.insert(none);
    307 	stencilFmts.insert(none);
    308 
    309 	for (Formats::const_iterator col = colorFmts.begin(); col != colorFmts.end(); col++)
    310 	{
    311 		comb.colorFmt = *col;
    312 		comb.colorKind = formatKind(*col);
    313 		for (Formats::const_iterator dep = depthFmts.begin(); dep != depthFmts.end(); dep++)
    314 		{
    315 			comb.depthFmt = *dep;
    316 			comb.depthKind = formatKind(*dep);
    317 			for (Formats::const_iterator stc = stencilFmts.begin();
    318 				 stc != stencilFmts.end(); stc++)
    319 			{
    320 				comb.stencilFmt = *stc;
    321 				comb.stencilKind = formatKind(*stc);
    322 				succ = tryCombination(comb);
    323 				if (succ)
    324 					break;
    325 			}
    326 		}
    327 	}
    328 
    329 	if (succ)
    330 		pass();
    331 	else
    332 		fail("No supported format combination found");
    333 
    334 	return STOP;
    335 }
    336 
    337 class ES2CheckerFactory : public CheckerFactory
    338 {
    339 public:
    340 	Checker*			createChecker	(const glu::RenderContext& ctx) { return new ES2Checker(ctx); }
    341 };
    342 
    343 class TestGroup : public TestCaseGroup
    344 {
    345 public:
    346 						TestGroup		(Context& ctx);
    347 	void				init			(void);
    348 private:
    349 	ES2CheckerFactory	m_checkerFactory;
    350 	fboc::Context		m_fboc;
    351 };
    352 
    353 TestGroup::TestGroup (Context& ctx)
    354 	: TestCaseGroup		(ctx, "completeness", "Completeness tests")
    355 	, m_checkerFactory	()
    356 	, m_fboc			(ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory)
    357 {
    358 	const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es2Formats);
    359 	const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es2ExtFormats);
    360 
    361 	m_fboc.addFormats(stdRange);
    362 	m_fboc.addExtFormats(extRange);
    363 	m_fboc.setHaveMulticolorAtts(
    364 		ctx.getContextInfo().isExtensionSupported("GL_NV_fbo_color_attachments"));
    365 }
    366 
    367 void TestGroup::init (void)
    368 {
    369 	tcu::TestCaseGroup* attCombTests = m_fboc.createAttachmentTests();
    370 	addChild(m_fboc.createRenderableTests());
    371 	attCombTests->addChild(new SupportedCombinationTest(
    372 							   m_fboc,
    373 							   "exists_supported",
    374 							   "Test for existence of a supported combination of formats"));
    375 	addChild(attCombTests);
    376 	addChild(m_fboc.createSizeTests());
    377 }
    378 
    379 tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
    380 {
    381 	return new TestGroup(context);
    382 }
    383 
    384 } // Functional
    385 } // gles2
    386 } // deqp
    387