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