summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-10-08 04:06:42 +0200
committerMarek Olšák <[email protected]>2012-10-11 21:12:16 +0200
commit369e46888904c6d379b8b477d9242cff1608e30e (patch)
tree528b10f900f23af3acd22a0edcf50fde0eeee86e /src/gallium/drivers/r300
parentec4c74a9dc10039d97ad24c4f16bd2400517991d (diff)
gallium: unify transfer functions
"get_transfer + transfer_map" becomes "transfer_map". "transfer_unmap + transfer_destroy" becomes "transfer_unmap". transfer_map must create and return the transfer object and transfer_unmap must destroy it. transfer_map is successful if the returned buffer pointer is not NULL. If transfer_map fails, the pointer to the transfer object remains unchanged (i.e. doesn't have to be NULL). Acked-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_resource.c2
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c80
-rw-r--r--src/gallium/drivers/r300/r300_texture.c2
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c105
-rw-r--r--src/gallium/drivers/r300/r300_transfer.h15
5 files changed, 80 insertions, 124 deletions
diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c
index 46399fb2397..701fd249d30 100644
--- a/src/gallium/drivers/r300/r300_resource.c
+++ b/src/gallium/drivers/r300/r300_resource.c
@@ -40,11 +40,9 @@ r300_resource_create(struct pipe_screen *screen,
void r300_init_resource_functions(struct r300_context *r300)
{
- r300->context.get_transfer = u_get_transfer_vtbl;
r300->context.transfer_map = u_transfer_map_vtbl;
r300->context.transfer_flush_region = u_default_transfer_flush_region;
r300->context.transfer_unmap = u_transfer_unmap_vtbl;
- r300->context.transfer_destroy = u_transfer_destroy_vtbl;
r300->context.transfer_inline_write = u_default_transfer_inline_write;
r300->context.create_surface = r300_create_surface;
r300->context.surface_destroy = r300_surface_destroy;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index f652bf72b0c..37a7c77010a 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -63,79 +63,63 @@ static void r300_buffer_destroy(struct pipe_screen *screen,
FREE(rbuf);
}
-static struct pipe_transfer*
-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_slab_alloc(&r300->pool_transfers);
-
- transfer->resource = resource;
- transfer->level = level;
- transfer->usage = usage;
- transfer->box = *box;
- transfer->stride = 0;
- transfer->layer_stride = 0;
- transfer->data = NULL;
-
- /* Note strides are zero, this is ok for buffers, but not for
- * textures 2d & higher at least.
- */
- return transfer;
-}
-
-static void r300_buffer_transfer_destroy(struct pipe_context *pipe,
- struct pipe_transfer *transfer)
-{
- struct r300_context *r300 = r300_context(pipe);
- util_slab_free(&r300->pool_transfers, transfer);
-}
-
static void *
-r300_buffer_transfer_map( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
+r300_buffer_transfer_map( struct pipe_context *context,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **ptransfer )
{
- struct r300_context *r300 = r300_context(pipe);
- struct r300_screen *r300screen = r300_screen(pipe->screen);
- struct radeon_winsys *rws = r300screen->rws;
- struct r300_resource *rbuf = r300_resource(transfer->resource);
+ struct r300_context *r300 = r300_context(context);
+ struct radeon_winsys *rws = r300->screen->rws;
+ struct r300_resource *rbuf = r300_resource(resource);
+ struct pipe_transfer *transfer;
uint8_t *map;
- enum pipe_transfer_usage usage;
- if (rbuf->malloced_buffer)
- return (uint8_t *) rbuf->malloced_buffer + transfer->box.x;
+ transfer = util_slab_alloc(&r300->pool_transfers);
+ transfer->resource = resource;
+ transfer->level = level;
+ transfer->usage = usage;
+ transfer->box = *box;
+ transfer->stride = 0;
+ transfer->layer_stride = 0;
+ transfer->data = NULL;
+
+ if (rbuf->malloced_buffer) {
+ *ptransfer = transfer;
+ return (uint8_t *) rbuf->malloced_buffer + box->x;
+ }
/* Buffers are never used for write, therefore mapping for read can be
* unsynchronized. */
- usage = transfer->usage;
if (!(usage & PIPE_TRANSFER_WRITE)) {
usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
}
map = rws->buffer_map(rbuf->cs_buf, r300->cs, usage);
- if (map == NULL)
+ if (map == NULL) {
+ util_slab_free(&r300->pool_transfers, transfer);
return NULL;
+ }
- return map + transfer->box.x;
+ *ptransfer = transfer;
+ return map + box->x;
}
static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
- struct pipe_transfer *transfer )
+ struct pipe_transfer *transfer )
{
- /* no-op */
+ struct r300_context *r300 = r300_context(pipe);
+
+ util_slab_free(&r300->pool_transfers, transfer);
}
static const struct u_resource_vtbl r300_buffer_vtbl =
{
NULL, /* get_handle */
r300_buffer_destroy, /* resource_destroy */
- r300_buffer_get_transfer, /* get_transfer */
- r300_buffer_transfer_destroy, /* transfer_destroy */
r300_buffer_transfer_map, /* transfer_map */
NULL, /* transfer_flush_region */
r300_buffer_transfer_unmap, /* transfer_unmap */
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 39cca78ebce..7f74538deea 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -937,8 +937,6 @@ static const struct u_resource_vtbl r300_texture_vtbl =
{
NULL, /* get_handle */
r300_texture_destroy, /* resource_destroy */
- r300_texture_get_transfer, /* get_transfer */
- r300_texture_transfer_destroy, /* transfer_destroy */
r300_texture_transfer_map, /* transfer_map */
NULL, /* transfer_flush_region */
r300_texture_transfer_unmap, /* transfer_unmap */
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index 9140bb191cf..fbae2df52b9 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -76,18 +76,21 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
r300_flush(ctx, 0, NULL);
}
-struct pipe_transfer*
-r300_texture_get_transfer(struct pipe_context *ctx,
+void *
+r300_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
- const struct pipe_box *box)
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer)
{
struct r300_context *r300 = r300_context(ctx);
struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans;
struct pipe_resource base;
boolean referenced_cs, referenced_hw;
+ enum pipe_format format = tex->b.b.format;
+ char *map;
referenced_cs =
r300->rws->cs_is_buffer_referenced(r300->cs, tex->cs_buf, RADEON_USAGE_READWRITE);
@@ -101,7 +104,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
/* Initialize the transfer object. */
- pipe_resource_reference(&trans->transfer.resource, texture);
+ trans->transfer.resource = texture;
trans->transfer.level = level;
trans->transfer.usage = usage;
trans->transfer.box = *box;
@@ -161,15 +164,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
&base));
if (!trans->linear_texture) {
- /* For linear textures, it's safe to fallback to
- * an unpipelined transfer. */
- if (!tex->tex.microtile && !tex->tex.macrotile[level]) {
- goto unpipelined;
- }
-
- /* Otherwise, go to hell. */
fprintf(stderr,
- "r300: Failed to create a transfer object, praise.\n");
+ "r300: Failed to create a transfer object.\n");
FREE(trans);
return NULL;
}
@@ -190,64 +186,43 @@ r300_texture_get_transfer(struct pipe_context *ctx,
/* Always referenced in the blit. */
r300_flush(ctx, 0, NULL);
}
- return &trans->transfer;
- }
-
- unpipelined:
- /* Unpipelined transfer. */
- trans->transfer.stride = tex->tex.stride_in_bytes[level];
- trans->offset = r300_texture_get_offset(tex, level, box->z);
-
- if (referenced_cs &&
- !(usage & PIPE_TRANSFER_UNSYNCHRONIZED))
- r300_flush(ctx, 0, NULL);
- return &trans->transfer;
- }
- return NULL;
-}
+ } else {
+ /* Unpipelined transfer. */
+ trans->transfer.stride = tex->tex.stride_in_bytes[level];
+ trans->offset = r300_texture_get_offset(tex, level, box->z);
-void r300_texture_transfer_destroy(struct pipe_context *ctx,
- struct pipe_transfer *trans)
-{
- struct r300_transfer *r300transfer = r300_transfer(trans);
-
- if (r300transfer->linear_texture) {
- if (trans->usage & PIPE_TRANSFER_WRITE) {
- r300_copy_into_tiled_texture(ctx, r300transfer);
+ if (referenced_cs &&
+ !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+ r300_flush(ctx, 0, NULL);
+ }
}
-
- pipe_resource_reference(
- (struct pipe_resource**)&r300transfer->linear_texture, NULL);
}
- pipe_resource_reference(&trans->resource, NULL);
- FREE(trans);
-}
-void* r300_texture_transfer_map(struct pipe_context *ctx,
- struct pipe_transfer *transfer)
-{
- struct r300_context *r300 = r300_context(ctx);
- struct r300_transfer *r300transfer = r300_transfer(transfer);
- struct r300_resource *tex = r300_resource(transfer->resource);
- char *map;
- enum pipe_format format = tex->b.b.format;
-
- if (r300transfer->linear_texture) {
+ if (trans->linear_texture) {
/* The detiled texture is of the same size as the region being mapped
* (no offset needed). */
- return r300->rws->buffer_map(r300transfer->linear_texture->cs_buf,
- r300->cs, transfer->usage);
+ map = r300->rws->buffer_map(trans->linear_texture->cs_buf,
+ r300->cs, usage);
+ if (!map) {
+ pipe_resource_reference(
+ (struct pipe_resource**)&trans->linear_texture, NULL);
+ FREE(trans);
+ return NULL;
+ }
+ *transfer = &trans->transfer;
+ return map;
} else {
/* Tiling is disabled. */
- map = r300->rws->buffer_map(tex->cs_buf, r300->cs, transfer->usage);
-
+ map = r300->rws->buffer_map(tex->cs_buf, r300->cs, usage);
if (!map) {
+ FREE(trans);
return NULL;
}
- return map + r300_transfer(transfer)->offset +
- transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
- transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+ *transfer = &trans->transfer;
+ return map + trans->offset +
+ box->y / util_format_get_blockheight(format) * trans->transfer.stride +
+ box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
}
}
@@ -255,12 +230,20 @@ void r300_texture_transfer_unmap(struct pipe_context *ctx,
struct pipe_transfer *transfer)
{
struct radeon_winsys *rws = r300_context(ctx)->rws;
- struct r300_transfer *r300transfer = r300_transfer(transfer);
+ struct r300_transfer *trans = r300_transfer(transfer);
struct r300_resource *tex = r300_resource(transfer->resource);
- if (r300transfer->linear_texture) {
- rws->buffer_unmap(r300transfer->linear_texture->cs_buf);
+ if (trans->linear_texture) {
+ rws->buffer_unmap(trans->linear_texture->cs_buf);
+
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ r300_copy_into_tiled_texture(ctx, trans);
+ }
+
+ pipe_resource_reference(
+ (struct pipe_resource**)&trans->linear_texture, NULL);
} else {
rws->buffer_unmap(tex->cs_buf);
}
+ FREE(transfer);
}
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
index 7977ef516f2..45477ae6d0d 100644
--- a/src/gallium/drivers/r300/r300_transfer.h
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -28,20 +28,13 @@
struct r300_context;
-struct pipe_transfer*
-r300_texture_get_transfer(struct pipe_context *ctx,
+void *
+r300_texture_transfer_map(struct pipe_context *ctx,
struct pipe_resource *texture,
unsigned level,
unsigned usage,
- const struct pipe_box *box);
-
-void
-r300_texture_transfer_destroy(struct pipe_context *ctx,
- struct pipe_transfer *trans);
-
-void*
-r300_texture_transfer_map(struct pipe_context *ctx,
- struct pipe_transfer *transfer);
+ const struct pipe_box *box,
+ struct pipe_transfer **transfer);
void
r300_texture_transfer_unmap(struct pipe_context *ctx,