diff options
author | Keith Whitwell <keithw@vmware.com> | 2010-11-03 14:06:33 +0000 |
---|---|---|
committer | Keith Whitwell <keithw@vmware.com> | 2010-11-09 20:12:46 +0000 |
commit | e3ea4aec033643a629e2fa48eb538fdb856adf4e (patch) | |
tree | 67b1048e76d2ec88a8c140a0f533b1a552548044 | |
parent | 6e2e136428b97d2424ebe626a30d7237015f7ea3 (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.
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 34 |
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; |