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 29using namespace glw; 30using deqp::gls::Range; 31using namespace deqp::gls::FboUtil; 32using namespace deqp::gls::FboUtil::config; 33namespace fboc = deqp::gls::fboc; 34typedef tcu::TestCase::IterateResult IterateResult; 35 36namespace deqp 37{ 38namespace gles2 39{ 40namespace Functional 41{ 42 43static 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 53static 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 60static const FormatKey s_es2DepthRenderables[] = 61{ 62 GL_DEPTH_COMPONENT16, 63}; 64 65static const FormatKey s_es2StencilRenderables[] = 66{ 67 GL_STENCIL_INDEX8, 68}; 69 70static 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 86static 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 93static 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 100static const FormatKey s_extSrgbWriteControlFormats[] = 101{ 102 GL_SRGB8_ALPHA8 103}; 104 105static 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 127class ES2Checker : public Checker 128{ 129public: 130 ES2Checker (void) : m_width(-1), m_height(-1) {} 131 void check (GLenum attPoint, const Attachment& att, 132 const Image* image); 133private: 134 GLsizei m_width; //< The common width of images 135 GLsizei m_height; //< The common height of images 136}; 137 138void 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 163struct FormatCombination 164{ 165 GLenum colorKind; 166 ImageFormat colorFmt; 167 GLenum depthKind; 168 ImageFormat depthFmt; 169 GLenum stencilKind; 170 ImageFormat stencilFmt; 171}; 172 173class SupportedCombinationTest : public fboc::TestBase 174{ 175public: 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 185bool 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 202GLenum 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 215IterateResult 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 257class ES2CheckerFactory : public CheckerFactory { 258public: 259 Checker* createChecker (void) { return new ES2Checker(); } 260}; 261 262class TestGroup : public TestCaseGroup 263{ 264public: 265 TestGroup (Context& ctx); 266 void init (void); 267private: 268 ES2CheckerFactory m_checkerFactory; 269 fboc::Context m_fboc; 270}; 271 272TestGroup::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 286void 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 298tcu::TestCaseGroup* createFboCompletenessTests (Context& context) 299{ 300 return new TestGroup(context); 301} 302 303} // Functional 304} // gles2 305} // deqp 306