diff options
author | Marek Olšák <[email protected]> | 2012-03-29 17:51:50 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-10-31 00:55:13 +0100 |
commit | e73bf3b805de78299f1a652668ba4e6eab9bac94 (patch) | |
tree | 11839d343c6aad3a8fb5c594cadf961288adbea0 /src/gallium/drivers/r600 | |
parent | a7c5be098aee3a8228cbd95558bac29cb7ff6a3d (diff) |
gallium: add start_slot parameter to set_vertex_buffers
This allows updating only a subrange of buffer bindings.
set_vertex_buffers(pipe, start_slot, count, NULL) unbinds buffers in that
range. Binding NULL resources unbinds buffers too (both buffer and user_buffer
must be NULL).
The meta ops are adapted to only save, change, and restore the single slot
they use. The cso_context can save and restore only one vertex buffer slot.
The clients can query which one it is using cso_get_aux_vertex_buffer_slot.
It's currently set to 0. (the Draw module breaks if it's set to non-zero)
It should decrease the CPU overhead when using a lot of meta ops, but
the drivers must be able to treat each vertex buffer slot as a separate
state (only r600g does so at the moment).
I can imagine this also being useful for optimizing some OpenGL use cases.
Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 53 |
2 files changed, 28 insertions, 29 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index a19248da3a2..085108d3709 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -55,9 +55,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op r600_suspend_nontimer_queries(rctx); - util_blitter_save_vertex_buffers(rctx->blitter, - util_last_bit(rctx->vertex_buffer_state.enabled_mask), - rctx->vertex_buffer_state.vb); + util_blitter_save_vertex_buffer_slot(rctx->blitter, rctx->vertex_buffer_state.vb); util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_fetch_shader.cso); util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets, diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index a4d3e461ef1..3503c3964a6 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -495,41 +495,42 @@ void r600_vertex_buffers_dirty(struct r600_context *rctx) } } -static void r600_set_vertex_buffers(struct pipe_context *ctx, unsigned count, - const struct pipe_vertex_buffer *input) +static void r600_set_vertex_buffers(struct pipe_context *ctx, + unsigned start_slot, unsigned count, + const struct pipe_vertex_buffer *input) { struct r600_context *rctx = (struct r600_context *)ctx; struct r600_vertexbuf_state *state = &rctx->vertex_buffer_state; - struct pipe_vertex_buffer *vb = state->vb; + struct pipe_vertex_buffer *vb = state->vb + start_slot; unsigned i; - /* This sets 1-bit for buffers with index >= count. */ - uint32_t disable_mask = ~((1ull << count) - 1); + uint32_t disable_mask = 0; /* These are the new buffers set by this function. */ uint32_t new_buffer_mask = 0; - /* Set buffers with index >= count to NULL. */ - uint32_t remaining_buffers_mask = - rctx->vertex_buffer_state.enabled_mask & disable_mask; - - while (remaining_buffers_mask) { - i = u_bit_scan(&remaining_buffers_mask); - pipe_resource_reference(&vb[i].buffer, NULL); - } - /* Set vertex buffers. */ - for (i = 0; i < count; i++) { - if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) { - if (input[i].buffer) { - vb[i].stride = input[i].stride; - vb[i].buffer_offset = input[i].buffer_offset; - pipe_resource_reference(&vb[i].buffer, input[i].buffer); - new_buffer_mask |= 1 << i; - } else { - pipe_resource_reference(&vb[i].buffer, NULL); - disable_mask |= 1 << i; + if (input) { + for (i = 0; i < count; i++) { + if (memcmp(&input[i], &vb[i], sizeof(struct pipe_vertex_buffer))) { + if (input[i].buffer) { + vb[i].stride = input[i].stride; + vb[i].buffer_offset = input[i].buffer_offset; + pipe_resource_reference(&vb[i].buffer, input[i].buffer); + new_buffer_mask |= 1 << i; + } else { + pipe_resource_reference(&vb[i].buffer, NULL); + disable_mask |= 1 << i; + } } } - } + } else { + for (i = 0; i < count; i++) { + pipe_resource_reference(&vb[i].buffer, NULL); + } + disable_mask = ((1ull << count) - 1); + } + + disable_mask <<= start_slot; + new_buffer_mask <<= start_slot; rctx->vertex_buffer_state.enabled_mask &= ~disable_mask; rctx->vertex_buffer_state.dirty_mask &= rctx->vertex_buffer_state.enabled_mask; @@ -1371,7 +1372,7 @@ void r600_draw_rectangle(struct blitter_context *blitter, } /* draw */ - util_draw_vertex_buffer(&rctx->context, NULL, buf, offset, + util_draw_vertex_buffer(&rctx->context, NULL, buf, rctx->blitter->vb_slot, offset, R600_PRIM_RECTANGLE_LIST, 3, 2); pipe_resource_reference(&buf, NULL); } |