diff options
author | Marek Olšák <[email protected]> | 2013-07-30 22:29:28 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2013-08-17 01:48:25 +0200 |
commit | 07955d4f2b969efb59b9c35c1fba5a0cae2cdc55 (patch) | |
tree | 8cc8ba025ba79593b2866204ea9880b0bf50b9eb /src/gallium/drivers/radeonsi/r600_blit.c | |
parent | c8e70e64accc914c58533b8336873e0995e901e7 (diff) |
radeonsi: implement uncompressed MSAA rendering and color resolving
This is basic MSAA support which should work with most apps.
Some features are missing, those will be implemented by other commits.
Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeonsi/r600_blit.c')
-rw-r--r-- | src/gallium/drivers/radeonsi/r600_blit.c | 132 |
1 files changed, 129 insertions, 3 deletions
diff --git a/src/gallium/drivers/radeonsi/r600_blit.c b/src/gallium/drivers/radeonsi/r600_blit.c index bdd9bb43c10..7ac92d4ac14 100644 --- a/src/gallium/drivers/radeonsi/r600_blit.c +++ b/src/gallium/drivers/radeonsi/r600_blit.c @@ -43,6 +43,8 @@ enum r600_blitter_op /* bitmask */ R600_DISABLE_RENDER_COND, R600_DECOMPRESS = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND, + + R600_COLOR_RESOLVE = R600_SAVE_FRAMEBUFFER | R600_DISABLE_RENDER_COND }; static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) @@ -463,22 +465,146 @@ static void r600_resource_copy_region(struct pipe_context *ctx, r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); } +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; +} + +/* For MSAA integer resolving to work, we change the format to NORM using this function. */ +static enum pipe_format int_to_norm_format(enum pipe_format format) +{ + switch (format) { +#define REPLACE_FORMAT_SIGN(format,sign) \ + case PIPE_FORMAT_##format##_##sign##INT: \ + return PIPE_FORMAT_##format##_##sign##NORM +#define REPLACE_FORMAT(format) \ + REPLACE_FORMAT_SIGN(format, U); \ + REPLACE_FORMAT_SIGN(format, S) + + REPLACE_FORMAT_SIGN(B10G10R10A2, U); + REPLACE_FORMAT(R8); + REPLACE_FORMAT(R8G8); + REPLACE_FORMAT(R8G8B8X8); + REPLACE_FORMAT(R8G8B8A8); + REPLACE_FORMAT(A8); + REPLACE_FORMAT(I8); + REPLACE_FORMAT(L8); + REPLACE_FORMAT(L8A8); + REPLACE_FORMAT(R16); + REPLACE_FORMAT(R16G16); + REPLACE_FORMAT(R16G16B16X16); + REPLACE_FORMAT(R16G16B16A16); + REPLACE_FORMAT(A16); + REPLACE_FORMAT(I16); + REPLACE_FORMAT(L16); + REPLACE_FORMAT(L16A16); + +#undef REPLACE_FORMAT +#undef REPLACE_FORMAT_SIGN + default: + return format; + } +} + +static void si_msaa_color_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; + unsigned sample_mask = ~0; + + assert(info->src.level == 0); + assert(info->src.box.depth == 1); + assert(info->dst.box.depth == 1); + + if (is_simple_msaa_resolve(info)) { + 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)); + r600_blitter_end(ctx); + return; + } + + /* 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); +} + static void si_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) { struct r600_context *rctx = (struct r600_context*)ctx; struct r600_texture *rsrc = (struct r600_texture*)info->src.resource; - 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(info->src.resource->format)) { - debug_printf("radeonsi: color resolve is unimplemented\n"); + si_msaa_color_resolve(ctx, info); return; } + assert(util_blitter_is_blit_supported(rctx->blitter, info)); + if (rsrc->is_depth && !rsrc->is_flushing_texture) { si_blit_decompress_depth_in_place(rctx, rsrc, info->src.level, info->src.level, |