Module: Mesa Branch: master Commit: 7d475bad66b99e171542bc9ea62abac56abfa6f2 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=7d475bad66b99e171542bc9ea62abac56abfa6f2
Author: Grazvydas Ignotas <[email protected]> Date: Thu Sep 3 01:54:27 2015 +0300 r600g: make all scissor states use single atom As suggested by Marek Olšák, we can use single atom to track all scissor states. This will allow to simplify dirty atom handling later. Signed-off-by: Marek Olšák <[email protected]> --- src/gallium/drivers/r600/evergreen_state.c | 36 ++++++++++++-------- src/gallium/drivers/r600/r600_blit.c | 2 +- src/gallium/drivers/r600/r600_hw_context.c | 4 ++- src/gallium/drivers/r600/r600_pipe.h | 8 ++--- src/gallium/drivers/r600/r600_state.c | 46 ++++++++++++++++---------- src/gallium/drivers/r600/r600_state_common.c | 6 ++-- 6 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 0d4b598..3a7f583 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -892,27 +892,38 @@ static void evergreen_set_scissor_states(struct pipe_context *ctx, const struct pipe_scissor_state *state) { struct r600_context *rctx = (struct r600_context *)ctx; + struct r600_scissor_state *rstate = &rctx->scissor; int i; - for (i = start_slot; i < start_slot + num_scissors; i++) { - rctx->scissor[i].scissor = state[i - start_slot]; - r600_mark_atom_dirty(rctx, &rctx->scissor[i].atom); - } + for (i = start_slot; i < start_slot + num_scissors; i++) + rstate->scissor[i] = state[i - start_slot]; + rstate->dirty_mask |= ((1 << num_scissors) - 1) << start_slot; + rstate->atom.num_dw = util_bitcount(rstate->dirty_mask) * 4; + r600_mark_atom_dirty(rctx, &rstate->atom); } static void evergreen_emit_scissor_state(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs; - struct r600_scissor_state *rstate = (struct r600_scissor_state *)atom; - struct pipe_scissor_state *state = &rstate->scissor; - unsigned offset = rstate->idx * 4 * 2; + struct r600_scissor_state *rstate = &rctx->scissor; + struct pipe_scissor_state *state; + uint32_t dirty_mask; + unsigned i, offset; uint32_t tl, br; - evergreen_get_scissor_rect(rctx, state->minx, state->miny, state->maxx, state->maxy, &tl, &br); + dirty_mask = rstate->dirty_mask; + while (dirty_mask != 0) { + i = u_bit_scan(&dirty_mask); + state = &rstate->scissor[i]; + evergreen_get_scissor_rect(rctx, state->minx, state->miny, state->maxx, state->maxy, &tl, &br); - radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + offset, 2); - radeon_emit(cs, tl); - radeon_emit(cs, br); + offset = i * 4 * 2; + radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + offset, 2); + radeon_emit(cs, tl); + radeon_emit(cs, br); + } + rstate->dirty_mask = 0; + rstate->atom.num_dw = 0; } /** @@ -3491,11 +3502,10 @@ void evergreen_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 0); r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, evergreen_emit_polygon_offset, 6); r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0); + r600_init_atom(rctx, &rctx->scissor.atom, id++, evergreen_emit_scissor_state, 0); for (i = 0; i < R600_MAX_VIEWPORTS; i++) { r600_init_atom(rctx, &rctx->viewport[i].atom, id++, r600_emit_viewport_state, 8); - r600_init_atom(rctx, &rctx->scissor[i].atom, id++, evergreen_emit_scissor_state, 4); rctx->viewport[i].idx = i; - rctx->scissor[i].idx = i; } r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, evergreen_emit_vertex_fetch_shader, 5); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 08b2f64..8774cb5 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -66,7 +66,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op if (op & R600_SAVE_FRAGMENT_STATE) { util_blitter_save_viewport(rctx->blitter, &rctx->viewport[0].state); - util_blitter_save_scissor(rctx->blitter, &rctx->scissor[0].scissor); + util_blitter_save_scissor(rctx->blitter, &rctx->scissor.scissor[0]); util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); util_blitter_save_blend(rctx->blitter, rctx->blend_state.cso); util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa_state.cso); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 2fe29e9..c540325 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -308,8 +308,10 @@ void r600_begin_new_cs(struct r600_context *ctx) r600_mark_atom_dirty(ctx, &ctx->poly_offset_state.atom); r600_mark_atom_dirty(ctx, &ctx->vgt_state.atom); r600_mark_atom_dirty(ctx, &ctx->sample_mask.atom); + ctx->scissor.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1; + ctx->scissor.atom.num_dw = R600_MAX_VIEWPORTS * 4; + r600_mark_atom_dirty(ctx, &ctx->scissor.atom); for (i = 0; i < R600_MAX_VIEWPORTS; i++) { - r600_mark_atom_dirty(ctx, &ctx->scissor[i].atom); r600_mark_atom_dirty(ctx, &ctx->viewport[i].atom); } if (ctx->b.chip_class < EVERGREEN) { diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 8d5fd99..e09bee1 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -38,7 +38,7 @@ #include "tgsi/tgsi_scan.h" -#define R600_NUM_ATOMS 75 +#define R600_NUM_ATOMS 60 #define R600_MAX_VIEWPORTS 16 @@ -393,9 +393,9 @@ struct r600_cso_state struct r600_scissor_state { struct r600_atom atom; - struct pipe_scissor_state scissor; + struct pipe_scissor_state scissor[R600_MAX_VIEWPORTS]; + uint32_t dirty_mask; bool enable; /* r6xx only */ - int idx; }; struct r600_fetch_shader { @@ -458,7 +458,7 @@ struct r600_context { struct r600_poly_offset_state poly_offset_state; struct r600_cso_state rasterizer_state; struct r600_sample_mask sample_mask; - struct r600_scissor_state scissor[R600_MAX_VIEWPORTS]; + struct r600_scissor_state scissor; struct r600_seamless_cube_map seamless_cube_map; struct r600_config_state config_state; struct r600_stencil_ref_state stencil_ref; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index f2d24a3..64a22e6 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -769,21 +769,32 @@ static void r600_set_polygon_stipple(struct pipe_context *ctx, static void r600_emit_scissor_state(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs; - struct r600_scissor_state *rstate = (struct r600_scissor_state *)atom; - struct pipe_scissor_state *state = &rstate->scissor; - unsigned offset = rstate->idx * 4 * 2; + struct r600_scissor_state *rstate = &rctx->scissor; + struct pipe_scissor_state *state; + uint32_t dirty_mask; + unsigned i, offset; - if (rctx->b.chip_class != R600 || rctx->scissor[0].enable) { - radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + offset, 2); - radeon_emit(cs, S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | - S_028240_WINDOW_OFFSET_DISABLE(1)); - radeon_emit(cs, S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy)); - } else { + if (rctx->b.chip_class == R600 && !rctx->scissor.enable) { radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2); radeon_emit(cs, S_028240_TL_X(0) | S_028240_TL_Y(0) | S_028240_WINDOW_OFFSET_DISABLE(1)); radeon_emit(cs, S_028244_BR_X(8192) | S_028244_BR_Y(8192)); + return; + } + + dirty_mask = rstate->dirty_mask; + while (dirty_mask != 0) + { + i = u_bit_scan(&dirty_mask); + offset = i * 4 * 2; + state = &rstate->scissor[i]; + radeon_set_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL + offset, 2); + radeon_emit(cs, S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | + S_028240_WINDOW_OFFSET_DISABLE(1)); + radeon_emit(cs, S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy)); } + rstate->dirty_mask = 0; + rstate->atom.num_dw = 0; } static void r600_set_scissor_states(struct pipe_context *ctx, @@ -792,18 +803,18 @@ static void r600_set_scissor_states(struct pipe_context *ctx, const struct pipe_scissor_state *state) { struct r600_context *rctx = (struct r600_context *)ctx; + struct r600_scissor_state *rstate = &rctx->scissor; int i; - for (i = start_slot ; i < start_slot + num_scissors; i++) { - rctx->scissor[i].scissor = state[i - start_slot]; - } + for (i = start_slot ; i < start_slot + num_scissors; i++) + rstate->scissor[i] = state[i - start_slot]; + rstate->dirty_mask |= ((1 << num_scissors) - 1) << start_slot; + rstate->atom.num_dw = util_bitcount(rstate->dirty_mask) * 4; - if (rctx->b.chip_class == R600 && !rctx->scissor[0].enable) + if (rctx->b.chip_class == R600 && !rstate->enable) return; - for (i = start_slot ; i < start_slot + num_scissors; i++) { - r600_mark_atom_dirty(rctx, &rctx->scissor[i].atom); - } + r600_mark_atom_dirty(rctx, &rstate->atom); } static struct r600_resource *r600_buffer_create_helper(struct r600_screen *rscreen, @@ -3065,10 +3076,9 @@ void r600_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->dsa_state.atom, id++, r600_emit_cso_state, 0); r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 6); r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0); + r600_init_atom(rctx, &rctx->scissor.atom, id++, r600_emit_scissor_state, 0); for (i = 0;i < R600_MAX_VIEWPORTS; i++) { - r600_init_atom(rctx, &rctx->scissor[i].atom, id++, r600_emit_scissor_state, 4); r600_init_atom(rctx, &rctx->viewport[i].atom, id++, r600_emit_viewport_state, 8); - rctx->scissor[i].idx = i; rctx->viewport[i].idx = i; } r600_init_atom(rctx, &rctx->config_state.atom, id++, r600_emit_config_state, 3); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 24ed74b..d2b6ebe 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -372,9 +372,9 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state) /* Workaround for a missing scissor enable on r600. */ if (rctx->b.chip_class == R600 && - rs->scissor_enable != rctx->scissor[0].enable) { - rctx->scissor[0].enable = rs->scissor_enable; - r600_mark_atom_dirty(rctx, &rctx->scissor[0].atom); + rs->scissor_enable != rctx->scissor.enable) { + rctx->scissor.enable = rs->scissor_enable; + r600_mark_atom_dirty(rctx, &rctx->scissor.atom); } /* Re-emit PA_SC_LINE_STIPPLE. */ _______________________________________________ mesa-commit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-commit
