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.
This commit is contained in:
Marek Olšák
2012-04-24 20:58:47 +02:00
parent 7a05459726
commit 4552fd50d9
17 changed files with 73 additions and 182 deletions
+3 -2
View File
@@ -236,12 +236,13 @@ static LLVMTypeRef
create_jit_vertex_buffer_type(struct gallivm_state *gallivm, const char *struct_name)
{
LLVMTargetDataRef target = gallivm->target;
LLVMTypeRef elem_types[3];
LLVMTypeRef elem_types[4];
LLVMTypeRef vb_type;
elem_types[0] =
elem_types[1] = LLVMInt32TypeInContext(gallivm->context);
elem_types[2] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
elem_types[2] =
elem_types[3] = LLVMPointerType(LLVMInt8TypeInContext(gallivm->context), 0); /* vs_constants */
#if HAVE_LLVM >= 0x0300
vb_type = LLVMStructCreateNamed(gallivm->context, struct_name);
+4
View File
@@ -62,6 +62,10 @@ util_draw_max_index(
const struct util_format_description *format_desc;
unsigned format_size;
if (!buffer->buffer) {
continue;
}
assert(buffer->buffer->height0 == 1);
assert(buffer->buffer->depth0 == 1);
buffer_size = buffer->buffer->width0;
+8 -9
View File
@@ -277,8 +277,8 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
unsigned offset = vb->buffer_offset + vb->stride * start_vertex;
uint8_t *map;
if (vb->buffer->user_ptr) {
map = vb->buffer->user_ptr + offset;
if (vb->user_buffer) {
map = (uint8_t*)vb->user_buffer + offset;
} else {
unsigned size = vb->stride ? num_vertices * vb->stride
: sizeof(double)*4;
@@ -713,6 +713,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[i];
pipe_resource_reference(&orig_vb->buffer, vb->buffer);
orig_vb->user_buffer = vb->user_buffer;
real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset;
real_vb->stride = orig_vb->stride = vb->stride;
@@ -721,7 +722,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
mgr->nonzero_stride_vb_mask |= 1 << i;
}
if (!vb->buffer) {
if (!vb->buffer && !vb->user_buffer) {
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
}
@@ -733,7 +734,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, unsigned count,
continue;
}
if (!mgr->caps.user_vertex_buffers && vb->buffer->user_ptr) {
if (!mgr->caps.user_vertex_buffers && vb->user_buffer) {
mgr->user_vb_mask |= 1 << i;
pipe_resource_reference(&real_vb->buffer, NULL);
continue;
@@ -798,9 +799,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
continue;
}
assert(vb->buffer);
if (!vb->buffer->user_ptr) {
if (!vb->user_buffer) {
continue;
}
@@ -837,7 +836,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
for (i = 0; i < nr_vbufs; i++) {
unsigned start, end = end_offset[i];
struct pipe_vertex_buffer *real_vb;
uint8_t *ptr;
const uint8_t *ptr;
if (!end) {
continue;
@@ -847,7 +846,7 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
assert(start < end);
real_vb = &mgr->real_vertex_buffer[i];
ptr = mgr->vertex_buffer[i].buffer->user_ptr;
ptr = mgr->vertex_buffer[i].user_buffer;
u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer);
+3 -1
View File
@@ -983,7 +983,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe,
/* map new */
for (i = 0; i < count; i++) {
void *buf = i915_buffer(buffers[i].buffer)->data;
const void *buf = buffers[i].user_buffer;
if (!buf)
buf = i915_buffer(buffers[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
@@ -67,7 +67,9 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
* Map vertex buffers
*/
for (i = 0; i < lp->num_vertex_buffers; i++) {
void *buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
const void *buf = lp->vertex_buffer[i].user_buffer;
if (!buf)
buf = llvmpipe_resource_data(lp->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
+6 -3
View File
@@ -366,7 +366,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
{
struct nv30_context *nv30 = nv30_context(pipe);
struct draw_context *draw = nv30->draw;
struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS];
struct pipe_transfer *transfer[PIPE_MAX_ATTRIBS] = {NULL};
struct pipe_transfer *transferi = NULL;
int i;
@@ -403,7 +403,9 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
}
for (i = 0; i < nv30->num_vtxbufs; i++) {
void *map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
const void *map = nv30->vtxbuf[i].user_buffer;
if (!map)
map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer,
PIPE_TRANSFER_UNSYNCHRONIZED |
PIPE_TRANSFER_READ, &transfer[i]);
draw_set_mapped_vertex_buffer(draw, i, map);
@@ -425,7 +427,8 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
if (info->indexed)
pipe_buffer_unmap(pipe, transferi);
for (i = 0; i < nv30->num_vtxbufs; i++)
pipe_buffer_unmap(pipe, transfer[i]);
if (transfer[i])
pipe_buffer_unmap(pipe, transfer[i]);
nv30->draw_dirty = 0;
nv30_state_release(nv30);
+2 -1
View File
@@ -78,10 +78,11 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
case PIPE_CAP_USER_VERTEX_BUFFERS:
case PIPE_CAP_USER_INDEX_BUFFERS:
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
case PIPE_CAP_USER_VERTEX_BUFFERS:
return 0;
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
return 16;
/* nv4x capabilities */
+1 -1
View File
@@ -149,8 +149,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
return 0; /* state trackers will know better */
case PIPE_CAP_USER_VERTEX_BUFFERS:
return 0; /* state trackers will know better */
case PIPE_CAP_USER_INDEX_BUFFERS:
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+1 -1
View File
@@ -139,8 +139,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
return 1;
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
return 0; /* state trackers will know better */
case PIPE_CAP_USER_VERTEX_BUFFERS:
return 0; /* state trackers will know better */
case PIPE_CAP_USER_INDEX_BUFFERS:
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+6 -2
View File
@@ -873,7 +873,10 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
indexed ? 256 : 6);
for (i = 0; i < r300->nr_vertex_buffers; i++) {
if (r300->vertex_buffer[i].buffer) {
if (r300->vertex_buffer[i].user_buffer) {
draw_set_mapped_vertex_buffer(r300->draw, i,
r300->vertex_buffer[i].user_buffer);
} else if (r300->vertex_buffer[i].buffer) {
void *buf = pipe_buffer_map(pipe,
r300->vertex_buffer[i].buffer,
PIPE_TRANSFER_READ |
@@ -899,7 +902,8 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
for (i = 0; i < r300->nr_vertex_buffers; i++) {
if (r300->vertex_buffer[i].buffer) {
pipe_buffer_unmap(pipe, vb_transfer[i]);
if (vb_transfer[i])
pipe_buffer_unmap(pipe, vb_transfer[i]);
draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
}
}
@@ -77,7 +77,9 @@ softpipe_draw_vbo(struct pipe_context *pipe,
/* Map vertex buffers */
for (i = 0; i < sp->num_vertex_buffers; i++) {
void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
const void *buf = sp->vertex_buffer[i].user_buffer;
if (!buf)
buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
draw_set_mapped_vertex_buffer(draw, i, buf);
}
+1
View File
@@ -161,6 +161,7 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_SWIZZLE:
return 1;
case PIPE_CAP_USER_VERTEX_BUFFERS:
return 0;
case PIPE_CAP_USER_INDEX_BUFFERS:
case PIPE_CAP_USER_CONSTANT_BUFFERS:
return 1;
+1
View File
@@ -447,6 +447,7 @@ struct pipe_vertex_buffer
unsigned stride; /**< stride to same attrib in next vertex, in bytes */
unsigned buffer_offset; /**< offset to start of data in buffer, in bytes */
struct pipe_resource *buffer; /**< the actual buffer */
const void *user_buffer; /**< pointer to a user buffer if buffer == NULL */
};
-5
View File
@@ -263,11 +263,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);
}
-12
View File
@@ -190,18 +190,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;
+17 -125
View File
@@ -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);
+14 -18
View File
@@ -108,7 +108,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;
GLuint attr, i;
const GLubyte *low_addr = NULL;
@@ -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);
}