• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_color_buffer_half_float
100 static const FormatKey s_extColorBufferHalfFloatUnsized[] =
101 {
102 	GLS_UNSIZED_FORMATKEY(GL_RGBA,	GL_HALF_FLOAT_OES),
103 };
104 
105 // GL_EXT_sRGB_write_control
106 static const FormatKey s_extSrgbWriteControlFormats[] =
107 {
108 	GL_SRGB8_ALPHA8
109 };
110 
111 // DEQP_gles3_core_no_extension_features
112 static const FormatKey s_es3NoExtRboFormats[] =
113 {
114 	GL_RGB10_A2,
115 	GL_SRGB8_ALPHA8,
116 };
117 static const FormatKey s_es3NoExtTextureFormats[] =
118 {
119 	GL_R16F,
120 	GL_RG16F,
121 	GL_RGB16F,
122 	GL_RGBA16F,
123 	GL_R11F_G11F_B10F,
124 };
125 static const FormatKey s_es3NoExtTextureColorRenderableFormats[] =
126 {
127 	GL_R8,
128 	GL_RG8,
129 	GL_RGB8,
130 	GL_RGBA4,
131 	GL_RGB5_A1,
132 	GL_RGBA8,
133 	GL_RGB10_A2,
134 	GL_RGB565,
135 	GL_SRGB8_ALPHA8,
136 };
137 
138 // with ES3 core and GL_EXT_color_buffer_float
139 static const FormatKey s_es3NoExtExtColorBufferFloatFormats[] =
140 {
141 	// \note Only the GLES2+exts subset of formats
142 	GL_R11F_G11F_B10F, GL_RGBA16F, GL_RG16F, GL_R16F,
143 };
144 
145 // with ES3 core with OES_texture_stencil8
146 static const FormatKey s_es3NoExtOesTextureStencil8Formats[] =
147 {
148 	GL_STENCIL_INDEX8,
149 };
150 
151 // DEQP_gles3_core_changed_features
152 static const FormatKey s_es3NoExtDepthRenderable[] =
153 {
154 	GL_DEPTH_COMPONENT16,
155 	GL_DEPTH_COMPONENT24,
156 	GL_DEPTH24_STENCIL8,
157 };
158 
159 static const FormatKey s_es3NoExtStencilRenderable[] =
160 {
161 	GL_DEPTH24_STENCIL8,
162 };
163 
164 static const FormatExtEntry s_es2ExtFormats[] =
165 {
166 	// The extension does not specify these to be color-renderable.
167 	{
168 		"GL_OES_texture_float",
169 		(deUint32)TEXTURE_VALID,
170 		GLS_ARRAY_RANGE(s_oesTextureFloatFormats)
171 	},
172 	{
173 		"GL_OES_texture_half_float",
174 		(deUint32)TEXTURE_VALID,
175 		GLS_ARRAY_RANGE(s_oesTextureHalfFloatFormats)
176 	},
177         // However GL_EXT_color_buffer_half_float does say explicitly
178         // that the RGBA variant should be renderable.
179 	{
180 		"GL_OES_texture_half_float GL_EXT_color_buffer_half_float",
181 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE),
182 		GLS_ARRAY_RANGE(s_extColorBufferHalfFloatUnsized)
183 	},
184 
185 	// GL_EXT_sRGB_write_control makes SRGB8_ALPHA8 color-renderable
186 	{
187 		"GL_EXT_sRGB_write_control",
188 		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID),
189 		GLS_ARRAY_RANGE(s_extSrgbWriteControlFormats)
190 	},
191 
192 	// Since GLES3 is "backwards compatible" to GLES2, we might actually be running on a GLES3
193 	// context. Since GLES3 added some features to core with no corresponding GLES2 extension,
194 	// some tests might produce wrong results (since they are using rules of GLES2 & extensions)
195 	//
196 	// To avoid this, require new features of GLES3 that have no matching GLES2 extension if
197 	// context is GLES3. This can be done with a DEQP_* extensions.
198 	//
199 	// \note Not all feature changes are listed here but only those that alter GLES2 subset of
200 	//       the formats
201 	{
202 		"DEQP_gles3_core_compatible",
203 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
204 		GLS_ARRAY_RANGE(s_es3NoExtRboFormats)
205 	},
206 	{
207 		"DEQP_gles3_core_compatible",
208 		(deUint32)TEXTURE_VALID,
209 		GLS_ARRAY_RANGE(s_es3NoExtTextureFormats)
210 	},
211 	{
212 		"DEQP_gles3_core_compatible",
213 		(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID),
214 		GLS_ARRAY_RANGE(s_es3NoExtTextureColorRenderableFormats)
215 	},
216 	{
217 		"DEQP_gles3_core_compatible GL_EXT_color_buffer_float",
218 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID),
219 		GLS_ARRAY_RANGE(s_es3NoExtExtColorBufferFloatFormats)
220 	},
221 	{
222 		"DEQP_gles3_core_compatible GL_OES_texture_stencil8",
223 		(deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID),
224 		GLS_ARRAY_RANGE(s_es3NoExtOesTextureStencil8Formats)
225 	},
226 	{
227 		"DEQP_gles3_core_compatible GL_OES_texture_half_float GL_EXT_color_buffer_half_float",
228 		(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE),
229 		GLS_ARRAY_RANGE(s_oesTextureHalfFloatFormats)
230 	},
231 	{
232 		"DEQP_gles3_core_compatible",
233 		(deUint32)(REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID),
234 		GLS_ARRAY_RANGE(s_es3NoExtDepthRenderable)
235 	},
236 	{
237 		"DEQP_gles3_core_compatible",
238 		(deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID | TEXTURE_VALID),
239 		GLS_ARRAY_RANGE(s_es3NoExtStencilRenderable)
240 	},
241 };
242 
243 class ES2Checker : public Checker
244 {
245 public:
246 			ES2Checker				(const glu::RenderContext& ctx, const FormatDB& formats);
247 	void	check					(GLenum attPoint, const Attachment& att,
248 									 const Image* image);
249 private:
250 	GLsizei	m_width;	//< The common width of images
251 	GLsizei	m_height;	//< The common height of images
252 };
253 
ES2Checker(const glu::RenderContext & ctx,const FormatDB & formats)254 ES2Checker::ES2Checker (const glu::RenderContext& ctx, const FormatDB& formats)\
255 	: Checker		(ctx, formats)
256 	, m_width		(-1)
257 	, m_height		(-1)
258 {
259 }
260 
check(GLenum attPoint,const Attachment & att,const Image * image)261 void ES2Checker::check (GLenum attPoint, const Attachment& att, const Image* image)
262 {
263 	DE_UNREF(attPoint);
264 	DE_UNREF(att);
265 	// GLES2: "All attached images have the same width and height."
266 	if (m_width == -1)
267 	{
268 		m_width = image->width;
269 		m_height = image->height;
270 	}
271 	else if (image->width != m_width || image->height != m_height)
272 	{
273 		// Since GLES3 is "backwards compatible" to GLES2, we might actually be running
274 		// on a GLES3 context. On GLES3, FRAMEBUFFER_INCOMPLETE_DIMENSIONS is not generated
275 		// if attachments have different sizes.
276 		if (!gls::FboUtil::checkExtensionSupport(m_renderCtx, "DEQP_gles3_core_compatible"))
277 		{
278 			// running on GLES2
279 			addFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "Sizes of attachments differ");
280 		}
281 	}
282 	// GLES2, 4.4.5: "some implementations may not support rendering to
283 	// particular combinations of internal formats. If the combination of
284 	// formats of the images attached to a framebuffer object are not
285 	// supported by the implementation, then the framebuffer is not complete
286 	// under the clause labeled FRAMEBUFFER_UNSUPPORTED."
287 	//
288 	// Hence it is _always_ allowed to report FRAMEBUFFER_UNSUPPORTED.
289 	addPotentialFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Particular format combinations need not to be supported");
290 }
291 
292 struct FormatCombination
293 {
294 	GLenum			colorKind;
295 	ImageFormat		colorFmt;
296 	GLenum			depthKind;
297 	ImageFormat		depthFmt;
298 	GLenum			stencilKind;
299 	ImageFormat		stencilFmt;
300 };
301 
302 class SupportedCombinationTest : public fboc::TestBase
303 {
304 public:
SupportedCombinationTest(fboc::Context & ctx,const char * name,const char * desc)305 					SupportedCombinationTest	(fboc::Context& ctx,
306 												 const char* name, const char* desc)
307 						: TestBase		(ctx, name, desc) {}
308 
309 	IterateResult	iterate						(void);
310 	bool			tryCombination				(const FormatCombination& comb);
311 	GLenum			formatKind					(ImageFormat fmt);
312 };
313 
tryCombination(const FormatCombination & comb)314 bool SupportedCombinationTest::tryCombination (const FormatCombination& comb)
315 {
316 	glu::Framebuffer fbo(m_ctx.getRenderContext());
317 	FboBuilder builder(*fbo, GL_FRAMEBUFFER, fboc::gl(*this));
318 
319 	attachTargetToNew(GL_COLOR_ATTACHMENT0,		comb.colorKind,		comb.colorFmt,
320 					  64,						64,					builder);
321 	attachTargetToNew(GL_DEPTH_ATTACHMENT,		comb.depthKind,		comb.depthFmt,
322 					  64,						64,					builder);
323 	attachTargetToNew(GL_STENCIL_ATTACHMENT,	comb.stencilKind,	comb.stencilFmt,
324 					  64,						64,					builder);
325 
326 	const GLenum glStatus = fboc::gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER);
327 
328 	return (glStatus == GL_FRAMEBUFFER_COMPLETE);
329 }
330 
formatKind(ImageFormat fmt)331 GLenum SupportedCombinationTest::formatKind (ImageFormat fmt)
332 {
333 	if (fmt.format == GL_NONE)
334 		return GL_NONE;
335 
336 	const FormatFlags flags = m_ctx.getCoreFormats().getFormatInfo(fmt);
337 	const bool rbo = (flags & RENDERBUFFER_VALID) != 0;
338 	// exactly one of renderbuffer and texture is supported by vanilla GLES2 formats
339 	DE_ASSERT(rbo != ((flags & TEXTURE_VALID) != 0));
340 
341 	return rbo ? GL_RENDERBUFFER : GL_TEXTURE;
342 }
343 
iterate(void)344 IterateResult SupportedCombinationTest::iterate (void)
345 {
346 	const FormatDB& db		= m_ctx.getCoreFormats();
347 	const ImageFormat none	= ImageFormat::none();
348 	Formats colorFmts		= db.getFormats(COLOR_RENDERABLE);
349 	Formats depthFmts		= db.getFormats(DEPTH_RENDERABLE);
350 	Formats stencilFmts		= db.getFormats(STENCIL_RENDERABLE);
351 	FormatCombination comb;
352 	bool succ = false;
353 
354 	colorFmts.insert(none);
355 	depthFmts.insert(none);
356 	stencilFmts.insert(none);
357 
358 	for (Formats::const_iterator col = colorFmts.begin(); col != colorFmts.end(); col++)
359 	{
360 		comb.colorFmt = *col;
361 		comb.colorKind = formatKind(*col);
362 		for (Formats::const_iterator dep = depthFmts.begin(); dep != depthFmts.end(); dep++)
363 		{
364 			comb.depthFmt = *dep;
365 			comb.depthKind = formatKind(*dep);
366 			for (Formats::const_iterator stc = stencilFmts.begin();
367 				 stc != stencilFmts.end(); stc++)
368 			{
369 				comb.stencilFmt = *stc;
370 				comb.stencilKind = formatKind(*stc);
371 				succ = tryCombination(comb);
372 				if (succ)
373 					break;
374 			}
375 		}
376 	}
377 
378 	if (succ)
379 		pass();
380 	else
381 		fail("No supported format combination found");
382 
383 	return STOP;
384 }
385 
386 class ES2CheckerFactory : public CheckerFactory
387 {
388 public:
createChecker(const glu::RenderContext & ctx,const FormatDB & formats)389 	Checker*			createChecker	(const glu::RenderContext& ctx, const FormatDB& formats) { return new ES2Checker(ctx, formats); }
390 };
391 
392 class TestGroup : public TestCaseGroup
393 {
394 public:
395 						TestGroup		(Context& ctx);
396 	void				init			(void);
397 private:
398 	ES2CheckerFactory	m_checkerFactory;
399 	fboc::Context		m_fboc;
400 };
401 
TestGroup(Context & ctx)402 TestGroup::TestGroup (Context& ctx)
403 	: TestCaseGroup		(ctx, "completeness", "Completeness tests")
404 	, m_checkerFactory	()
405 	, m_fboc			(ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory)
406 {
407 	const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es2Formats);
408 	const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es2ExtFormats);
409 
410 	m_fboc.addFormats(stdRange);
411 	m_fboc.addExtFormats(extRange);
412 	m_fboc.setHaveMulticolorAtts(
413 		ctx.getContextInfo().isExtensionSupported("GL_NV_fbo_color_attachments"));
414 }
415 
init(void)416 void TestGroup::init (void)
417 {
418 	tcu::TestCaseGroup* attCombTests = m_fboc.createAttachmentTests();
419 	addChild(m_fboc.createRenderableTests());
420 	attCombTests->addChild(new SupportedCombinationTest(
421 							   m_fboc,
422 							   "exists_supported",
423 							   "Test for existence of a supported combination of formats"));
424 	addChild(attCombTests);
425 	addChild(m_fboc.createSizeTests());
426 }
427 
createFboCompletenessTests(Context & context)428 tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
429 {
430 	return new TestGroup(context);
431 }
432 
433 } // Functional
434 } // gles2
435 } // deqp
436