summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600/r600_texture.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2010-09-23 13:34:36 +1000
committerDave Airlie <airlied@redhat.com>2010-09-23 16:00:16 +1000
commit2f8453eea3b5ff8d2818517753d3990490f699b8 (patch)
tree54adba7cb140c6233c3f9f287656615718d7b6da /src/gallium/drivers/r600/r600_texture.c
parentc262c4a2ff1a19d0136771767ba63f04cf3b83e3 (diff)
r600g: use blitter to do db->cb flushing.
use the blitter + custom stage to avoid doing a whole lot of state setup by hand. This makes life a lot easier for doing this on evergreen it also keeps all the state setup in one place. We setup a custom context state at the start with a flag to denote its for the flush, when it gets generated we generate the correct state for the flush and no longer have to do it all by hand. this should also make adding texture *to* depth easier.
Diffstat (limited to 'src/gallium/drivers/r600/r600_texture.c')
-rw-r--r--src/gallium/drivers/r600/r600_texture.c168
1 files changed, 63 insertions, 105 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 37822903e8..b0d3b28c72 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -136,19 +136,6 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
return &resource->base.b;
}
-static void r600_texture_destroy_state(struct pipe_resource *ptexture)
-{
- struct r600_resource_texture *rtexture = (struct r600_resource_texture*)ptexture;
-
- for (int i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) {
- radeon_state_fini(&rtexture->scissor[i]);
- radeon_state_fini(&rtexture->db[i]);
- for (int j = 0; j < 8; j++) {
- radeon_state_fini(&rtexture->cb[j][i]);
- }
- }
-}
-
static void r600_texture_destroy(struct pipe_screen *screen,
struct pipe_resource *ptex)
{
@@ -156,13 +143,12 @@ static void r600_texture_destroy(struct pipe_screen *screen,
struct r600_resource *resource = &rtex->resource;
struct radeon *radeon = (struct radeon *)screen->winsys;
+ if (rtex->flushed_depth_texture)
+ pipe_resource_reference(&rtex->flushed_depth_texture, NULL);
+
if (resource->bo) {
radeon_ws_bo_reference(radeon, &resource->bo, NULL);
}
- if (rtex->uncompressed) {
- radeon_ws_bo_reference(radeon, &rtex->uncompressed, NULL);
- }
- r600_texture_destroy_state(ptex);
FREE(rtex);
}
@@ -248,6 +234,39 @@ static unsigned int r600_texture_is_referenced(struct pipe_context *context,
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
}
+int r600_texture_depth_flush(struct pipe_context *ctx,
+ struct pipe_resource *texture)
+{
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
+ struct pipe_resource resource;
+
+ if (rtex->flushed_depth_texture)
+ goto out;
+
+ resource.target = PIPE_TEXTURE_2D;
+ resource.format = texture->format;
+ resource.width0 = texture->width0;
+ resource.height0 = texture->height0;
+ resource.depth0 = 0;
+ resource.last_level = 0;
+ resource.nr_samples = 0;
+ resource.usage = PIPE_USAGE_DYNAMIC;
+ resource.bind = 0;
+ resource.flags = 0;
+
+ resource.bind |= PIPE_BIND_RENDER_TARGET;
+
+ rtex->flushed_depth_texture = ctx->screen->resource_create(ctx->screen, &resource);
+ if (rtex->flushed_depth_texture == NULL) {
+ R600_ERR("failed to create temporary texture to hold untiled copy\n");
+ return -ENOMEM;
+ }
+
+out:
+ r600_blit_uncompress_depth(ctx, rtex);
+ return 0;
+}
+
struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
struct pipe_resource *texture,
struct pipe_subresource sr,
@@ -257,6 +276,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
struct r600_resource_texture *rtex = (struct r600_resource_texture*)texture;
struct pipe_resource resource;
struct r600_transfer *trans;
+ int r;
trans = CALLOC_STRUCT(r600_transfer);
if (trans == NULL)
@@ -267,7 +287,15 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
trans->transfer.box = *box;
trans->transfer.stride = rtex->pitch[sr.level];
trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
- if (rtex->tiled && !rtex->depth) {
+ if (rtex->depth) {
+ r = r600_texture_depth_flush(ctx, texture);
+ 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;
+ }
+ } else if (rtex->tiled) {
resource.target = PIPE_TEXTURE_2D;
resource.format = texture->format;
resource.width0 = box->width;
@@ -311,10 +339,17 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx,
struct pipe_transfer *transfer)
{
struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
if (rtransfer->linear_texture) {
pipe_resource_reference(&rtransfer->linear_texture, NULL);
}
+ if (rtex->flushed_depth_texture) {
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ // TODO
+ }
+ pipe_resource_reference(&rtex->flushed_depth_texture, NULL);
+ }
pipe_resource_reference(&transfer->resource, NULL);
FREE(transfer);
}
@@ -326,25 +361,19 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
struct radeon_ws_bo *bo;
enum pipe_format format = transfer->resource->format;
struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
- struct r600_resource_texture *rtex;
unsigned long offset = 0;
char *map;
- int r;
if (rtransfer->linear_texture) {
bo = ((struct r600_resource *)rtransfer->linear_texture)->bo;
} else {
- rtex = (struct r600_resource_texture*)transfer->resource;
- if (rtex->depth && radeon_get_family_class(radeon) != EVERGREEN) {
- r = r600_texture_from_depth(ctx, rtex, transfer->sr.level);
- if (r) {
- return NULL;
- }
- r600_flush(ctx, 0, NULL);
- bo = rtex->uncompressed;
- } else {
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
+
+ if (rtex->flushed_depth_texture)
+ bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo;
+ else
bo = ((struct r600_resource *)transfer->resource)->bo;
- }
+
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);
@@ -362,15 +391,15 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx,
{
struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
struct radeon *radeon = (struct radeon *)ctx->screen->winsys;
- struct r600_resource_texture *rtex;
struct radeon_ws_bo *bo;
if (rtransfer->linear_texture) {
bo = ((struct r600_resource *)rtransfer->linear_texture)->bo;
} else {
- rtex = (struct r600_resource_texture*)transfer->resource;
- if (rtex->depth) {
- bo = rtex->uncompressed;
+ struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
+
+ if (rtex->flushed_depth_texture) {
+ bo = ((struct r600_resource *)rtex->flushed_depth_texture)->bo;
} else {
bo = ((struct r600_resource *)transfer->resource)->bo;
}
@@ -644,74 +673,3 @@ out_unknown:
// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
return ~0;
}
-
-int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- int r;
-
- /* TODO possible dirty handling */
-
- /* allocate uncompressed texture */
- if (rtexture->uncompressed == NULL) {
- rtexture->uncompressed = radeon_ws_bo(rscreen->rw, rtexture->size, 4096, 0);
- if (rtexture->uncompressed == NULL) {
- return -ENOMEM;
- }
- }
-
- /* render a rectangle covering whole buffer to uncompress depth */
- r = r600_blit_uncompress_depth(ctx, rtexture, level);
- if (r) {
- return r;
- }
-
- rtexture->dirty = 0;
- return 0;
-}
-
-
-
-int r600_texture_scissor(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
-
- if (!rtexture->scissor[level].cpm4) {
- rctx->vtbl->texture_state_scissor(rscreen, rtexture, level);
- }
- return 0;
-}
-
-int r600_texture_cb(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned cb, unsigned level)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
-
- if (!rtexture->cb[cb][level].cpm4) {
- rctx->vtbl->texture_state_cb(rscreen, rtexture, cb, level);
- }
- return 0;
-}
-
-int r600_texture_db(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
-
- if (!rtexture->db[level].cpm4) {
- rctx->vtbl->texture_state_db(rscreen, rtexture, level);
- }
- return 0;
-}
-
-int r600_texture_viewport(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
-{
- struct r600_screen *rscreen = r600_screen(ctx->screen);
- struct r600_context *rctx = r600_context(ctx);
-
- if (!rtexture->viewport[level].cpm4) {
- rctx->vtbl->texture_state_viewport(rscreen, rtexture, level);
- }
- return 0;
-}