Mesa (master): gallium/u_blitter: add a query for checking whether copying is supported

Marek Olšák mareko at kemper.freedesktop.org
Sat Aug 4 13:01:11 UTC 2012


Module: Mesa
Branch: master
Commit: 84645fa61390475e6efb080685e0dec059622a39
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=84645fa61390475e6efb080685e0dec059622a39

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sat Jul 28 01:19:18 2012 +0200

gallium/u_blitter: add a query for checking whether copying is supported

v2: add comments

---

 src/gallium/auxiliary/util/u_blitter.c           |   87 ++++++++++++++--------
 src/gallium/auxiliary/util/u_blitter.h           |   13 +++
 src/gallium/drivers/i915/i915_resource_texture.c |    7 +-
 src/gallium/drivers/i915/i915_surface.c          |    7 ++
 4 files changed, 77 insertions(+), 37 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 21dc19f..fa71f25 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -932,6 +932,61 @@ void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
     src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA;
 }
 
+boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
+                                       const struct pipe_resource *dst,
+                                       const struct pipe_resource *src,
+                                       unsigned mask)
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+   struct pipe_screen *screen = ctx->base.pipe->screen;
+
+   if (dst) {
+      unsigned bind;
+      boolean is_stencil;
+      const struct util_format_description *desc =
+            util_format_description(dst->format);
+
+      is_stencil = util_format_has_stencil(desc);
+
+      /* Stencil export must be supported for stencil copy. */
+      if ((mask & PIPE_MASK_S) && is_stencil && !ctx->has_stencil_export) {
+         return FALSE;
+      }
+
+      if (is_stencil || util_format_has_depth(desc))
+         bind = PIPE_BIND_DEPTH_STENCIL;
+      else
+         bind = PIPE_BIND_RENDER_TARGET;
+
+      if (!screen->is_format_supported(screen, dst->format, dst->target,
+                                       dst->nr_samples, bind)) {
+         return FALSE;
+      }
+   }
+
+   if (src) {
+      if (!screen->is_format_supported(screen, src->format, src->target,
+                                 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
+         return FALSE;
+      }
+
+      /* Check stencil sampler support for stencil copy. */
+      if (util_format_has_stencil(util_format_description(src->format))) {
+         enum pipe_format stencil_format =
+               util_format_stencil_only(src->format);
+         assert(stencil_format != PIPE_FORMAT_NONE);
+
+         if (stencil_format != src->format &&
+             !screen->is_format_supported(screen, stencil_format, src->target,
+                                 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
+            return FALSE;
+         }
+      }
+   }
+
+   return TRUE;
+}
+
 void util_blitter_copy_texture(struct blitter_context *blitter,
                                struct pipe_resource *dst,
                                unsigned dst_level,
@@ -942,44 +997,12 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
    struct pipe_context *pipe = ctx->base.pipe;
-   struct pipe_screen *screen = pipe->screen;
    struct pipe_surface *dst_view, dst_templ;
    struct pipe_sampler_view src_templ, *src_view;
-   unsigned bind;
-   boolean is_stencil, is_depth;
-   const struct util_format_description *src_desc;
 
-   /* Give up if textures are not set. */
    assert(dst && src);
-   if (!dst || !src)
-      return;
-
-   src_desc = util_format_description(src->format);
-
    assert(src->target < PIPE_MAX_TEXTURE_TYPES);
 
-   /* Is this a ZS format? */
-   is_depth = util_format_has_depth(src_desc);
-   is_stencil = util_format_has_stencil(src_desc);
-
-   if (is_depth || is_stencil)
-      bind = PIPE_BIND_DEPTH_STENCIL;
-   else
-      bind = PIPE_BIND_RENDER_TARGET;
-
-   /* Check if we can sample from and render to the surfaces. */
-   /* (assuming copying a stencil buffer is not possible) */
-   if (!screen->is_format_supported(screen, dst->format, dst->target,
-                                    dst->nr_samples, bind) ||
-       !screen->is_format_supported(screen, src->format, src->target,
-                                    src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
-      blitter_set_running_flag(ctx);
-      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
-                                src, src_level, srcbox);
-      blitter_unset_running_flag(ctx);
-      return;
-   }
-
    /* Initialize the surface. */
    util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, srcbox);
    dst_view = pipe->create_surface(pipe, dst, &dst_templ);
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 80a1152..7600391 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -161,6 +161,16 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter,
                                      double depth, void *custom_dsa);
 
 /**
+ * Check if the blitter (with the help of the driver) can blit between
+ * the two resources.
+ * The mask is a combination of the PIPE_MASK_* flags.
+ * Set to PIPE_MASK_RGBAZS if unsure.
+ */
+boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
+                                       const struct pipe_resource *dst,
+                                       const struct pipe_resource *src,
+                                       unsigned mask);
+/**
  * Copy a block of pixels from one surface to another.
  *
  * You can copy from any color format to any other color format provided
@@ -201,6 +211,9 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
  * coordinates. The dst dimensions are supplied through pipe_surface::width
  * and height.
  *
+ * The mask is a combination of the PIPE_MASK_* flags.
+ * Set to PIPE_MASK_RGBAZS if unsure.
+ *
  * NOTE: There are no checks whether the blit is actually supported.
  */
 void util_blitter_copy_texture_view(struct blitter_context *blitter,
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c
index 8ff733a..e60b5b4 100644
--- a/src/gallium/drivers/i915/i915_resource_texture.c
+++ b/src/gallium/drivers/i915/i915_resource_texture.c
@@ -739,11 +739,8 @@ i915_texture_get_transfer(struct pipe_context *pipe,
    /* if we use staging transfers, only support textures we can render to,
     * because we need that for u_blitter */
    if (i915->blitter &&
-       i915_is_format_supported(NULL, /* screen */
-                                transfer->b.resource->format,
-                                0, /* target */
-                                1, /* sample count */
-                                PIPE_BIND_RENDER_TARGET) &&
+       util_blitter_is_copy_supported(i915->blitter, resource, resource,
+				      PIPE_MASK_RGBAZS) &&
        (usage & PIPE_TRANSFER_WRITE) &&
        !(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
       use_staging_texture = TRUE;
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index c51689d..a25676e 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -59,6 +59,13 @@ i915_surface_copy_render(struct pipe_context *pipe,
       return;
    }
 
+   if (!util_blitter_is_copy_supported(i915->blitter, dst, src,
+                                       PIPE_MASK_RGBAZS)) {
+      util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz,
+                                src, src_level, src_box);
+      return;
+   }
+
    util_blitter_save_blend(i915->blitter, (void *)i915->blend);
    util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil);
    util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref);




More information about the mesa-commit mailing list