radeonsi: move the guardband registers into a separate state atom
authorMarek Olšák <marek.olsak@amd.com>
Thu, 31 May 2018 02:38:05 +0000 (22:38 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Thu, 14 Jun 2018 02:00:31 +0000 (22:00 -0400)
They have a different frequency of updates and don't change when scissors
change.

I think this even fixes something in si_update_vs_viewport_state.

Tested-by: Dieter Nützel <Dieter@nuetzel-hh.de>
src/gallium/drivers/radeonsi/si_gfx_cs.c
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c
src/gallium/drivers/radeonsi/si_state_viewport.c

index b81773e01a077d7656ec6db07d6d4b2282681275..e01705d0775a788fe282d9dd36001bd06787abb7 100644 (file)
@@ -284,6 +284,7 @@ void si_begin_new_gfx_cs(struct si_context *ctx)
        ctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
        ctx->viewports.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
        ctx->viewports.depth_range_dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
+       si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
        si_mark_atom_dirty(ctx, &ctx->atoms.s.scissors);
        si_mark_atom_dirty(ctx, &ctx->atoms.s.viewports);
 
index c87f79e01905d808ea37303a2b2a14824f006f4b..69a53f7a10bcdd81db7b67518e3e6f72045bf378 100644 (file)
@@ -1007,13 +1007,16 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
        si_update_poly_offset_state(sctx);
 
        if (!old_rs ||
-           (old_rs->scissor_enable != rs->scissor_enable ||
-            old_rs->line_width != rs->line_width ||
-            old_rs->max_point_size != rs->max_point_size)) {
+           old_rs->scissor_enable != rs->scissor_enable) {
                sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
                si_mark_atom_dirty(sctx, &sctx->atoms.s.scissors);
        }
 
+       if (!old_rs ||
+           old_rs->line_width != rs->line_width ||
+           old_rs->max_point_size != rs->max_point_size)
+               si_mark_atom_dirty(sctx, &sctx->atoms.s.guardband);
+
        if (!old_rs ||
            old_rs->clip_halfz != rs->clip_halfz) {
                sctx->viewports.depth_range_dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
index dc05021f4920e2a84ecda56dac965a7c7e407eca..5b9d7402019f963024a2645820b8c122b808328d 100644 (file)
@@ -207,6 +207,7 @@ union si_state_atoms {
                struct si_atom clip_regs;
                struct si_atom clip_state;
                struct si_atom shader_pointers;
+               struct si_atom guardband;
                struct si_atom scissors;
                struct si_atom viewports;
                struct si_atom stencil_ref;
@@ -234,6 +235,7 @@ static inline unsigned si_atoms_that_roll_context(void)
                SI_ATOM_BIT(blend_color) |
                SI_ATOM_BIT(clip_regs) |
                SI_ATOM_BIT(clip_state) |
+               SI_ATOM_BIT(guardband) |
                SI_ATOM_BIT(scissors) |
                SI_ATOM_BIT(viewports) |
                SI_ATOM_BIT(stencil_ref) |
index 5588c9a2c53955c46a179a76f4abfb6d18bf5071..e33e235620a3873adb30f3f47fdf38c3ee6e5cfc 100644 (file)
@@ -1277,10 +1277,8 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
        if (rast_prim != sctx->current_rast_prim) {
                bool old_is_poly = sctx->current_rast_prim >= PIPE_PRIM_TRIANGLES;
                bool new_is_poly = rast_prim >= PIPE_PRIM_TRIANGLES;
-               if (old_is_poly != new_is_poly) {
-                       sctx->scissors.dirty_mask = (1 << SI_MAX_VIEWPORTS) - 1;
-                       si_mark_atom_dirty(sctx, &sctx->atoms.s.scissors);
-               }
+               if (old_is_poly != new_is_poly)
+                       si_mark_atom_dirty(sctx, &sctx->atoms.s.guardband);
 
                sctx->current_rast_prim = rast_prim;
                sctx->do_update_shaders = true;
index bffb1f91827272539df70c2187898ebd6588672a..97b1b89b48b0502b6b6d7ba644db78cc94430855 100644 (file)
@@ -136,14 +136,28 @@ static void si_emit_one_scissor(struct si_context *ctx,
 /* the range is [-MAX, MAX] */
 #define SI_MAX_VIEWPORT_RANGE 32768
 
-static void si_emit_guardband(struct si_context *ctx,
-                             struct si_signed_scissor *vp_as_scissor)
+static void si_emit_guardband(struct si_context *ctx)
 {
+       const struct si_signed_scissor *vp_as_scissor;
+       struct si_signed_scissor max_vp_scissor;
        struct radeon_winsys_cs *cs = ctx->gfx_cs;
        struct pipe_viewport_state vp;
        float left, top, right, bottom, max_range, guardband_x, guardband_y;
        float discard_x, discard_y;
 
+       if (ctx->vs_writes_viewport_index) {
+               /* Shaders can draw to any viewport. Make a union of all
+                * viewports. */
+               max_vp_scissor = ctx->viewports.as_scissor[0];
+               for (unsigned i = 1; i < SI_MAX_VIEWPORTS; i++) {
+                       si_scissor_make_union(&max_vp_scissor,
+                                             &ctx->viewports.as_scissor[i]);
+               }
+               vp_as_scissor = &max_vp_scissor;
+       } else {
+               vp_as_scissor = &ctx->viewports.as_scissor[0];
+       }
+
        /* Reconstruct the viewport transformation from the scissor. */
        vp.translate[0] = (vp_as_scissor->minx + vp_as_scissor->maxx) / 2.0;
        vp.translate[1] = (vp_as_scissor->miny + vp_as_scissor->maxy) / 2.0;
@@ -216,8 +230,6 @@ static void si_emit_scissors(struct si_context *ctx)
        struct pipe_scissor_state *states = ctx->scissors.states;
        unsigned mask = ctx->scissors.dirty_mask;
        bool scissor_enabled = false;
-       struct si_signed_scissor max_vp_scissor;
-       int i;
 
        if (ctx->queued.named.rasterizer)
                scissor_enabled = ctx->queued.named.rasterizer->scissor_enable;
@@ -231,17 +243,10 @@ static void si_emit_scissors(struct si_context *ctx)
 
                radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2);
                si_emit_one_scissor(ctx, cs, vp, scissor_enabled ? &states[0] : NULL);
-               si_emit_guardband(ctx, vp);
                ctx->scissors.dirty_mask &= ~1; /* clear one bit */
                return;
        }
 
-       /* Shaders can draw to any viewport. Make a union of all viewports. */
-       max_vp_scissor = ctx->viewports.as_scissor[0];
-       for (i = 1; i < SI_MAX_VIEWPORTS; i++)
-               si_scissor_make_union(&max_vp_scissor,
-                                     &ctx->viewports.as_scissor[i]);
-
        while (mask) {
                int start, count, i;
 
@@ -254,7 +259,6 @@ static void si_emit_scissors(struct si_context *ctx)
                                            scissor_enabled ? &states[i] : NULL);
                }
        }
-       si_emit_guardband(ctx, &max_vp_scissor);
        ctx->scissors.dirty_mask = 0;
 }
 
@@ -280,6 +284,7 @@ static void si_set_viewport_states(struct pipe_context *pctx,
        ctx->viewports.depth_range_dirty_mask |= mask;
        ctx->scissors.dirty_mask |= mask;
        si_mark_atom_dirty(ctx, &ctx->atoms.s.viewports);
+       si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
        si_mark_atom_dirty(ctx, &ctx->atoms.s.scissors);
 }
 
@@ -419,7 +424,13 @@ void si_update_vs_viewport_state(struct si_context *ctx)
        }
 
        /* Viewport index handling. */
+       if (ctx->vs_writes_viewport_index == info->writes_viewport_index)
+               return;
+
+       /* This changes how the guardband is computed. */
        ctx->vs_writes_viewport_index = info->writes_viewport_index;
+       si_mark_atom_dirty(ctx, &ctx->atoms.s.guardband);
+
        if (!ctx->vs_writes_viewport_index)
                return;
 
@@ -433,6 +444,7 @@ void si_update_vs_viewport_state(struct si_context *ctx)
 
 void si_init_viewport_functions(struct si_context *ctx)
 {
+       ctx->atoms.s.guardband.emit = si_emit_guardband;
        ctx->atoms.s.scissors.emit = si_emit_scissors;
        ctx->atoms.s.viewports.emit = si_emit_viewport_states;