aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/cso_cache
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-03-29 17:51:50 +0200
committerMarek Olšák <[email protected]>2012-10-31 00:55:13 +0100
commite73bf3b805de78299f1a652668ba4e6eab9bac94 (patch)
tree11839d343c6aad3a8fb5c594cadf961288adbea0 /src/gallium/auxiliary/cso_cache
parenta7c5be098aee3a8228cbd95558bac29cb7ff6a3d (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.c86
-rw-r--r--src/gallium/auxiliary/cso_cache/cso_context.h10
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,