Mesa (9.0): i965/blorp: Add support for blits between SRGB and linear formats (fixed).

Paul Berry stereotype441 at kemper.freedesktop.org
Fri Sep 28 18:30:38 UTC 2012


Module: Mesa
Branch: 9.0
Commit: 8c1c18769ef4838b11065b353f6f62bfd1de1cd2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8c1c18769ef4838b11065b353f6f62bfd1de1cd2

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Tue Sep 11 16:20:43 2012 -0700

i965/blorp: Add support for blits between SRGB and linear formats (fixed).

This is a squash of 2 commits from master.
The first commit is:

i965/blorp: Add support for blits between SRGB and linear formats.

Fixes colorspace issues in L4D2 when multisampling is enabled (the
scene was far too dark, but the flashlight area was way too bright).

The nVidia and AMD binary drivers both allow this kind of blit.

Reviewed-by: Paul Berry <stereotype441 at gmail.com>
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
(cherry picked from commit e2249e8c4d06a85d6389ba1689e15d7e29aa4dff)

The second commit is:

i965/blorp: Fix sRGB MSAA resolves.

Commit e2249e8c4d06a85d6389ba1689e15d7e29aa4dff (i965/blorp: Add
support for blits between SRGB and linear formats) changed blorp to
always configure surface states for in linear format (even if the
underlying surface is sRGB).  This allowed sRGB-to-linear and
linear-to-sRGB blits to occur without causing the image to be
inappropriately brightened or darkened.

However, it broke sRGB MSAA resolves, since they rely on the
destination buffer format being sRGB in order to ensure that samples
are averaged together in sRGB-correct fashion.

This patch fixes the problem by instead configuring the source buffer
to use the *same* format as the destination buffer.  This ensures that
the image won't be brightened or darkened, but preserves proper sRGB
averaging.

Fixes piglit tests "EXT_framebuffer_multisample/accuracy srgb".

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55265

Reviewed-by: Eric Anholt <eric at anholt.net>
Reviewed-and-tested-by: Kenneth Graunke <kenneth at whitecape.org>
(cherry picked from commit 124b214f094fa63ff1ddb7e9f0a1c2e0ba8214fb)

---

 src/mesa/drivers/dri/i965/brw_blorp.cpp      |    9 ++++-----
 src/mesa/drivers/dri/i965/brw_blorp_blit.cpp |   20 ++++++++++++++++++--
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index b08ce07..b847980 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -102,11 +102,10 @@ brw_blorp_surface_info::set(struct brw_context *brw,
       this->brw_surfaceformat = BRW_SURFACEFORMAT_R8G8_UNORM;
       break;
    default:
-      /* Blorp blits don't support any sort of format conversion, so we can
-       * safely assume that the same format is being used for the source and
-       * destination.  Therefore the format must be supported as a render
-       * target, even if this is the source image.  So we can convert to a
-       * surface format using brw->render_target_format.
+      /* Blorp blits don't support any sort of format conversion (except
+       * between sRGB and linear), so we can safely assume that the format is
+       * supported as a render target, even if this is the source image.  So
+       * we can convert to a surface format using brw->render_target_format.
        */
       assert(brw->format_supported_as_render_target[mt->format]);
       this->brw_surfaceformat = brw->render_target_format[mt->format];
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index 2207230..e8604e7 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -180,8 +180,11 @@ formats_match(GLbitfield buffer_bit, struct intel_renderbuffer *src_irb,
     * example MESA_FORMAT_X8_Z24 and MESA_FORMAT_S8_Z24), and we can blit
     * between those formats.
     */
-   return find_miptree(buffer_bit, src_irb)->format ==
-      find_miptree(buffer_bit, dst_irb)->format;
+   gl_format src_format = find_miptree(buffer_bit, src_irb)->format;
+   gl_format dst_format = find_miptree(buffer_bit, dst_irb)->format;
+
+   return _mesa_get_srgb_format_linear(src_format) ==
+          _mesa_get_srgb_format_linear(dst_format);
 }
 
 
@@ -1638,6 +1641,19 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
    src.set(brw, src_mt, src_level, src_layer);
    dst.set(brw, dst_mt, dst_level, dst_layer);
 
+   /* If we are blitting from sRGB to linear or vice versa, we still want the
+    * blit to be a direct copy, so we need source and destination to use the
+    * same format.  However, we want the destination sRGB/linear state to be
+    * correct (so that sRGB blending is used when doing an MSAA resolve to an
+    * sRGB surface, and linear blending is used when doing an MSAA resolve to
+    * a linear surface).  Since blorp blits don't support any format
+    * conversion (except between sRGB and linear), we can accomplish this by
+    * simply setting up the source to use the same format as the destination.
+    */
+   assert(_mesa_get_srgb_format_linear(src_mt->format) ==
+          _mesa_get_srgb_format_linear(dst_mt->format));
+   src.brw_surfaceformat = dst.brw_surfaceformat;
+
    use_wm_prog = true;
    memset(&wm_prog_key, 0, sizeof(wm_prog_key));
 




More information about the mesa-commit mailing list