diff options
author | Jerome Glisse <[email protected]> | 2010-12-03 20:47:02 -0500 |
---|---|---|
committer | Jerome Glisse <[email protected]> | 2010-12-06 15:50:50 -0500 |
commit | fa86fc564aea4e40c89f6fc889e6a5bf817634b3 (patch) | |
tree | 01ee2a066008b93387562771563cf1b83e2a4230 /src/gallium/drivers/r600/evergreen_state.c | |
parent | a9fa0f3a2f318a7c57163491abe931e86b2cd4c3 (diff) |
r600g: build fetch shader from vertex elements
Vertex elements change are less frequent than draw call, those to
avoid rebuilding fetch shader to often build the fetch shader along
vertex elements. This also allow to move vertex buffer setup out
of draw path and make update to it less frequent.
Shader update can still be improved to only update SPI regs (based
on some rasterizer state like flat shading or point sprite ...).
Signed-off-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600/evergreen_state.c')
-rw-r--r-- | src/gallium/drivers/r600/evergreen_state.c | 97 |
1 files changed, 94 insertions, 3 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index ebd541d5f8d..b313d525012 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -1259,6 +1259,90 @@ void evergreen_polygon_offset_update(struct r600_pipe_context *rctx) } } +void evergreen_vertex_buffer_update(struct r600_pipe_context *rctx) +{ + struct r600_pipe_state *rstate; + struct r600_resource *rbuffer; + struct pipe_vertex_buffer *vertex_buffer; + unsigned i, offset; + + /* we don't update until we know vertex elements */ + if (rctx->vertex_elements == NULL || !rctx->nvertex_buffer) + return; + + /* delete previous translated vertex elements */ + if (rctx->tran.new_velems) { + r600_end_vertex_translate(rctx); + } + + if (rctx->vertex_elements->incompatible_layout) { + /* translate rebind new vertex elements so + * return once translated + */ + r600_begin_vertex_translate(rctx); + return; + } + + if (rctx->any_user_vbs) { + r600_upload_user_buffers(rctx); + rctx->any_user_vbs = FALSE; + } + + if (rctx->vertex_elements->vbuffer_need_offset) { + /* one resource per vertex elements */ + rctx->nvs_resource = rctx->vertex_elements->count; + } else { + /* bind vertex buffer once */ + rctx->nvs_resource = rctx->nvertex_buffer; + } + + for (i = 0 ; i < rctx->nvs_resource; i++) { + rstate = &rctx->vs_resource[i]; + rstate->id = R600_PIPE_STATE_RESOURCE; + rstate->nregs = 0; + + if (rctx->vertex_elements->vbuffer_need_offset) { + /* one resource per vertex elements */ + unsigned vbuffer_index; + vbuffer_index = rctx->vertex_elements->elements[i].vertex_buffer_index; + vertex_buffer = &rctx->vertex_buffer[vbuffer_index]; + rbuffer = (struct r600_resource*)vertex_buffer->buffer; + offset = rctx->vertex_elements->vbuffer_offset[i] + + vertex_buffer->buffer_offset + + r600_bo_offset(rbuffer->bo); + } else { + /* bind vertex buffer once */ + vertex_buffer = &rctx->vertex_buffer[i]; + rbuffer = (struct r600_resource*)vertex_buffer->buffer; + offset = vertex_buffer->buffer_offset + + r600_bo_offset(rbuffer->bo); + } + + r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, + offset, 0xFFFFFFFF, rbuffer->bo); + r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, + rbuffer->size - offset - 1, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, + S_030008_STRIDE(vertex_buffer->stride), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, + S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | + S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) | + S_03000C_DST_SEL_Z(V_03000C_SQ_SEL_Z) | + S_03000C_DST_SEL_W(V_03000C_SQ_SEL_W), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_030018_RESOURCE0_WORD6, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, + 0xC0000000, 0xFFFFFFFF, NULL); + evergreen_fs_resource_set(&rctx->ctx, rstate, i); + } +} + int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) { @@ -1273,6 +1357,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) struct r600_drawl draw; boolean translate = FALSE; +#if 0 if (rctx->vertex_elements->incompatible_layout) { r600_begin_vertex_translate(rctx); translate = TRUE; @@ -1282,6 +1367,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_upload_user_buffers(rctx); rctx->any_user_vbs = FALSE; } +#endif memset(&draw, 0, sizeof(struct r600_drawl)); draw.ctx = ctx; @@ -1338,6 +1424,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader)) return; +#if 0 for (i = 0 ; i < rctx->vertex_elements->count; i++) { uint32_t word3, word2; uint32_t format; @@ -1372,6 +1459,7 @@ void evergreen_draw(struct pipe_context *ctx, const struct pipe_draw_info *info) r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7, 0xC0000000, 0xFFFFFFFF, NULL); evergreen_fs_resource_set(&rctx->ctx, rstate, i); } +#endif mask = 0; for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { @@ -1588,14 +1676,17 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader R_028864_SQ_PGM_RESOURCES_2_VS, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, - R_0288A8_SQ_PGM_RESOURCES_FS, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_02885C_SQ_PGM_START_VS, (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo); + +#if 0 + r600_pipe_state_add_reg(rstate, + R_0288A8_SQ_PGM_RESOURCES_FS, + 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS, (r600_bo_offset(shader->bo)) >> 8, 0xFFFFFFFF, shader->bo_fetch); +#endif r600_pipe_state_add_reg(rstate, R_03A200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, |