meta: Make Meta's BlitFramebuffer() follow the GL 4.4 sRGB rules.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 2 Aug 2016 23:32:52 +0000 (16:32 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Mon, 8 Aug 2016 21:04:01 +0000 (14:04 -0700)
Just avoid whacking GL_FRAMEBUFFER_SRGB altogether, so we respect
the application's setting.  This appears to work.

v2: Update one more comment (requested by Ian).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/mesa/drivers/common/meta_blit.c

index d6d3a42304093aad2f0ab536cf5454119a7b5995..991d52f21e9e1e12e73fe161447f5a94600aae33 100644 (file)
@@ -606,7 +606,6 @@ blitframebuffer_texture(struct gl_context *ctx,
                         GLenum filter, GLint flipX, GLint flipY,
                         GLboolean glsl_version, GLboolean do_depth)
 {
-   struct save_state *save = &ctx->Meta->Save[ctx->Meta->SaveStackDepth - 1];
    int att_index = do_depth ? BUFFER_DEPTH : readFb->_ColorReadBufferIndex;
    const struct gl_renderbuffer_attachment *readAtt =
       &readFb->Attachment[att_index];
@@ -719,57 +718,32 @@ blitframebuffer_texture(struct gl_context *ctx,
    fb_tex_blit.samp_obj = _mesa_meta_setup_sampler(ctx, texObj, target, filter,
                                                    srcLevel);
 
-   /* For desktop GL, we do our blits with no net sRGB decode or encode.
-    *
-    * However, if both the src and dst can be srgb decode/encoded, enable them
-    * so that we do any blending (from scaling or from MSAA resolves) in the
-    * right colorspace.
-    *
-    * Our choice of not doing any net encode/decode is from the GL 3.0
-    * specification:
-    *
-    *     "Blit operations bypass the fragment pipeline. The only fragment
-    *      operations which affect a blit are the pixel ownership test and the
-    *      scissor test."
-    *
-    * The GL 4.4 specification disagrees and says that the sRGB part of the
-    * fragment pipeline applies, but this was found to break applications
-    * (such as Left 4 Dead 2).
-    *
-    * However, for ES 3.0, we follow the specification and perform sRGB
-    * decoding and encoding.  The specification has always been clear in
-    * the ES world, and hasn't changed over time.
-    */
    if (ctx->Extensions.EXT_texture_sRGB_decode) {
-      bool src_srgb = _mesa_get_format_color_encoding(rb->Format) == GL_SRGB;
-      if (save->API == API_OPENGLES2 && ctx->Version >= 30) {
-         /* From the ES 3.0.4 specification, page 198:
-          * "When values are taken from the read buffer, if the value of
-          *  FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer
-          *  attachment corresponding to the read buffer is SRGB (see section
-          *  6.1.13), the red, green, and blue components are converted from
-          *  the non-linear sRGB color space according to equation 3.24.
-          *
-          *  When values are written to the draw buffers, blit operations
-          *  bypass the fragment pipeline. The only fragment operations which
-          *  affect a blit are the pixel ownership test, the scissor test,
-          *  and sRGB conversion (see section 4.1.8)."
-          */
-         _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj,
-                                       src_srgb ? GL_DECODE_EXT
-                                                : GL_SKIP_DECODE_EXT);
-         _mesa_set_framebuffer_srgb(ctx, drawFb->Visual.sRGBCapable);
-      } else {
-         if (src_srgb && drawFb->Visual.sRGBCapable) {
-            _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj,
-                                          GL_DECODE_EXT);
-            _mesa_set_framebuffer_srgb(ctx, GL_TRUE);
-         } else {
-            _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj,
-                                          GL_SKIP_DECODE_EXT);
-            /* set_framebuffer_srgb was set by _mesa_meta_begin(). */
-         }
-      }
+      /* The GL 4.4 spec, section 18.3.1 ("Blitting Pixel Rectangles") says:
+       *
+       *    "When values are taken from the read buffer, if FRAMEBUFFER_SRGB
+       *     is enabled and the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
+       *     for the framebuffer attachment corresponding to the read buffer
+       *     is SRGB (see section 9.2.3), the red, green, and blue components
+       *     are converted from the non-linear sRGB color space according to
+       *     equation 3.24.
+       *
+       *     When values are written to the draw buffers, blit operations
+       *     bypass most of the fragment pipeline.  The only fragment
+       *     operations which affect a blit are the pixel ownership test,
+       *     the scissor test, and sRGB conversion (see section 17.3.9)."
+       *
+       * ES 3.0 contains nearly the exact same text, but omits the part
+       * about GL_FRAMEBUFFER_SRGB as that doesn't exist in ES.  Mesa
+       * defaults it to on for ES contexts, so we can safely check it.
+       */
+      const bool decode =
+         ctx->Color.sRGBEnabled &&
+         _mesa_get_format_color_encoding(rb->Format) == GL_SRGB;
+
+      _mesa_set_sampler_srgb_decode(ctx, fb_tex_blit.samp_obj,
+                                    decode ? GL_DECODE_EXT
+                                           : GL_SKIP_DECODE_EXT);
    }
 
    if (!glsl_version) {
@@ -1012,10 +986,12 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
       return 0;
    }
 
-   /* Only scissor affects blit, but we're doing to set a custom scissor if
-    * necessary anyway, so save/clear state.
+   /* Only scissor and FRAMEBUFFER_SRGB affect blit.  Leave sRGB alone, but
+    * save restore scissor as we'll set a custom scissor if necessary.
     */
-   _mesa_meta_begin(ctx, MESA_META_ALL & ~MESA_META_DRAW_BUFFERS);
+   _mesa_meta_begin(ctx, MESA_META_ALL &
+                         ~(MESA_META_DRAW_BUFFERS |
+                           MESA_META_FRAMEBUFFER_SRGB));
 
    /* Dithering shouldn't be performed for glBlitFramebuffer */
    _mesa_set_enable(ctx, GL_DITHER, GL_FALSE);