From 9804cf3118ae7249098af2a9c78b36f4fb576ee4 Mon Sep 17 00:00:00 2001 From: Vadim Girlin Date: Fri, 4 Nov 2011 21:24:03 +0400 Subject: [PATCH] r600g: move SPI setup to PS setup SPI semantic indices for PS/VS are now static, so we don't need to update spi config for every shaders combination. We can move the functionality of r600_spi_update to r600(evergreen)_pipe_shader_ps. Flatshade state is now controlled by the global FLAT_SHADE_ENA flag instead of updating FLAT_SHADE for all inputs. Sprite coord still requires the update of spi setup when sprite_coord_enable is first changed from zero (enabled), and then only when it's changed to other non-zero value (enabled for other input). Change to zero (disabling) and back to the same value is handled via global SPRITE_COORD_ENA. New field "sprite_coord_enable" added to "struct r600_pipe_shader" to track current state for the pixel shader. It's checked in the r600_update_derived_state. Signed-off-by: Vadim Girlin --- src/gallium/drivers/r600/evergreen_state.c | 30 +++++++++- src/gallium/drivers/r600/r600_pipe.h | 4 +- src/gallium/drivers/r600/r600_state.c | 29 +++++++++- src/gallium/drivers/r600/r600_state_common.c | 84 ++++++---------------------- 4 files changed, 73 insertions(+), 74 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 904267da1bd..c0b057cc334 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -908,7 +908,7 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; - tmp = S_0286D4_FLAT_SHADE_ENA(1); + tmp = S_0286D4_FLAT_SHADE_ENA(state->flatshade); if (state->sprite_coord_enable) { tmp |= S_0286D4_PNT_SPRITE_ENA(1) | S_0286D4_PNT_SPRITE_OVRD_X(2) | @@ -2246,7 +2246,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader int pos_index = -1, face_index = -1; int ninterp = 0; boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE; - unsigned spi_baryc_cntl; + unsigned spi_baryc_cntl, sid, tmp, idx = 0; rstate->nregs = 0; @@ -2267,7 +2267,31 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader if (rshader->input[i].centroid) have_centroid = TRUE; } + + sid = rshader->input[i].spi_sid; + + if (sid) { + + tmp = S_028644_SEMANTIC(sid); + + if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || + rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || + rshader->input[i].name == TGSI_SEMANTIC_POSITION) { + tmp |= S_028644_FLAT_SHADE(1); + } + + if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && + rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { + tmp |= S_028644_PT_SPRITE_TEX(1); + } + + r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + idx * 4, + tmp, 0xFFFFFFFF, NULL, 0); + + idx++; + } } + for (i = 0; i < rshader->noutput; i++) { if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1); @@ -2368,6 +2392,8 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader r600_pipe_state_add_reg(rstate, R_03A200_SQ_LOOP_CONST_0, 0x01000FFF, 0xFFFFFFFF, NULL, 0); + + shader->sprite_coord_enable = rctx->sprite_coord_enable; } void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader) diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 330e3202bab..92cb34dacad 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -68,7 +68,6 @@ enum r600_pipe_state_id { R600_PIPE_STATE_RESOURCE, R600_PIPE_STATE_POLYGON_OFFSET, R600_PIPE_STATE_FETCH_SHADER, - R600_PIPE_STATE_SPI, R600_PIPE_NSTATES }; @@ -133,6 +132,7 @@ struct r600_pipe_shader { struct r600_resource *bo_fetch; struct r600_vertex_element vertex_elements; struct tgsi_token *tokens; + unsigned sprite_coord_enable; }; struct r600_pipe_sampler_state { @@ -215,9 +215,7 @@ struct r600_pipe_context { /* shader information */ boolean clamp_vertex_color; boolean clamp_fragment_color; - boolean spi_dirty; unsigned sprite_coord_enable; - boolean flatshade; boolean export_16bpc; unsigned alpha_ref; boolean alpha_ref_dirty; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index ce65da668df..863a7a4ba5a 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -958,7 +958,7 @@ static void *r600_create_rs_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_RASTERIZER; if (state->flatshade_first) prov_vtx = 0; - tmp = S_0286D4_FLAT_SHADE_ENA(1); + tmp = S_0286D4_FLAT_SHADE_ENA(state->flatshade); if (state->sprite_coord_enable) { tmp |= S_0286D4_PNT_SPRITE_ENA(1) | S_0286D4_PNT_SPRITE_OVRD_X(2) | @@ -2049,6 +2049,7 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad struct r600_shader *rshader = &shader->shader; unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control; int pos_index = -1, face_index = -1; + unsigned tmp, sid; rstate->nregs = 0; @@ -2057,6 +2058,30 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad pos_index = i; if (rshader->input[i].name == TGSI_SEMANTIC_FACE) face_index = i; + + sid = rshader->input[i].spi_sid; + + tmp = S_028644_SEMANTIC(sid); + + if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || + rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || + rshader->input[i].name == TGSI_SEMANTIC_POSITION) { + tmp |= S_028644_FLAT_SHADE(1); + } + + if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && + rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { + tmp |= S_028644_PT_SPRITE_TEX(1); + } + + if (rshader->input[i].centroid) + tmp |= S_028644_SEL_CENTROID(1); + + if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) + tmp |= S_028644_SEL_LINEAR(1); + + r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, + tmp, 0xFFFFFFFF, NULL, 0); } db_shader_control = 0; @@ -2134,6 +2159,8 @@ void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shad r600_pipe_state_add_reg(rstate, R_03E200_SQ_LOOP_CONST_0, 0x01000FFF, 0xFFFFFFFF, NULL, 0); + + shader->sprite_coord_enable = rctx->sprite_coord_enable; } void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader) diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 3d0345addce..b81fba10467 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -34,8 +34,6 @@ #include "r600_pipe.h" #include "r600d.h" -static void r600_spi_update(struct r600_pipe_context *rctx); - static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim) { static const int prim_conv[] = { @@ -103,8 +101,9 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) rctx->clamp_vertex_color = rs->clamp_vertex_color; rctx->clamp_fragment_color = rs->clamp_fragment_color; - rctx->flatshade = rs->flatshade; + rctx->sprite_coord_enable = rs->sprite_coord_enable; + rctx->rasterizer = rs; rctx->states[rs->rstate.id] = &rs->rstate; @@ -115,8 +114,6 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) } else { r600_polygon_offset_update(rctx); } - if (rctx->ps_shader && rctx->vs_shader) - rctx->spi_dirty = true; } void r600_delete_rs_state(struct pipe_context *ctx, void *state) @@ -280,7 +277,6 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); } if (rctx->ps_shader && rctx->vs_shader) { - rctx->spi_dirty = true; r600_adjust_gprs(rctx); } } @@ -295,7 +291,6 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate); } if (rctx->ps_shader && rctx->vs_shader) { - rctx->spi_dirty = true; r600_adjust_gprs(rctx); } } @@ -343,63 +338,6 @@ static void r600_update_alpha_ref(struct r600_pipe_context *rctx) rctx->alpha_ref_dirty = false; } -/* FIXME optimize away spi update when it's not needed */ -static void r600_spi_block_init(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate) -{ - int i; - rstate->nregs = 0; - rstate->id = R600_PIPE_STATE_SPI; - for (i = 0; i < 32; i++) { - r600_pipe_state_add_reg(rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, 0, 0xFFFFFFFF, NULL, 0); - } -} - -static void r600_spi_update(struct r600_pipe_context *rctx) -{ - struct r600_pipe_shader *shader = rctx->ps_shader; - struct r600_pipe_state *rstate = &rctx->spi; - struct r600_shader *rshader = &shader->shader; - unsigned i, tmp, sid; - - if (rctx->spi.id == 0) - r600_spi_block_init(rctx, &rctx->spi); - - rstate->nregs = 0; - for (i = 0; i < rshader->ninput; i++) { - - sid = rshader->input[i].spi_sid; - - if (!sid && (rctx->chip_class >= EVERGREEN)) - continue; - - tmp = S_028644_SEMANTIC(sid); - - if (rshader->input[i].name == TGSI_SEMANTIC_COLOR || - rshader->input[i].name == TGSI_SEMANTIC_BCOLOR || - rshader->input[i].name == TGSI_SEMANTIC_POSITION) { - tmp |= S_028644_FLAT_SHADE(rctx->flatshade); - } - - if (rshader->input[i].name == TGSI_SEMANTIC_GENERIC && - rctx->sprite_coord_enable & (1 << rshader->input[i].sid)) { - tmp |= S_028644_PT_SPRITE_TEX(1); - } - - if (rctx->chip_class < EVERGREEN) { - if (rshader->input[i].centroid) - tmp |= S_028644_SEL_CENTROID(1); - - if (rshader->input[i].interpolate == TGSI_INTERPOLATE_LINEAR) - tmp |= S_028644_SEL_LINEAR(1); - } - - r600_pipe_state_mod_reg(rstate, tmp); - } - - rctx->spi_dirty = false; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, struct pipe_resource *buffer) { @@ -552,6 +490,8 @@ static int r600_shader_rebuild(struct pipe_context * ctx, struct r600_pipe_shade static void r600_update_derived_state(struct r600_pipe_context *rctx) { + struct pipe_context * ctx = (struct pipe_context*)rctx; + if (!rctx->blitter->running) { if (rctx->have_depth_fb || rctx->have_depth_texture) r600_flush_depth_textures(rctx); @@ -571,13 +511,21 @@ static void r600_update_derived_state(struct r600_pipe_context *rctx) r600_shader_rebuild(&rctx->context, rctx->ps_shader); } - if (rctx->spi_dirty) { - r600_spi_update(rctx); - } - if (rctx->alpha_ref_dirty) { r600_update_alpha_ref(rctx); } + + if (rctx->ps_shader && rctx->sprite_coord_enable && + (rctx->ps_shader->sprite_coord_enable != rctx->sprite_coord_enable)) { + + if (rctx->chip_class >= EVERGREEN) + evergreen_pipe_shader_ps(ctx, rctx->ps_shader); + else + r600_pipe_shader_ps(ctx, rctx->ps_shader); + + r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); + } + } void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo) -- 2.11.0