From 0b841b0349d7aca218eac4e9d9b7b1406ad71944 Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Fri, 3 Dec 2010 12:20:40 -0500 Subject: r600g: update polygon offset only when rasterizer or zbuffer change Aim is to build as little state as possible in draw functions. Signed-off-by: Jerome Glisse --- src/gallium/drivers/r600/evergreen_state.c | 92 ++++++++++++++++------------ src/gallium/drivers/r600/r600_pipe.h | 4 ++ src/gallium/drivers/r600/r600_state.c | 92 ++++++++++++++++------------ src/gallium/drivers/r600/r600_state_common.c | 6 ++ 4 files changed, 114 insertions(+), 80 deletions(-) (limited to 'src/gallium/drivers/r600') diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index bee675243d..9f446456da 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -833,6 +833,10 @@ static void evergreen_set_framebuffer_state(struct pipe_context *ctx, free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]); rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate; r600_context_pipe_state_set(&rctx->ctx, rstate); + + if (state->zsbuf) { + evergreen_polygon_offset_update(rctx); + } } static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, @@ -1208,6 +1212,54 @@ r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, r600_context_pipe_state_set(&rctx->ctx, rstate); } +void evergreen_polygon_offset_update(struct r600_pipe_context *rctx) +{ + struct r600_pipe_state state; + + state.id = R600_PIPE_STATE_POLYGON_OFFSET; + state.nregs = 0; + if (rctx->rasterizer && rctx->framebuffer.zsbuf) { + float offset_units = rctx->rasterizer->offset_units; + unsigned offset_db_fmt_cntl = 0, depth; + + switch (rctx->framebuffer.zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + depth = -23; + offset_units *= 1.0f; + offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + depth = -16; + offset_units *= 4.0f; + break; + default: + return; + } + offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth); + r600_pipe_state_add_reg(&state, + R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + offset_db_fmt_cntl, 0xFFFFFFFF, NULL); + r600_context_pipe_state_set(&rctx->ctx, &state); + } +} + int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) { @@ -1336,46 +1388,6 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_pipe_state_add_reg(&vgt, R_028404_VGT_MIN_VTX_INDX, draw.min_index, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, 0, 0xFFFFFFFF, NULL); - - if (rctx->rasterizer && rctx->framebuffer.zsbuf) { - float offset_units = rctx->rasterizer->offset_units; - unsigned offset_db_fmt_cntl = 0, depth; - - switch (rctx->framebuffer.zsbuf->texture->format) { - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - depth = -24; - offset_units *= 2.0f; - break; - case PIPE_FORMAT_Z32_FLOAT: - depth = -23; - offset_units *= 1.0f; - offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1); - break; - case PIPE_FORMAT_Z16_UNORM: - depth = -16; - offset_units *= 4.0f; - break; - default: - return; - } - offset_db_fmt_cntl |= S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(depth); - r600_pipe_state_add_reg(&vgt, - R_028B80_PA_SU_POLY_OFFSET_FRONT_SCALE, - fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028B84_PA_SU_POLY_OFFSET_FRONT_OFFSET, - fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028B88_PA_SU_POLY_OFFSET_BACK_SCALE, - fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028B8C_PA_SU_POLY_OFFSET_BACK_OFFSET, - fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL, - offset_db_fmt_cntl, 0xFFFFFFFF, NULL); - } r600_context_pipe_state_set(&rctx->ctx, &vgt); rdraw.vgt_num_indices = draw.count; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 835aa33600..e4d5dd4743 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -53,6 +53,7 @@ enum r600_pipe_state_id { R600_PIPE_STATE_CONSTANT, R600_PIPE_STATE_SAMPLER, R600_PIPE_STATE_RESOURCE, + R600_PIPE_STATE_POLYGON_OFFSET, R600_PIPE_NSTATES }; @@ -181,6 +182,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx); +void evergreen_polygon_offset_update(struct r600_pipe_context *rctx); /* r600_blit.c */ void r600_init_blit_functions(struct r600_pipe_context *rctx); @@ -218,6 +220,8 @@ void r600_init_state_functions(struct r600_pipe_context *rctx); void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info); void r600_init_config(struct r600_pipe_context *rctx); void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx); +void r600_polygon_offset_update(struct r600_pipe_context *rctx); + /* r600_helper.h */ int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index cd089e83e7..c592ef2bd0 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -46,6 +46,54 @@ #include "r600_pipe.h" #include "r600_state_inlines.h" +void r600_polygon_offset_update(struct r600_pipe_context *rctx) +{ + struct r600_pipe_state state; + + state.id = R600_PIPE_STATE_POLYGON_OFFSET; + state.nregs = 0; + if (rctx->rasterizer && rctx->framebuffer.zsbuf) { + float offset_units = rctx->rasterizer->offset_units; + unsigned offset_db_fmt_cntl = 0, depth; + + switch (rctx->framebuffer.zsbuf->texture->format) { + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_USCALED: + depth = -24; + offset_units *= 2.0f; + break; + case PIPE_FORMAT_Z32_FLOAT: + depth = -23; + offset_units *= 1.0f; + offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); + break; + case PIPE_FORMAT_Z16_UNORM: + depth = -16; + offset_units *= 4.0f; + break; + default: + return; + } + 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, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, + fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, + fui(offset_units), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(&state, + R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, + offset_db_fmt_cntl, 0xFFFFFFFF, NULL); + r600_context_pipe_state_set(&rctx->ctx, &state); + } +} + static void r600_draw_common(struct r600_drawl *draw) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)draw->ctx; @@ -126,46 +174,6 @@ static void r600_draw_common(struct r600_drawl *draw) r600_pipe_state_add_reg(&vgt, R_028238_CB_TARGET_MASK, rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, 0, 0xFFFFFFFF, NULL); - /* build late state */ - if (rctx->rasterizer && rctx->framebuffer.zsbuf) { - float offset_units = rctx->rasterizer->offset_units; - unsigned offset_db_fmt_cntl = 0, depth; - - switch (rctx->framebuffer.zsbuf->texture->format) { - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_USCALED: - depth = -24; - offset_units *= 2.0f; - break; - case PIPE_FORMAT_Z32_FLOAT: - depth = -23; - offset_units *= 1.0f; - offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_DB_IS_FLOAT_FMT(1); - break; - case PIPE_FORMAT_Z16_UNORM: - depth = -16; - offset_units *= 4.0f; - break; - default: - return; - } - offset_db_fmt_cntl |= S_028DF8_POLY_OFFSET_NEG_NUM_DB_BITS(depth); - r600_pipe_state_add_reg(&vgt, - R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE, - fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET, - fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE, - fui(rctx->rasterizer->offset_scale), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET, - fui(offset_units), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(&vgt, - R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL, - offset_db_fmt_cntl, 0xFFFFFFFF, NULL); - } r600_context_pipe_state_set(&rctx->ctx, &vgt); rdraw.vgt_num_indices = draw->count; @@ -1023,6 +1031,10 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx, free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]); rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate; r600_context_pipe_state_set(&rctx->ctx, rstate); + + if (state->zsbuf) { + r600_polygon_offset_update(rctx); + } } static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 55bc5d0d22..856f79158c 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -58,6 +58,12 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state) rctx->states[rs->rstate.id] = &rs->rstate; r600_context_pipe_state_set(&rctx->ctx, &rs->rstate); + + if (rctx->family >= CHIP_CEDAR) { + evergreen_polygon_offset_update(rctx); + } else { + r600_polygon_offset_update(rctx); + } } void r600_delete_rs_state(struct pipe_context *ctx, void *state) -- cgit v1.2.3