summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-07-28 01:19:18 +0200
committerMarek Olšák <[email protected]>2012-08-04 14:05:37 +0200
commit84645fa61390475e6efb080685e0dec059622a39 (patch)
tree03da220d7d9dd31568704f10a4cd4610ae693d34 /src/gallium
parente2f623f1d6da9bc987582ff68d0471061ae44030 (diff)
gallium/u_blitter: add a query for checking whether copying is supported
v2: add comments
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c87
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h13
-rw-r--r--src/gallium/drivers/i915/i915_resource_texture.c7
-rw-r--r--src/gallium/drivers/i915/i915_surface.c7
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 21dc19fa107..fa71f25ea75 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 80a11526e77..7600391c511 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 8ff733a7be5..e60b5b435cc 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 c51689dcb4c..a25676efeca 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);