diff options
author | Marek Olšák <[email protected]> | 2012-10-08 04:06:42 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-10-11 21:12:16 +0200 |
commit | 369e46888904c6d379b8b477d9242cff1608e30e (patch) | |
tree | 528b10f900f23af3acd22a0edcf50fde0eeee86e /src/gallium/drivers/r600/r600_texture.c | |
parent | ec4c74a9dc10039d97ad24c4f16bd2400517991d (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/r600/r600_texture.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 138 |
1 files changed, 61 insertions, 77 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 4fb10ca031d..785eeffcab5 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -240,17 +240,7 @@ static void r600_texture_destroy(struct pipe_screen *screen, FREE(rtex); } -static const struct u_resource_vtbl r600_texture_vtbl = -{ - r600_texture_get_handle, /* get_handle */ - r600_texture_destroy, /* resource_destroy */ - r600_texture_get_transfer, /* get_transfer */ - r600_texture_transfer_destroy, /* transfer_destroy */ - r600_texture_transfer_map, /* transfer_map */ - NULL, /* transfer_flush_region */ - r600_texture_transfer_unmap, /* transfer_unmap */ - NULL /* transfer_inline_write */ -}; +static const struct u_resource_vtbl r600_texture_vtbl; /* The number of samples can be specified independently of the texture. */ void r600_texture_get_fmask_info(struct r600_screen *rscreen, @@ -603,17 +593,26 @@ bool r600_init_flushed_depth_texture(struct pipe_context *ctx, return true; } -struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, - struct pipe_resource *texture, - unsigned level, - unsigned usage, - const struct pipe_box *box) +static void *r600_texture_transfer_map(struct pipe_context *ctx, + struct pipe_resource *texture, + unsigned level, + unsigned usage, + const struct pipe_box *box, + struct pipe_transfer **ptransfer) { struct r600_context *rctx = (struct r600_context*)ctx; struct r600_texture *rtex = (struct r600_texture*)texture; struct pipe_resource resource; struct r600_transfer *trans; boolean use_staging_texture = FALSE; + enum pipe_format format = texture->format; + struct radeon_winsys_cs_handle *buf; + unsigned offset = 0; + char *map; + + if ((texture->bind & PIPE_BIND_GLOBAL) && texture->target == PIPE_BUFFER) { + return r600_compute_global_transfer_map(ctx, texture, level, usage, box, ptransfer); + } /* We cannot map a tiled texture directly because the data is * in a different order, therefore we do detiling using a blit. @@ -644,7 +643,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans = CALLOC_STRUCT(r600_transfer); if (trans == NULL) return NULL; - pipe_resource_reference(&trans->transfer.resource, texture); + trans->transfer.resource = texture; trans->transfer.level = level; trans->transfer.usage = usage; trans->transfer.box = *box; @@ -657,7 +656,6 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); - pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); return NULL; } @@ -670,7 +668,6 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.stride = staging_depth->surface.level[level].pitch_bytes; trans->offset = r600_texture_get_offset(staging_depth, level, box->z); trans->staging = (struct r600_resource*)staging_depth; - return &trans->transfer; } else if (use_staging_texture) { resource.target = PIPE_TEXTURE_2D; resource.format = texture->format; @@ -697,7 +694,6 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->staging = (struct r600_resource*)ctx->screen->resource_create(ctx->screen, &resource); if (trans->staging == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); - pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); return NULL; } @@ -709,79 +705,41 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, /* Always referenced in the blit. */ r600_flush(ctx, NULL, 0); } - return &trans->transfer; - } - trans->transfer.stride = rtex->surface.level[level].pitch_bytes; - trans->transfer.layer_stride = rtex->surface.level[level].slice_size; - trans->offset = r600_texture_get_offset(rtex, level, box->z); - return &trans->transfer; -} - -void r600_texture_transfer_destroy(struct pipe_context *ctx, - struct pipe_transfer *transfer) -{ - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct pipe_resource *texture = transfer->resource; - struct r600_texture *rtex = (struct r600_texture*)texture; - - if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) { - if (rtex->is_depth) { - ctx->resource_copy_region(ctx, texture, transfer->level, - transfer->box.x, transfer->box.y, transfer->box.z, - &rtransfer->staging->b.b, transfer->level, - &transfer->box); - } else { - r600_copy_from_staging_texture(ctx, rtransfer); - } - } - - if (rtransfer->staging) - pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL); - - pipe_resource_reference(&transfer->resource, NULL); - FREE(transfer); -} - -void* r600_texture_transfer_map(struct pipe_context *ctx, - struct pipe_transfer* transfer) -{ - struct r600_context *rctx = (struct r600_context *)ctx; - struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; - struct radeon_winsys_cs_handle *buf; - struct r600_texture *rtex = - (struct r600_texture*)transfer->resource; - enum pipe_format format = transfer->resource->format; - unsigned offset = 0; - char *map; - - if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) { - return r600_compute_global_transfer_map(ctx, transfer); + } else { + trans->transfer.stride = rtex->surface.level[level].pitch_bytes; + trans->transfer.layer_stride = rtex->surface.level[level].slice_size; + trans->offset = r600_texture_get_offset(rtex, level, box->z); } - if (rtransfer->staging) { - buf = ((struct r600_resource *)rtransfer->staging)->cs_buf; + if (trans->staging) { + buf = ((struct r600_resource *)trans->staging)->cs_buf; } else { - buf = ((struct r600_resource *)transfer->resource)->cs_buf; + buf = ((struct r600_resource *)texture)->cs_buf; } - if (rtex->is_depth || !rtransfer->staging) - offset = rtransfer->offset + - transfer->box.y / util_format_get_blockheight(format) * transfer->stride + - transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); + if (rtex->is_depth || !trans->staging) + offset = trans->offset + + box->y / util_format_get_blockheight(format) * trans->transfer.stride + + box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); - if (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) { + if (!(map = rctx->ws->buffer_map(buf, rctx->cs, usage))) { + pipe_resource_reference((struct pipe_resource**)&trans->staging, NULL); + FREE(trans); return NULL; } + *ptransfer = &trans->transfer; return map + offset; } -void r600_texture_transfer_unmap(struct pipe_context *ctx, - struct pipe_transfer* transfer) +static void r600_texture_transfer_unmap(struct pipe_context *ctx, + struct pipe_transfer* transfer) { struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; struct r600_context *rctx = (struct r600_context*)ctx; struct radeon_winsys_cs_handle *buf; + struct pipe_resource *texture = transfer->resource; + struct r600_texture *rtex = (struct r600_texture*)texture; if ((transfer->resource->bind & PIPE_BIND_GLOBAL) && transfer->resource->target == PIPE_BUFFER) { return r600_compute_global_transfer_unmap(ctx, transfer); @@ -793,6 +751,22 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, buf = ((struct r600_resource *)transfer->resource)->cs_buf; } rctx->ws->buffer_unmap(buf); + + if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtransfer->staging) { + if (rtex->is_depth) { + ctx->resource_copy_region(ctx, texture, transfer->level, + transfer->box.x, transfer->box.y, transfer->box.z, + &rtransfer->staging->b.b, transfer->level, + &transfer->box); + } else { + r600_copy_from_staging_texture(ctx, rtransfer); + } + } + + if (rtransfer->staging) + pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL); + + FREE(transfer); } void r600_init_surface_functions(struct r600_context *r600) @@ -1178,3 +1152,13 @@ out_unknown: /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ return ~0; } + +static const struct u_resource_vtbl r600_texture_vtbl = +{ + r600_texture_get_handle, /* get_handle */ + r600_texture_destroy, /* resource_destroy */ + r600_texture_transfer_map, /* transfer_map */ + NULL, /* transfer_flush_region */ + r600_texture_transfer_unmap, /* transfer_unmap */ + NULL /* transfer_inline_write */ +}; |