[Mesa-dev] [PATCH 1/3] meta: Implement sensible behavior for BlitFramebuffer with sRGB.

Eric Anholt eric at anholt.net
Tue Jul 31 18:04:36 PDT 2012

Prior to GL 4.2 spec, there was no guidance on how to implement
BlitFramebuffer for sRGB.  Mesa chose to implement skipping decode and encode,
providing a reasonable behavior for sRGB -> sRGB or RGB -> RGB, but providing
something absurd for mixing and matching the two.

In GL 4.2, some text appeared in the spec saying to skip decode (search for
"no linearization").  The only non-absurd interpretation of that would be to
have no encode (same as Mesa's current implementation), otherwise sRGB -> sRGB
blits wouldn't work.

However, it seems clear that you should be able to blit sRGB to RGB and RGB to
sRGB and get appropriate conversion.  The ARB has been discussing the issue,
and appears to agree.  So, instead implement the same behavior as gallium, and
always do the decode if the texture is sRGB, and do the encode if the
application asked for it.

Breaks piglit fbo-srgb-blit, which was expecting our previous no-conversion
 src/mesa/drivers/common/meta.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 6846bbc..e35f0c8 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -1357,7 +1357,6 @@ blitframebuffer_texture(struct gl_context *ctx,
          const GLenum wrapSSave = texObj->Sampler.WrapS;
          const GLenum wrapTSave = texObj->Sampler.WrapT;
          const GLenum srgbSave = texObj->Sampler.sRGBDecode;
-         const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;
          const GLenum target = texObj->Target;
          if (drawAtt->Texture == readAtt->Texture) {
@@ -1390,14 +1389,14 @@ blitframebuffer_texture(struct gl_context *ctx,
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
          _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-	 /* Always do our blits with no sRGB decode or encode.*/
+	 /* Always do sRGB decode on the read, and do sRGB encode on the write
+          * if we've been asked to on this framebuffer by leaving
+          * GL_FRAMEBUFFER_SRGB in place.
+          */
 	 if (ctx->Extensions.EXT_texture_sRGB_decode) {
 	    _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT,
-         if (ctx->Extensions.EXT_framebuffer_sRGB) {
-            _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);
-         }
          _mesa_set_enable(ctx, target, GL_TRUE);
@@ -1463,9 +1462,6 @@ blitframebuffer_texture(struct gl_context *ctx,
 	 if (ctx->Extensions.EXT_texture_sRGB_decode) {
 	    _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, srgbSave);
-	 if (ctx->Extensions.EXT_framebuffer_sRGB && fbo_srgb_save) {
-	    _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);
-	 }
          /* Done with color buffer */
          mask &= ~GL_COLOR_BUFFER_BIT;

More information about the mesa-dev mailing list