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