X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_buffer.c;h=6ebe6ab2364ca40712175dcb111d09cf46d4e2cf;hb=8c631cfeae29b5236928f759e222aa35e6e4984c;hp=3c45d782a2c1fa3bfb6da82411c1fa0d9620ce57;hpb=29c4a15bf61a76cd71ffa5b8f09706d0eab84281;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 3c45d782a2c..6ebe6ab2364 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -29,42 +29,18 @@ #include #include #include -#include +#include "util/u_upload_mgr.h" + #include "state_tracker/drm_driver.h" + #include #include "radeon_drm.h" + #include "r600.h" #include "r600_pipe.h" extern struct u_resource_vtbl r600_buffer_vtbl; -u32 r600_domain_from_usage(unsigned usage) -{ - u32 domain = RADEON_GEM_DOMAIN_GTT; - - if (usage & PIPE_BIND_RENDER_TARGET) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_DEPTH_STENCIL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_SAMPLER_VIEW) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - /* also need BIND_BLIT_SOURCE/DESTINATION ? */ - if (usage & PIPE_BIND_VERTEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_INDEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_CONSTANT_BUFFER) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - - return domain; -} - struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { @@ -79,13 +55,12 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, rbuffer->magic = R600_BUFFER_MAGIC; rbuffer->user_buffer = NULL; - rbuffer->num_ranges = 0; rbuffer->r.base.b = *templ; pipe_reference_init(&rbuffer->r.base.b.reference, 1); rbuffer->r.base.b.screen = screen; rbuffer->r.base.vtbl = &r600_buffer_vtbl; rbuffer->r.size = rbuffer->r.base.b.width0; - rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind); + rbuffer->r.bo_size = rbuffer->r.size; bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); if (bo == NULL) { FREE(rbuffer); @@ -116,9 +91,10 @@ struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen, rbuffer->r.base.b.width0 = bytes; rbuffer->r.base.b.height0 = 1; rbuffer->r.base.b.depth0 = 1; + rbuffer->r.base.b.array_size = 1; rbuffer->r.base.b.flags = 0; - rbuffer->num_ranges = 0; rbuffer->r.bo = NULL; + rbuffer->r.bo_size = 0; rbuffer->user_buffer = ptr; return &rbuffer->r.base.b; } @@ -131,6 +107,7 @@ static void r600_buffer_destroy(struct pipe_screen *screen, if (rbuffer->r.bo) { r600_bo_reference((struct radeon*)screen->winsys, &rbuffer->r.bo, NULL); } + rbuffer->r.bo = NULL; FREE(rbuffer); } @@ -140,29 +117,10 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); int write = 0; uint8_t *data; - int i; - boolean flush = FALSE; if (rbuffer->user_buffer) return (uint8_t*)rbuffer->user_buffer + transfer->box.x; - if (transfer->usage & PIPE_TRANSFER_DISCARD) { - for (i = 0; i < rbuffer->num_ranges; i++) { - if ((transfer->box.x >= rbuffer->ranges[i].start) && - (transfer->box.x < rbuffer->ranges[i].end)) - flush = TRUE; - - if (flush) { - r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL); - rbuffer->num_ranges = 0; - rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys, - rbuffer->r.base.b.width0, 0, - rbuffer->r.base.b.bind, - rbuffer->r.base.b.usage); - break; - } - } - } if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { /* FIXME */ } @@ -181,41 +139,22 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe, { struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); + if (rbuffer->user_buffer) + return; + if (rbuffer->r.bo) r600_bo_unmap((struct radeon*)pipe->winsys, rbuffer->r.bo); } static void r600_buffer_transfer_flush_region(struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) + struct pipe_transfer *transfer, + const struct pipe_box *box) { - struct r600_resource_buffer *rbuffer = r600_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 (rbuffer->user_buffer) - return; - - /* mark the range as used */ - for(i = 0; i < rbuffer->num_ranges; ++i) { - if(offset <= rbuffer->ranges[i].end && rbuffer->ranges[i].start <= (offset+box->width)) { - rbuffer->ranges[i].start = MIN2(rbuffer->ranges[i].start, offset); - rbuffer->ranges[i].end = MAX2(rbuffer->ranges[i].end, (offset+length)); - return; - } - } - - rbuffer->ranges[rbuffer->num_ranges].start = offset; - rbuffer->ranges[rbuffer->num_ranges].end = offset+length; - rbuffer->num_ranges++; } unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, struct pipe_resource *buf, - unsigned face, unsigned level) + unsigned level, int layer) { /* FIXME */ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; @@ -260,60 +199,71 @@ struct u_resource_vtbl r600_buffer_vtbl = u_default_transfer_inline_write /* transfer_inline_write */ }; -int r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw) +void r600_upload_index_buffer(struct r600_pipe_context *rctx, struct r600_drawl *draw) { - struct pipe_resource *upload_buffer = NULL; - unsigned index_offset = draw->index_buffer_offset; - int ret = 0; - - if (r600_buffer_is_user_buffer(draw->index_buffer)) { - ret = u_upload_buffer(rctx->upload_ib, - index_offset, - draw->count * draw->index_size, - draw->index_buffer, - &index_offset, - &upload_buffer); - if (ret) { - goto done; - } - draw->index_buffer_offset = index_offset; + struct r600_resource_buffer *rbuffer = r600_buffer(draw->index_buffer); + boolean flushed; + + u_upload_data(rctx->upload_vb, 0, + draw->info.count * draw->index_size, + rbuffer->user_buffer, + &draw->index_buffer_offset, + &draw->index_buffer, &flushed); +} - /* Transfer ownership. */ - pipe_resource_reference(&draw->index_buffer, upload_buffer); - pipe_resource_reference(&upload_buffer, NULL); - } +void r600_upload_user_buffers(struct r600_pipe_context *rctx, + int min_index, int max_index) +{ + int i, nr = rctx->vertex_elements->count; + unsigned count = max_index + 1 - min_index; + boolean flushed; + boolean uploaded[32] = {0}; + + for (i = 0; i < nr; i++) { + unsigned index = rctx->vertex_elements->elements[i].vertex_buffer_index; + struct pipe_vertex_buffer *vb = &rctx->vertex_buffer[index]; + struct r600_resource_buffer *userbuf = r600_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 = rctx->vertex_elements->hw_format_size[i]; + } + + u_upload_data(rctx->upload_vb, first, size, + userbuf->user_buffer + first, + &vb->buffer_offset, + &rctx->real_vertex_buffer[index], + &flushed); -done: - return ret; + vb->buffer_offset -= first; + + /* vertex_arrays_dirty = TRUE; */ + uploaded[index] = TRUE; + } else { + assert(rctx->real_vertex_buffer[index]); + } + } } -int r600_upload_user_buffers(struct r600_pipe_context *rctx) +void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer, + uint32_t *const_offset) { - enum pipe_error ret = PIPE_OK; - int i, nr; + if ((*rbuffer)->user_buffer) { + uint8_t *ptr = (*rbuffer)->user_buffer; + unsigned size = (*rbuffer)->r.base.b.width0; + boolean flushed; - nr = rctx->vertex_elements->count; + *rbuffer = NULL; - for (i = 0; i < nr; i++) { - struct pipe_vertex_buffer *vb = - &rctx->vertex_buffer[rctx->vertex_elements->elements[i].vertex_buffer_index]; - - if (r600_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(rctx->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; - } + u_upload_data(rctx->upload_const, 0, size, ptr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); + } else { + *const_offset = 0; } - return ret; }