diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_screen_buffer.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_screen_buffer.c | 260 |
1 files changed, 123 insertions, 137 deletions
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index 37a080b..cc3c1d7 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -40,10 +40,10 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context, struct r300_context *r300 = r300_context(context); struct r300_buffer *rbuf = r300_buffer(buf); - if (r300_buffer_is_user_buffer(buf)) + if (r300_is_user_buffer(buf)) return PIPE_UNREFERENCED; - if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain)) + if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf, domain)) return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; return PIPE_UNREFERENCED; @@ -51,76 +51,86 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context, static unsigned r300_buffer_is_referenced_by_cs(struct pipe_context *context, struct pipe_resource *buf, - unsigned face, unsigned level) + unsigned level, int layer) { return r300_buffer_is_referenced(context, buf, R300_REF_CS); } -/* External helper, not required to implent u_resource_vtbl: - */ -int r300_upload_index_buffer(struct r300_context *r300, - struct pipe_resource **index_buffer, - unsigned index_size, - unsigned start, - unsigned count, - unsigned *out_offset) +void r300_upload_index_buffer(struct r300_context *r300, + struct pipe_resource **index_buffer, + unsigned index_size, unsigned *start, + unsigned count) { - struct pipe_resource *upload_buffer = NULL; - unsigned index_offset = start * index_size; - int ret = 0; - - if (r300_buffer_is_user_buffer(*index_buffer)) { - ret = u_upload_buffer(r300->upload_ib, - index_offset, - count * index_size, - *index_buffer, - &index_offset, - &upload_buffer); - if (ret) { - goto done; - } - *index_buffer = upload_buffer; - *out_offset = index_offset / index_size; - } else - *out_offset = start; - - done: - // if (upload_buffer) - // pipe_resource_reference(&upload_buffer, NULL); - return ret; + unsigned index_offset; + uint8_t *ptr = r300_buffer(*index_buffer)->user_buffer; + boolean flushed; + + *index_buffer = NULL; + + u_upload_data(r300->upload_ib, + 0, count * index_size, + ptr + (*start * index_size), + &index_offset, + index_buffer, &flushed); + + *start = index_offset / index_size; + + if (flushed || !r300->upload_ib_validated) { + r300->upload_ib_validated = FALSE; + r300->validate_buffers = TRUE; + } } -/* External helper, not required to implement u_resource_vtbl: - */ -int r300_upload_user_buffers(struct r300_context *r300) +void r300_upload_user_buffers(struct r300_context *r300, + int min_index, int max_index) { - enum pipe_error ret = PIPE_OK; - int i, nr; - - nr = r300->velems->count; + int i, nr = r300->velems->count; + unsigned count = max_index + 1 - min_index; + boolean flushed; + boolean uploaded[16] = {0}; for (i = 0; i < nr; i++) { - struct pipe_vertex_buffer *vb = - &r300->vertex_buffer[r300->velems->velem[i].vertex_buffer_index]; - - if (r300_buffer_is_user_buffer(vb->buffer)) { - struct pipe_resource *upload_buffer = NULL; - unsigned offset = 0; /*vb->buffer_offset * 4;*/ - unsigned size = vb->buffer->width0; - unsigned upload_offset; - ret = u_upload_buffer(r300->upload_vb, - offset, size, - vb->buffer, - &upload_offset, &upload_buffer); - if (ret) - return ret; - - pipe_resource_reference(&vb->buffer, NULL); - vb->buffer = upload_buffer; - vb->buffer_offset = upload_offset; + unsigned index = r300->velems->velem[i].vertex_buffer_index; + struct pipe_vertex_buffer *vb = &r300->vertex_buffer[index]; + struct r300_buffer *userbuf = r300_buffer(vb->buffer); + + if (userbuf && userbuf->user_buffer && !uploaded[index]) { + unsigned first, size; + + if (vb->stride) { + first = vb->stride * min_index; + size = vb->stride * count; + } else { + first = 0; + size = r300->velems->hw_format_size[i]; + } + + DBG(r300, DBG_UPLOAD, + "Uploading %i bytes, index: %i, buffer: %p, userptr: %p " + "offset: %i, stride: %i.\n", + size, index, userbuf, userbuf->user_buffer, + vb->buffer_offset, vb->stride); + + u_upload_data(r300->upload_vb, first, size, + userbuf->user_buffer + first, + &vb->buffer_offset, + &r300->valid_vertex_buffer[index], + &flushed); + + vb->buffer_offset -= first; + + r300->vertex_arrays_dirty = TRUE; + + if (flushed || !r300->upload_vb_validated) { + r300->upload_vb_validated = FALSE; + r300->validate_buffers = TRUE; + } + uploaded[index] = TRUE; + } else { + assert(r300->valid_vertex_buffer[index]); } } - return ret; + DBG(r300, DBG_UPLOAD, "-------\n"); } static void r300_buffer_destroy(struct pipe_screen *screen, @@ -136,26 +146,26 @@ static void r300_buffer_destroy(struct pipe_screen *screen, if (rbuf->buf) rws->buffer_reference(rws, &rbuf->buf, NULL); - util_mempool_free(&r300screen->pool_buffers, rbuf); + util_slab_free(&r300screen->pool_buffers, rbuf); } static struct pipe_transfer* -r300_default_get_transfer(struct pipe_context *context, - struct pipe_resource *resource, - struct pipe_subresource sr, - unsigned usage, - const struct pipe_box *box) +r300_buffer_get_transfer(struct pipe_context *context, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box) { struct r300_context *r300 = r300_context(context); struct pipe_transfer *transfer = - util_mempool_malloc(&r300->pool_transfers); + util_slab_alloc(&r300->pool_transfers); transfer->resource = resource; - transfer->sr = sr; + transfer->level = level; transfer->usage = usage; transfer->box = *box; transfer->stride = 0; - transfer->slice_stride = 0; + transfer->layer_stride = 0; transfer->data = NULL; /* Note strides are zero, this is ok for buffers, but not for @@ -164,11 +174,11 @@ r300_default_get_transfer(struct pipe_context *context, return transfer; } -static void r300_default_transfer_destroy(struct pipe_context *pipe, - struct pipe_transfer *transfer) +static void r300_buffer_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) { struct r300_context *r300 = r300_context(pipe); - util_mempool_free(&r300->pool_transfers, transfer); + util_slab_free(&r300->pool_transfers, transfer); } static void * @@ -180,46 +190,17 @@ r300_buffer_transfer_map( struct pipe_context *pipe, struct r300_winsys_screen *rws = r300screen->rws; struct r300_buffer *rbuf = r300_buffer(transfer->resource); uint8_t *map; - boolean flush = FALSE; - unsigned i; if (rbuf->user_buffer) return (uint8_t *) rbuf->user_buffer + transfer->box.x; if (rbuf->constant_buffer) return (uint8_t *) rbuf->constant_buffer + transfer->box.x; - /* check if the mapping is to a range we already flushed */ - if (transfer->usage & PIPE_TRANSFER_DISCARD) { - for (i = 0; i < rbuf->num_ranges; i++) { - if ((transfer->box.x >= rbuf->ranges[i].start) && - (transfer->box.x < rbuf->ranges[i].end)) - flush = TRUE; - - if (flush) { - /* unreference this hw buffer and allocate a new one */ - rws->buffer_reference(rws, &rbuf->buf, NULL); - - rbuf->num_ranges = 0; - rbuf->buf = - r300screen->rws->buffer_create(r300screen->rws, - rbuf->b.b.width0, 16, - rbuf->b.b.bind, - rbuf->b.b.usage, - rbuf->domain); - break; - } - } - } - map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage); if (map == NULL) return NULL; - /* map_buffer() returned a pointer to the beginning of the buffer, - * but transfers are expected to return a pointer to just the - * region specified in the box. - */ return map + transfer->box.x; } @@ -227,30 +208,7 @@ static void r300_buffer_transfer_flush_region( struct pipe_context *pipe, struct pipe_transfer *transfer, const struct pipe_box *box) { - struct r300_buffer *rbuf = r300_buffer(transfer->resource); - unsigned i; - unsigned offset = transfer->box.x + box->x; - unsigned length = box->width; - - assert(box->x + box->width <= transfer->box.width); - - if (rbuf->user_buffer) - return; - if (rbuf->constant_buffer) - return; - - /* mark the range as used */ - for(i = 0; i < rbuf->num_ranges; ++i) { - if(offset <= rbuf->ranges[i].end && rbuf->ranges[i].start <= (offset+box->width)) { - rbuf->ranges[i].start = MIN2(rbuf->ranges[i].start, offset); - rbuf->ranges[i].end = MAX2(rbuf->ranges[i].end, (offset+length)); - return; - } - } - - rbuf->ranges[rbuf->num_ranges].start = offset; - rbuf->ranges[rbuf->num_ranges].end = offset+length; - rbuf->num_ranges++; + /* no-op */ } static void r300_buffer_transfer_unmap( struct pipe_context *pipe, @@ -265,17 +223,45 @@ static void r300_buffer_transfer_unmap( struct pipe_context *pipe, } } -struct u_resource_vtbl r300_buffer_vtbl = +static void r300_buffer_transfer_inline_write(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box, + const void *data, + unsigned stride, + unsigned layer_stride) +{ + struct r300_context *r300 = r300_context(pipe); + struct r300_winsys_screen *rws = r300->screen->rws; + struct r300_buffer *rbuf = r300_buffer(resource); + uint8_t *map = NULL; + + if (rbuf->constant_buffer) { + memcpy(rbuf->constant_buffer + box->x, data, box->width); + return; + } + assert(rbuf->user_buffer == NULL); + + map = rws->buffer_map(rws, rbuf->buf, r300->cs, + PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage); + + memcpy(map + box->x, data, box->width); + + rws->buffer_unmap(rws, rbuf->buf); +} + +struct u_resource_vtbl r300_buffer_vtbl = { u_default_resource_get_handle, /* get_handle */ r300_buffer_destroy, /* resource_destroy */ r300_buffer_is_referenced_by_cs, /* is_buffer_referenced */ - r300_default_get_transfer, /* get_transfer */ - r300_default_transfer_destroy, /* transfer_destroy */ + r300_buffer_get_transfer, /* get_transfer */ + r300_buffer_transfer_destroy, /* transfer_destroy */ r300_buffer_transfer_map, /* transfer_map */ r300_buffer_transfer_flush_region, /* transfer_flush_region */ r300_buffer_transfer_unmap, /* transfer_unmap */ - u_default_transfer_inline_write /* transfer_inline_write */ + r300_buffer_transfer_inline_write /* transfer_inline_write */ }; struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, @@ -285,7 +271,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, struct r300_buffer *rbuf; unsigned alignment = 16; - rbuf = util_mempool_malloc(&r300screen->pool_buffers); + rbuf = util_slab_alloc(&r300screen->pool_buffers); rbuf->magic = R300_BUFFER_MAGIC; @@ -294,7 +280,6 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, pipe_reference_init(&rbuf->b.b.reference, 1); rbuf->b.b.screen = screen; rbuf->domain = R300_DOMAIN_GTT; - rbuf->num_ranges = 0; rbuf->buf = NULL; rbuf->constant_buffer = NULL; rbuf->user_buffer = NULL; @@ -310,9 +295,11 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, rbuf->b.b.width0, alignment, rbuf->b.b.bind, rbuf->b.b.usage, rbuf->domain); + rbuf->cs_buf = + r300screen->rws->buffer_get_cs_handle(r300screen->rws, rbuf->buf); if (!rbuf->buf) { - util_mempool_free(&r300screen->pool_buffers, rbuf); + util_slab_free(&r300screen->pool_buffers, rbuf); return NULL; } @@ -320,14 +307,13 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, } struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, - void *ptr, - unsigned bytes, + void *ptr, unsigned size, unsigned bind) { struct r300_screen *r300screen = r300_screen(screen); struct r300_buffer *rbuf; - rbuf = util_mempool_malloc(&r300screen->pool_buffers); + rbuf = util_slab_alloc(&r300screen->pool_buffers); rbuf->magic = R300_BUFFER_MAGIC; @@ -338,12 +324,12 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE; rbuf->b.b.bind = bind; - rbuf->b.b.width0 = bytes; + rbuf->b.b.width0 = ~0; rbuf->b.b.height0 = 1; rbuf->b.b.depth0 = 1; + rbuf->b.b.array_size = 1; rbuf->b.b.flags = 0; rbuf->domain = R300_DOMAIN_GTT; - rbuf->num_ranges = 0; rbuf->buf = NULL; rbuf->constant_buffer = NULL; rbuf->user_buffer = ptr; |