On 25 September 2012 06:53, Brian Paul <span dir="ltr"><<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On 09/24/2012 05:49 PM, Paul Berry wrote:<br>
</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
Previously, meta logic was saving and restoring the value of<br>
GL_FRAMEBUFFER_SRGB in an ad-hoc fashion.  As a result, it was not<br>
properly disabled and/or restored for some meta operations.<br>
<br>
This patch causes GL_FRAMEBUFFER_SRGB to be saved/restored in the<br>
conventional way of meta-ops (using _mesa_meta_begin() and<br>
_mesa_meta_end()).  It is now reliably saved/restored for<br>
_mesa_meta_BlitFramebuffer, _mesa_meta_GenerateMipmap, and<br>
decompress_texture_image, and preserved for all other meta ops.<br>
<br>
Fixes piglit tests "ARB_framebuffer_sRGB/blit renderbuffer<br>
{linear_to_srgb,srgb} scaled {disabled,enabled}".<br>
---<br>
  src/mesa/drivers/common/meta.c | 47 ++++++++++++++++++------------<u></u>------------<br>
  src/mesa/drivers/common/meta.h |  1 +<br>
  2 files changed, 21 insertions(+), 27 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/common/<u></u>meta.c b/src/mesa/drivers/common/<u></u>meta.c<br>
index 28a79b0..6689337 100644<br>
--- a/src/mesa/drivers/common/<u></u>meta.c<br>
+++ b/src/mesa/drivers/common/<u></u>meta.c<br>
@@ -187,6 +187,9 @@ struct save_state<br>
     /** MESA_META_MULTISAMPLE */<br>
     GLboolean MultisampleEnabled;<br>
<br>
+   /** MESA_META_FRAMEBUFFER_SRGB */<br>
+   GLboolean sRGBEnabled;<br>
+<br>
     /** Miscellaneous (always disabled) */<br>
     GLboolean Lighting;<br>
     GLboolean RasterDiscard;<br>
@@ -773,6 +776,12 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state)<br>
           _mesa_set_multisample(ctx, GL_FALSE);<br>
     }<br>
<br></div></div>
+   if (state&  MESA_META_FRAMEBUFFER_SRGB) {<div class="im"><br>
+      save->sRGBEnabled = ctx->Color.sRGBEnabled;<br>
+      if (ctx->Color.sRGBEnabled)<br>
+         _mesa_set_framebuffer_srgb(<u></u>ctx, GL_FALSE);<br>
+   }<br>
+<br>
     /* misc */<br>
     {<br>
        save->Lighting = ctx->Light.Enabled;<br>
@@ -1075,6 +1084,11 @@ _mesa_meta_end(struct gl_context *ctx)<br>
           _mesa_set_multisample(ctx, save->MultisampleEnabled);<br>
     }<br>
<br></div>
+   if (state&  MESA_META_FRAMEBUFFER_SRGB) {<div><div class="h5"><br>
+      if (ctx->Color.sRGBEnabled != save->sRGBEnabled)<br>
+         _mesa_set_framebuffer_srgb(<u></u>ctx, save->sRGBEnabled);<br>
+   }<br>
+<br>
     /* misc */<br>
     if (save->Lighting) {<br>
        _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);<br>
@@ -1394,7 +1408,6 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
           const GLuint srcLevel = readAtt->TextureLevel;<br>
           const GLint baseLevelSave = texObj->BaseLevel;<br>
           const GLint maxLevelSave = texObj->MaxLevel;<br>
-         const GLenum fbo_srgb_save = ctx->Color.sRGBEnabled;<br>
           const GLenum target = texObj->Target;<br>
           GLuint sampler, samplerSave =<br>
              ctx->Texture.Unit[ctx-><u></u>Texture.CurrentUnit].Sampler ?<br>
@@ -1433,15 +1446,14 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
           _mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);<br>
           _mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);<br>
<br>
-        /* Always do our blits with no sRGB decode or encode.*/<br>
+        /* Always do our blits with no sRGB decode or encode.  Note that<br>
+          * GL_FRAMEBUFFER_SRGB has already been disabled by<br>
+          * _mesa_meta_begin().<br>
+          */<br>
         if (ctx->Extensions.EXT_texture_<u></u>sRGB_decode) {<br>
            _mesa_SamplerParameteri(<u></u>sampler, GL_TEXTURE_SRGB_DECODE_EXT,<br>
                                GL_SKIP_DECODE_EXT);<br>
         }<br></div></div>
-         if ((_mesa_is_desktop_gl(ctx)&&  ctx->Extensions.EXT_<u></u>framebuffer_sRGB)<div class="im"><br>
-             || _mesa_is_gles3(ctx)) {<br>
-            _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
-         }<br>
<br>
           _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);<br>
           _mesa_set_enable(ctx, target, GL_TRUE);<br>
@@ -1500,9 +1512,6 @@ blitframebuffer_texture(struct gl_context *ctx,<br>
              _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);<br>
              _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);<br>
           }<br></div>
-        if (ctx->Extensions.EXT_<u></u>framebuffer_sRGB&&  fbo_srgb_save) {<div class="im"><br>
-           _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);<br>
-        }<br>
<br>
           _mesa_BindSampler(ctx-><u></u>Texture.CurrentUnit, samplerSave);<br>
           _mesa_DeleteSamplers(1,&<u></u>sampler);<br>
