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 static const FormatExtEntry s_es2ExtFormats[] =
    106 {
    107 	// The extension does not specify these to be color-renderable.
    108 	{
    109 		"GL_OES_texture_float",
    110 		TEXTURE_VALID,
    111 		GLS_ARRAY_RANGE(s_oesTextureFloatFormats)
    112 	},
    113 	{
    114 		"GL_OES_texture_half_float",
    115 		TEXTURE_VALID,
    116 		GLS_ARRAY_RANGE(s_oesTextureHalfFloatFormats)
    117 	},
    118 
    119 	// GL_EXT_sRGB_write_control makes SRGB8_ALPHA8 color-renderable
    120 	{
    121 		"GL_EXT_sRGB_write_control",
    122 		REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID,
    123 		GLS_ARRAY_RANGE(s_extSrgbWriteControlFormats)
    124 	},
    125 };
    126 
    127 class ES2Checker : public Checker
    128 {
    129 public:
    130 			ES2Checker				(void) : m_width(-1), m_height(-1) {}
    131 	void	check					(GLenum attPoint, const Attachment& att,
    132 									 const Image* image);
    133 private:
    134 	GLsizei	m_width;	//< The common width of images
    135 	GLsizei	m_height;	//< The common height of images
    136 };
    137 
    138 void ES2Checker::check(GLenum attPoint, const Attachment& att, const Image* image)
    139 {
    140 	DE_UNREF(attPoint);
    141 	DE_UNREF(att);
    142 	// GLES2: "All attached images have the same width and height."
    143 	if (m_width == -1)
    144 	{
    145 		m_width = image->width;
    146 		m_height = image->height;
    147 	}
    148 	else
    149 	{
    150 		require(image->width == m_width && image->height == m_height,
    151 				GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
    152 	}
    153 	// GLES2, 4.4.5: "some implementations may not support rendering to
    154 	// particular combinations of internal formats. If the combination of
    155 	// formats of the images attached to a framebuffer object are not
    156 	// supported by the implementation, then the framebuffer is not complete
    157 	// under the clause labeled FRAMEBUFFER_UNSUPPORTED."
    158 	//
    159 	// Hence it is _always_ allowed to report FRAMEBUFFER_UNSUPPORTED.
    160 	canRequire(false, GL_FRAMEBUFFER_UNSUPPORTED);
    161 }
    162 
    163 struct FormatCombination
    164 {
    165 	GLenum			colorKind;
    166 	ImageFormat		colorFmt;
    167 	GLenum			depthKind;
    168 	ImageFormat		depthFmt;
    169 	GLenum			stencilKind;
    170 	ImageFormat		stencilFmt;
    171 };
    172 
    173 class SupportedCombinationTest : public fboc::TestBase
    174 {
    175 public:
    176 					SupportedCombinationTest	(fboc::Context& ctx,
    177 												 const char* name, const char* desc)
    178 						: TestBase		(ctx, name, desc) {}
    179 
    180 	IterateResult	iterate						(void);
    181 	bool			tryCombination				(const FormatCombination& comb);
    182 	GLenum			formatKind					(ImageFormat fmt);
    183 };
    184 
    185 bool SupportedCombinationTest::tryCombination (const FormatCombination& comb)
    186 {
    187 	glu::Framebuffer fbo(m_ctx.getRenderContext());
    188 	FboBuilder builder(*fbo, GL_FRAMEBUFFER, fboc::gl(*this));
    189 
    190 	attachTargetToNew(GL_COLOR_ATTACHMENT0,		comb.colorKind,		comb.colorFmt,
    191 					  64, 						64,					builder);
    192 	attachTargetToNew(GL_DEPTH_ATTACHMENT,		comb.depthKind,		comb.depthFmt,
    193 					  64,						64,					builder);
    194 	attachTargetToNew(GL_STENCIL_ATTACHMENT,	comb.stencilKind,	comb.stencilFmt,
    195 					  64,						64,					builder);
    196 
    197 	const GLenum glStatus = fboc::gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER);
    198 
    199 	return (glStatus == GL_FRAMEBUFFER_COMPLETE);
    200 }
    201 
    202 GLenum SupportedCombinationTest::formatKind (ImageFormat fmt)
    203 {
    204 	if (fmt.format == GL_NONE)
    205 		return GL_NONE;
    206 
    207 	const FormatFlags flags = m_ctx.getMinFormats().getFormatInfo(fmt, ANY_FORMAT);
    208 	const bool rbo = (flags & RENDERBUFFER_VALID) != 0;
    209 	// exactly one of renderbuffer and texture is supported by vanilla GLES2 formats
    210 	DE_ASSERT(rbo != ((flags & TEXTURE_VALID) != 0));
    211 
    212 	return rbo ? GL_RENDERBUFFER : GL_TEXTURE;
    213 }
    214 
    215 IterateResult SupportedCombinationTest::iterate (void)
    216 {
    217 	const FormatDB& db		= m_ctx.getMinFormats();
    218 	const ImageFormat none	= ImageFormat::none();
    219 	Formats colorFmts		= db.getFormats(COLOR_RENDERABLE);
    220 	Formats depthFmts		= db.getFormats(DEPTH_RENDERABLE);
    221 	Formats stencilFmts		= db.getFormats(STENCIL_RENDERABLE);
    222 	FormatCombination comb;
    223 	bool succ = false;
    224 
    225 	colorFmts.insert(none);
    226 	depthFmts.insert(none);
    227 	stencilFmts.insert(none);
    228 
    229 	for (Formats::const_iterator col = colorFmts.begin(); col != colorFmts.end(); col++)
    230 	{
    231 		comb.colorFmt = *col;
    232 		comb.colorKind = formatKind(*col);
    233 		for (Formats::const_iterator dep = depthFmts.begin(); dep != depthFmts.end(); dep++)
    234 		{
    235 			comb.depthFmt = *dep;
    236 			comb.depthKind = formatKind(*dep);
    237 			for (Formats::const_iterator stc = stencilFmts.begin();
    238 				 stc != stencilFmts.end(); stc++)
    239 			{
    240 				comb.stencilFmt = *stc;
    241 				comb.stencilKind = formatKind(*stc);
    242 				succ = tryCombination(comb);
    243 				if (succ)
    244 					break;
    245 			}
    246 		}
    247 	}
    248 
    249 	if (succ)
    250 		pass();
    251 	else
    252 		fail("No supported format combination found");
    253 
    254 	return STOP;
    255 }
    256 
    257 class ES2CheckerFactory : public CheckerFactory {
    258 public:
    259 	Checker*			createChecker	(void) { return new ES2Checker(); }
    260 };
    261 
    262 class TestGroup : public TestCaseGroup
    263 {
    264 public:
    265 						TestGroup		(Context& ctx);
    266 	void				init			(void);
    267 private:
    268 	ES2CheckerFactory	m_checkerFactory;
    269 	fboc::Context		m_fboc;
    270 };
    271 
    272 TestGroup::TestGroup (Context& ctx)
    273 	: TestCaseGroup		(ctx, "completeness", "Completeness tests")
    274 	, m_checkerFactory	()
    275 	, m_fboc			(ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory)
    276 {
    277 	const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es2Formats);
    278 	const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es2ExtFormats);
    279 
    280 	m_fboc.addFormats(stdRange);
    281 	m_fboc.addExtFormats(extRange);
    282 	m_fboc.setHaveMulticolorAtts(
    283 		ctx.getContextInfo().isExtensionSupported("GL_NV_fbo_color_attachments"));
    284 }
    285 
    286 void TestGroup::init (void)
    287 {
    288 	tcu::TestCaseGroup* attCombTests = m_fboc.createAttachmentTests();
    289 	addChild(m_fboc.createRenderableTests());
    290 	attCombTests->addChild(new SupportedCombinationTest(
    291 							   m_fboc,
    292 							   "exists_supported",
    293 							   "Test for existence of a supported combination of formats"));
    294 	addChild(attCombTests);
    295 	addChild(m_fboc.createSizeTests());
    296 }
    297 
    298 tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
    299 {
    300 	return new TestGroup(context);
    301 }
    302 
    303 } // Functional
    304 } // gles2
    305 } // deqp
    306