[Mesa-dev] [PATCH] mesa: fix format checking when doing a multisample resolve

Marek Olšák maraeo at gmail.com
Sat Jul 21 14:30:14 PDT 2012


v2: make it more bullet-proof
---
 src/mesa/main/fbobject.c |  112 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 4370c72..ca43f81 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2633,6 +2633,116 @@ compatible_color_datatypes(gl_format srcFormat, gl_format dstFormat)
 
 
 /**
+ * Return the equivalent non-generic internal format.
+ * This is useful for comparing whether two internal formats are semantically
+ * equivalent.
+ */
+static GLenum
+get_nongeneric_internalformat(GLenum format)
+{
+   switch (format) {
+      /* GL 1.1 formats. */
+      case 4:
+      case GL_RGBA:
+         return GL_RGBA8;
+
+      case 3:
+      case GL_RGB:
+         return GL_RGB8;
+
+      case 2:
+      case GL_LUMINANCE_ALPHA:
+         return GL_LUMINANCE8_ALPHA8;
+
+      case 1:
+      case GL_LUMINANCE:
+         return GL_LUMINANCE8;
+
+      case GL_ALPHA:
+         return GL_ALPHA8;
+
+      case GL_INTENSITY:
+         return GL_INTENSITY8;
+
+      /* GL_ARB_texture_rg */
+      case GL_RED:
+         return GL_R8;
+
+      case GL_RG:
+         return GL_RG8;
+
+      /* GL_EXT_texture_sRGB */
+      case GL_SRGB:
+         return GL_SRGB8;
+
+      case GL_SRGB_ALPHA:
+         return GL_SRGB8_ALPHA8;
+
+      case GL_SLUMINANCE:
+         return GL_SLUMINANCE8;
+
+      case GL_SLUMINANCE_ALPHA:
+         return GL_SLUMINANCE8_ALPHA8;
+
+      /* GL_EXT_texture_snorm */
+      case GL_RGBA_SNORM:
+         return GL_RGBA8_SNORM;
+
+      case GL_RGB_SNORM:
+         return GL_RGB8_SNORM;
+
+      case GL_RG_SNORM:
+         return GL_RG8_SNORM;
+
+      case GL_RED_SNORM:
+         return GL_R8_SNORM;
+
+      case GL_LUMINANCE_ALPHA_SNORM:
+         return GL_LUMINANCE8_ALPHA8_SNORM;
+
+      case GL_LUMINANCE_SNORM:
+         return GL_LUMINANCE8_SNORM;
+
+      case GL_ALPHA_SNORM:
+         return GL_ALPHA8_SNORM;
+
+      case GL_INTENSITY_SNORM:
+         return GL_INTENSITY8_SNORM;
+
+      default:
+         return format;
+   }
+}
+
+
+static GLboolean
+compatible_resolve_formats(const struct gl_renderbuffer *colorReadRb,
+                           const struct gl_renderbuffer *colorDrawRb)
+{
+   /* The simple case where we know the backing formats are the same.
+    */
+   if (colorReadRb->Format == colorDrawRb->Format) {
+      return GL_TRUE;
+   }
+
+   /* The Mesa formats are different, so we must check whether the internal
+    * formats are compatible.
+    *
+    * Under some circumstances, the user may request e.g. two GL_RGBA8
+    * textures and get two entirely different Mesa formats like RGBA8888 and
+    * ARGB8888. Drivers behaving like that should be able to cope with
+    * non-matching formats by themselves, because it's not the user's fault.
+    */
+   if (get_nongeneric_internalformat(colorReadRb->InternalFormat) ==
+       get_nongeneric_internalformat(colorDrawRb->InternalFormat)) {
+      return GL_TRUE;
+   }
+
+   return GL_FALSE;
+}
+
+
+/**
  * Blit rectangular region, optionally from one framebuffer to another.
  *
  * Note, if the src buffer is multisampled and the dest is not, this is
@@ -2798,7 +2908,7 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
       /* color formats must match */
       if (colorReadRb &&
           colorDrawRb &&
-          colorReadRb->Format != colorDrawRb->Format) {
+          !compatible_resolve_formats(colorReadRb, colorDrawRb)) {
          _mesa_error(ctx, GL_INVALID_OPERATION,
                 "glBlitFramebufferEXT(bad src/dst multisample pixel formats)");
          return;
-- 
1.7.9.5



More information about the mesa-dev mailing list