diff options
Diffstat (limited to 'src/mesa/state_tracker/st_draw.c')
-rw-r--r-- | src/mesa/state_tracker/st_draw.c | 179 |
1 files changed, 98 insertions, 81 deletions
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index 40afa436292..d27043ec296 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -181,7 +181,7 @@ static GLuint fixed_types[4] = { /** * Return a PIPE_FORMAT_x for the given GL datatype and size. */ -GLuint +enum pipe_format st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, GLboolean normalized) { @@ -211,7 +211,7 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, case GL_UNSIGNED_BYTE: return ubyte_types_norm[size-1]; case GL_FIXED: return fixed_types[size-1]; default: assert(0); return 0; - } + } } else { switch (type) { @@ -226,15 +226,13 @@ st_pipe_vertex_format(GLenum type, GLuint size, GLenum format, case GL_UNSIGNED_BYTE: return ubyte_types_scale[size-1]; case GL_FIXED: return fixed_types[size-1]; default: assert(0); return 0; - } + } } - return 0; /* silence compiler warning */ + return PIPE_FORMAT_NONE; /* silence compiler warning */ } - - /** * Examine the active arrays to determine if we have interleaved * vertex arrays all living in one VBO, or all living in user space. @@ -253,8 +251,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp, for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; - const struct gl_buffer_object *bufObj = arrays[mesaAttr]->BufferObj; - const GLsizei stride = arrays[mesaAttr]->StrideB; /* in bytes */ + const struct gl_client_array *array = arrays[mesaAttr]; + const struct gl_buffer_object *bufObj = array->BufferObj; + const GLsizei stride = array->StrideB; /* in bytes */ if (firstStride < 0) { firstStride = stride; @@ -272,9 +271,9 @@ is_interleaved_arrays(const struct st_vertex_program *vp, return GL_FALSE; } if (!client_addr) { - client_addr = arrays[mesaAttr]->Ptr; + client_addr = array->Ptr; } - else if (abs(arrays[mesaAttr]->Ptr - client_addr) > firstStride) { + else if (abs(array->Ptr - client_addr) > firstStride) { /* arrays start too far apart */ return GL_FALSE; } @@ -315,8 +314,8 @@ setup_interleaved_attribs(struct gl_context *ctx, GLuint attr; const GLubyte *low_addr = NULL; - /* Find the lowest address. */ - if(vpv->num_inputs) { + /* Find the lowest address of the arrays we're drawing */ + if (vpv->num_inputs) { low_addr = arrays[vp->index_to_input[0]]->Ptr; for (attr = 1; attr < vpv->num_inputs; attr++) { @@ -327,41 +326,48 @@ setup_interleaved_attribs(struct gl_context *ctx, for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; - struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; + const struct gl_client_array *array = arrays[mesaAttr]; + struct gl_buffer_object *bufobj = array->BufferObj; struct st_buffer_object *stobj = st_buffer_object(bufobj); - GLsizei stride = arrays[mesaAttr]->StrideB; + unsigned src_offset = (unsigned) (array->Ptr - low_addr); + GLuint element_size = array->_ElementSize; + GLsizei stride = array->StrideB; + + assert(element_size == array->Size * _mesa_sizeof_type(array->Type)); if (attr == 0) { if (bufobj && bufobj->Name) { vbuffer->buffer = NULL; pipe_resource_reference(&vbuffer->buffer, stobj->buffer); vbuffer->buffer_offset = pointer_to_offset(low_addr); - } else { - uint divisor = arrays[mesaAttr]->InstanceDivisor; - uint length = (divisor ? num_instances / divisor : max_index) + 1; - vbuffer->buffer = - pipe_user_buffer_create(pipe->screen, (void*)low_addr, - stride * length, - PIPE_BIND_VERTEX_BUFFER); + } + else { + uint divisor = array->InstanceDivisor; + uint last_index = divisor ? num_instances / divisor : max_index; + uint bytes = src_offset + stride * last_index + element_size; + + vbuffer->buffer = pipe_user_buffer_create(pipe->screen, + (void*) low_addr, + bytes, + PIPE_BIND_VERTEX_BUFFER); vbuffer->buffer_offset = 0; /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_vb[0], vbuffer->buffer); - st->user_vb_stride[0] = stride; - st->num_user_vbs = 1; + pipe_resource_reference(&st->user_attrib[0].buffer, vbuffer->buffer); + st->user_attrib[0].element_size = element_size; + st->user_attrib[0].stride = stride; + st->num_user_attribs = 1; } vbuffer->stride = stride; /* in bytes */ } - velements[attr].src_offset = - (unsigned) (arrays[mesaAttr]->Ptr - low_addr); - velements[attr].instance_divisor = arrays[mesaAttr]->InstanceDivisor; + velements[attr].src_offset = src_offset; + velements[attr].instance_divisor = array->InstanceDivisor; velements[attr].vertex_buffer_index = 0; - velements[attr].src_format = - st_pipe_vertex_format(arrays[mesaAttr]->Type, - arrays[mesaAttr]->Size, - arrays[mesaAttr]->Format, - arrays[mesaAttr]->Normalized); + velements[attr].src_format = st_pipe_vertex_format(array->Type, + array->Size, + array->Format, + array->Normalized); assert(velements[attr].src_format); } } @@ -389,8 +395,12 @@ setup_non_interleaved_attribs(struct gl_context *ctx, for (attr = 0; attr < vpv->num_inputs; attr++) { const GLuint mesaAttr = vp->index_to_input[attr]; - struct gl_buffer_object *bufobj = arrays[mesaAttr]->BufferObj; - GLsizei stride = arrays[mesaAttr]->StrideB; + 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)); if (bufobj && bufobj->Name) { /* Attribute data is in a VBO. @@ -402,49 +412,54 @@ setup_non_interleaved_attribs(struct gl_context *ctx, vbuffer[attr].buffer = NULL; pipe_resource_reference(&vbuffer[attr].buffer, stobj->buffer); - vbuffer[attr].buffer_offset = pointer_to_offset(arrays[mesaAttr]->Ptr); + vbuffer[attr].buffer_offset = pointer_to_offset(array->Ptr); } else { /* wrap user data */ - if (arrays[mesaAttr]->Ptr) { - uint divisor = arrays[mesaAttr]->InstanceDivisor; - uint length = (divisor ? num_instances / divisor : max_index) + 1; - vbuffer[attr].buffer = - pipe_user_buffer_create(pipe->screen, - (void *) arrays[mesaAttr]->Ptr, - stride * length, - PIPE_BIND_VERTEX_BUFFER); + 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 */ - uint bytes = sizeof(ctx->Current.Attrib[0]); - vbuffer[attr].buffer = - pipe_user_buffer_create(pipe->screen, - (void *) ctx->Current.Attrib[mesaAttr], - bytes, - PIPE_BIND_VERTEX_BUFFER); + 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_offset = 0; /* Track user vertex buffers. */ - pipe_resource_reference(&st->user_vb[attr], vbuffer[attr].buffer); - st->user_vb_stride[attr] = stride; - st->num_user_vbs = MAX2(st->num_user_vbs, attr+1); + 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); } /* common-case setup */ vbuffer[attr].stride = stride; /* in bytes */ velements[attr].src_offset = 0; - velements[attr].instance_divisor = arrays[mesaAttr]->InstanceDivisor; + velements[attr].instance_divisor = array->InstanceDivisor; velements[attr].vertex_buffer_index = attr; - velements[attr].src_format - = st_pipe_vertex_format(arrays[mesaAttr]->Type, - arrays[mesaAttr]->Size, - arrays[mesaAttr]->Format, - arrays[mesaAttr]->Normalized); + velements[attr].src_format = st_pipe_vertex_format(array->Type, + array->Size, + array->Format, + array->Normalized); assert(velements[attr].src_format); } } @@ -575,10 +590,10 @@ 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_vbs; i++) { - pipe_resource_reference(&st->user_vb[i], NULL); + for (i = 0; i < st->num_user_attribs; i++) { + pipe_resource_reference(&st->user_attrib[i].buffer, NULL); } - st->num_user_vbs = 0; + st->num_user_attribs = 0; /* * Setup the vbuffer[] and velements[] arrays. @@ -594,7 +609,8 @@ st_validate_varrays(struct gl_context *ctx, } else { setup_non_interleaved_attribs(ctx, vp, vpv, arrays, - vbuffer, velements, max_index, num_instances); + vbuffer, velements, max_index, + num_instances); num_vbuffers = vpv->num_inputs; num_velements = vpv->num_inputs; } @@ -647,7 +663,8 @@ st_draw_vbo(struct gl_context *ctx, for (i = 0; i < nr_prims; i++) { num_instances = MAX2(num_instances, prims[i].num_instances); } - } else { + } + else { /* Get min/max index for non-indexed drawing. */ min_index = ~0; max_index = 0; @@ -690,20 +707,20 @@ st_draw_vbo(struct gl_context *ctx, /* Notify the driver that the content of user buffers may have been * changed. */ - if (!new_array && st->num_user_vbs) { - for (i = 0; i < st->num_user_vbs; i++) { - if (st->user_vb[i]) { - unsigned stride = st->user_vb_stride[i]; - - if (stride) { - pipe->redefine_user_buffer(pipe, st->user_vb[i], - min_index * stride, - (max_index + 1 - min_index) * stride); - } else { - /* stride == 0 */ - pipe->redefine_user_buffer(pipe, st->user_vb[i], - 0, st->user_vb[i]->width0); - } + 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 * stride + element_size; + + assert(max_offset > min_offset); + + pipe->redefine_user_buffer(pipe, st->user_attrib[i].buffer, + min_offset, + max_offset - min_offset); } } } @@ -743,7 +760,8 @@ st_draw_vbo(struct gl_context *ctx, } -void st_init_draw( struct st_context *st ) +void +st_init_draw(struct st_context *st) { struct gl_context *ctx = st->ctx; @@ -763,11 +781,10 @@ void st_init_draw( struct st_context *st ) } -void st_destroy_draw( struct st_context *st ) +void +st_destroy_draw(struct st_context *st) { #if FEATURE_feedback || FEATURE_rastpos draw_destroy(st->draw); #endif } - - |