From: Marek Olšák Date: Fri, 27 Jul 2012 23:19:18 +0000 (+0200) Subject: gallium/u_blitter: add a query for checking whether copying is supported X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=84645fa61390475e6efb080685e0dec059622a39;p=mesa.git gallium/u_blitter: add a query for checking whether copying is supported v2: add comments --- 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 @@ -160,6 +160,16 @@ void util_blitter_clear_depth_custom(struct blitter_context *blitter, unsigned width, unsigned height, 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. * @@ -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);