diff options
author | Marek Olšák <[email protected]> | 2012-05-11 16:38:13 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-05-11 16:38:13 +0200 |
commit | bb4c5d72d7c7cb1d9e7016e2c07c36875f30011a (patch) | |
tree | 153444ff535900f82ae63b5af8ccd09fb2f063af /src/mesa | |
parent | 96956dc5076fc03b9290368ca90e3f3b870ee613 (diff) | |
parent | 8dd3e341b337ca2d22bcc0e7548a78a6c36ca77d (diff) |
Merge branch 'gallium-userbuf'
Conflicts:
src/gallium/docs/source/screen.rst
src/gallium/drivers/nv50/nv50_state.c
src/gallium/include/pipe/p_defines.h
src/mesa/state_tracker/st_draw.c
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/state_tracker/st_atom_constbuf.c | 27 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.c | 53 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_context.h | 16 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 240 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_draw_feedback.c | 32 |
5 files changed, 111 insertions, 257 deletions
diff --git a/src/mesa/state_tracker/st_atom_constbuf.c b/src/mesa/state_tracker/st_atom_constbuf.c index 05667a74305..fd9228583d2 100644 --- a/src/mesa/state_tracker/st_atom_constbuf.c +++ b/src/mesa/state_tracker/st_atom_constbuf.c @@ -38,6 +38,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" +#include "util/u_upload_mgr.h" #include "st_debug.h" #include "st_context.h" @@ -55,15 +56,13 @@ void st_upload_constants( struct st_context *st, struct gl_program_parameter_list *params, unsigned shader_type) { - struct pipe_context *pipe = st->pipe; - assert(shader_type == PIPE_SHADER_VERTEX || shader_type == PIPE_SHADER_FRAGMENT || shader_type == PIPE_SHADER_GEOMETRY); /* update constants */ if (params && params->NumParameters) { - struct pipe_resource *cbuf; + struct pipe_constant_buffer cb; const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4; /* Update the constants which come from fixed-function state, such as @@ -77,20 +76,28 @@ void st_upload_constants( struct st_context *st, * avoid gratuitous rendering synchronization. * Let's use a user buffer to avoid an unnecessary copy. */ - cbuf = pipe_user_buffer_create(pipe->screen, - params->ParameterValues, - paramBytes, - PIPE_BIND_CONSTANT_BUFFER); + if (st->constbuf_uploader) { + cb.buffer = NULL; + cb.user_buffer = NULL; + u_upload_data(st->constbuf_uploader, 0, paramBytes, + params->ParameterValues, &cb.buffer_offset, &cb.buffer); + u_upload_unmap(st->constbuf_uploader); + } else { + cb.buffer = NULL; + cb.user_buffer = params->ParameterValues; + cb.buffer_offset = 0; + } + cb.buffer_size = paramBytes; if (ST_DEBUG & DEBUG_CONSTANTS) { - debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", + debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n", __FUNCTION__, shader_type, params->NumParameters, params->StateFlags); _mesa_print_parameter_list(params); } - st->pipe->set_constant_buffer(st->pipe, shader_type, 0, cbuf); - pipe_resource_reference(&cbuf, NULL); + st->pipe->set_constant_buffer(st->pipe, shader_type, 0, &cb); + pipe_resource_reference(&cb.buffer, NULL); st->state.constants[shader_type].ptr = params->ParameterValues; st->state.constants[shader_type].size = paramBytes; diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index ce7dbb3f39a..b4497652539 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -65,7 +65,6 @@ #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) @@ -112,32 +111,12 @@ 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.buffer_offset_unaligned || - !caps.buffer_stride_unaligned || - !caps.velem_src_offset_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 ) { + struct pipe_screen *screen = pipe->screen; uint i; struct st_context *st = ST_CALLOC_STRUCT( st_context ); @@ -156,9 +135,22 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe ) st->dirty.st = ~0; st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); + + if (!screen->get_param(screen, PIPE_CAP_USER_INDEX_BUFFERS)) { + st->indexbuf_uploader = u_upload_create(st->pipe, 128 * 1024, 4, + PIPE_BIND_INDEX_BUFFER); + } + + if (!screen->get_param(screen, PIPE_CAP_USER_CONSTANT_BUFFERS)) { + unsigned alignment = + screen->get_param(screen, PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT); + + st->constbuf_uploader = u_upload_create(pipe, 128 * 1024, alignment, + PIPE_BIND_CONSTANT_BUFFER); + } + st->cso_context = cso_create_context(pipe); - st_init_vbuf(st); st_init_atoms( st ); st_init_bitmap(st); st_init_clear(st); @@ -254,11 +246,6 @@ static void st_destroy_context_priv( struct st_context *st ) st_destroy_drawpix(st); st_destroy_drawtex(st); - /* Unreference any user vertex buffers. */ - for (i = 0; i < st->num_user_attribs; i++) { - pipe_resource_reference(&st->user_attrib[i].buffer, NULL); - } - for (i = 0; i < Elements(st->state.sampler_views); i++) { pipe_sampler_view_reference(&st->state.sampler_views[i], NULL); } @@ -269,6 +256,12 @@ static void st_destroy_context_priv( struct st_context *st ) } u_upload_destroy(st->uploader); + if (st->indexbuf_uploader) { + u_upload_destroy(st->indexbuf_uploader); + } + if (st->constbuf_uploader) { + u_upload_destroy(st->constbuf_uploader); + } free( st ); } @@ -276,7 +269,6 @@ static void st_destroy_context_priv( struct st_context *st ) void st_destroy_context( struct st_context *st ) { struct pipe_context *pipe = st->pipe; - struct u_vbuf *vbuf = st->vbuf; struct cso_context *cso = st->cso_context; struct gl_context *ctx = st->ctx; GLuint i; @@ -312,9 +304,6 @@ void st_destroy_context( struct st_context *st ) st_destroy_context_priv(st); st = NULL; - if (vbuf) - u_vbuf_destroy(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 4786ed22fe9..00a405b69f9 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -41,7 +41,6 @@ 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 */ @@ -74,8 +73,7 @@ struct st_context struct pipe_context *pipe; - struct u_upload_mgr *uploader; - struct u_vbuf *vbuf; + struct u_upload_mgr *uploader, *indexbuf_uploader, *constbuf_uploader; struct draw_context *draw; /**< For selection/feedback/rastpos only */ struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */ @@ -191,18 +189,6 @@ struct st_context int force_msaa; void *winsys_drawable_handle; - /* User vertex buffers. */ - struct { - struct pipe_resource *buffer; - - /** Element size */ - GLuint element_size; - - /** Attribute stride */ - GLsizei stride; - } user_attrib[PIPE_MAX_ATTRIBS]; - unsigned num_user_attribs; - /* Active render condition. */ struct pipe_query *render_condition; unsigned condition_mode; diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 42dc3757615..a8c20f45acd 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -61,6 +61,7 @@ #include "util/u_format.h" #include "util/u_prim.h" #include "util/u_draw_quad.h" +#include "util/u_upload_mgr.h" #include "draw/draw_context.h" #include "cso_cache/cso_context.h" @@ -402,18 +403,12 @@ setup_interleaved_attribs(struct gl_context *ctx, const struct st_vp_variant *vpv, const struct gl_client_array **arrays, struct pipe_vertex_buffer *vbuffer, - struct pipe_vertex_element velements[], - unsigned max_index, - unsigned num_instances) + struct pipe_vertex_element velements[]) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; GLuint attr; const GLubyte *low_addr = NULL; GLboolean usingVBO; /* all arrays in a VBO? */ struct gl_buffer_object *bufobj; - GLuint user_buffer_size = 0; - GLuint vertex_size = 0; /* bytes per vertex, in bytes */ GLsizei stride; /* Find the lowest address of the arrays we're drawing, @@ -464,18 +459,6 @@ setup_interleaved_attribs(struct gl_context *ctx, array->Normalized, array->Integer); assert(velements[attr].src_format); - - if (!usingVBO) { - /* how many bytes referenced by this attribute array? */ - uint divisor = array->InstanceDivisor; - uint last_index = divisor ? num_instances / divisor : max_index; - uint bytes = src_offset + stride * last_index + element_size; - - user_buffer_size = MAX2(user_buffer_size, bytes); - - /* update vertex size */ - vertex_size = MAX2(vertex_size, src_offset + element_size); - } } /* @@ -484,9 +467,9 @@ setup_interleaved_attribs(struct gl_context *ctx, if (vpv->num_inputs == 0) { /* just defensive coding here */ vbuffer->buffer = NULL; + vbuffer->user_buffer = NULL; vbuffer->buffer_offset = 0; vbuffer->stride = 0; - st->num_user_attribs = 0; } else if (usingVBO) { /* all interleaved arrays in a VBO */ @@ -497,26 +480,17 @@ setup_interleaved_attribs(struct gl_context *ctx, return GL_FALSE; } - vbuffer->buffer = NULL; - pipe_resource_reference(&vbuffer->buffer, stobj->buffer); + vbuffer->buffer = stobj->buffer; + vbuffer->user_buffer = NULL; vbuffer->buffer_offset = pointer_to_offset(low_addr); vbuffer->stride = stride; - st->num_user_attribs = 0; } else { /* all interleaved arrays in user memory */ - vbuffer->buffer = pipe_user_buffer_create(pipe->screen, - (void*) low_addr, - user_buffer_size, - PIPE_BIND_VERTEX_BUFFER); + vbuffer->buffer = NULL; + vbuffer->user_buffer = low_addr; vbuffer->buffer_offset = 0; vbuffer->stride = stride; - - /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer); - st->user_attrib[0].element_size = vertex_size; - st->user_attrib[0].stride = stride; - st->num_user_attribs = 1; } return GL_TRUE; @@ -536,22 +510,17 @@ setup_non_interleaved_attribs(struct gl_context *ctx, const struct st_vp_variant *vpv, const struct gl_client_array **arrays, struct pipe_vertex_buffer vbuffer[], - struct pipe_vertex_element velements[], - unsigned max_index, - unsigned num_instances) + struct pipe_vertex_element velements[]) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; GLuint attr; for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; const struct gl_client_array *array = arrays[mesaAttr]; struct gl_buffer_object *bufobj = array->BufferObj; - GLuint element_size = array->_ElementSize; GLsizei stride = array->StrideB; - assert(element_size == array->Size * _mesa_sizeof_type(array->Type)); + assert(array->_ElementSize == array->Size * _mesa_sizeof_type(array->Type)); if (_mesa_is_bufferobj(bufobj)) { /* Attribute data is in a VBO. @@ -565,49 +534,28 @@ setup_non_interleaved_attribs(struct gl_context *ctx, return GL_FALSE; } - vbuffer[attr].buffer = NULL; - pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer); + vbuffer[attr].buffer = stobj->buffer; + vbuffer[attr].user_buffer = NULL; vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr); } else { /* wrap user data */ - uint bytes; void *ptr; if (array->Ptr) { - uint divisor = array->InstanceDivisor; - uint last_index = divisor ? num_instances / divisor : max_index; - - bytes = stride * last_index + element_size; - ptr = (void *) array->Ptr; } else { /* no array, use ctx->Current.Attrib[] value */ - bytes = element_size = sizeof(ctx->Current.Attrib[0]); ptr = (void *) ctx->Current.Attrib[mesaAttr]; stride = 0; } assert(ptr); - assert(bytes); - - vbuffer[attr].buffer = - pipe_user_buffer_create(pipe->screen, ptr, bytes, - PIPE_BIND_VERTEX_BUFFER); + vbuffer[attr].buffer = NULL; + vbuffer[attr].user_buffer = ptr; vbuffer[attr].buffer_offset = 0; - - /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_attrib[attr].buffer, vbuffer[attr].buffer); - st->user_attrib[attr].element_size = element_size; - st->user_attrib[attr].stride = stride; - st->num_user_attribs = MAX2(st->num_user_attribs, attr + 1); - - if (!vbuffer[attr].buffer) { - /* probably ran out of memory */ - return GL_FALSE; - } } /* common-case setup */ @@ -629,34 +577,31 @@ setup_non_interleaved_attribs(struct gl_context *ctx, static void -setup_index_buffer(struct gl_context *ctx, +setup_index_buffer(struct st_context *st, const struct _mesa_index_buffer *ib, struct pipe_index_buffer *ibuffer) { - struct st_context *st = st_context(ctx); - struct pipe_context *pipe = st->pipe; + struct gl_buffer_object *bufobj = ib->obj; - memset(ibuffer, 0, sizeof(*ibuffer)); - if (ib) { - struct gl_buffer_object *bufobj = ib->obj; - - ibuffer->index_size = vbo_sizeof_ib_type(ib->type); + ibuffer->index_size = vbo_sizeof_ib_type(ib->type); - /* get/create the index buffer object */ - if (_mesa_is_bufferobj(bufobj)) { - /* elements/indexes are in a real VBO */ - struct st_buffer_object *stobj = st_buffer_object(bufobj); - pipe_resource_reference(&ibuffer->buffer, stobj->buffer); - ibuffer->offset = pointer_to_offset(ib->ptr); - } - else { - /* element/indicies are in user space memory */ - ibuffer->buffer = - pipe_user_buffer_create(pipe->screen, (void *) ib->ptr, - ib->count * ibuffer->index_size, - PIPE_BIND_INDEX_BUFFER); - } + /* get/create the index buffer object */ + if (_mesa_is_bufferobj(bufobj)) { + /* indices are in a real VBO */ + ibuffer->buffer = st_buffer_object(bufobj)->buffer; + ibuffer->offset = pointer_to_offset(ib->ptr); } + else if (st->indexbuf_uploader) { + u_upload_data(st->indexbuf_uploader, 0, ib->count * ibuffer->index_size, + ib->ptr, &ibuffer->offset, &ibuffer->buffer); + u_upload_unmap(st->indexbuf_uploader); + } + else { + /* indices are in user space memory */ + ibuffer->user_buffer = ib->ptr; + } + + cso_set_index_buffer(st->cso_context, ibuffer); } @@ -811,10 +756,10 @@ handle_fallback_primitive_restart(struct cso_context *cso, unsigned num_sub_prims; assert(info.indexed); - assert(ibuffer->buffer); + assert(ibuffer->buffer || ibuffer->user_buffer); assert(ib); - if (!ibuffer->buffer || !ib) + if (!ibuffer->buffer || !ibuffer->user_buffer || !ib) return; info.primitive_restart = FALSE; @@ -894,9 +839,7 @@ translate_prim(const struct gl_context *ctx, unsigned prim) */ static GLboolean st_validate_varrays(struct gl_context *ctx, - const struct gl_client_array **arrays, - unsigned max_index, - unsigned num_instances) + const struct gl_client_array **arrays) { struct st_context *st = st_context(ctx); const struct st_vertex_program *vp; @@ -904,8 +847,6 @@ st_validate_varrays(struct gl_context *ctx, struct pipe_vertex_buffer vbuffer[PIPE_MAX_SHADER_INPUTS]; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; unsigned num_vbuffers, num_velements; - GLuint attr; - unsigned i; /* must get these after state validation! */ vp = st->vp; @@ -913,18 +854,12 @@ st_validate_varrays(struct gl_context *ctx, memset(velements, 0, sizeof(struct pipe_vertex_element) * vpv->num_inputs); - /* Unreference any user vertex buffers. */ - for (i = 0; i < st->num_user_attribs; i++) { - pipe_resource_reference(&st->user_attrib[i].buffer, NULL); - } - st->num_user_attribs = 0; - /* * Setup the vbuffer[] and velements[] arrays. */ if (is_interleaved_arrays(vp, vpv, arrays)) { - if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, velements, - max_index, num_instances)) { + if (!setup_interleaved_attribs(ctx, vp, vpv, arrays, vbuffer, + velements)) { return GL_FALSE; } @@ -935,8 +870,7 @@ st_validate_varrays(struct gl_context *ctx, } else { if (!setup_non_interleaved_attribs(ctx, vp, vpv, arrays, - vbuffer, velements, max_index, - num_instances)) { + vbuffer, velements)) { return GL_FALSE; } @@ -947,14 +881,6 @@ st_validate_varrays(struct gl_context *ctx, cso_set_vertex_buffers(st->cso_context, num_vbuffers, vbuffer); cso_set_vertex_elements(st->cso_context, num_velements, velements); - /* unreference buffers (frees wrapped user-space buffer objects) - * This is OK, because the pipe driver should reference buffers by itself - * in set_vertex_buffers. */ - for (attr = 0; attr < num_vbuffers; attr++) { - pipe_resource_reference(&vbuffer[attr].buffer, NULL); - assert(!vbuffer[attr].buffer); - } - return GL_TRUE; } @@ -976,11 +902,10 @@ st_draw_vbo(struct gl_context *ctx, { struct st_context *st = st_context(ctx); struct pipe_context *pipe = st->pipe; - struct pipe_index_buffer ibuffer; + struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; const struct gl_client_array **arrays = ctx->Array._DrawArrays; - unsigned i, num_instances = 1; - unsigned max_index_plus_base; + unsigned i; GLboolean new_array; /* Mesa core state should have been validated already */ @@ -994,43 +919,6 @@ st_draw_vbo(struct gl_context *ctx, (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) || (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; - if (ib) { - int max_base_vertex = 0; - - /* Gallium probably doesn't want this in some cases. */ - if (!index_bounds_valid) - if (!all_varyings_in_vbos(arrays)) - vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, - nr_prims); - - for (i = 0; i < nr_prims; i++) { - num_instances = MAX2(num_instances, prims[i].num_instances); - max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex); - } - - /* Compute the sum of max_index and max_base_vertex. That's the value - * we need to use when creating buffers. - */ - if (max_index == ~0) - max_index_plus_base = max_index; - else - max_index_plus_base = max_index + max_base_vertex; - } - else { - /* Get min/max index for non-indexed drawing. */ - min_index = ~0; - max_index = 0; - - for (i = 0; i < nr_prims; i++) { - min_index = MIN2(min_index, prims[i].start); - max_index = MAX2(max_index, prims[i].start + prims[i].count - 1); - num_instances = MAX2(num_instances, prims[i].num_instances); - } - - /* The base vertex offset only applies to indexed drawing */ - max_index_plus_base = max_index; - } - /* Validate state. */ if (st->dirty.st) { GLboolean vertDataEdgeFlags; @@ -1045,8 +933,7 @@ st_draw_vbo(struct gl_context *ctx, st_validate_state(st); if (new_array) { - if (!st_validate_varrays(ctx, arrays, max_index_plus_base, - num_instances)) { + if (!st_validate_varrays(ctx, arrays)) { /* probably out of memory, no-op the draw call */ return; } @@ -1061,31 +948,16 @@ st_draw_vbo(struct gl_context *ctx, #endif } - /* Notify the driver that the content of user buffers may have been - * changed. */ - assert(max_index >= min_index); - if (!new_array && st->num_user_attribs) { - for (i = 0; i < st->num_user_attribs; i++) { - if (st->user_attrib[i].buffer) { - unsigned element_size = st->user_attrib[i].element_size; - unsigned stride = st->user_attrib[i].stride; - unsigned min_offset = min_index * stride; - unsigned max_offset = max_index_plus_base * stride + element_size; - - assert(max_offset > min_offset); - - pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer, - min_offset, - max_offset - min_offset); - } - } - } - - setup_index_buffer(ctx, ib, &ibuffer); - cso_set_index_buffer(st->cso_context, &ibuffer); - util_draw_init_info(&info); if (ib) { + /* Get index bounds for user buffers. */ + if (!index_bounds_valid) + if (!all_varyings_in_vbos(arrays)) + vbo_get_minmax_indices(ctx, prims, ib, &min_index, &max_index, + nr_prims); + + setup_index_buffer(st, ib, &ibuffer); + info.indexed = TRUE; if (min_index != ~0 && max_index != ~0) { info.min_index = min_index; @@ -1098,10 +970,12 @@ st_draw_vbo(struct gl_context *ctx, info.primitive_restart = ctx->Array.PrimitiveRestart; info.restart_index = ctx->Array.RestartIndex; } - - /* Set info.count_from_stream_output. */ - if (tfb_vertcount) { - st_transform_feedback_draw_init(tfb_vertcount, &info); + else { + /* Transform feedback drawing is always non-indexed. */ + /* Set info.count_from_stream_output. */ + if (tfb_vertcount) { + st_transform_feedback_draw_init(tfb_vertcount, &info); + } } /* do actual drawing */ @@ -1134,7 +1008,9 @@ st_draw_vbo(struct gl_context *ctx, cso_draw_vbo(st->cso_context, &info); } - pipe_resource_reference(&ibuffer.buffer, NULL); + if (ib && st->indexbuf_uploader && !_mesa_is_bufferobj(ib->obj)) { + pipe_resource_reference(&ibuffer.buffer, NULL); + } } diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 257618aa992..4209fb214f8 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -107,7 +107,7 @@ st_feedback_draw_vbo(struct gl_context *ctx, struct pipe_vertex_buffer vbuffers[PIPE_MAX_SHADER_INPUTS]; struct pipe_vertex_element velements[PIPE_MAX_ATTRIBS]; struct pipe_index_buffer ibuffer; - struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS]; + struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {NULL}; struct pipe_transfer *ib_transfer = NULL; const struct gl_client_array **arrays = ctx->Array._DrawArrays; GLuint attr, i; @@ -169,23 +169,24 @@ st_feedback_draw_vbo(struct gl_context *ctx, assert(stobj->buffer); vbuffers[attr].buffer = NULL; + vbuffers[attr].user_buffer = NULL; pipe_resource_reference(&vbuffers[attr].buffer, stobj->buffer); vbuffers[attr].buffer_offset = pointer_to_offset(low_addr); velements[attr].src_offset = arrays[mesaAttr]->Ptr - low_addr; + + /* map the attrib buffer */ + map = pipe_buffer_map(pipe, vbuffers[attr].buffer, + PIPE_TRANSFER_READ, + &vb_transfer[attr]); + draw_set_mapped_vertex_buffer(draw, attr, map); } else { - /* attribute data is in user-space memory, not a VBO */ - uint bytes = (arrays[mesaAttr]->Size - * _mesa_sizeof_type(arrays[mesaAttr]->Type) - * (max_index + 1)); - - /* wrap user data */ - vbuffers[attr].buffer - = pipe_user_buffer_create(pipe->screen, (void *) arrays[mesaAttr]->Ptr, - bytes, - PIPE_BIND_VERTEX_BUFFER); + vbuffers[attr].buffer = NULL; + vbuffers[attr].user_buffer = arrays[mesaAttr]->Ptr; vbuffers[attr].buffer_offset = 0; velements[attr].src_offset = 0; + + draw_set_mapped_vertex_buffer(draw, attr, vbuffers[attr].user_buffer); } /* common-case setup */ @@ -204,12 +205,6 @@ st_feedback_draw_vbo(struct gl_context *ctx, #if 0 draw_set_vertex_buffer(draw, attr, &vbuffer[attr]); #endif - - /* map the attrib buffer */ - map = pipe_buffer_map(pipe, vbuffers[attr].buffer, - PIPE_TRANSFER_READ, - &vb_transfer[attr]); - draw_set_mapped_vertex_buffer(draw, attr, map); } draw_set_vertex_buffers(draw, vp->num_inputs, vbuffers); @@ -267,7 +262,8 @@ st_feedback_draw_vbo(struct gl_context *ctx, out_unref_vertex: for (attr = 0; attr < vp->num_inputs; attr++) { - pipe_buffer_unmap(pipe, vb_transfer[attr]); + if (vb_transfer[attr]) + pipe_buffer_unmap(pipe, vb_transfer[attr]); draw_set_mapped_vertex_buffer(draw, attr, NULL); pipe_resource_reference(&vbuffers[attr].buffer, NULL); } |