Make fbo completeness format rules forward compatible.
authorJarkko Pöyry <jpoyry@google.com>
Thu, 19 Mar 2015 20:17:35 +0000 (13:17 -0700)
committerJarkko Pöyry <jpoyry@google.com>
Mon, 23 Mar 2015 19:28:57 +0000 (12:28 -0700)
- Detect and expose context version as an extension in glsFBOUtil.
- Add rules for GLES2 formats changed in GLES3 but with no GLES2
  extension with same functionality.
- Add rules for GLES3 formats changed in GLES31 but with no GLES31
  extension with same functionality.

Bug: 18800966
Change-Id: I297fa9738d8e51e87ccf84dfde6a13c7fd45c7ce

modules/gles2/functional/es2fFboCompletenessTests.cpp
modules/gles3/functional/es3fFboCompletenessTests.cpp
modules/glshared/glsFboCompletenessTests.cpp
modules/glshared/glsFboUtil.cpp
modules/glshared/glsFboUtil.hpp

index 49c52de..a74abd3 100644 (file)
@@ -102,6 +102,38 @@ static const FormatKey s_extSrgbWriteControlFormats[] =
        GL_SRGB8_ALPHA8
 };
 
+// DEQP_gles3_core_no_extension_features
+static const FormatKey s_es3NoExtRboFormats[] =
+{
+       GL_RGB10_A2,
+};
+static const FormatKey s_es3NoExtTextureFormats[] =
+{
+       GL_R16F,
+       GL_RG16F,
+       GL_RGB16F,
+       GL_RGBA16F,
+       GL_R11F_G11F_B10F,
+};
+static const FormatKey s_es3NoExtTextureColorRenderableFormats[] =
+{
+       GL_R8,
+       GL_RG8,
+};
+
+// with ES3 core and GL_EXT_color_buffer_float
+static const FormatKey s_es3NoExtExtColorBufferFloatFormats[] =
+{
+       // \note Only the GLES2+exts subset of formats
+       GL_R11F_G11F_B10F, GL_RGBA16F, GL_RG16F, GL_R16F,
+};
+
+// with ES3 core with OES_texture_stencil8
+static const FormatKey s_es3NoExtOesTextureStencil8Formats[] =
+{
+       GL_STENCIL_INDEX8,
+};
+
 static const FormatExtEntry s_es2ExtFormats[] =
 {
        // The extension does not specify these to be color-renderable.
@@ -122,6 +154,41 @@ static const FormatExtEntry s_es2ExtFormats[] =
                REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID,
                GLS_ARRAY_RANGE(s_extSrgbWriteControlFormats)
        },
+
+       // Since GLES3 is "backwards compatible" to GLES2, we might actually be running on a GLES3
+       // context. Since GLES3 added some features to core with no corresponding GLES2 extension,
+       // some tests might produce wrong results (since they are using rules of GLES2 & extensions)
+       //
+       // To avoid this, require new features of GLES3 that have no matching GLES2 extension if
+       // context is GLES3. This can be done with a DEQP_* extensions.
+       //
+       // \note Not all feature changes are listed here but only those that alter GLES2 subset of
+       //       the formats
+       {
+               "DEQP_gles3_core_compatible",
+               REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
+               GLS_ARRAY_RANGE(s_es3NoExtRboFormats)
+       },
+       {
+               "DEQP_gles3_core_compatible",
+               TEXTURE_VALID,
+               GLS_ARRAY_RANGE(s_es3NoExtTextureFormats)
+       },
+       {
+               "DEQP_gles3_core_compatible",
+               REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE,
+               GLS_ARRAY_RANGE(s_es3NoExtTextureColorRenderableFormats)
+       },
+       {
+               "DEQP_gles3_core_compatible GL_EXT_color_buffer_float",
+               REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
+               GLS_ARRAY_RANGE(s_es3NoExtExtColorBufferFloatFormats)
+       },
+       {
+               "DEQP_gles3_core_compatible GL_OES_texture_stencil8",
+               REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID,
+               GLS_ARRAY_RANGE(s_es3NoExtOesTextureStencil8Formats)
+       },
 };
 
 class ES2Checker : public Checker
index 858da35..7bfa647 100644 (file)
@@ -136,19 +136,39 @@ static const FormatKey s_extOESTextureStencil8[] =
        GL_STENCIL_INDEX8,
 };
 
+// GL_EXT_render_snorm
+static const FormatKey s_extRenderSnorm[] =
+{
+       GL_R8_SNORM, GL_RG8_SNORM, GL_RGBA8_SNORM,
+};
 
 static const FormatExtEntry s_es3ExtFormats[] =
 {
-       { "GL_EXT_color_buffer_float",
-         // These are already texture-valid in ES3, the extension just adds RBO
-         // support and makes them color-renderable.
-         REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
-         GLS_ARRAY_RANGE(s_extColorBufferFloatFormats) },
-       { "GL_OES_texture_stencil8",
-         // Note: es3 RBO tests actually cover the first two requirements
-      // - kept here for completeness
-      REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID,
-         GLS_ARRAY_RANGE(s_extOESTextureStencil8) }
+       {
+               "GL_EXT_color_buffer_float",
+               // These are already texture-valid in ES3, the extension just adds RBO
+               // support and makes them color-renderable.
+               REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID,
+               GLS_ARRAY_RANGE(s_extColorBufferFloatFormats)
+       },
+       {
+               "GL_OES_texture_stencil8",
+               // \note: es3 RBO tests actually cover the first two requirements
+               // - kept here for completeness
+               REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID,
+               GLS_ARRAY_RANGE(s_extOESTextureStencil8)
+       },
+
+       // Since GLES31 is backwards compatible to GLES3, we might actually be running on a GLES31.
+       // Add rule changes of GLES31 that have no corresponding GLES3 extension.
+       //
+       // \note Not all feature changes are listed here but only those that alter GLES3 subset of
+       //       the formats
+       {
+               "DEQP_gles31_core_compatible GL_EXT_render_snorm",
+               REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID | RENDERBUFFER_VALID,
+               GLS_ARRAY_RANGE(s_extRenderSnorm)
+       },
 };
 
 class ES3Checker : public Checker
