From 573758fd094431c8b3220786cea28dfdb4cfad1c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 2 Jun 2011 15:03:52 +1000 Subject: [PATCH] r600g: decrease CPU time on set buffer resources This splits the initialisation and the setting of values in the resource buffers. We only should end up initialising once and updateing with new values when needed. Signed-off-by: Dave Airlie --- src/gallium/drivers/r600/evergreen_state.c | 24 ++++++++++-- src/gallium/drivers/r600/r600.h | 15 +++++++ src/gallium/drivers/r600/r600_pipe.h | 14 +++++-- src/gallium/drivers/r600/r600_state.c | 22 +++++++++-- src/gallium/drivers/r600/r600_state_common.c | 41 ++++++++++++++------ 5 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 27f88f1cab1..9bef3f89ca6 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1769,11 +1769,13 @@ void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx) return rstate; } -void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride) +void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx, + struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride) { + rstate->id = R600_PIPE_STATE_RESOURCE; + rstate->nregs = 0; r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, @@ -1796,3 +1798,17 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, 0xC0000000, 0xFFFFFFFF, NULL); } + + +void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride) +{ + rstate->nregs = 0; + r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo); + r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1); + r600_pipe_state_mod_reg(rstate, S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | + S_030008_STRIDE(stride)); + rstate->nregs = 8; + +} diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index df02787ef69..50a07537d3e 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -319,4 +319,19 @@ void _r600_pipe_state_add_reg(struct r600_context *ctx, #define r600_pipe_state_add_reg(state, offset, value, mask, bo) _r600_pipe_state_add_reg(&rctx->ctx, state, offset, value, mask, CTX_RANGE_ID(offset), CTX_BLOCK_ID(offset), bo) +static inline void r600_pipe_state_mod_reg(struct r600_pipe_state *state, + u32 value) +{ + state->regs[state->nregs].value = value; + state->nregs++; +} + +static inline void r600_pipe_state_mod_reg_bo(struct r600_pipe_state *state, + u32 value, struct r600_bo *bo) +{ + state->regs[state->nregs].value = value; + state->regs[state->nregs].bo = bo; + state->nregs++; +} + #endif diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index ae809a28713..05381c244b0 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -221,8 +221,11 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx); void evergreen_polygon_offset_update(struct r600_pipe_context *rctx); -void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, +void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx, + struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride); +void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); @@ -262,8 +265,11 @@ void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shad void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve); void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx); void r600_polygon_offset_update(struct r600_pipe_context *rctx); -void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, +void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, + struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride); +void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index f1fbfa570f6..3043c5e1c8b 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1481,11 +1481,13 @@ void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx) return rstate; } -void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, - struct r600_pipe_state *rstate, - struct r600_resource *rbuffer, - unsigned offset, unsigned stride) +void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, + struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride) { + rstate->id = R600_PIPE_STATE_RESOURCE; + rstate->nregs = 0; r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, offset, 0xFFFFFFFF, rbuffer->bo); r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, @@ -1502,3 +1504,15 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6, 0xC0000000, 0xFFFFFFFF, NULL); } + +void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate, + struct r600_resource *rbuffer, + unsigned offset, unsigned stride) +{ + rstate->nregs = 0; + r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo); + r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1); + r600_pipe_state_mod_reg(rstate, S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | + S_038008_STRIDE(stride)); + rstate->nregs = 7; +} diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index db9451f9b0e..cbf7ff017a4 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -410,13 +410,19 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer); rstate = &rctx->vs_const_buffer_resource[index]; - rstate->id = R600_PIPE_STATE_RESOURCE; - rstate->nregs = 0; + if (!rstate->id) { + if (rctx->family >= CHIP_CEDAR) { + evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + } else { + r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + } + } + if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16); evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); } else { - r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16); r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index); } break; @@ -432,13 +438,18 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index, r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer); rstate = &rctx->ps_const_buffer_resource[index]; - rstate->id = R600_PIPE_STATE_RESOURCE; - rstate->nregs = 0; + if (!rstate->id) { + if (rctx->family >= CHIP_CEDAR) { + evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + } else { + r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + } + } if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16); evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); } else { - r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16); + r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16); r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index); } break; @@ -468,8 +479,6 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) for (i = 0 ; i < count; i++) { rstate = &rctx->fs_resource[i]; - rstate->id = R600_PIPE_STATE_RESOURCE; - rstate->nregs = 0; if (rctx->vertex_elements->vbuffer_need_offset) { /* one resource per vertex elements */ @@ -488,11 +497,19 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx) continue; offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo); + if (!rstate->id) { + if (rctx->family >= CHIP_CEDAR) { + evergreen_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + } else { + r600_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + } + } + if (rctx->family >= CHIP_CEDAR) { - evergreen_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride); evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); } else { - r600_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride); + r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride); r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i); } } -- 2.30.2