From: Marek Olšák Date: Thu, 31 May 2018 02:38:05 +0000 (-0400) Subject: radeonsi: move the guardband registers into a separate state atom X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d6974feb90e7c813a0ceb93fa77812a0197ffe31;hp=68b1c669e7291fc3e5629b1f44cdd97f92db702a;p=mesa.git radeonsi: move the guardband registers into a separate state atom 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 --- diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index b81773e01a0..e01705d0775 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -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); diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index c87f79e0190..69a53f7a10b 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index dc05021f492..5b9d7402019 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -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) | diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 5588c9a2c53..e33e235620a 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/si_state_viewport.c b/src/gallium/drivers/radeonsi/si_state_viewport.c index bffb1f91827..97b1b89b48b 100644 --- a/src/gallium/drivers/radeonsi/si_state_viewport.c +++ b/src/gallium/drivers/radeonsi/si_state_viewport.c @@ -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;