[Mesa-dev] [PATCH 13/18] gallium/u_blitter: add a query for checking whether copying is supported

Marek Olšák maraeo at gmail.com
Thu Aug 2 06:14:41 PDT 2012


Cc: Stephane Marchesin <stephane.marchesin at gmail.com>
---
 src/gallium/auxiliary/util/u_blitter.c           |   86 ++++++++++++++--------
 src/gallium/auxiliary/util/u_blitter.h           |    4 +
 src/gallium/drivers/i915/i915_resource_texture.c |    7 +-
 src/gallium/drivers/i915/i915_surface.c          |    7 ++
 4 files changed, 68 insertions(+), 36 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index a64bafc..920836a 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,
+                                       struct pipe_resource *dst,
+                                       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,43 +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 =
-         util_format_description(src->format);
 
-   /* Give up if textures are not set. */
    assert(dst && src);
-   if (!dst || !src)
-      return;
-
    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..2231387 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -160,6 +160,10 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter,
                                      unsigned width, unsigned height,
                                      double depth, void *custom_dsa);
 
+boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
+                                       struct pipe_resource *dst,
+                                       struct pipe_resource *src,
+                                       unsigned mask);
 /**
  * Copy a block of pixels from one surface to another.
  *
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);
-- 
1.7.9.5



More information about the mesa-dev mailing list