From 18a189188ab5f209942ccc85cb8aac51f419b591 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 5 Oct 2012 05:37:38 +0200 Subject: [PATCH] r600g: atomize scissor state The workaround for R600 lacking VPORT_SCISSOR_ENABLE has also been simplified. Reviewed-by: Jerome Glisse --- .../drivers/r600/evergreen_hw_context.c | 4 -- src/gallium/drivers/r600/evergreen_state.c | 24 +++++----- src/gallium/drivers/r600/r600_blit.c | 2 +- src/gallium/drivers/r600/r600_hw_context.c | 3 +- src/gallium/drivers/r600/r600_pipe.c | 3 -- src/gallium/drivers/r600/r600_pipe.h | 19 ++++---- src/gallium/drivers/r600/r600_state.c | 45 +++++++++---------- src/gallium/drivers/r600/r600_state_common.c | 26 ++--------- 8 files changed, 48 insertions(+), 78 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_hw_context.c b/src/gallium/drivers/r600/evergreen_hw_context.c index 35cd639c214..f9b344d78b1 100644 --- a/src/gallium/drivers/r600/evergreen_hw_context.c +++ b/src/gallium/drivers/r600/evergreen_hw_context.c @@ -38,8 +38,6 @@ static const struct r600_reg evergreen_context_reg_list[] = { {R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0, 0}, - {R_028250_PA_SC_VPORT_SCISSOR_0_TL, 0, 0}, - {R_028254_PA_SC_VPORT_SCISSOR_0_BR, 0, 0}, {R_028350_SX_MISC, 0, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_02861C_SPI_VS_OUT_ID_0, 0, 0}, @@ -120,8 +118,6 @@ static const struct r600_reg cayman_context_reg_list[] = { {R_028014_DB_HTILE_DATA_BASE, REG_FLAG_NEED_BO, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_028234_PA_SU_HARDWARE_SCREEN_OFFSET, 0, 0}, - {R_028250_PA_SC_VPORT_SCISSOR_0_TL, 0, 0}, - {R_028254_PA_SC_VPORT_SCISSOR_0_BR, 0, 0}, {R_028350_SX_MISC, 0, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_02861C_SPI_VS_OUT_ID_0, 0, 0}, diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 4e3f2e59e93..872fedfaf9d 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1168,23 +1168,22 @@ static void evergreen_set_scissor_state(struct pipe_context *ctx, const struct pipe_scissor_state *state) { struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); - uint32_t tl, br; - rctx->scissor = *state; + rctx->scissor.scissor = *state; + rctx->scissor.atom.dirty = true; +} - if (rstate == NULL) - return; +static void evergreen_emit_scissor_state(struct r600_context *rctx, struct r600_atom *atom) +{ + struct radeon_winsys_cs *cs = rctx->cs; + struct pipe_scissor_state *state = &rctx->scissor.scissor; + uint32_t tl, br; evergreen_get_scissor_rect(rctx, state->minx, state->miny, state->maxx, state->maxy, &tl, &br); - rstate->id = R600_PIPE_STATE_SCISSOR; - r600_pipe_state_add_reg(rstate, R_028250_PA_SC_VPORT_SCISSOR_0_TL, tl); - r600_pipe_state_add_reg(rstate, R_028254_PA_SC_VPORT_SCISSOR_0_BR, br); - - free(rctx->states[R600_PIPE_STATE_SCISSOR]); - rctx->states[R600_PIPE_STATE_SCISSOR] = rstate; - r600_context_pipe_state_set(rctx, rstate); + r600_write_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2); + r600_write_value(cs, tl); + r600_write_value(cs, br); } /** @@ -2421,6 +2420,7 @@ void evergreen_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->clip_state.atom, id++, evergreen_emit_clip_state, 26); r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, evergreen_emit_db_misc_state, 7); r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, evergreen_emit_polygon_offset, 6); + r600_init_atom(rctx, &rctx->scissor.atom, id++, evergreen_emit_scissor_state, 4); r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8); 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 0c41294e95f..63867986d2d 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.state); - util_blitter_save_scissor(rctx->blitter, &rctx->scissor); + util_blitter_save_scissor(rctx->blitter, &rctx->scissor.scissor); 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->states[R600_PIPE_STATE_DSA]); diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index e624187981f..db641596461 100644 --- a/src/gallium/drivers/r600/r600_hw_context.c +++ b/src/gallium/drivers/r600/r600_hw_context.c @@ -225,8 +225,6 @@ static const struct r600_reg r600_context_reg_list[] = { {R_02880C_DB_SHADER_CONTROL, 0, 0}, {GROUP_FORCE_NEW_BLOCK, 0, 0}, {R_028D24_DB_HTILE_SURFACE, 0, 0}, - {R_028250_PA_SC_VPORT_SCISSOR_0_TL, 0, 0}, - {R_028254_PA_SC_VPORT_SCISSOR_0_BR, 0, 0}, {R_0286D4_SPI_INTERP_CONTROL_0, 0, 0}, {R_028814_PA_SU_SC_MODE_CNTL, 0, 0}, {R_028A00_PA_SU_POINT_SIZE, 0, 0}, @@ -866,6 +864,7 @@ void r600_begin_new_cs(struct r600_context *ctx) ctx->vgt_state.atom.dirty = true; ctx->vgt2_state.atom.dirty = true; ctx->sample_mask.atom.dirty = true; + ctx->scissor.atom.dirty = true; ctx->stencil_ref.atom.dirty = true; ctx->vertex_fetch_shader.atom.dirty = true; ctx->viewport.atom.dirty = true; diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 35fa9d49f1a..ba1954f5e0f 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -298,9 +298,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void r600_begin_new_cs(rctx); r600_get_backend_mask(rctx); /* this emits commands and must be last */ - if (rctx->chip_class == R600) - r600_set_max_scissor(rctx); - rctx->dummy_pixel_shader = util_make_fragment_cloneinput_shader(&rctx->context, 0, TGSI_SEMANTIC_GENERIC, diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index a548846beef..fc3591d1dd9 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -35,7 +35,7 @@ #include "r600_resource.h" #include "evergreen_compute.h" -#define R600_NUM_ATOMS 32 +#define R600_NUM_ATOMS 33 #define R600_MAX_CONST_BUFFERS 2 #define R600_MAX_CONST_BUFFER_SIZE 4096 @@ -161,7 +161,6 @@ struct r600_viewport_state { }; enum r600_pipe_state_id { - R600_PIPE_STATE_SCISSOR, R600_PIPE_STATE_RASTERIZER, R600_PIPE_STATE_DSA, R600_PIPE_NSTATES @@ -362,6 +361,13 @@ struct r600_cso_state struct r600_command_buffer *cb; }; +struct r600_scissor_state +{ + struct r600_atom atom; + struct pipe_scissor_state scissor; + bool enable; /* r6xx only */ +}; + struct r600_context { struct pipe_context context; struct blitter_context *blitter; @@ -381,7 +387,6 @@ struct r600_context { unsigned db_shader_control; unsigned pa_sc_line_stipple; /* for saving when using blitter */ - struct pipe_scissor_state scissor; struct r600_pipe_shader_selector *ps_shader; struct r600_pipe_shader_selector *vs_shader; struct r600_pipe_rasterizer *rasterizer; @@ -420,6 +425,7 @@ struct r600_context { struct r600_framebuffer framebuffer; struct r600_poly_offset_state poly_offset_state; struct r600_sample_mask sample_mask; + struct r600_scissor_state scissor; struct r600_seamless_cube_map seamless_cube_map; struct r600_stencil_ref_state stencil_ref; struct r600_vgt_state vgt_state; @@ -478,10 +484,6 @@ struct r600_context { boolean streamout_start; unsigned streamout_append_bitmask; - /* There is no scissor enable bit on r6xx, so we must use a workaround. - * This tracks if the scissor is enabled. */ - bool scissor_enable; - /* With rasterizer discard, there doesn't have to be a pixel shader. * In that case, we bind this one: */ void *dummy_pixel_shader; @@ -615,8 +617,6 @@ r600_create_sampler_view_custom(struct pipe_context *ctx, struct pipe_resource *texture, const struct pipe_sampler_view *state, unsigned width_first_level, unsigned height_first_level); -void r600_set_scissor_state(struct r600_context *rctx, - const struct pipe_scissor_state *state); void r600_init_state_functions(struct r600_context *rctx); void r600_init_atom_start_cs(struct r600_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); @@ -669,7 +669,6 @@ void r600_sampler_views_dirty(struct r600_context *rctx, struct r600_samplerview_state *state); void r600_sampler_states_dirty(struct r600_context *rctx, struct r600_sampler_states *state); -void r600_set_max_scissor(struct r600_context *rctx); void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state); void r600_draw_rectangle(struct blitter_context *blitter, int x1, int y1, int x2, int y2, float depth, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 728fcb6d60a..b675d270f23 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1134,39 +1134,35 @@ static void r600_set_polygon_stipple(struct pipe_context *ctx, { } -void r600_set_scissor_state(struct r600_context *rctx, - const struct pipe_scissor_state *state) +static void r600_emit_scissor_state(struct r600_context *rctx, struct r600_atom *atom) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); - uint32_t tl, br; - - if (rstate == NULL) - return; - - rstate->id = R600_PIPE_STATE_SCISSOR; - tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1); - br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy); - r600_pipe_state_add_reg(rstate, - R_028250_PA_SC_VPORT_SCISSOR_0_TL, tl); - r600_pipe_state_add_reg(rstate, - R_028254_PA_SC_VPORT_SCISSOR_0_BR, br); + struct radeon_winsys_cs *cs = rctx->cs; + struct pipe_scissor_state *state = &rctx->scissor.scissor; - free(rctx->states[R600_PIPE_STATE_SCISSOR]); - rctx->states[R600_PIPE_STATE_SCISSOR] = rstate; - r600_context_pipe_state_set(rctx, rstate); + if (rctx->chip_class != R600 || rctx->scissor.enable) { + r600_write_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2); + r600_write_value(cs, S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | + S_028240_WINDOW_OFFSET_DISABLE(1)); + r600_write_value(cs, S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy)); + } else { + r600_write_context_reg_seq(cs, R_028250_PA_SC_VPORT_SCISSOR_0_TL, 2); + r600_write_value(cs, S_028240_TL_X(0) | S_028240_TL_Y(0) | + S_028240_WINDOW_OFFSET_DISABLE(1)); + r600_write_value(cs, S_028244_BR_X(8192) | S_028244_BR_Y(8192)); + } } -static void r600_pipe_set_scissor_state(struct pipe_context *ctx, - const struct pipe_scissor_state *state) +static void r600_set_scissor_state(struct pipe_context *ctx, + const struct pipe_scissor_state *state) { struct r600_context *rctx = (struct r600_context *)ctx; - rctx->scissor = *state; + rctx->scissor.scissor = *state; - if (rctx->chip_class == R600 && !rctx->scissor_enable) + if (rctx->chip_class == R600 && !rctx->scissor.enable) return; - r600_set_scissor_state(rctx, state); + rctx->scissor.atom.dirty = true; } static struct r600_resource *r600_buffer_create_helper(struct r600_screen *rscreen, @@ -2183,6 +2179,7 @@ void r600_init_state_functions(struct r600_context *rctx) r600_init_atom(rctx, &rctx->clip_state.atom, id++, r600_emit_clip_state, 26); r600_init_atom(rctx, &rctx->db_misc_state.atom, id++, r600_emit_db_misc_state, 4); r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 6); + r600_init_atom(rctx, &rctx->scissor.atom, id++, r600_emit_scissor_state, 4); r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4); r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 8); r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5); @@ -2194,7 +2191,7 @@ void r600_init_state_functions(struct r600_context *rctx) rctx->context.create_sampler_view = r600_create_sampler_view; rctx->context.set_framebuffer_state = r600_set_framebuffer_state; rctx->context.set_polygon_stipple = r600_set_polygon_stipple; - rctx->context.set_scissor_state = r600_pipe_set_scissor_state; + rctx->context.set_scissor_state = r600_set_scissor_state; } /* Adjust GPR allocation on R6xx/R7xx */ diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index e30ec3dae7d..3bc6d81fdba 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -298,18 +298,6 @@ static void r600_bind_dsa_state(struct pipe_context *ctx, void *state) } } -void r600_set_max_scissor(struct r600_context *rctx) -{ - /* Set a scissor state such that it doesn't do anything. */ - struct pipe_scissor_state scissor; - scissor.minx = 0; - scissor.miny = 0; - scissor.maxx = 8192; - scissor.maxy = 8192; - - r600_set_scissor_state(rctx, &scissor); -} - static void r600_bind_rs_state(struct pipe_context *ctx, void *state) { struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; @@ -345,16 +333,10 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state) } /* Workaround for a missing scissor enable on r600. */ - if (rctx->chip_class == R600) { - if (rs->scissor_enable != rctx->scissor_enable) { - rctx->scissor_enable = rs->scissor_enable; - - if (rs->scissor_enable) { - r600_set_scissor_state(rctx, &rctx->scissor); - } else { - r600_set_max_scissor(rctx); - } - } + if (rctx->chip_class == R600 && + rs->scissor_enable != rctx->scissor.enable) { + rctx->scissor.enable = rs->scissor_enable; + rctx->scissor.atom.dirty = true; } } -- 2.30.2