radeonsi: Don't modify PA_SC_RASTER_CONFIG register value if rb_mask == 0
[mesa.git] / src / gallium / drivers / radeonsi / si_state.c
index 6eb00062e549be03653d1b7604a8ee227d321f51..5a417b0211c54989e0cf1e5a5071334291b19eeb 100644 (file)
@@ -210,13 +210,19 @@ static unsigned si_pack_float_12p4(float x)
 }
 
 /*
- * inferred framebuffer and blender state
+ * Inferred framebuffer and blender state.
+ *
+ * One of the reasons this must be derived from the framebuffer state is that:
+ * - The blend state mask is 0xf most of the time.
+ * - The COLOR1 format isn't INVALID because of possible dual-source blending,
+ *   so COLOR1 is enabled pretty much all the time.
+ * So CB_TARGET_MASK is the only register that can disable COLOR1.
  */
 static void si_update_fb_blend_state(struct si_context *sctx)
 {
        struct si_pm4_state *pm4;
        struct si_state_blend *blend = sctx->queued.named.blend;
-       uint32_t mask;
+       uint32_t mask = 0, i;
 
        if (blend == NULL)
                return;
@@ -225,10 +231,12 @@ static void si_update_fb_blend_state(struct si_context *sctx)
        if (pm4 == NULL)
                return;
 
-       mask = (1ULL << ((unsigned)sctx->framebuffer.state.nr_cbufs * 4)) - 1;
+       for (i = 0; i < sctx->framebuffer.state.nr_cbufs; i++)
+               if (sctx->framebuffer.state.cbufs[i])
+                       mask |= 0xf << (4*i);
        mask &= blend->cb_target_mask;
-       si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
 
+       si_pm4_set_reg(pm4, R_028238_CB_TARGET_MASK, mask);
        si_pm4_set_state(sctx, fb_blend, pm4);
 }
 
@@ -450,6 +458,36 @@ static void si_set_clip_state(struct pipe_context *ctx,
        si_pm4_set_state(sctx, clip, pm4);
 }
 
+#define SIX_BITS 0x3F
+
+static void si_emit_clip_regs(struct si_context *sctx, struct r600_atom *atom)
+{
+       struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs;
+       struct tgsi_shader_info *info = si_get_vs_info(sctx);
+       struct si_shader *vs = si_get_vs_state(sctx);
+       unsigned window_space =
+          vs->selector->info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION];
+       unsigned clipdist_mask =
+               info->writes_clipvertex ? SIX_BITS : info->clipdist_writemask;
+
+       r600_write_context_reg(cs, R_02881C_PA_CL_VS_OUT_CNTL,
+               S_02881C_USE_VTX_POINT_SIZE(info->writes_psize) |
+               S_02881C_USE_VTX_EDGE_FLAG(info->writes_edgeflag) |
+               S_02881C_USE_VTX_RENDER_TARGET_INDX(info->writes_layer) |
+               S_02881C_VS_OUT_CCDIST0_VEC_ENA((clipdist_mask & 0x0F) != 0) |
+               S_02881C_VS_OUT_CCDIST1_VEC_ENA((clipdist_mask & 0xF0) != 0) |
+               S_02881C_VS_OUT_MISC_VEC_ENA(info->writes_psize ||
+                                           info->writes_edgeflag ||
+                                           info->writes_layer) |
+               (sctx->queued.named.rasterizer->clip_plane_enable &
+                clipdist_mask));
+       r600_write_context_reg(cs, R_028810_PA_CL_CLIP_CNTL,
+               sctx->queued.named.rasterizer->pa_cl_clip_cntl |
+               (clipdist_mask ? 0 :
+                sctx->queued.named.rasterizer->clip_plane_enable & SIX_BITS) |
+               S_028810_CLIP_DISABLE(window_space));
+}
+
 static void si_set_scissor_states(struct pipe_context *ctx,
                                   unsigned start_slot,
                                   unsigned num_scissors,
@@ -670,7 +708,6 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
                return;
 
        // TODO
-       sctx->sprite_coord_enable = rs->sprite_coord_enable;
        sctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
        sctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
 
@@ -680,6 +717,9 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
 
        si_pm4_bind_state(sctx, rasterizer, rs);
        si_update_fb_rs_state(sctx);
+
+       sctx->clip_regs.dirty = true;
+       sctx->last_rast_prim = -1; /* reset this so that it gets updated */
 }
 
 static void si_delete_rs_state(struct pipe_context *ctx, void *state)
@@ -2738,6 +2778,7 @@ void si_init_state_functions(struct si_context *sctx)
 {
        si_init_atom(&sctx->framebuffer.atom, &sctx->atoms.s.framebuffer, si_emit_framebuffer_state, 0);
        si_init_atom(&sctx->db_render_state, &sctx->atoms.s.db_render_state, si_emit_db_render_state, 10);
+       si_init_atom(&sctx->clip_regs, &sctx->atoms.s.clip_regs, si_emit_clip_regs, 6);
 
        sctx->b.b.create_blend_state = si_create_blend_state;
        sctx->b.b.bind_blend_state = si_bind_blend_state;
@@ -2991,8 +3032,10 @@ void si_init_config(struct si_context *sctx)
                        break;
                }
 
-               /* Always use the default config when all backends are enabled. */
-               if (rb_mask && util_bitcount(rb_mask) >= num_rb) {
+               /* Always use the default config when all backends are enabled
+                * (or when we failed to determine the enabled backends).
+                */
+               if (!rb_mask || util_bitcount(rb_mask) >= num_rb) {
                        si_pm4_set_reg(pm4, R_028350_PA_SC_RASTER_CONFIG,
                                       raster_config);
                } else {