index 9627198..5b2a7e7 100644 (file)
@@ -459,12 +459,12 @@ static void logAffectingExtensions (const char* prefix, const FormatDB& db, cons
                extName = *it++;
                while (it != requiredExtensions.end())
                {
-                       msg << extName;
+                       msg << getExtensionDescription(extName);
                        extName = *it++;
                        msg << (it == requiredExtensions.end() ? " and " : ", ");
                }
 
-               msg << extName << '\n';
+               msg << getExtensionDescription(extName) << '\n';
        }
 }
 
index 76c1c6d..c18521c 100644 (file)
@@ -162,6 +162,58 @@ bool FormatDB::ExtensionInfo::operator< (const ExtensionInfo& other) const
                   ((requiredExtensions == other.requiredExtensions) && (flags < other.flags));
 }
 
+static bool detectGLESCompatibleContext (const RenderContext& ctx, int requiredMajor, int requiredMinor)
+{
+       const glw::Functions&   gl                              = ctx.getFunctions();
+       glw::GLint                              majorVersion    = 0;
+       glw::GLint                              minorVersion    = 0;
+
+       // Detect compatible GLES context by querying GL_MAJOR_VERSION.
+       // This query does not exist on GLES2 so a failing query implies
+       // GLES2 context.
+
+       gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
+       if (gl.getError() != GL_NO_ERROR)
+               majorVersion = 2;
+
+       gl.getIntegerv(GL_MINOR_VERSION, &minorVersion);
+       if (gl.getError() != GL_NO_ERROR)
+               minorVersion = 0;
+
+       return (majorVersion > requiredMajor) || (majorVersion == requiredMajor && minorVersion >= requiredMinor);
+}
+
+// Check support for GL_* and DEQP_* extensions
+static bool checkExtensionSupport (const ContextInfo& ctxInfo, const RenderContext& ctx, const std::string& extension)
+{
+       if (de::beginsWith(extension, "GL_"))
+               return ctxInfo.isExtensionSupported(extension.c_str());
+       else if (extension == "DEQP_gles3_core_compatible")
+               return detectGLESCompatibleContext(ctx, 3, 0);
+       else if (extension == "DEQP_gles31_core_compatible")
+               return detectGLESCompatibleContext(ctx, 3, 1);
+       else
+       {
+               DE_ASSERT(false);
+               return false;
+       }
+}
+
+std::string getExtensionDescription (const std::string& extension)
+{
+       if (de::beginsWith(extension, "GL_"))
+               return extension;
+       else if (extension == "DEQP_gles3_core_compatible")
+               return "GLES3 compatible context";
+       else if (extension == "DEQP_gles31_core_compatible")
+               return "GLES3.1 compatible context";
+       else
+       {
+               DE_ASSERT(false);
+               return "";
+       }
+}
+
 void addFormats (FormatDB& db, FormatEntries stdFmts)
 {
        for (const FormatEntry* it = stdFmts.begin(); it != stdFmts.end(); it++)
@@ -196,7 +248,7 @@ void addExtFormats (FormatDB& db, FormatExtEntries extFmts, const RenderContext*
                {
                        for (std::set<std::string>::const_iterator extIt = requiredExtensions.begin(); extIt != requiredExtensions.end(); ++extIt)
                        {
-                               if (!ctxInfo->isExtensionSupported(extIt->c_str()))
+                               if (!checkExtensionSupport(*ctxInfo, *ctx, *extIt))
                                {
                                        supported = false;
                                        break;
index c6a14e7..f0788ac 100644 (file)
@@ -181,10 +181,12 @@ struct FormatExtEntry
 
 typedef Range<FormatExtEntry>                                          FormatExtEntries;
 
-void                           addFormats                      (FormatDB& db, FormatEntries stdFmts);
-void                           addExtFormats           (FormatDB& db, FormatExtEntries extFmts,
-                                                                                const glu::RenderContext* ctx);
-glu::TransferFormat    transferImageFormat     (const ImageFormat& imgFormat);
+// Accepts GL_* and DEQP_* extension strings and converts DEQP_* strings to a human readable string
+std::string                    getExtensionDescription         (const std::string& extensionName);
+
+void                           addFormats                                      (FormatDB& db, FormatEntries stdFmts);
+void                           addExtFormats                           (FormatDB& db, FormatExtEntries extFmts, const glu::RenderContext* ctx);
+glu::TransferFormat    transferImageFormat                     (const ImageFormat& imgFormat);
 
 namespace config
 {