radeonsi: fix Polaris MSAA regression
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Sat, 16 Jul 2016 18:37:29 +0000 (20:37 +0200)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Sat, 23 Jul 2016 13:36:38 +0000 (15:36 +0200)
The regression was introduced by commit d938b8c. The problem here is that in
order to use the small primitive filter, we need to explicitly set the sample
locations to 0. But the DB doesn't properly process the change of sample
locations without a flush, and so we can end up with incorrect Z values.

Instead of doing a flush, just disable the small primitive filter when MSAA
is force-disabled.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96908
Cc: 12.0 <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/sid.h

index f801ca55829956d6daa46b97321b0334d69afc6e..c5b61e9411414af2021c6d054fbd20ce18c76ef1 100644 (file)
@@ -2569,22 +2569,31 @@ static void si_emit_msaa_sample_locs(struct si_context *sctx,
        if (nr_samples <= 1 && sctx->smoothing_enabled)
                nr_samples = SI_NUM_SMOOTH_AA_SAMPLES;
 
-       /* The small primitive filter on Polaris requires explicitly setting
-        * sample locations to 0 when MSAA is disabled.
+       /* On Polaris, the small primitive filter uses the sample locations
+        * even when MSAA is off, so we need to make sure they're set to 0.
         */
-       if (sctx->b.family >= CHIP_POLARIS10) {
-               struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
-
-               if (!sctx->smoothing_enabled &&
-                   rs && !rs->multisample_enable)
-                       nr_samples = 1;
-       }
-
        if ((nr_samples > 1 || sctx->b.family >= CHIP_POLARIS10) &&
            (nr_samples != sctx->msaa_sample_locs.nr_samples)) {
                sctx->msaa_sample_locs.nr_samples = nr_samples;
                cayman_emit_msaa_sample_locs(cs, nr_samples);
        }
+
+       if (sctx->b.family >= CHIP_POLARIS10) {
+               struct si_state_rasterizer *rs = sctx->queued.named.rasterizer;
+               unsigned small_prim_filter_cntl =
+                       S_028830_SMALL_PRIM_FILTER_ENABLE(1) |
+                       S_028830_LINE_FILTER_DISABLE(1); /* line bug */
+
+               /* The alternative of setting sample locations to 0 would
+                * require a DB flush to avoid Z errors, see
+                * https://bugs.freedesktop.org/show_bug.cgi?id=96908
+                */
+               if (sctx->framebuffer.nr_samples > 1 && rs && !rs->multisample_enable)
+                       small_prim_filter_cntl &= C_028830_SMALL_PRIM_FILTER_ENABLE;
+
+               radeon_set_context_reg(cs, R_028830_PA_SU_SMALL_PRIM_FILTER_CNTL,
+                                      small_prim_filter_cntl);
+       }
 }
 
 static void si_emit_msaa_config(struct si_context *sctx, struct r600_atom *atom)
@@ -3957,11 +3966,6 @@ static void si_init_config(struct si_context *sctx)
        if (sctx->b.family == CHIP_STONEY)
                si_pm4_set_reg(pm4, R_028C40_PA_SC_SHADER_CONTROL, 0);
 
-       if (sctx->b.family >= CHIP_POLARIS10)
-               si_pm4_set_reg(pm4, R_028830_PA_SU_SMALL_PRIM_FILTER_CNTL,
-                              S_028830_SMALL_PRIM_FILTER_ENABLE(1) |
-                              S_028830_LINE_FILTER_DISABLE(1)); /* line bug */
-
        si_pm4_set_reg(pm4, R_028080_TA_BC_BASE_ADDR, border_color_va >> 8);
        if (sctx->b.chip_class >= CIK)
                si_pm4_set_reg(pm4, R_028084_TA_BC_BASE_ADDR_HI, border_color_va >> 40);
index f6a05c544aede1196e558ba2dfd092c6633e6d99..0d2ac372dfb2b43cf831062fe39cb6ef50c9a934 100644 (file)
 /*     */
 #define R_028830_PA_SU_SMALL_PRIM_FILTER_CNTL                           0x028830 /* Polaris */
 #define   S_028830_SMALL_PRIM_FILTER_ENABLE(x)                        (((x) & 0x1) << 0)
+#define   C_028830_SMALL_PRIM_FILTER_ENABLE                           0xFFFFFFFE
 #define   S_028830_TRIANGLE_FILTER_DISABLE(x)                         (((x) & 0x1) << 1)
 #define   S_028830_LINE_FILTER_DISABLE(x)                             (((x) & 0x1) << 2)
 #define   S_028830_POINT_FILTER_DISABLE(x)                            (((x) & 0x1) << 3)