From afc56b1861c1dae4137493af4c0e6dacc6ee41f9 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 5 Dec 2010 19:24:03 -0500 Subject: r600g: avoid useless shader rebuild at draw call Avoid rebuilding constant shader state at each draw call, factor out spi update that might change at each draw call. Best would be to update spi only when revealent states change (likely only flat shading & sprite point). Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/r600_state.c | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'src/gallium/drivers/r600/r600_state.c') diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 9b70942eeb..2ba15b818a 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -74,6 +74,7 @@ void r600_polygon_offset_update(struct r600_pipe_context *rctx) default: return; } + /* FIXME some of those reg can be computed with cso */ offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); r600_pipe_state_add_reg(&state, R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, @@ -94,6 +95,36 @@ void r600_polygon_offset_update(struct r600_pipe_context *rctx) } } +/* FIXME optimize away spi update when it's not needed */ +static void r600_spi_update(struct r600_pipe_context *rctx) +{ + struct r600_pipe_shader *shader = rctx->ps_shader; + struct r600_pipe_state rstate; + struct r600_shader *rshader = &shader->shader; + unsigned i, tmp; + + rstate.nregs = 0; + for (i = 0; i < rshader->ninput; i++) { + tmp = S_028644_SEMANTIC(r600_find_vs_semantic_index(&rctx->vs_shader->shader, rshader, i)); + 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); + + 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); + } + r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL); + } + r600_context_pipe_state_set(&rctx->ctx, &rstate); +} + void r600_vertex_buffer_update(struct r600_pipe_context *rctx) { struct r600_pipe_state *rstate; @@ -202,13 +233,30 @@ static void r600_draw_common(struct r600_drawl *draw) } if (r600_conv_pipe_prim(draw->mode, &prim)) return; + if (unlikely(rctx->ps_shader == NULL)) { + R600_ERR("missing vertex shader\n"); + return; + } + if (unlikely(rctx->vs_shader == NULL)) { + R600_ERR("missing vertex shader\n"); + return; + } + /* there should be enough input */ + if (rctx->vertex_elements->count < rctx->vs_shader->shader.bc.nresource) { + R600_ERR("%d resources provided, expecting %d\n", + rctx->vertex_elements->count, rctx->vs_shader->shader.bc.nresource); + return; + } - +#if 0 /* rebuild vertex shader if input format changed */ if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader)) return; if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader)) return; +#endif + + r600_spi_update(rctx); #if 0 for (i = 0 ; i < rctx->vertex_elements->count; i++) { -- cgit v1.2.3