diff options
author | Marek Olšák <[email protected]> | 2013-12-12 18:09:08 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2013-12-14 17:42:08 +0100 |
commit | 696229523d919de15ebc25d0f475bf56d7dad4a9 (patch) | |
tree | 640fc3ea09f595d61574fdd43e0a6f7ceab2b834 /src/gallium/drivers/r600/r600_blit.c | |
parent | 9ebb9a3c8e0d93bae2408daae3cb8b1045e0a473 (diff) |
r600g: use shader-based MSAA resolving when hw-based one cannot be used
This fixes some MSAA integer tests.
Diffstat (limited to 'src/gallium/drivers/r600/r600_blit.c')
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 117 |
1 files changed, 35 insertions, 82 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 3fb4d3b9951..7e29cc51f7b 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -385,33 +385,6 @@ static bool r600_decompress_subresource(struct pipe_context *ctx, return true; } -static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info) -{ - unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level); - unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level); - struct r600_texture *dst = (struct r600_texture*)info->dst.resource; - unsigned dst_tile_mode = dst->surface.level[info->dst.level].mode; - - return info->dst.resource->format == info->src.resource->format && - info->dst.resource->format == info->dst.format && - info->src.resource->format == info->src.format && - !info->scissor_enable && - info->mask == PIPE_MASK_RGBA && - dst_width == info->src.resource->width0 && - dst_height == info->src.resource->height0 && - info->dst.box.x == 0 && - info->dst.box.y == 0 && - info->dst.box.width == dst_width && - info->dst.box.height == dst_height && - info->src.box.x == 0 && - info->src.box.y == 0 && - info->src.box.width == dst_width && - info->src.box.height == dst_height && - /* Dst must be tiled. If it's not, we have to use a temporary - * resource which is tiled. */ - dst_tile_mode >= RADEON_SURF_MODE_1D; -} - static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource *dst, unsigned offset, unsigned size, unsigned value); @@ -863,67 +836,51 @@ static enum pipe_format int_to_norm_format(enum pipe_format format) } } -static void r600_msaa_color_resolve(struct pipe_context *ctx, - const struct pipe_blit_info *info) +static bool do_hardware_msaa_resolve(struct pipe_context *ctx, + const struct pipe_blit_info *info) { - struct r600_context *rctx = (struct r600_context *)ctx; - struct pipe_screen *screen = ctx->screen; - struct pipe_resource *tmp, templ; - struct pipe_blit_info blit; + struct r600_context *rctx = (struct r600_context*)ctx; + struct r600_texture *dst = (struct r600_texture*)info->dst.resource; + unsigned dst_width = u_minify(info->dst.resource->width0, info->dst.level); + unsigned dst_height = u_minify(info->dst.resource->height0, info->dst.level); + enum pipe_format format = int_to_norm_format(info->dst.format); unsigned sample_mask = rctx->b.chip_class == CAYMAN ? ~0 : ((1ull << MAX2(1, info->src.resource->nr_samples)) - 1); - assert(info->src.level == 0); - assert(info->src.box.depth == 1); - assert(info->dst.box.depth == 1); - - if (is_simple_msaa_resolve(info)) { + if (info->src.resource->nr_samples > 1 && + info->dst.resource->nr_samples <= 1 && + util_max_layer(info->src.resource, 0) == 0 && + util_max_layer(info->dst.resource, info->dst.level) == 0 && + info->dst.format == info->src.format && + !util_format_is_pure_integer(format) && + !util_format_is_depth_or_stencil(format) && + !info->scissor_enable && + (info->mask & PIPE_MASK_RGBA) == PIPE_MASK_RGBA && + dst_width == info->src.resource->width0 && + dst_height == info->src.resource->height0 && + info->dst.box.x == 0 && + info->dst.box.y == 0 && + info->dst.box.width == dst_width && + info->dst.box.height == dst_height && + info->dst.box.depth == 1 && + info->src.box.x == 0 && + info->src.box.y == 0 && + info->src.box.width == dst_width && + info->src.box.height == dst_height && + info->src.box.depth == 1 && + dst->surface.level[info->dst.level].mode >= RADEON_SURF_MODE_1D) { r600_blitter_begin(ctx, R600_COLOR_RESOLVE); util_blitter_custom_resolve_color(rctx->blitter, info->dst.resource, info->dst.level, info->dst.box.z, info->src.resource, info->src.box.z, sample_mask, rctx->custom_blend_resolve, - int_to_norm_format(info->dst.format)); + format); r600_blitter_end(ctx); - return; + return true; } - - /* resolve into a temporary texture, then blit */ - templ.target = PIPE_TEXTURE_2D; - templ.format = info->src.resource->format; - templ.width0 = info->src.resource->width0; - templ.height0 = info->src.resource->height0; - templ.depth0 = 1; - templ.array_size = 1; - templ.last_level = 0; - templ.nr_samples = 0; - templ.usage = PIPE_USAGE_STATIC; - templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; - templ.flags = R600_RESOURCE_FLAG_FORCE_TILING; /* dst must not have a linear layout */ - - tmp = screen->resource_create(screen, &templ); - - /* resolve */ - r600_blitter_begin(ctx, R600_COLOR_RESOLVE); - util_blitter_custom_resolve_color(rctx->blitter, - tmp, 0, 0, - info->src.resource, info->src.box.z, - sample_mask, rctx->custom_blend_resolve, - int_to_norm_format(tmp->format)); - r600_blitter_end(ctx); - - /* blit */ - blit = *info; - blit.src.resource = tmp; - blit.src.box.z = 0; - - r600_blitter_begin(ctx, R600_BLIT); - util_blitter_blit(rctx->blitter, &blit); - r600_blitter_end(ctx); - - pipe_resource_reference(&tmp, NULL); + return false; } static void r600_blit(struct pipe_context *ctx, @@ -931,16 +888,12 @@ static void r600_blit(struct pipe_context *ctx, { struct r600_context *rctx = (struct r600_context*)ctx; - assert(util_blitter_is_blit_supported(rctx->blitter, info)); - - if (info->src.resource->nr_samples > 1 && - info->dst.resource->nr_samples <= 1 && - !util_format_is_depth_or_stencil(info->src.resource->format) && - !util_format_is_pure_integer(int_to_norm_format(info->src.resource->format))) { - r600_msaa_color_resolve(ctx, info); + if (do_hardware_msaa_resolve(ctx, info)) { return; } + assert(util_blitter_is_blit_supported(rctx->blitter, info)); + /* The driver doesn't decompress resources automatically while * u_blitter is rendering. */ if (!r600_decompress_subresource(ctx, info->src.resource, info->src.level, |