diff options
author | Marek Olšák <[email protected]> | 2012-12-09 16:43:16 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-12-12 13:11:52 +0100 |
commit | 2478fcd87c4361ce288b042cc922373ef40b113c (patch) | |
tree | 13497df85def5ab476dd031e217cea984a7e4d90 /src | |
parent | 448cd5ea60403576c3eec86ffb2b892e78b9dfe0 (diff) |
r600g: use u_upload_mgr for allocating staging transfer buffers
u_upload_mgr suballocates memory from a large buffer and maps the allocated
range (unsychronized), which is perfect for short-lived staging buffers.
This reduces the number of relocations sent to the kernel.
Tested-by: Aaron Watry <[email protected]>
Reviewed-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/gallium/drivers/r600/r600_buffer.c | 30 |
1 files changed, 15 insertions, 15 deletions
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 9e2cf6650ad..e674e13a144 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -66,7 +66,8 @@ static void *r600_buffer_get_transfer(struct pipe_context *ctx, unsigned usage, const struct pipe_box *box, struct pipe_transfer **ptransfer, - void *data, struct r600_resource *staging) + void *data, struct r600_resource *staging, + unsigned offset) { struct r600_context *rctx = (struct r600_context*)ctx; struct r600_transfer *transfer = util_slab_alloc(&rctx->pool_transfers); @@ -77,8 +78,7 @@ static void *r600_buffer_get_transfer(struct pipe_context *ctx, transfer->transfer.box = *box; transfer->transfer.stride = 0; transfer->transfer.layer_stride = 0; - transfer->staging = NULL; - transfer->offset = 0; + transfer->offset = offset; transfer->staging = staging; *ptransfer = &transfer->transfer; return data; @@ -147,18 +147,17 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx, if (rctx->ws->cs_is_buffer_referenced(rctx->cs, rbuffer->cs_buf, RADEON_USAGE_READWRITE) || rctx->ws->buffer_is_busy(rbuffer->buf, RADEON_USAGE_READWRITE)) { /* Do a wait-free write-only transfer using a temporary buffer. */ - struct r600_resource *staging = (struct r600_resource*) - pipe_buffer_create(ctx->screen, PIPE_BIND_VERTEX_BUFFER, - PIPE_USAGE_STAGING, - box->width + (box->x % R600_MAP_BUFFER_ALIGNMENT)); - data = rctx->ws->buffer_map(staging->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE); + unsigned offset; + struct r600_resource *staging = NULL; - if (!data) - return NULL; + u_upload_alloc(rctx->uploader, 0, box->width + (box->x % R600_MAP_BUFFER_ALIGNMENT), + &offset, (struct pipe_resource**)&staging, (void**)&data); - data += box->x % R600_MAP_BUFFER_ALIGNMENT; - return r600_buffer_get_transfer(ctx, resource, level, usage, box, - ptransfer, data, staging); + if (staging) { + data += box->x % R600_MAP_BUFFER_ALIGNMENT; + return r600_buffer_get_transfer(ctx, resource, level, usage, box, + ptransfer, data, staging, offset); + } } } @@ -169,7 +168,7 @@ static void *r600_buffer_transfer_map(struct pipe_context *ctx, data += box->x; return r600_buffer_get_transfer(ctx, resource, level, usage, box, - ptransfer, data, NULL); + ptransfer, data, NULL, 0); } static void r600_buffer_transfer_unmap(struct pipe_context *pipe, @@ -180,7 +179,8 @@ static void r600_buffer_transfer_unmap(struct pipe_context *pipe, if (rtransfer->staging) { struct pipe_box box; - u_box_1d(transfer->box.x % R600_MAP_BUFFER_ALIGNMENT, transfer->box.width, &box); + u_box_1d(rtransfer->offset + transfer->box.x % R600_MAP_BUFFER_ALIGNMENT, + transfer->box.width, &box); /* Copy the staging buffer into the original one. */ r600_copy_buffer(pipe, transfer->resource, transfer->box.x, |