[Mesa-dev] [PATCH 11/14] radeonsi: decompress to flushed depth texture when required
Marek Olšák
maraeo at gmail.com
Sat Jul 2 15:32:10 UTC 2016
On Fri, Jul 1, 2016 at 4:25 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> ---
> src/gallium/drivers/radeonsi/si_blit.c | 132 +++++++++++++++++++++++++--------
> 1 file changed, 103 insertions(+), 29 deletions(-)
>
> diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
> index 85c8ca3..6678b23 100644
> --- a/src/gallium/drivers/radeonsi/si_blit.c
> +++ b/src/gallium/drivers/radeonsi/si_blit.c
> @@ -101,7 +101,7 @@ static unsigned u_max_sample(struct pipe_resource *r)
> return r->nr_samples ? r->nr_samples - 1 : 0;
> }
>
> -static void
> +static unsigned
> si_blit_dbcb_copy(struct si_context *sctx,
> struct r600_texture *src,
> struct r600_texture *dst,
> @@ -111,6 +111,7 @@ si_blit_dbcb_copy(struct si_context *sctx,
> {
> struct pipe_surface surf_tmpl = {{0}};
> unsigned layer, sample, checked_last_layer, max_layer;
> + unsigned fully_copied_levels = 0;
>
> if (planes & PIPE_MASK_Z)
> sctx->dbcb_depth_copy_enabled = true;
> @@ -157,11 +158,17 @@ si_blit_dbcb_copy(struct si_context *sctx,
> pipe_surface_reference(&zsurf, NULL);
> pipe_surface_reference(&cbsurf, NULL);
> }
> +
> + if (first_layer == 0 && last_layer >= max_layer &&
> + first_sample == 0 && last_sample >= u_max_sample(&src->resource.b.b))
> + fully_copied_levels |= 1u << level;
> }
>
> sctx->dbcb_depth_copy_enabled = false;
> sctx->dbcb_stencil_copy_enabled = false;
> si_mark_atom_dirty(sctx, &sctx->db_render_state);
> +
> + return fully_copied_levels;
> }
>
> static void si_blit_decompress_depth(struct pipe_context *ctx,
> @@ -254,52 +261,119 @@ si_blit_decompress_zs_planes_in_place(struct si_context *sctx,
> si_mark_atom_dirty(sctx, &sctx->db_render_state);
> }
>
> -/* Decompress Z and/or S planes in place, depending on mask.
> +/* Helper function of si_flush_depth_texture: decompress the given levels
> + * of Z and/or S planes in place.
> */
> static void
> si_blit_decompress_zs_in_place(struct si_context *sctx,
> struct r600_texture *texture,
> - unsigned planes,
> - unsigned first_level, unsigned last_level,
> + unsigned levels_z, unsigned levels_s,
> unsigned first_layer, unsigned last_layer)
> {
> - unsigned level_mask =
> - u_bit_consecutive(first_level, last_level - first_level + 1);
> - unsigned cur_level_mask;
> + unsigned both = levels_z & levels_s;
>
> /* First, do combined Z & S decompresses for levels that need it. */
> - if (planes == (PIPE_MASK_Z | PIPE_MASK_S)) {
> - cur_level_mask =
> - level_mask &
> - texture->dirty_level_mask &
> - texture->stencil_dirty_level_mask;
> + if (both) {
> si_blit_decompress_zs_planes_in_place(
> sctx, texture, PIPE_MASK_Z | PIPE_MASK_S,
> - cur_level_mask,
> + both,
> first_layer, last_layer);
> - level_mask &= ~cur_level_mask;
> + levels_z &= ~both;
> + levels_s &= ~both;
> }
>
> /* Now do separate Z and S decompresses. */
> - if (planes & PIPE_MASK_Z) {
> - cur_level_mask = level_mask & texture->dirty_level_mask;
> + if (levels_z) {
> si_blit_decompress_zs_planes_in_place(
> sctx, texture, PIPE_MASK_Z,
> - cur_level_mask,
> + levels_z,
> first_layer, last_layer);
> - level_mask &= ~cur_level_mask;
> }
>
> - if (planes & PIPE_MASK_S) {
> - cur_level_mask = level_mask & texture->stencil_dirty_level_mask;
> + if (levels_s) {
> si_blit_decompress_zs_planes_in_place(
> sctx, texture, PIPE_MASK_S,
> - cur_level_mask,
> + levels_s,
> first_layer, last_layer);
> }
> }
>
> static void
> +si_flush_depth_texture(struct si_context *sctx,
> + struct r600_texture *tex,
> + unsigned required_planes,
> + unsigned first_level, unsigned last_level,
> + unsigned first_layer, unsigned last_layer)
> +{
> + unsigned inplace_planes = 0;
> + unsigned copy_planes = 0;
> + unsigned level_mask = u_bit_consecutive(first_level, last_level - first_level + 1);
> + unsigned levels_z = 0;
> + unsigned levels_s = 0;
> +
> + if (required_planes & PIPE_MASK_Z) {
> + levels_z = level_mask & tex->dirty_level_mask;
> +
> + if (levels_z) {
> + if (r600_can_sample_zs(tex, false))
> + inplace_planes |= PIPE_MASK_Z;
> + else
> + copy_planes |= PIPE_MASK_Z;
> + }
> + }
> + if (required_planes & PIPE_MASK_S) {
> + levels_s = level_mask & tex->stencil_dirty_level_mask;
> +
> + if (levels_s) {
> + if (r600_can_sample_zs(tex, true))
> + inplace_planes |= PIPE_MASK_S;
> + else
> + copy_planes |= PIPE_MASK_S;
> + }
> + }
> +
> + /* We may have to allocate the flushed texture here when called from
> + * si_decompress_subresource.
> + */
> + if (copy_planes &&
> + (tex->flushed_depth_texture ||
> + r600_init_flushed_depth_texture(&sctx->b.b, &tex->resource.b.b, NULL))) {
> + struct r600_texture *dst = tex->flushed_depth_texture;
> + unsigned fully_copied_levels;
> + unsigned levels = 0;
> +
> + if (util_format_is_depth_and_stencil(dst->resource.b.b.format))
> + copy_planes = PIPE_MASK_Z | PIPE_MASK_S;
> +
> + if (copy_planes & PIPE_MASK_Z) {
> + levels |= levels_z;
> + levels_z = 0;
> + }
> + if (copy_planes & PIPE_MASK_S) {
> + levels |= levels_s;
> + levels_s = 0;
> + }
> +
> + fully_copied_levels = si_blit_dbcb_copy(
> + sctx, tex, dst, copy_planes, levels,
> + first_layer, last_layer,
> + 0, u_max_sample(&tex->resource.b.b));
> +
> + if (copy_planes & PIPE_MASK_Z)
> + tex->dirty_level_mask &= ~fully_copied_levels;
> + if (copy_planes & PIPE_MASK_S)
> + tex->dirty_level_mask &= ~fully_copied_levels;
tex->stencil_dirty_level_mask?
Marek
More information about the mesa-dev
mailing list