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/auxiliary/cso_cache | |
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/auxiliary/cso_cache')
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.c | 86 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.h | 10 |
2 files changed, 53 insertions, 43 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index db4fa019a35..b3decc58f0e 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -86,11 +86,9 @@ struct cso_context { struct sampler_info samplers[PIPE_SHADER_TYPES]; - uint nr_vertex_buffers; - struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; - - uint nr_vertex_buffers_saved; - struct pipe_vertex_buffer vertex_buffers_saved[PIPE_MAX_ATTRIBS]; + struct pipe_vertex_buffer aux_vertex_buffer_current; + struct pipe_vertex_buffer aux_vertex_buffer_saved; + unsigned aux_vertex_buffer_index; unsigned nr_so_targets; struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS]; @@ -246,7 +244,8 @@ static void cso_init_vbuf(struct cso_context *cso) !caps.format_norm32 || !caps.format_scaled32 || !caps.user_vertex_buffers) { - cso->vbuf = u_vbuf_create(cso->pipe, &caps); + cso->vbuf = u_vbuf_create(cso->pipe, &caps, + cso->aux_vertex_buffer_index); } } @@ -266,6 +265,8 @@ struct cso_context *cso_create_context( struct pipe_context *pipe ) ctx->pipe = pipe; ctx->sample_mask_saved = ~0; + ctx->aux_vertex_buffer_index = 0; /* 0 for now */ + cso_init_vbuf(ctx); /* Enable for testing: */ @@ -323,12 +324,8 @@ void cso_release_all( struct cso_context *ctx ) util_unreference_framebuffer_state(&ctx->fb); util_unreference_framebuffer_state(&ctx->fb_saved); - util_copy_vertex_buffers(ctx->vertex_buffers, - &ctx->nr_vertex_buffers, - NULL, 0); - util_copy_vertex_buffers(ctx->vertex_buffers_saved, - &ctx->nr_vertex_buffers_saved, - NULL, 0); + pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer, NULL); + pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL); for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) { pipe_so_target_reference(&ctx->so_targets[i], NULL); @@ -904,62 +901,71 @@ void cso_restore_vertex_elements(struct cso_context *ctx) /* vertex buffers */ void cso_set_vertex_buffers(struct cso_context *ctx, - unsigned count, + unsigned start_slot, unsigned count, const struct pipe_vertex_buffer *buffers) { struct u_vbuf *vbuf = ctx->vbuf; if (vbuf) { - u_vbuf_set_vertex_buffers(vbuf, count, buffers); + u_vbuf_set_vertex_buffers(vbuf, start_slot, count, buffers); return; } - if (count != ctx->nr_vertex_buffers || - memcmp(buffers, ctx->vertex_buffers, - sizeof(struct pipe_vertex_buffer) * count) != 0) { - util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers, - buffers, count); - ctx->pipe->set_vertex_buffers(ctx->pipe, count, buffers); + /* Save what's in the auxiliary slot, so that we can save and restore it + * for meta ops. */ + if (start_slot <= ctx->aux_vertex_buffer_index && + start_slot+count > ctx->aux_vertex_buffer_index) { + if (buffers) { + const struct pipe_vertex_buffer *vb = + buffers + (ctx->aux_vertex_buffer_index - start_slot); + + pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer, + vb->buffer); + memcpy(&ctx->aux_vertex_buffer_current, vb, + sizeof(struct pipe_vertex_buffer)); + } + else { + pipe_resource_reference(&ctx->aux_vertex_buffer_current.buffer, + NULL); + ctx->aux_vertex_buffer_current.user_buffer = NULL; + } } + + ctx->pipe->set_vertex_buffers(ctx->pipe, start_slot, count, buffers); } -void cso_save_vertex_buffers(struct cso_context *ctx) +void cso_save_aux_vertex_buffer_slot(struct cso_context *ctx) { struct u_vbuf *vbuf = ctx->vbuf; if (vbuf) { - u_vbuf_save_vertex_buffers(vbuf); + u_vbuf_save_aux_vertex_buffer_slot(vbuf); return; } - util_copy_vertex_buffers(ctx->vertex_buffers_saved, - &ctx->nr_vertex_buffers_saved, - ctx->vertex_buffers, - ctx->nr_vertex_buffers); + pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, + ctx->aux_vertex_buffer_current.buffer); + memcpy(&ctx->aux_vertex_buffer_saved, &ctx->aux_vertex_buffer_current, + sizeof(struct pipe_vertex_buffer)); } -void cso_restore_vertex_buffers(struct cso_context *ctx) +void cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx) { - unsigned i; struct u_vbuf *vbuf = ctx->vbuf; if (vbuf) { - u_vbuf_restore_vertex_buffers(vbuf); + u_vbuf_restore_aux_vertex_buffer_slot(vbuf); return; } - util_copy_vertex_buffers(ctx->vertex_buffers, - &ctx->nr_vertex_buffers, - ctx->vertex_buffers_saved, - ctx->nr_vertex_buffers_saved); - - for (i = 0; i < ctx->nr_vertex_buffers_saved; i++) { - pipe_resource_reference(&ctx->vertex_buffers_saved[i].buffer, NULL); - } - ctx->nr_vertex_buffers_saved = 0; + cso_set_vertex_buffers(ctx, ctx->aux_vertex_buffer_index, 1, + &ctx->aux_vertex_buffer_saved); + pipe_resource_reference(&ctx->aux_vertex_buffer_saved.buffer, NULL); +} - ctx->pipe->set_vertex_buffers(ctx->pipe, ctx->nr_vertex_buffers, - ctx->vertex_buffers); +unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx) +{ + return ctx->aux_vertex_buffer_index; } diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index f49b2b706a4..16158edacc3 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -102,10 +102,14 @@ void cso_restore_vertex_elements(struct cso_context *ctx); void cso_set_vertex_buffers(struct cso_context *ctx, - unsigned count, + unsigned start_slot, unsigned count, const struct pipe_vertex_buffer *buffers); -void cso_save_vertex_buffers(struct cso_context *ctx); -void cso_restore_vertex_buffers(struct cso_context *ctx); + +/* One vertex buffer slot is provided with the save/restore functionality. + * cso_context chooses the slot, it can be non-zero. */ +void cso_save_aux_vertex_buffer_slot(struct cso_context *ctx); +void cso_restore_aux_vertex_buffer_slot(struct cso_context *ctx); +unsigned cso_get_aux_vertex_buffer_slot(struct cso_context *ctx); void cso_set_stream_outputs(struct cso_context *ctx, |