r600g: avoid recursion with staged uploads
authorKeith Whitwell <keithw@vmware.com>
Wed, 3 Nov 2010 14:06:33 +0000 (14:06 +0000)
committerKeith Whitwell <keithw@vmware.com>
Tue, 9 Nov 2010 20:12:46 +0000 (20:12 +0000)
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.

src/gallium/drivers/r600/r600_texture.c

index 0c9b99937565fefd06be6409be9e051f93bbaa7d..06d17f7709ae0bcc3b17bff77ed1ebfdb375c7e2 100644 (file)
@@ -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;