summaryrefslogtreecommitdiff
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorKeith Whitwell <keithw@vmware.com>2010-11-03 14:06:33 +0000
committerKeith Whitwell <keithw@vmware.com>2010-11-09 20:12:46 +0000
commite3ea4aec033643a629e2fa48eb538fdb856adf4e (patch)
tree67b1048e76d2ec88a8c140a0f533b1a552548044 /src/gallium/drivers
parent6e2e136428b97d2424ebe626a30d7237015f7ea3 (diff)
r600g: avoid recursion with staged uploads
Don't use an intermediate for formats which don't support hardware blits under u_blitter.c, as these will recursively attempt to create a transfer.
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r600/r600_texture.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 0c9b999375..06d17f7709 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -466,6 +466,36 @@ static INLINE unsigned u_box_volume( const struct pipe_box *box )
};
+/* Figure out whether u_blitter will fallback to a transfer operation.
+ * If so, don't use a staging resource.
+ */
+static boolean permit_hardware_blit(struct pipe_screen *screen,
+ struct pipe_resource *res)
+{
+ unsigned bind;
+
+ if (util_format_is_depth_or_stencil(res->format))
+ bind = PIPE_BIND_DEPTH_STENCIL;
+ else
+ bind = PIPE_BIND_RENDER_TARGET;
+
+ if (!screen->is_format_supported(screen,
+ res->format,
+ res->target,
+ res->nr_samples,
+ bind, 0))
+ return FALSE;
+
+ if (!screen->is_format_supported(screen,
+ res->format,
+ res->target,
+ res->nr_samples,
+ PIPE_BIND_SAMPLER_VIEW, 0))
+ return FALSE;
+
+ return TRUE;
+}
+
struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
struct pipe_resource *texture,
struct pipe_subresource sr,
@@ -506,6 +536,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
!(usage & (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;
+
trans = CALLOC_STRUCT(r600_transfer);
if (trans == NULL)
return NULL;