[Mesa-dev] [PATCH] meta: fix broken sRGB mipmap generation

Brian Paul brian.e.paul at gmail.com
Sat Sep 17 10:33:38 PDT 2011


From: Brian Paul <brianp at vmware.com>

If we're generating a mipmap for an sRGB texture we need to bypass
sRGB->linear conversion.  Otherwise the destination mipmap level
(drawn with a textured quad) will have the wrong colors.
If we can't turn of sRGB->linear conversion (GL_EXT_texture_sRGB_decode)
we need to use the software fallback for mipmap generation.

Note: This is a candidate for the 7.11 branch.
---
 src/mesa/drivers/common/meta.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 1b71aa1..82b072e 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -2452,6 +2452,15 @@ _mesa_meta_check_generate_mipmap_fallback(struct gl_context *ctx, GLenum target,
       return GL_TRUE;
    }
 
+   if (_mesa_get_format_color_encoding(baseImage->TexFormat) == GL_SRGB &&
+       !ctx->Extensions.EXT_texture_sRGB_decode) {
+      /* The texture format is sRGB but we can't turn off sRGB->linear
+       * texture sample conversion.  So we won't be able to generate the
+       * right colors when rendering.  Need to use a fallback.
+       */
+      return GL_TRUE;
+   }
+
    /*
     * Test that we can actually render in the texture's format.
     */
@@ -2669,6 +2678,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
    const GLenum wrapSSave = texObj->Sampler.WrapS;
    const GLenum wrapTSave = texObj->Sampler.WrapT;
    const GLenum wrapRSave = texObj->Sampler.WrapR;
+   const GLenum srgbDecodeSave = texObj->Sampler.sRGBDecode;
+   const GLenum srgbBufferSave = ctx->Color.sRGBEnabled;
    const GLuint fboSave = ctx->DrawBuffer->Name;
    const GLuint original_active_unit = ctx->Texture.CurrentUnit;
    GLenum faceTarget;
@@ -2731,6 +2742,15 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
 
+   /* We don't want to encode or decode sRGB values; treat them as linear */
+   if (ctx->Extensions.EXT_texture_sRGB_decode) {
+      _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
+                          GL_SKIP_DECODE_EXT);
+   }
+   if (ctx->Extensions.EXT_framebuffer_sRGB) {
+      _mesa_Disable(GL_FRAMEBUFFER_SRGB_EXT);
+   }
+
    _mesa_set_enable(ctx, target, GL_TRUE);
 
    /* setup texcoords (XXX what about border?) */
@@ -2875,6 +2895,14 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
 
+   if (ctx->Extensions.EXT_texture_sRGB_decode) {
+      _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
+                          srgbDecodeSave);
+   }
+   if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) {
+      _mesa_Enable(GL_FRAMEBUFFER_SRGB_EXT);
+   }
+
    _mesa_lock_texture(ctx, texObj); /* relock */
 
    _mesa_meta_end(ctx);
-- 
1.7.3.4



More information about the mesa-dev mailing list