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