diff options
author | Marek Olšák <maraeo@gmail.com> | 2012-04-24 20:58:47 +0200 |
---|---|---|
committer | Marek Olšák <maraeo@gmail.com> | 2012-04-30 01:14:26 +0200 |
commit | 4552fd50d959ab99546cfa994f8ba5bdf5d66bc7 (patch) | |
tree | 6fa793d4b11531704029adfd33bfd5a94b90e230 /src/mesa/state_tracker/st_draw.c | |
parent | 7a0545972694e6afc6c5ac60db563defa79c20d9 (diff) |
gallium: add void *user_buffer in pipe_vertex_buffer
This reduces CPU overhead in st_draw_vbo and removes a lot of unnecessary code
in that function which was required only to comply with the gallium interface,
but wasn't any useful really.
Adapted drivers: i915, llvmpipe, r300, softpipe.
No changes required in: r600, radeonsi.
User vertex buffers have been disabled in nv30, nv50, nvc0 and svga to keep
things working.
Diffstat (limited to 'src/mesa/state_tracker/st_draw.c')
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 142 |
1 files changed, 17 insertions, 125 deletions
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index fa7c18895c7..09f41abc13b 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -403,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, @@ -465,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); - } } /* @@ -485,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 */ @@ -498,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; @@ -537,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. @@ -566,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 */ @@ -896,9 +843,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; @@ -906,8 +851,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; @@ -915,18 +858,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; } @@ -937,8 +874,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; } @@ -949,14 +885,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; } @@ -982,7 +910,6 @@ st_draw_vbo(struct gl_context *ctx, struct pipe_index_buffer ibuffer = {0}; struct pipe_draw_info info; unsigned i, num_instances = 1; - unsigned max_index_plus_base; GLboolean new_array = st->dirty.st && (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0; @@ -991,8 +918,6 @@ st_draw_vbo(struct gl_context *ctx, assert(ctx->NewState == 0x0); 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)) @@ -1001,16 +926,7 @@ st_draw_vbo(struct gl_context *ctx, 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. */ @@ -1022,9 +938,6 @@ st_draw_vbo(struct gl_context *ctx, 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. */ @@ -1041,8 +954,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; } @@ -1057,26 +969,6 @@ 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); - } - } - } - util_draw_init_info(&info); if (ib) { setup_index_buffer(st, ib, &ibuffer); |