diff options
author | Marek Olšák <[email protected]> | 2012-04-10 06:00:17 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-04-24 01:39:22 +0200 |
commit | e0773da1e897164ed7597437070e32b867734ee5 (patch) | |
tree | 1653bdb8fab0d8e250f7fcc0ca225e7245043184 /src/gallium/auxiliary | |
parent | 79eafc14ca70a684b4ea8b89723c1dad3e61eb3d (diff) |
gallium: make user vertex buffers optional
This couldn't be split because it would break bisecting.
Summary:
* r300g,r600g: stop using u_vbuf
* r300g,r600g: also report that the FIXED vertex type is unsupported
* u_vbuf: refactor for use in the state tracker
* cso: wire up u_vbuf with cso_context
* st/mesa: conditionally install u_vbuf
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.c | 66 | ||||
-rw-r--r-- | src/gallium/auxiliary/cso_cache/cso_context.h | 3 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_vbuf.c | 304 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_vbuf.h | 50 |
4 files changed, 236 insertions, 187 deletions
diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index 9ec7a2a9676..1cd5f8de184 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -41,6 +41,7 @@ #include "util/u_inlines.h" #include "util/u_math.h" #include "util/u_memory.h" +#include "util/u_vbuf.h" #include "tgsi/tgsi_parse.h" #include "cso_cache/cso_context.h" @@ -78,6 +79,7 @@ struct sampler_info struct cso_context { struct pipe_context *pipe; struct cso_cache *cache; + struct u_vbuf *vbuf; boolean has_geometry_shader; boolean has_streamout; @@ -268,6 +270,10 @@ out: return NULL; } +void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf) +{ + ctx->vbuf = vbuf; +} /** * Prior to context destruction, this function unbinds all state objects. @@ -780,11 +786,17 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, unsigned count, const struct pipe_vertex_element *states) { + struct u_vbuf *vbuf = ctx->vbuf; unsigned key_size, hash_key; struct cso_hash_iter iter; void *handle; struct cso_velems_state velems_state; + if (vbuf) { + u_vbuf_set_vertex_elements(vbuf, count, states); + return PIPE_OK; + } + /* need to include the count into the stored state data too. Otherwise first few count pipe_vertex_elements could be identical even if count is different, and there's no guarantee the hash would be different in that @@ -826,12 +838,26 @@ enum pipe_error cso_set_vertex_elements(struct cso_context *ctx, void cso_save_vertex_elements(struct cso_context *ctx) { + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf) { + u_vbuf_save_vertex_elements(vbuf); + return; + } + assert(!ctx->velements_saved); ctx->velements_saved = ctx->velements; } void cso_restore_vertex_elements(struct cso_context *ctx) { + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf) { + u_vbuf_restore_vertex_elements(vbuf); + return; + } + if (ctx->velements != ctx->velements_saved) { ctx->velements = ctx->velements_saved; ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->velements_saved); @@ -845,6 +871,13 @@ void cso_set_vertex_buffers(struct cso_context *ctx, unsigned count, const struct pipe_vertex_buffer *buffers) { + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf) { + u_vbuf_set_vertex_buffers(vbuf, count, buffers); + return; + } + if (count != ctx->nr_vertex_buffers || memcmp(buffers, ctx->vertex_buffers, sizeof(struct pipe_vertex_buffer) * count) != 0) { @@ -856,6 +889,13 @@ void cso_set_vertex_buffers(struct cso_context *ctx, void cso_save_vertex_buffers(struct cso_context *ctx) { + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf) { + u_vbuf_save_vertex_buffers(vbuf); + return; + } + util_copy_vertex_buffers(ctx->vertex_buffers_saved, &ctx->nr_vertex_buffers_saved, ctx->vertex_buffers, @@ -865,6 +905,12 @@ void cso_save_vertex_buffers(struct cso_context *ctx) void cso_restore_vertex_buffers(struct cso_context *ctx) { unsigned i; + struct u_vbuf *vbuf = ctx->vbuf; + + if (vbuf) { + u_vbuf_restore_vertex_buffers(vbuf); + return; + } util_copy_vertex_buffers(ctx->vertex_buffers, &ctx->nr_vertex_buffers, @@ -1298,16 +1344,28 @@ void cso_set_index_buffer(struct cso_context *cso, const struct pipe_index_buffer *ib) { - struct pipe_context *pipe = cso->pipe; - pipe->set_index_buffer(pipe, ib); + struct u_vbuf *vbuf = cso->vbuf; + + if (vbuf) { + u_vbuf_set_index_buffer(vbuf, ib); + } else { + struct pipe_context *pipe = cso->pipe; + pipe->set_index_buffer(pipe, ib); + } } void cso_draw_vbo(struct cso_context *cso, const struct pipe_draw_info *info) { - struct pipe_context *pipe = cso->pipe; - pipe->draw_vbo(pipe, info); + struct u_vbuf *vbuf = cso->vbuf; + + if (vbuf) { + u_vbuf_draw_vbo(vbuf, info); + } else { + struct pipe_context *pipe = cso->pipe; + pipe->draw_vbo(pipe, info); + } } void diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index d0f8bc29550..79279343c39 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -39,9 +39,12 @@ extern "C" { #endif struct cso_context; +struct u_vbuf; struct cso_context *cso_create_context( struct pipe_context *pipe ); +void cso_install_vbuf(struct cso_context *ctx, struct u_vbuf *vbuf); + void cso_release_all( struct cso_context *ctx ); void cso_destroy_context( struct cso_context *cso ); diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 653f71ececd..6a93daa3c89 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -66,12 +66,22 @@ enum { VB_NUM = 3 }; -struct u_vbuf_priv { - struct u_vbuf b; +struct u_vbuf { struct u_vbuf_caps caps; + struct pipe_context *pipe; struct translate_cache *translate_cache; struct cso_cache *cso_cache; + struct u_upload_mgr *uploader; + + /* This is what was set in set_vertex_buffers. + * May contain user buffers. */ + struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers; + + /* Saved vertex buffers. */ + struct pipe_vertex_buffer vertex_buffer_saved[PIPE_MAX_ATTRIBS]; + unsigned nr_vertex_buffers_saved; /* Vertex buffers for the driver. * There are no user buffers. */ @@ -82,14 +92,14 @@ struct u_vbuf_priv { /* The index buffer. */ struct pipe_index_buffer index_buffer; - /* and its associated helper structure for this module. */ - struct u_vbuf_elements *ve; + /* Vertex elements. */ + struct u_vbuf_elements *ve, *ve_saved; /* Vertex elements used for the translate fallback. */ struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; /* If non-NULL, this is a vertex element state used for the translate * fallback and therefore used for rendering too. */ - void *fallback_ve; + boolean using_translate; /* The vertex buffer slot index where translated vertices have been * stored in. */ unsigned fallback_vbs[VB_NUM]; @@ -100,21 +110,14 @@ struct u_vbuf_priv { boolean incompatible_vb_layout; /* Per-buffer flags. */ boolean incompatible_vb[PIPE_MAX_ATTRIBS]; - - void (*driver_set_index_buffer)(struct pipe_context *pipe, - const struct pipe_index_buffer *); - void (*driver_set_vertex_buffers)(struct pipe_context *, - unsigned num_buffers, - const struct pipe_vertex_buffer *); - void *(*driver_create_vertex_elements_state)(struct pipe_context *, - unsigned num_elements, - const struct pipe_vertex_element *); - void (*driver_bind_vertex_elements_state)(struct pipe_context *, void *); - void (*driver_delete_vertex_elements_state)(struct pipe_context *, void *); - void (*driver_draw_vbo)(struct pipe_context *pipe, - const struct pipe_draw_info *info); }; +static void * +u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_element *attribs); +static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso); + + void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps) { caps->format_fixed32 = @@ -153,16 +156,11 @@ void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps) screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS); } -static void u_vbuf_install(struct u_vbuf_priv *mgr); - struct u_vbuf * u_vbuf_create(struct pipe_context *pipe, - struct u_vbuf_caps *caps, - unsigned upload_buffer_size, - unsigned upload_buffer_alignment, - unsigned upload_buffer_bind) + struct u_vbuf_caps *caps) { - struct u_vbuf_priv *mgr = CALLOC_STRUCT(u_vbuf_priv); + struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf); mgr->caps = *caps; mgr->pipe = pipe; @@ -170,23 +168,22 @@ u_vbuf_create(struct pipe_context *pipe, mgr->translate_cache = translate_cache_create(); memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs)); - mgr->b.uploader = u_upload_create(pipe, upload_buffer_size, - upload_buffer_alignment, - upload_buffer_bind); + mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4, + PIPE_BIND_VERTEX_BUFFER); - u_vbuf_install(mgr); - return &mgr->b; + return mgr; } -/* XXX I had to fork this off of cso_context. */ -static void * -u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr, - unsigned count, - const struct pipe_vertex_element *states) +/* u_vbuf uses its own caching for vertex elements, because it needs to keep + * its own preprocessed state per vertex element CSO. */ +static struct u_vbuf_elements * +u_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_element *states) { + struct pipe_context *pipe = mgr->pipe; unsigned key_size, hash_key; struct cso_hash_iter iter; - void *handle; + struct u_vbuf_elements *ve; struct cso_velems_state velems_state; /* need to include the count into the stored state data too. */ @@ -201,50 +198,50 @@ u_vbuf_cache_set_vertex_elements(struct u_vbuf_priv *mgr, if (cso_hash_iter_is_null(iter)) { struct cso_velements *cso = MALLOC_STRUCT(cso_velements); memcpy(&cso->state, &velems_state, key_size); - cso->data = - mgr->driver_create_vertex_elements_state(mgr->pipe, count, - &cso->state.velems[0]); - cso->delete_state = - (cso_state_callback)mgr->driver_delete_vertex_elements_state; - cso->context = mgr->pipe; + cso->data = u_vbuf_create_vertex_elements(mgr, count, states); + cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements; + cso->context = (void*)mgr; iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso); - handle = cso->data; + ve = cso->data; } else { - handle = ((struct cso_velements *)cso_hash_iter_data(iter))->data; + ve = ((struct cso_velements *)cso_hash_iter_data(iter))->data; } - mgr->driver_bind_vertex_elements_state(mgr->pipe, handle); - return handle; + assert(ve); + pipe->bind_vertex_elements_state(pipe, ve->driver_cso); + return ve; } -void u_vbuf_destroy(struct u_vbuf *mgrb) +void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_element *states) { - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)mgrb; - unsigned i; + mgr->ve = u_vbuf_set_vertex_elements_internal(mgr, count, states); +} - assert(mgr->pipe->draw); - mgr->pipe->draw = NULL; +void u_vbuf_destroy(struct u_vbuf *mgr) +{ + unsigned i; - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); + for (i = 0; i < mgr->nr_vertex_buffers; i++) { + pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL); } for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); } translate_cache_destroy(mgr->translate_cache); - u_upload_destroy(mgr->b.uploader); + u_upload_destroy(mgr->uploader); cso_cache_delete(mgr->cso_cache); FREE(mgr); } static void -u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, +u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, unsigned vb_mask, unsigned out_vb, int start_vertex, unsigned num_vertices, int start_index, unsigned num_indices, int min_index, - bool unroll_indices) + boolean unroll_indices) { struct translate *tr; struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; @@ -256,9 +253,9 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, tr = translate_cache_find(mgr->translate_cache, key); /* Map buffers we want to translate. */ - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + for (i = 0; i < mgr->nr_vertex_buffers; i++) { if (vb_mask & (1 << i)) { - struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i]; + struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[i]; unsigned offset = vb->buffer_offset + vb->stride * start_vertex; uint8_t *map; @@ -303,7 +300,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, } /* Create and map the output buffer. */ - u_upload_alloc(mgr->b.uploader, 0, + u_upload_alloc(mgr->uploader, 0, key->output_stride * num_indices, &out_offset, &out_buffer, (void**)&out_map); @@ -325,7 +322,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, } } else { /* Create and map the output buffer. */ - u_upload_alloc(mgr->b.uploader, + u_upload_alloc(mgr->uploader, key->output_stride * start_vertex, key->output_stride * num_vertices, &out_offset, &out_buffer, @@ -337,7 +334,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, } /* Unmap all buffers. */ - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + for (i = 0; i < mgr->nr_vertex_buffers; i++) { if (vb_transfer[i]) { pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); } @@ -354,7 +351,7 @@ u_vbuf_translate_buffers(struct u_vbuf_priv *mgr, struct translate_key *key, } static boolean -u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr, +u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr, unsigned mask[VB_NUM]) { unsigned i, type; @@ -392,7 +389,7 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr, } if (i == PIPE_MAX_ATTRIBS) { /* fail, reset the number to its original value */ - mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; + mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers; return FALSE; } } @@ -403,11 +400,11 @@ u_vbuf_translate_find_free_vb_slots(struct u_vbuf_priv *mgr, } static boolean -u_vbuf_translate_begin(struct u_vbuf_priv *mgr, +u_vbuf_translate_begin(struct u_vbuf *mgr, int start_vertex, unsigned num_vertices, int start_instance, unsigned num_instances, int start_index, unsigned num_indices, int min_index, - bool unroll_indices) + boolean unroll_indices) { unsigned mask[VB_NUM] = {0}; struct translate_key key[VB_NUM]; @@ -434,7 +431,7 @@ u_vbuf_translate_begin(struct u_vbuf_priv *mgr, for (i = 0; i < mgr->ve->count; i++) { unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index; - if (!mgr->b.vertex_buffer[vb_index].stride) { + if (!mgr->vertex_buffer[vb_index].stride) { if (!mgr->ve->incompatible_layout_elem[i] && !mgr->incompatible_vb[vb_index]) { continue; @@ -543,18 +540,19 @@ u_vbuf_translate_begin(struct u_vbuf_priv *mgr, } } - mgr->fallback_ve = u_vbuf_cache_set_vertex_elements(mgr, mgr->ve->count, - mgr->fallback_velems); + u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count, + mgr->fallback_velems); + mgr->using_translate = TRUE; return TRUE; } -static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) +static void u_vbuf_translate_end(struct u_vbuf *mgr) { unsigned i; /* Restore vertex elements. */ - mgr->driver_bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso); - mgr->fallback_ve = NULL; + mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso); + mgr->using_translate = FALSE; /* Unreference the now-unused VBOs. */ for (i = 0; i < VB_NUM; i++) { @@ -564,18 +562,17 @@ static void u_vbuf_translate_end(struct u_vbuf_priv *mgr) mgr->fallback_vbs[i] = ~0; } } - mgr->nr_real_vertex_buffers = mgr->b.nr_vertex_buffers; + mgr->nr_real_vertex_buffers = mgr->nr_vertex_buffers; } #define FORMAT_REPLACE(what, withwhat) \ case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break static void * -u_vbuf_create_vertex_elements(struct pipe_context *pipe, - unsigned count, +u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count, const struct pipe_vertex_element *attribs) { - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; + struct pipe_context *pipe = mgr->pipe; unsigned i; struct pipe_vertex_element native_attribs[PIPE_MAX_ATTRIBS]; struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); @@ -670,36 +667,22 @@ u_vbuf_create_vertex_elements(struct pipe_context *pipe, } ve->driver_cso = - mgr->driver_create_vertex_elements_state(pipe, count, native_attribs); + pipe->create_vertex_elements_state(pipe, count, native_attribs); return ve; } -static void u_vbuf_bind_vertex_elements(struct pipe_context *pipe, - void *cso) +static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso) { - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; - struct u_vbuf_elements *ve = cso; - - mgr->ve = ve; - mgr->b.vertex_elements = ve; - mgr->driver_bind_vertex_elements_state(pipe, ve ? ve->driver_cso : NULL); -} - -static void u_vbuf_delete_vertex_elements(struct pipe_context *pipe, - void *cso) -{ - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; + struct pipe_context *pipe = mgr->pipe; struct u_vbuf_elements *ve = cso; - mgr->driver_delete_vertex_elements_state(pipe, ve->driver_cso); + pipe->delete_vertex_elements_state(pipe, ve->driver_cso); FREE(ve); } -static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe, - unsigned count, - const struct pipe_vertex_buffer *bufs) +void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_buffer *bufs) { - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; unsigned i; mgr->any_user_vbs = FALSE; @@ -722,13 +705,13 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe, for (i = 0; i < count; i++) { const struct pipe_vertex_buffer *vb = &bufs[i]; - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer); + pipe_resource_reference(&mgr->vertex_buffer[i].buffer, vb->buffer); mgr->real_vertex_buffer[i].buffer_offset = - mgr->b.vertex_buffer[i].buffer_offset = vb->buffer_offset; + mgr->vertex_buffer[i].buffer_offset = vb->buffer_offset; mgr->real_vertex_buffer[i].stride = - mgr->b.vertex_buffer[i].stride = vb->stride; + mgr->vertex_buffer[i].stride = vb->stride; if (!vb->buffer || mgr->incompatible_vb[i]) { @@ -745,22 +728,22 @@ static void u_vbuf_set_vertex_buffers(struct pipe_context *pipe, pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, vb->buffer); } - for (i = count; i < mgr->b.nr_vertex_buffers; i++) { - pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL); + for (i = count; i < mgr->nr_vertex_buffers; i++) { + pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL); } for (i = count; i < mgr->nr_real_vertex_buffers; i++) { pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); } - mgr->b.nr_vertex_buffers = count; + mgr->nr_vertex_buffers = count; mgr->nr_real_vertex_buffers = count; mgr->vertex_buffers_dirty = TRUE; } -static void u_vbuf_set_index_buffer(struct pipe_context *pipe, - const struct pipe_index_buffer *ib) +void u_vbuf_set_index_buffer(struct u_vbuf *mgr, + const struct pipe_index_buffer *ib) { - struct u_vbuf_priv *mgr = pipe->draw; + struct pipe_context *pipe = mgr->pipe; if (ib && ib->buffer) { assert(ib->offset % ib->index_size == 0); @@ -771,19 +754,19 @@ static void u_vbuf_set_index_buffer(struct pipe_context *pipe, pipe_resource_reference(&mgr->index_buffer.buffer, NULL); } - mgr->driver_set_index_buffer(pipe, ib); + pipe->set_index_buffer(pipe, ib); } static void -u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, +u_vbuf_upload_buffers(struct u_vbuf *mgr, int start_vertex, unsigned num_vertices, int start_instance, unsigned num_instances) { unsigned i; unsigned nr_velems = mgr->ve->count; - unsigned nr_vbufs = mgr->b.nr_vertex_buffers; + unsigned nr_vbufs = mgr->nr_vertex_buffers; struct pipe_vertex_element *velems = - mgr->fallback_ve ? mgr->fallback_velems : mgr->ve->ve; + mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve; unsigned start_offset[PIPE_MAX_ATTRIBS]; unsigned end_offset[PIPE_MAX_ATTRIBS] = {0}; @@ -791,7 +774,7 @@ u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, for (i = 0; i < nr_velems; i++) { struct pipe_vertex_element *velem = &velems[i]; unsigned index = velem->vertex_buffer_index; - struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index]; + struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index]; unsigned instance_div, first, size; /* Skip the buffers generated by translate. */ @@ -850,16 +833,16 @@ u_vbuf_upload_buffers(struct u_vbuf_priv *mgr, assert(start < end); real_vb = &mgr->real_vertex_buffer[i]; - ptr = mgr->b.vertex_buffer[i].buffer->user_ptr; + ptr = mgr->vertex_buffer[i].buffer->user_ptr; - u_upload_data(mgr->b.uploader, start, end - start, ptr + start, + u_upload_data(mgr->uploader, start, end - start, ptr + start, &real_vb->buffer_offset, &real_vb->buffer); real_vb->buffer_offset -= start; } } -static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) +static boolean u_vbuf_need_minmax_index(struct u_vbuf *mgr) { unsigned i, nr = mgr->ve->count; @@ -873,7 +856,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) } index = mgr->ve->ve[i].vertex_buffer_index; - vb = &mgr->b.vertex_buffer[index]; + vb = &mgr->vertex_buffer[index]; /* Constant attribs don't need min/max_index. */ if (!vb->stride) { @@ -891,7 +874,7 @@ static boolean u_vbuf_need_minmax_index(struct u_vbuf_priv *mgr) return FALSE; } -static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf_priv *mgr) +static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr) { unsigned i, nr = mgr->ve->count; @@ -905,7 +888,7 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf_priv *mgr) } index = mgr->ve->ve[i].vertex_buffer_index; - vb = &mgr->b.vertex_buffer[index]; + vb = &mgr->vertex_buffer[index]; /* Constant attribs are not per-vertex data. */ if (!vb->stride) { @@ -1023,13 +1006,12 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe, } } -static void u_vbuf_draw_vbo(struct pipe_context *pipe, - const struct pipe_draw_info *info) +void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) { - struct u_vbuf_priv *mgr = (struct u_vbuf_priv*)pipe->draw; + struct pipe_context *pipe = mgr->pipe; int start_vertex, min_index; unsigned num_vertices; - bool unroll_indices = false; + boolean unroll_indices = FALSE; /* Normal draw. No fallback and no user buffers. */ if (!mgr->incompatible_vb_layout && @@ -1037,27 +1019,27 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe, !mgr->any_user_vbs) { /* Set vertex buffers if needed. */ if (mgr->vertex_buffers_dirty) { - mgr->driver_set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers, - mgr->real_vertex_buffer); + pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers, + mgr->real_vertex_buffer); mgr->vertex_buffers_dirty = FALSE; } - mgr->driver_draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info); return; } if (info->indexed) { int max_index; - bool index_bounds_valid = false; + boolean index_bounds_valid = FALSE; if (info->max_index != ~0) { min_index = info->min_index; max_index = info->max_index; - index_bounds_valid = true; + index_bounds_valid = TRUE; } else if (u_vbuf_need_minmax_index(mgr)) { u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info, &min_index, &max_index); - index_bounds_valid = true; + index_bounds_valid = TRUE; } /* If the index bounds are valid, it means some upload or translation @@ -1077,7 +1059,7 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe, num_vertices-info->count > 32 && !u_vbuf_mapping_vertex_buffer_blocks(mgr)) { /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/ - unroll_indices = true; + unroll_indices = TRUE; } } else { /* Nothing to do for per-vertex attribs. */ @@ -1117,9 +1099,9 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe, } unsigned i; - for (i = 0; i < mgr->b.nr_vertex_buffers; i++) { + for (i = 0; i < mgr->nr_vertex_buffers; i++) { printf("input %i: ", i); - util_dump_vertex_buffer(stdout, mgr->b.vertex_buffer+i); + util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i); printf("\n"); } for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { @@ -1129,8 +1111,9 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe, } */ - mgr->driver_set_vertex_buffers(mgr->pipe, mgr->nr_real_vertex_buffers, - mgr->real_vertex_buffer); + u_upload_unmap(mgr->uploader); + pipe->set_vertex_buffers(pipe, mgr->nr_real_vertex_buffers, + mgr->real_vertex_buffer); if (unlikely(unroll_indices)) { struct pipe_draw_info new_info = *info; @@ -1140,36 +1123,51 @@ static void u_vbuf_draw_vbo(struct pipe_context *pipe, new_info.max_index = info->count - 1; new_info.start = 0; - mgr->driver_draw_vbo(pipe, &new_info); + pipe->draw_vbo(pipe, &new_info); } else { - mgr->driver_draw_vbo(pipe, info); + pipe->draw_vbo(pipe, info); } - if (mgr->fallback_ve) { + if (mgr->using_translate) { u_vbuf_translate_end(mgr); } mgr->vertex_buffers_dirty = TRUE; } -static void u_vbuf_install(struct u_vbuf_priv *mgr) +void u_vbuf_save_vertex_elements(struct u_vbuf *mgr) { - struct pipe_context *pipe = mgr->pipe; - assert(!pipe->draw); - - pipe->draw = mgr; - mgr->driver_set_index_buffer = pipe->set_index_buffer; - mgr->driver_set_vertex_buffers = pipe->set_vertex_buffers; - mgr->driver_create_vertex_elements_state = - pipe->create_vertex_elements_state; - mgr->driver_bind_vertex_elements_state = pipe->bind_vertex_elements_state; - mgr->driver_delete_vertex_elements_state = - pipe->delete_vertex_elements_state; - mgr->driver_draw_vbo = pipe->draw_vbo; - - pipe->set_index_buffer = u_vbuf_set_index_buffer; - pipe->set_vertex_buffers = u_vbuf_set_vertex_buffers; - pipe->create_vertex_elements_state = u_vbuf_create_vertex_elements; - pipe->bind_vertex_elements_state = u_vbuf_bind_vertex_elements; - pipe->delete_vertex_elements_state = u_vbuf_delete_vertex_elements; - pipe->draw_vbo = u_vbuf_draw_vbo; + assert(!mgr->ve_saved); + mgr->ve_saved = mgr->ve; +} + +void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr) +{ + if (mgr->ve != mgr->ve_saved) { + struct pipe_context *pipe = mgr->pipe; + + mgr->ve = mgr->ve_saved; + pipe->bind_vertex_elements_state(pipe, + mgr->ve ? mgr->ve->driver_cso : NULL); + } + mgr->ve_saved = NULL; +} + +void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr) +{ + util_copy_vertex_buffers(mgr->vertex_buffer_saved, + &mgr->nr_vertex_buffers_saved, + mgr->vertex_buffer, + mgr->nr_vertex_buffers); +} + +void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr) +{ + unsigned i; + + u_vbuf_set_vertex_buffers(mgr, mgr->nr_vertex_buffers_saved, + mgr->vertex_buffer_saved); + for (i = 0; i < mgr->nr_vertex_buffers_saved; i++) { + pipe_resource_reference(&mgr->vertex_buffer_saved[i].buffer, NULL); + } + mgr->nr_vertex_buffers_saved = 0; } diff --git a/src/gallium/auxiliary/util/u_vbuf.h b/src/gallium/auxiliary/util/u_vbuf.h index 80983f70a33..161349970a1 100644 --- a/src/gallium/auxiliary/util/u_vbuf.h +++ b/src/gallium/auxiliary/util/u_vbuf.h @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef U_VBUF_MGR_H -#define U_VBUF_MGR_H +#ifndef U_VBUF_H +#define U_VBUF_H /* This module builds upon u_upload_mgr and translate_cache and takes care of * user buffer uploads and vertex format fallbacks. It's designed @@ -36,6 +36,9 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +struct cso_context; +struct u_vbuf; + /* Hardware vertex fetcher limitations can be described by this structure. */ struct u_vbuf_caps { /* Vertex format CAPs. */ @@ -54,41 +57,28 @@ struct u_vbuf_caps { unsigned user_vertex_buffers:1; }; -/* The manager. - * This structure should also be used to access vertex buffers - * from a driver. */ -struct u_vbuf { - /* This is what was set in set_vertex_buffers. - * May contain user buffers. */ - struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; - unsigned nr_vertex_buffers; - - /* This uploader can optionally be used by the driver. - * - * Allowed functions: - * - u_upload_alloc - * - u_upload_data - * - u_upload_buffer - * - u_upload_flush */ - struct u_upload_mgr *uploader; - - /* Vertex elements state as created by u_vbuf. - * This is used when saving the state into u_blitter, there's no other - * usage. */ - void *vertex_elements; -}; - void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps); struct u_vbuf * u_vbuf_create(struct pipe_context *pipe, - struct u_vbuf_caps *caps, - unsigned upload_buffer_size, - unsigned upload_buffer_alignment, - unsigned upload_buffer_bind); + struct u_vbuf_caps *caps); void u_vbuf_destroy(struct u_vbuf *mgr); +/* State and draw functions. */ +void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_element *states); +void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count, + const struct pipe_vertex_buffer *bufs); +void u_vbuf_set_index_buffer(struct u_vbuf *mgr, + const struct pipe_index_buffer *ib); +void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info); + +/* Save/restore functionality. */ +void u_vbuf_save_vertex_elements(struct u_vbuf *mgr); +void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr); +void u_vbuf_save_vertex_buffers(struct u_vbuf *mgr); +void u_vbuf_restore_vertex_buffers(struct u_vbuf *mgr); #endif |