diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_transfer.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_transfer.c | 105 |
1 files changed, 44 insertions, 61 deletions
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); } |