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:
ES2Checker(void)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
check(GLenum attPoint,const Attachment & att,const Image * image)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:
SupportedCombinationTest(fboc::Context & ctx,const char * name,const char * desc)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
tryCombination(const FormatCombination & comb)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
formatKind(ImageFormat fmt)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
iterate(void)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:
createChecker(void)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
TestGroup(Context & ctx)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
init(void)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
createFboCompletenessTests(Context & context)298 tcu::TestCaseGroup* createFboCompletenessTests (Context& context)
299 {
300 return new TestGroup(context);
301 }
302
303 } // Functional
304 } // gles2
305 } // deqp
306