diff --git a/src/gallium/drivers/radeonsi/si_build_pm4.h b/src/gallium/drivers/radeonsi/si_build_pm4.h index 0c92b1a35c0..b339cd57ce7 100644 --- a/src/gallium/drivers/radeonsi/si_build_pm4.h +++ b/src/gallium/drivers/radeonsi/si_build_pm4.h @@ -181,4 +181,37 @@ static inline void radeon_opt_set_context_reg3(struct si_context *sctx, unsigned } } +/** + * Set 4 consecutive registers if any registers value is different. + */ +static inline void radeon_opt_set_context_reg4(struct si_context *sctx, unsigned offset, + enum si_tracked_reg reg, unsigned value1, + unsigned value2, unsigned value3, + unsigned value4) +{ + struct radeon_cmdbuf *cs = sctx->gfx_cs; + + if (!(sctx->tracked_regs.reg_saved & (1 << reg)) || + !(sctx->tracked_regs.reg_saved & (1 << (reg + 1))) || + !(sctx->tracked_regs.reg_saved & (1 << (reg + 2))) || + !(sctx->tracked_regs.reg_saved & (1 << (reg + 3))) || + sctx->tracked_regs.reg_value[reg] != value1 || + sctx->tracked_regs.reg_value[reg+1] != value2 || + sctx->tracked_regs.reg_value[reg+2] != value3 || + sctx->tracked_regs.reg_value[reg+3] != value4 ) { + + radeon_set_context_reg_seq(cs, offset, 4); + radeon_emit(cs, value1); + radeon_emit(cs, value2); + radeon_emit(cs, value3); + radeon_emit(cs, value4); + + sctx->tracked_regs.reg_value[reg] = value1; + sctx->tracked_regs.reg_value[reg+1] = value2; + sctx->tracked_regs.reg_value[reg+2] = value3; + sctx->tracked_regs.reg_value[reg+3] = value4; + sctx->tracked_regs.reg_saved |= 0xf << reg; + } +} + #endif diff --git a/src/gallium/drivers/radeonsi/si_gfx_cs.c b/src/gallium/drivers/radeonsi/si_gfx_cs.c index ac4909a847a..628b6c50e46 100644 --- a/src/gallium/drivers/radeonsi/si_gfx_cs.c +++ b/src/gallium/drivers/radeonsi/si_gfx_cs.c @@ -342,6 +342,10 @@ void si_begin_new_gfx_cs(struct si_context *ctx) ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_CLIP_CNTL] = 0x00090000; ctx->tracked_regs.reg_value[SI_TRACKED_PA_SC_BINNER_CNTL_0] = 0x00000003; ctx->tracked_regs.reg_value[SI_TRACKED_DB_DFSM_CONTROL] = 0x00000000; + ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_GB_VERT_CLIP_ADJ] = 0x3f800000; + ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_GB_VERT_DISC_ADJ] = 0x3f800000; + ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_GB_HORZ_CLIP_ADJ] = 0x3f800000; + ctx->tracked_regs.reg_value[SI_TRACKED_PA_CL_GB_HORZ_DISC_ADJ] = 0x3f800000; /* Set all saved registers state to saved. */ ctx->tracked_regs.reg_saved = 0xffffffff; diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index f8748bdfffb..71056c76c38 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -276,6 +276,11 @@ enum si_tracked_reg { SI_TRACKED_PA_SC_BINNER_CNTL_0, SI_TRACKED_DB_DFSM_CONTROL, + SI_TRACKED_PA_CL_GB_VERT_CLIP_ADJ, /* 4 consecutive registers */ + SI_TRACKED_PA_CL_GB_VERT_DISC_ADJ, + SI_TRACKED_PA_CL_GB_HORZ_CLIP_ADJ, + SI_TRACKED_PA_CL_GB_HORZ_DISC_ADJ, + SI_NUM_TRACKED_REGS, }; diff --git a/src/gallium/drivers/radeonsi/si_state_viewport.c b/src/gallium/drivers/radeonsi/si_state_viewport.c index 3b16bdcb17f..4183be0c880 100644 --- a/src/gallium/drivers/radeonsi/si_state_viewport.c +++ b/src/gallium/drivers/radeonsi/si_state_viewport.c @@ -140,7 +140,6 @@ 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_cmdbuf *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; @@ -214,13 +213,14 @@ static void si_emit_guardband(struct si_context *ctx) discard_y = MIN2(discard_y, guardband_y); } - /* If any of the GB registers is updated, all of them must be updated. */ - radeon_set_context_reg_seq(cs, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, 4); - - radeon_emit(cs, fui(guardband_y)); /* R_028BE8_PA_CL_GB_VERT_CLIP_ADJ */ - radeon_emit(cs, fui(discard_y)); /* R_028BEC_PA_CL_GB_VERT_DISC_ADJ */ - radeon_emit(cs, fui(guardband_x)); /* R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ */ - radeon_emit(cs, fui(discard_x)); /* R_028BF4_PA_CL_GB_HORZ_DISC_ADJ */ + /* If any of the GB registers is updated, all of them must be updated. + * R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, R_028BEC_PA_CL_GB_VERT_DISC_ADJ + * R_028BF0_PA_CL_GB_HORZ_CLIP_ADJ, R_028BF4_PA_CL_GB_HORZ_DISC_ADJ + */ + radeon_opt_set_context_reg4(ctx, R_028BE8_PA_CL_GB_VERT_CLIP_ADJ, + SI_TRACKED_PA_CL_GB_VERT_CLIP_ADJ, + fui(guardband_y), fui(discard_y), + fui(guardband_x), fui(discard_x)); } static void si_emit_scissors(struct si_context *ctx)