@@ -1713,7 +1722,8 @@ _mesa_meta_Clear(struct gl_context *ctx, GLbitfield buffers)<br>
     GLbitfield metaSave = (MESA_META_ALL -<br>
                          MESA_META_SCISSOR -<br>
                          MESA_META_PIXEL_STORE -<br>
-                         MESA_META_CONDITIONAL_RENDER);<br>
+                         MESA_META_CONDITIONAL_RENDER -<br>
+                          MESA_META_FRAMEBUFFER_SRGB);<br>
     const GLuint stencilMax = (1<<  ctx->DrawBuffer->Visual.<u></u>stencilBits) - 1;<br>
<br></div>
     if (buffers&  BUFFER_BITS_COLOR) {<div class="im"><br>
@@ -3236,7 +3246,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
     const GLuint maxLevel = texObj->MaxLevel;<br>
     const GLint maxLevelSave = texObj->MaxLevel;<br>
     const GLboolean genMipmapSave = texObj->GenerateMipmap;<br>
-   const GLenum srgbBufferSave = ctx->Color.sRGBEnabled;<br>
     const GLuint fboSave = ctx->DrawBuffer->Name;<br>
     const GLuint currentTexUnitSave = ctx->Texture.CurrentUnit;<br>
     const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_<u></u>shader&&<br>
@@ -3330,12 +3339,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
     else<br>
        assert(!genMipmapSave);<br>
<br>
-   if ((ctx->Extensions.EXT_<u></u>framebuffer_sRGB&&<br>
-        _mesa_is_desktop_gl(ctx)) ||<br>
-       _mesa_is_gles3(ctx)) {<br>
-      _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
-   }<br>
-<br>
    /* Setup texture coordinates */<br>
     setup_texture_coords(<u></u>faceTarget,<br>
                          slice,<br>
@@ -3452,10 +3455,6 @@ _mesa_meta_GenerateMipmap(<u></u>struct gl_context *ctx, GLenum target,<br>
        _mesa_DrawArrays(GL_TRIANGLE_<u></u>FAN, 0, 4);<br>
     }<br>
<br></div>
-   if (ctx->Extensions.EXT_<u></u>framebuffer_sRGB&&  srgbBufferSave) {<div class="im"><br>
-      _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE);<br>
-   }<br>
-<br>
     _mesa_lock_texture(ctx, texObj); /* relock */<br>
<br>
     _mesa_BindSampler(ctx-><u></u>Texture.CurrentUnit, samplerSave);<br>
@@ -3734,12 +3733,6 @@ decompress_texture_image(<u></u>struct gl_context *ctx,<br>
           _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level);<br>
        }<br>
<br>
-      /* No sRGB decode or encode.*/<br></div>
-      if ((_mesa_is_desktop_gl(ctx)&&  ctx->Extensions.EXT_<u></u>framebuffer_sRGB)<div class="im"><br>
-          || _mesa_is_gles3(ctx)) {<br>
-         _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE);<br>
-      }<br>
-<br>
        /* render quad w/ texture into renderbuffer */<br>
        _mesa_DrawArrays(GL_TRIANGLE_<u></u>FAN, 0, 4);<br>
<br>
diff --git a/src/mesa/drivers/common/<u></u>meta.h b/src/mesa/drivers/common/<u></u>meta.h<br>
index d8dfb56..6ffc5b5 100644<br>
--- a/src/mesa/drivers/common/<u></u>meta.h<br>
+++ b/src/mesa/drivers/common/<u></u>meta.h<br>
@@ -56,6 +56,7 @@<br>
  #define MESA_META_CLIP                  0x40000<br>
  #define MESA_META_SELECT_FEEDBACK       0x80000<br>
  #define MESA_META_MULTISAMPLE          0x100000<br>
+#define MESA_META_FRAMEBUFFER_SRGB     0x200000<br>
  /**\}*/<br>
<br>
  extern void<br>
</div></blockquote>
<br>
Assuming you've checked all the _mesa_meta_begin() calls to check if the new MESA_META_FRAMEBUFFER_SRGB flag is needed,<br>
<br>
Reviewed-by: Brian Paul <<a href="mailto:brianp@vmware.com" target="_blank">brianp@vmware.com</a>><br>
<br>
</blockquote></div><br>I have checked all the _mesa_meta_begin() calls, but if someone wants to verify that my reasoning is correct, I would appreciate it.  Specifically, I reasoned that:<br><br>- The calls to _mesa_meta_begin() in _mesa_meta_CopyPixels(), _mesa_meta_DrawPixels(), _mesa_meta_Bitmap(), and _mesa_meta_DrawTex() should *not* include MESA_META_FRAMEBUFFER_SRGB, because fragments produced by these calls are supposed to undergo normal fragment processing.<br>
<br>- The call to _mesa_meta_begin() in _mesa_meta_GenerateMipmap() *should* include MESA_META_FRAMEBUFFER_SRGB, because sRGB encoding during mipmap generation would cause different miplevels to have different brightness.<br>
<br>- The calls to _mesa_meta_begin() in _mesa_meta_CopyTexSubImage() don't need to include MESA_META_FRAMEBUFFER_SRGB, because the only operations that this function performs while meta is active are ReadPixels() and TexSubImage(), which won't be affected by the FRAMEBUFFER_SRGB setting.<br>
<br>- The call to _mesa_meta_begin() in decompress_texture_image() *should* include MESA_META_FRAMEBUFFER_SRGB, since the behaviour of textures shouldn't depend on the setting of MESA_META_FRAMEBUFFER_SRGB. <br><br>Do those sound right?  I'm confident about the others.<br>