i965/gen6: Fix multisample resolve blits for luminance/intensity 32F formats.
authorPaul Berry <stereotype441@gmail.com>
Wed, 27 Nov 2013 15:43:03 +0000 (07:43 -0800)
committerPaul Berry <stereotype441@gmail.com>
Sat, 30 Nov 2013 05:46:31 +0000 (21:46 -0800)
On gen6, multisamble resolve blits use the SAMPLE message to blend
together the 4 samples for each texel.  For some reason, SAMPLE
doesn't blend together the proper samples when the source format is
L32_FLOAT or I32_FLOAT, resulting in blocky artifacts.

To work around this problem, sample from the source surface using
R32_FLOAT.  This shouldn't affect rendering correctness, because when
doing these resolve blits, the destination format is R32_FLOAT, so the
channel replication done by L32_FLOAT and I32_FLOAT is unnecessary.

Fixes piglit tests on Sandy Bridge:
- spec/ARB_texture_float/multisample-formats 2 GL_ARB_texture_float
- spec/ARB_texture_float/multisample-formats 4 GL_ARB_texture_float

No piglit regressions on Sandy Bridge.

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

Cc: Kenneth Graunke <kenneth@whitecape.org>
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_blorp_blit.cpp

index 2d2edc1649c5bc257212b43dd5a3f9302d9436c9..9c48eacef5d6f5542c62f19391fabaffa2225b70 100644 (file)
@@ -2099,6 +2099,21 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
       src.brw_surfaceformat = dst.brw_surfaceformat;
    }
 
+   /* When doing a multisample resolve of a GL_LUMINANCE32F or GL_INTENSITY32F
+    * texture, the above code configures the source format for L32_FLOAT or
+    * I32_FLOAT, and the destination format for R32_FLOAT.  On Sandy Bridge,
+    * the SAMPLE message appears to handle multisampled L32_FLOAT and
+    * I32_FLOAT textures incorrectly, resulting in blocky artifacts.  So work
+    * around the problem by using a source format of R32_FLOAT.  This
+    * shouldn't affect rendering correctness, since the destination format is
+    * R32_FLOAT, so only the contents of the red channel matters.
+    */
+   if (brw->gen == 6 && src.num_samples > 1 && dst.num_samples <= 1 &&
+       src_mt->format == dst_mt->format &&
+       dst.brw_surfaceformat == BRW_SURFACEFORMAT_R32_FLOAT) {
+      src.brw_surfaceformat = dst.brw_surfaceformat;
+   }
+
    use_wm_prog = true;
    memset(&wm_prog_key, 0, sizeof(wm_prog_key));