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