From e0773da1e897164ed7597437070e32b867734ee5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 10 Apr 2012 06:00:17 +0200 Subject: [PATCH] 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 --- src/gallium/auxiliary/cso_cache/cso_context.c | 66 +++- src/gallium/auxiliary/cso_cache/cso_context.h | 3 + src/gallium/auxiliary/util/u_vbuf.c | 304 +++++++++--------- src/gallium/auxiliary/util/u_vbuf.h | 50 ++- src/gallium/drivers/r300/r300_blit.c | 12 +- src/gallium/drivers/r300/r300_context.c | 18 +- src/gallium/drivers/r300/r300_context.h | 2 - src/gallium/drivers/r300/r300_screen.c | 7 +- src/gallium/drivers/r600/r600.h | 1 - src/gallium/drivers/r600/r600_blit.c | 6 +- src/gallium/drivers/r600/r600_buffer.c | 4 +- src/gallium/drivers/r600/r600_formats.h | 3 +- src/gallium/drivers/r600/r600_pipe.c | 14 - src/gallium/drivers/r600/r600_pipe.h | 1 - src/mesa/state_tracker/st_context.c | 26 ++ src/mesa/state_tracker/st_context.h | 3 + 16 files changed, 277 insertions(+), 243 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 diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 5b76c4b16e1..8d82bb920f6 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -62,15 +62,9 @@ static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op o util_blitter_save_fragment_shader(r300->blitter, r300->fs.state); util_blitter_save_vertex_shader(r300->blitter, r300->vs_state.state); util_blitter_save_viewport(r300->blitter, &r300->viewport); - if (r300->vbuf_mgr) { - util_blitter_save_vertex_buffers(r300->blitter, r300->vbuf_mgr->nr_vertex_buffers, - r300->vbuf_mgr->vertex_buffer); - util_blitter_save_vertex_elements(r300->blitter, r300->vbuf_mgr->vertex_elements); - } else { - util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers, - r300->vertex_buffer); - util_blitter_save_vertex_elements(r300->blitter, r300->velems); - } + util_blitter_save_vertex_buffers(r300->blitter, r300->nr_vertex_buffers, + r300->vertex_buffer); + util_blitter_save_vertex_elements(r300->blitter, r300->velems); if (op & R300_SAVE_FRAMEBUFFER) { util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index cb8cef15134..e1330a42a1d 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -100,9 +100,6 @@ static void r300_destroy_context(struct pipe_context* context) if (r300->draw) draw_destroy(r300->draw); - if (r300->vbuf_mgr) - u_vbuf_destroy(r300->vbuf_mgr); - u_upload_destroy(r300->uploader); /* XXX: This function assumes r300->query_list was initialized */ @@ -429,20 +426,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300->context.create_video_decoder = vl_create_decoder; r300->context.create_video_buffer = vl_video_buffer_create; - if (r300->screen->caps.has_tcl) { - struct u_vbuf_caps caps; - - u_vbuf_get_caps(screen, &caps); - caps.format_fixed32 = 0; - - r300->vbuf_mgr = u_vbuf_create(&r300->context, &caps, 1024 * 1024, 4, - PIPE_BIND_VERTEX_BUFFER | - PIPE_BIND_INDEX_BUFFER); - if (!r300->vbuf_mgr) - goto fail; - } - - r300->uploader = u_upload_create(&r300->context, 256 * 1024, 16, + r300->uploader = u_upload_create(&r300->context, 256 * 1024, 4, PIPE_BIND_INDEX_BUFFER); r300->blitter = util_blitter_create(&r300->context); diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8f125d19c16..ca57a5c7857 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -30,7 +30,6 @@ #include "pipe/p_context.h" #include "util/u_inlines.h" #include "util/u_transfer.h" -#include "util/u_vbuf.h" #include "r300_defines.h" #include "r300_screen.h" @@ -576,7 +575,6 @@ struct r300_context { void *dsa_decompress_zmask; - struct u_vbuf *vbuf_mgr; struct pipe_index_buffer index_buffer; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned nr_vertex_buffers; diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 8c12865e9ce..0803a0808b5 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -361,10 +361,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_R16G16B16_FLOAT || format == PIPE_FORMAT_R16G16B16A16_FLOAT; - boolean is_fixed = format == PIPE_FORMAT_R32_FIXED || - format == PIPE_FORMAT_R32G32_FIXED || - format == PIPE_FORMAT_R32G32B32_FIXED || - format == PIPE_FORMAT_R32G32B32A32_FIXED; if (!util_format_is_supported(format, usage)) return FALSE; @@ -428,8 +424,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, if (usage & PIPE_BIND_VERTEX_BUFFER && /* Half float is supported on >= R400. */ (is_r400 || is_r500 || !is_half_float) && - /* We have a fallback for FIXED. */ - (is_fixed || r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT)) { + r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) { retval |= PIPE_BIND_VERTEX_BUFFER; } diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index dd4fc009d3d..d95eadaa9c6 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -29,7 +29,6 @@ #include "../../winsys/radeon/drm/radeon_winsys.h" #include "util/u_double_list.h" #include "util/u_transfer.h" -#include "util/u_vbuf.h" #define R600_ERR(fmt, args...) \ fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args) diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index a7a0d9dfc1c..1122f3ec9ce 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -55,13 +55,13 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]); util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); - util_blitter_save_vertex_elements(rctx->blitter, rctx->vbuf_mgr->vertex_elements); + util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); if (rctx->states[R600_PIPE_STATE_VIEWPORT]) { util_blitter_save_viewport(rctx->blitter, &rctx->viewport); } util_blitter_save_vertex_buffers(rctx->blitter, - rctx->vbuf_mgr->nr_vertex_buffers, - rctx->vbuf_mgr->vertex_buffer); + rctx->nr_vertex_buffers, + rctx->vertex_buffer); util_blitter_save_so_targets(rctx->blitter, rctx->num_so_targets, (struct pipe_stream_output_target**)rctx->so_targets); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index c22d36147df..cb3ea214cfe 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -106,8 +106,8 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, /* We changed the buffer, now we need to bind it where the old one was bound. */ /* Vertex buffers. */ - for (i = 0; i < rctx->vbuf_mgr->nr_vertex_buffers; i++) { - if (rctx->vbuf_mgr->vertex_buffer[i].buffer == &rbuffer->b.b) { + for (i = 0; i < rctx->nr_vertex_buffers; i++) { + if (rctx->vertex_buffer[i].buffer == &rbuffer->b.b) { r600_inval_vertex_cache(rctx); r600_atom_dirty(rctx, &rctx->vertex_buffer_state); } diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h index af6de1cd797..6f5722851d4 100644 --- a/src/gallium/drivers/r600/r600_formats.h +++ b/src/gallium/drivers/r600/r600_formats.h @@ -101,7 +101,8 @@ static INLINE bool r600_is_vertex_format_supported(enum pipe_format format) /* No fixed, no double. */ if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || (desc->channel[i].size == 64 && - desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)) + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) || + desc->channel[i].type == UTIL_FORMAT_TYPE_FIXED) return false; /* No scaled/norm formats with 32 bits per channel. */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 7dfa2bfb3a7..062b94af720 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -192,9 +192,6 @@ static void r600_destroy_context(struct pipe_context *context) free(rctx->states[i]); } - if (rctx->vbuf_mgr) { - u_vbuf_destroy(rctx->vbuf_mgr); - } if (rctx->uploader) { u_upload_destroy(rctx->uploader); } @@ -216,7 +213,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void { struct r600_context *rctx = CALLOC_STRUCT(r600_context); struct r600_screen* rscreen = (struct r600_screen *)screen; - struct u_vbuf_caps vbuf_caps; if (rctx == NULL) return NULL; @@ -298,16 +294,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx); r600_emit_atom(rctx, &rctx->start_cs_cmd.atom); - u_vbuf_get_caps(screen, &vbuf_caps); - vbuf_caps.format_fixed32 = 0; - rctx->vbuf_mgr = u_vbuf_create(&rctx->context, &vbuf_caps, - 1024 * 1024, 256, - PIPE_BIND_VERTEX_BUFFER | - PIPE_BIND_INDEX_BUFFER | - PIPE_BIND_CONSTANT_BUFFER); - if (!rctx->vbuf_mgr) - goto fail; - rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256, PIPE_BIND_INDEX_BUFFER | PIPE_BIND_CONSTANT_BUFFER); diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 69f3644d8d2..450fcc4ccfe 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -284,7 +284,6 @@ struct r600_context { struct r600_textures_info vs_samplers; struct r600_textures_info ps_samplers; - struct u_vbuf *vbuf_mgr; struct u_upload_mgr *uploader; struct util_slab_mempool pool_transfers; boolean have_depth_texture, have_depth_fb; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 0245fd92b3e..b27f2f677b6 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -65,6 +65,7 @@ #include "util/u_inlines.h" #include "util/u_upload_mgr.h" #include "cso_cache/cso_context.h" +#include "util/u_vbuf.h" DEBUG_GET_ONCE_BOOL_OPTION(mesa_mvp_dp4, "MESA_MVP_DP4", FALSE) @@ -111,6 +112,27 @@ st_get_msaa(void) } +static void st_init_vbuf(struct st_context *st) +{ + struct u_vbuf_caps caps; + + u_vbuf_get_caps(st->pipe->screen, &caps); + + /* Create u_vbuf if there is anything unsupported. */ + if (!caps.fetch_dword_unaligned || + !caps.format_fixed32 || + !caps.format_float16 || + !caps.format_float64 || + !caps.format_norm32 || + !caps.format_scaled32 || + !caps.user_vertex_buffers) { + /* XXX user vertex buffers are always uploaded regardless of the CAP. */ + st->vbuf = u_vbuf_create(st->pipe, &caps); + cso_install_vbuf(st->cso_context, st->vbuf); + } +} + + static struct st_context * st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) { @@ -134,6 +156,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); st->cso_context = cso_create_context(pipe); + st_init_vbuf(st); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); @@ -277,6 +300,9 @@ void st_destroy_context( struct st_context *st ) st_destroy_context_priv(st); + if (st->vbuf) + u_vbuf_destroy(st->vbuf); + cso_destroy_context(cso); pipe->destroy( pipe ); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index e3d65d97aa5..3ec98ada196 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -41,6 +41,7 @@ struct gen_mipmap_state; struct st_context; struct st_fragment_program; struct u_upload_mgr; +struct u_vbuf; #define ST_NEW_MESA (1 << 0) /* Mesa state has changed */ @@ -73,6 +74,8 @@ struct st_context struct pipe_context *pipe; struct u_upload_mgr *uploader; + struct u_vbuf *vbuf; + struct draw_context *draw; /**< For selection/feedback/rastpos only */ struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */ -- 2.30.2