summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeonsi/r600_texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/radeonsi/r600_texture.c')
-rw-r--r--src/gallium/drivers/radeonsi/r600_texture.c414
1 files changed, 207 insertions, 207 deletions
diff --git a/src/gallium/drivers/radeonsi/r600_texture.c b/src/gallium/drivers/radeonsi/r600_texture.c
index 392f177f634..905f2184226 100644
--- a/src/gallium/drivers/radeonsi/r600_texture.c
+++ b/src/gallium/drivers/radeonsi/r600_texture.c
@@ -66,7 +66,7 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
0, &sbox);
}
-unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
+static unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,
unsigned level, unsigned layer)
{
unsigned offset = rtex->offset[level];
@@ -489,15 +489,209 @@ static void r600_texture_destroy(struct pipe_screen *screen,
FREE(rtex);
}
+/* Needs adjustment for pixelformat:
+ */
+static INLINE unsigned u_box_volume( const struct pipe_box *box )
+{
+ return box->width * box->depth * box->height;
+};
+
+static struct pipe_transfer* si_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box)
+{
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
+ struct pipe_resource resource;
+ struct r600_transfer *trans;
+ int r;
+ boolean use_staging_texture = FALSE;
+
+ /* We cannot map a tiled texture directly because the data is
+ * in a different order, therefore we do detiling using a blit.
+ *
+ * Also, use a temporary in GTT memory for read transfers, as
+ * the CPU is much happier reading out of cached system memory
+ * than uncached VRAM.
+ */
+ if (R600_TEX_IS_TILED(rtex, level))
+ use_staging_texture = TRUE;
+
+ if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
+ use_staging_texture = TRUE;
+
+ /* XXX: Use a staging texture for uploads if the underlying BO
+ * is busy. No interface for checking that currently? so do
+ * it eagerly whenever the transfer doesn't require a readback
+ * and might block.
+ */
+ if ((usage & PIPE_TRANSFER_WRITE) &&
+ !(usage & (PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_DONTBLOCK |
+ PIPE_TRANSFER_UNSYNCHRONIZED)))
+ use_staging_texture = TRUE;
+
+ if (!permit_hardware_blit(ctx->screen, texture) ||
+ (texture->flags & R600_RESOURCE_FLAG_TRANSFER))
+ use_staging_texture = FALSE;
+
+ if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
+ return NULL;
+
+ trans = CALLOC_STRUCT(r600_transfer);
+ if (trans == NULL)
+ return NULL;
+ pipe_resource_reference(&trans->transfer.resource, texture);
+ trans->transfer.level = level;
+ trans->transfer.usage = usage;
+ trans->transfer.box = *box;
+ if (rtex->depth) {
+ /* XXX: only readback the rectangle which is being mapped?
+ */
+ /* XXX: when discard is true, no need to read back from depth texture
+ */
+ r = r600_texture_depth_flush(ctx, texture, FALSE);
+ if (r < 0) {
+ R600_ERR("failed to create temporary texture to hold untiled copy\n");
+ pipe_resource_reference(&trans->transfer.resource, NULL);
+ FREE(trans);
+ return NULL;
+ }
+ trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level];
+ trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
+ return &trans->transfer;
+ } else if (use_staging_texture) {
+ resource.target = PIPE_TEXTURE_2D;
+ resource.format = texture->format;
+ resource.width0 = box->width;
+ resource.height0 = box->height;
+ resource.depth0 = 1;
+ resource.array_size = 1;
+ resource.last_level = 0;
+ resource.nr_samples = 0;
+ resource.usage = PIPE_USAGE_STAGING;
+ resource.bind = 0;
+ resource.flags = R600_RESOURCE_FLAG_TRANSFER;
+ /* For texture reading, the temporary (detiled) texture is used as
+ * a render target when blitting from a tiled texture. */
+ if (usage & PIPE_TRANSFER_READ) {
+ resource.bind |= PIPE_BIND_RENDER_TARGET;
+ }
+ /* For texture writing, the temporary texture is used as a sampler
+ * when blitting into a tiled texture. */
+ if (usage & PIPE_TRANSFER_WRITE) {
+ resource.bind |= PIPE_BIND_SAMPLER_VIEW;
+ }
+ /* Create the temporary texture. */
+ trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
+ if (trans->staging_texture == NULL) {
+ R600_ERR("failed to create temporary texture to hold untiled copy\n");
+ pipe_resource_reference(&trans->transfer.resource, NULL);
+ FREE(trans);
+ return NULL;
+ }
+
+ trans->transfer.stride =
+ ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
+ if (usage & PIPE_TRANSFER_READ) {
+ r600_copy_to_staging_texture(ctx, trans);
+ /* Always referenced in the blit. */
+ radeonsi_flush(ctx, NULL, 0);
+ }
+ return &trans->transfer;
+ }
+ trans->transfer.stride = rtex->pitch_in_bytes[level];
+ trans->transfer.layer_stride = rtex->layer_size[level];
+ trans->offset = r600_texture_get_offset(rtex, level, box->z);
+ return &trans->transfer;
+}
+
+static void si_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_resource_texture *rtex = (struct r600_resource_texture*)texture;
+
+ if (rtransfer->staging_texture) {
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ r600_copy_from_staging_texture(ctx, rtransfer);
+ }
+ pipe_resource_reference(&rtransfer->staging_texture, NULL);
+ }
+
+ if (rtex->depth && !rtex->is_flushing_texture) {
+ if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
+ r600_blit_push_depth(ctx, rtex);
+ }
+
+ pipe_resource_reference(&transfer->resource, NULL);
+ FREE(transfer);
+}
+
+static void* si_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;
+ enum pipe_format format = transfer->resource->format;
+ unsigned offset = 0;
+ char *map;
+
+ if (rtransfer->staging_texture) {
+ buf = si_resource(rtransfer->staging_texture)->cs_buf;
+ } else {
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
+
+ if (rtex->flushed_depth_texture)
+ buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
+ else
+ buf = si_resource(transfer->resource)->cs_buf;
+
+ 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 (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
+ return NULL;
+ }
+
+ return map + offset;
+}
+
+static void si_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;
+
+ if (rtransfer->staging_texture) {
+ buf = si_resource(rtransfer->staging_texture)->cs_buf;
+ } else {
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
+
+ if (rtex->flushed_depth_texture) {
+ buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
+ } else {
+ buf = si_resource(transfer->resource)->cs_buf;
+ }
+ }
+ rctx->ws->buffer_unmap(buf);
+}
+
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 */
+ si_texture_get_transfer, /* get_transfer */
+ si_texture_transfer_destroy, /* transfer_destroy */
+ si_texture_transfer_map, /* transfer_map */
u_default_transfer_flush_region,/* transfer_flush_region */
- r600_texture_transfer_unmap, /* transfer_unmap */
+ si_texture_transfer_unmap, /* transfer_unmap */
NULL /* transfer_inline_write */
};
@@ -546,7 +740,7 @@ r600_texture_create_object(struct pipe_screen *screen,
unsigned base_align = r600_get_base_alignment(screen, ptex->format, array_mode);
base_align = rtex->surface.bo_alignment;
- if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
+ if (!si_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
FREE(rtex);
return NULL;
}
@@ -559,8 +753,8 @@ r600_texture_create_object(struct pipe_screen *screen,
return rtex;
}
-struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
- const struct pipe_resource *templ)
+struct pipe_resource *si_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
struct radeon_surface surface;
@@ -625,9 +819,9 @@ static void r600_surface_destroy(struct pipe_context *pipe,
FREE(surface);
}
-struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
- const struct pipe_resource *templ,
- struct winsys_handle *whandle)
+struct pipe_resource *si_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
struct pb_buffer *buf = NULL;
@@ -701,205 +895,11 @@ out:
/* XXX: only do this if the depth texture has actually changed:
*/
- r600_blit_uncompress_depth(ctx, rtex);
+ si_blit_uncompress_depth(ctx, rtex);
return 0;
}
-/* Needs adjustment for pixelformat:
- */
-static INLINE unsigned u_box_volume( const struct pipe_box *box )
-{
- return box->width * box->depth * box->height;
-};
-
-struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
- struct pipe_resource *texture,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box)
-{
- struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
- struct pipe_resource resource;
- struct r600_transfer *trans;
- int r;
- boolean use_staging_texture = FALSE;
-
- /* We cannot map a tiled texture directly because the data is
- * in a different order, therefore we do detiling using a blit.
- *
- * Also, use a temporary in GTT memory for read transfers, as
- * the CPU is much happier reading out of cached system memory
- * than uncached VRAM.
- */
- if (R600_TEX_IS_TILED(rtex, level))
- use_staging_texture = TRUE;
-
- if ((usage & PIPE_TRANSFER_READ) && u_box_volume(box) > 1024)
- use_staging_texture = TRUE;
-
- /* XXX: Use a staging texture for uploads if the underlying BO
- * is busy. No interface for checking that currently? so do
- * it eagerly whenever the transfer doesn't require a readback
- * and might block.
- */
- if ((usage & PIPE_TRANSFER_WRITE) &&
- !(usage & (PIPE_TRANSFER_READ |
- PIPE_TRANSFER_DONTBLOCK |
- PIPE_TRANSFER_UNSYNCHRONIZED)))
- use_staging_texture = TRUE;
-
- if (!permit_hardware_blit(ctx->screen, texture) ||
- (texture->flags & R600_RESOURCE_FLAG_TRANSFER))
- use_staging_texture = FALSE;
-
- if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
- return NULL;
-
- trans = CALLOC_STRUCT(r600_transfer);
- if (trans == NULL)
- return NULL;
- pipe_resource_reference(&trans->transfer.resource, texture);
- trans->transfer.level = level;
- trans->transfer.usage = usage;
- trans->transfer.box = *box;
- if (rtex->depth) {
- /* XXX: only readback the rectangle which is being mapped?
- */
- /* XXX: when discard is true, no need to read back from depth texture
- */
- r = r600_texture_depth_flush(ctx, texture, FALSE);
- if (r < 0) {
- R600_ERR("failed to create temporary texture to hold untiled copy\n");
- pipe_resource_reference(&trans->transfer.resource, NULL);
- FREE(trans);
- return NULL;
- }
- trans->transfer.stride = rtex->flushed_depth_texture->pitch_in_bytes[level];
- trans->offset = r600_texture_get_offset(rtex->flushed_depth_texture, level, box->z);
- return &trans->transfer;
- } else if (use_staging_texture) {
- resource.target = PIPE_TEXTURE_2D;
- resource.format = texture->format;
- resource.width0 = box->width;
- resource.height0 = box->height;
- resource.depth0 = 1;
- resource.array_size = 1;
- resource.last_level = 0;
- resource.nr_samples = 0;
- resource.usage = PIPE_USAGE_STAGING;
- resource.bind = 0;
- resource.flags = R600_RESOURCE_FLAG_TRANSFER;
- /* For texture reading, the temporary (detiled) texture is used as
- * a render target when blitting from a tiled texture. */
- if (usage & PIPE_TRANSFER_READ) {
- resource.bind |= PIPE_BIND_RENDER_TARGET;
- }
- /* For texture writing, the temporary texture is used as a sampler
- * when blitting into a tiled texture. */
- if (usage & PIPE_TRANSFER_WRITE) {
- resource.bind |= PIPE_BIND_SAMPLER_VIEW;
- }
- /* Create the temporary texture. */
- trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource);
- if (trans->staging_texture == NULL) {
- R600_ERR("failed to create temporary texture to hold untiled copy\n");
- pipe_resource_reference(&trans->transfer.resource, NULL);
- FREE(trans);
- return NULL;
- }
-
- trans->transfer.stride =
- ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0];
- if (usage & PIPE_TRANSFER_READ) {
- r600_copy_to_staging_texture(ctx, trans);
- /* Always referenced in the blit. */
- radeonsi_flush(ctx, NULL, 0);
- }
- return &trans->transfer;
- }
- trans->transfer.stride = rtex->pitch_in_bytes[level];
- trans->transfer.layer_stride = rtex->layer_size[level];
- 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_resource_texture *rtex = (struct r600_resource_texture*)texture;
-
- if (rtransfer->staging_texture) {
- if (transfer->usage & PIPE_TRANSFER_WRITE) {
- r600_copy_from_staging_texture(ctx, rtransfer);
- }
- pipe_resource_reference(&rtransfer->staging_texture, NULL);
- }
-
- if (rtex->depth && !rtex->is_flushing_texture) {
- if ((transfer->usage & PIPE_TRANSFER_WRITE) && rtex->flushed_depth_texture)
- r600_blit_push_depth(ctx, rtex);
- }
-
- 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;
- enum pipe_format format = transfer->resource->format;
- unsigned offset = 0;
- char *map;
-
- if (rtransfer->staging_texture) {
- buf = si_resource(rtransfer->staging_texture)->cs_buf;
- } else {
- struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
-
- if (rtex->flushed_depth_texture)
- buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
- else
- buf = si_resource(transfer->resource)->cs_buf;
-
- 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 (!(map = rctx->ws->buffer_map(buf, rctx->cs, transfer->usage))) {
- return NULL;
- }
-
- return map + offset;
-}
-
-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;
-
- if (rtransfer->staging_texture) {
- buf = si_resource(rtransfer->staging_texture)->cs_buf;
- } else {
- struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
-
- if (rtex->flushed_depth_texture) {
- buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
- } else {
- buf = si_resource(transfer->resource)->cs_buf;
- }
- }
- rctx->ws->buffer_unmap(buf);
-}
-
-void r600_init_surface_functions(struct r600_context *r600)
+void si_init_surface_functions(struct r600_context *r600)
{
r600->context.create_surface = r600_create_surface;
r600->context.surface_destroy = r600_surface_destroy;