From: Grazvydas Ignotas Date: Wed, 2 Sep 2015 22:54:29 +0000 (+0300) Subject: r600g: make all viewport states use single atom X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4d9af438bc41ed20da1963a438249fee43213121;p=mesa.git r600g: make all viewport states use single atom Similarly to scissor states, we can use single atom to track all viewport states. This will allow to simplify dirty atom handling later. Signed-off-by: Marek Olšák --- diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 3a7f583ecfa..5212db3c1a7 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -3450,7 +3450,7 @@ fallback: void evergreen_init_state_functions(struct r600_context *rctx) { unsigned id = 4; - int i; + /* !!! * To avoid GPU lockup registers must be emited in a specific order * (no kidding ...). The order below is important and have been @@ -3503,10 +3503,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) 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); - rctx->viewport[i].idx = i; - } + r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 0); 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); r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 8774cb5d655..d1370cd8f26 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -65,7 +65,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer_state.cso); if (op & R600_SAVE_FRAGMENT_STATE) { - util_blitter_save_viewport(rctx->blitter, &rctx->viewport[0].state); + util_blitter_save_viewport(rctx->blitter, &rctx->viewport.state[0]); 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); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index c5403252d36..092f261700c 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -287,7 +287,7 @@ void r600_context_gfx_flush(void *context, unsigned flags, void r600_begin_new_cs(struct r600_context *ctx) { unsigned shader; - int i; + ctx->b.flags = 0; ctx->b.gtt = 0; ctx->b.vram = 0; @@ -311,9 +311,9 @@ void r600_begin_new_cs(struct r600_context *ctx) 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->viewport[i].atom); - } + ctx->viewport.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1; + ctx->viewport.atom.num_dw = R600_MAX_VIEWPORTS * 8; + r600_mark_atom_dirty(ctx, &ctx->viewport.atom); if (ctx->b.chip_class < EVERGREEN) { r600_mark_atom_dirty(ctx, &ctx->config_state.atom); } diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index e09bee15d46..bf6bd766097 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 60 +#define R600_NUM_ATOMS 45 #define R600_MAX_VIEWPORTS 16 @@ -208,8 +208,8 @@ struct r600_stencil_ref_state { struct r600_viewport_state { struct r600_atom atom; - struct pipe_viewport_state state; - int idx; + struct pipe_viewport_state state[R600_MAX_VIEWPORTS]; + uint32_t dirty_mask; }; struct r600_shader_stages_state { @@ -463,7 +463,7 @@ struct r600_context { struct r600_config_state config_state; struct r600_stencil_ref_state stencil_ref; struct r600_vgt_state vgt_state; - struct r600_viewport_state viewport[R600_MAX_VIEWPORTS]; + struct r600_viewport_state viewport; /* Shaders and shader resources. */ struct r600_cso_state vertex_fetch_shader; struct r600_shader_state vertex_shader; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index c3db1437200..6724cc080b5 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -3032,7 +3032,6 @@ fallback: void r600_init_state_functions(struct r600_context *rctx) { unsigned id = 4; - int i; /* !!! * To avoid GPU lockup registers must be emited in a specific order @@ -3081,10 +3080,7 @@ void r600_init_state_functions(struct r600_context *rctx) 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->viewport[i].atom, id++, r600_emit_viewport_state, 8); - rctx->viewport[i].idx = i; - } + r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 0); r600_init_atom(rctx, &rctx->config_state.atom, id++, r600_emit_config_state, 3); r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 0b3fe857591..1f96ed6e12c 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -704,28 +704,39 @@ static void r600_set_viewport_states(struct pipe_context *ctx, const struct pipe_viewport_state *state) { struct r600_context *rctx = (struct r600_context *)ctx; + struct r600_viewport_state *rstate = &rctx->viewport; int i; - for (i = start_slot; i < start_slot + num_viewports; i++) { - rctx->viewport[i].state = state[i - start_slot]; - r600_mark_atom_dirty(rctx, &rctx->viewport[i].atom); - } + for (i = start_slot; i < start_slot + num_viewports; i++) + rstate->state[i] = state[i - start_slot]; + rstate->dirty_mask |= ((1 << num_viewports) - 1) << start_slot; + rstate->atom.num_dw = util_bitcount(rstate->dirty_mask) * 8; + r600_mark_atom_dirty(rctx, &rctx->viewport.atom); } void r600_emit_viewport_state(struct r600_context *rctx, struct r600_atom *atom) { struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs; - struct r600_viewport_state *rstate = (struct r600_viewport_state *)atom; - struct pipe_viewport_state *state = &rstate->state; - int offset = rstate->idx * 6 * 4; - - radeon_set_context_reg_seq(cs, R_02843C_PA_CL_VPORT_XSCALE_0 + offset, 6); - radeon_emit(cs, fui(state->scale[0])); /* R_02843C_PA_CL_VPORT_XSCALE_0 */ - radeon_emit(cs, fui(state->translate[0])); /* R_028440_PA_CL_VPORT_XOFFSET_0 */ - radeon_emit(cs, fui(state->scale[1])); /* R_028444_PA_CL_VPORT_YSCALE_0 */ - radeon_emit(cs, fui(state->translate[1])); /* R_028448_PA_CL_VPORT_YOFFSET_0 */ - radeon_emit(cs, fui(state->scale[2])); /* R_02844C_PA_CL_VPORT_ZSCALE_0 */ - radeon_emit(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */ + struct r600_viewport_state *rstate = &rctx->viewport; + struct pipe_viewport_state *state; + uint32_t dirty_mask; + unsigned i, offset; + + dirty_mask = rstate->dirty_mask; + while (dirty_mask != 0) { + i = u_bit_scan(&dirty_mask); + offset = i * 6 * 4; + radeon_set_context_reg_seq(cs, R_02843C_PA_CL_VPORT_XSCALE_0 + offset, 6); + state = &rstate->state[i]; + radeon_emit(cs, fui(state->scale[0])); /* R_02843C_PA_CL_VPORT_XSCALE_0 */ + radeon_emit(cs, fui(state->translate[0])); /* R_028440_PA_CL_VPORT_XOFFSET_0 */ + radeon_emit(cs, fui(state->scale[1])); /* R_028444_PA_CL_VPORT_YSCALE_0 */ + radeon_emit(cs, fui(state->translate[1])); /* R_028448_PA_CL_VPORT_YOFFSET_0 */ + radeon_emit(cs, fui(state->scale[2])); /* R_02844C_PA_CL_VPORT_ZSCALE_0 */ + radeon_emit(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */ + } + rstate->dirty_mask = 0; + rstate->atom.num_dw = 0; } /* Compute the key for the hw shader variant */