aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-12-09 16:43:16 +0100
committerMarek Olšák <[email protected]>2012-12-12 13:11:52 +0100
commit2478fcd87c4361ce288b042cc922373ef40b113c (patch)
tree13497df85def5ab476dd031e217cea984a7e4d90 /src/gallium/drivers
parent448cd5ea60403576c3eec86ffb2b892e78b9dfe0 (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/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c30
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,