[Mesa-dev] [PATCH 3/8] radeonsi: Enable DCC.

Marek Olšák maraeo at gmail.com
Wed Sep 23 16:36:31 PDT 2015


On Fri, Sep 4, 2015 at 9:47 PM, Bas Nieuwenhuizen
<bas at basnieuwenhuizen.nl> wrote:
> The flags to be enabled in the control registers have been taken from
> Catalyst traces.
>
> Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
> ---
>  src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
>  src/gallium/drivers/radeon/r600_texture.c     |  2 ++
>  src/gallium/drivers/radeon/r600d_common.h     |  1 +
>  src/gallium/drivers/radeonsi/si_blit.c        | 16 ++++++++++++----
>  src/gallium/drivers/radeonsi/si_pipe.c        |  2 ++
>  src/gallium/drivers/radeonsi/si_pipe.h        |  1 +
>  src/gallium/drivers/radeonsi/si_state.c       | 27 +++++++++++++++++++++++----
>  src/gallium/drivers/radeonsi/sid.h            |  1 +
>  8 files changed, 43 insertions(+), 8 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
> index f05318f..dac270e 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.h
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.h
> @@ -244,6 +244,7 @@ struct r600_surface {
>         unsigned cb_color_dim;          /* EG only */
>         unsigned cb_color_pitch;        /* EG and later */
>         unsigned cb_color_slice;        /* EG and later */
> +       unsigned cb_dcc_base;           /* VI and later */
>         unsigned cb_color_attrib;       /* EG and later */
>         unsigned cb_dcc_control;        /* VI and later */
>         unsigned cb_color_fmask;        /* CB_COLORn_FMASK (EG and later) or CB_COLORn_FRAG (r600) */
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 46e735e..017f5e7 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -495,6 +495,8 @@ static void vi_texture_alloc_dcc_separate(struct r600_common_screen *rscreen,
>
>         r600_screen_clear_buffer(rscreen, &rtex->dcc_buffer->b.b, 0, rtex->surface.dcc_size,
>                                  0xFFFFFFFF, true);
> +
> +       rtex->cb_color_info |= VI_S_028C70_DCC_ENABLE(1);
>  }
>
>  static unsigned r600_texture_get_htile_size(struct r600_common_screen *rscreen,
> diff --git a/src/gallium/drivers/radeon/r600d_common.h b/src/gallium/drivers/radeon/r600d_common.h
> index 115042d..a3d182c 100644
> --- a/src/gallium/drivers/radeon/r600d_common.h
> +++ b/src/gallium/drivers/radeon/r600d_common.h
> @@ -202,6 +202,7 @@
>
>  #define   EG_S_028C70_FAST_CLEAR(x)                       (((x) & 0x1) << 17)
>  #define   SI_S_028C70_FAST_CLEAR(x)                       (((x) & 0x1) << 13)
> +#define   VI_S_028C70_DCC_ENABLE(x)                       (((x) & 0x1) << 28)
>
>  /*CIK+*/
>  #define R_0300FC_CP_STRMOUT_CNTL                    0x0300FC
> diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
> index 13bb457..98913e5 100644
> --- a/src/gallium/drivers/radeonsi/si_blit.c
> +++ b/src/gallium/drivers/radeonsi/si_blit.c
> @@ -264,7 +264,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
>                 return;
>
>         for (level = first_level; level <= last_level; level++) {
> -               if (!(rtex->dirty_level_mask & (1 << level)))
> +               if (!(rtex->dirty_level_mask & (1 << level)) && !(rtex->dcc_compressed_level_mask & (1 << level)))
>                         continue;
>
>                 /* The smaller the mipmap level, the less layers there are
> @@ -274,6 +274,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
>
>                 for (layer = first_layer; layer <= checked_last_layer; layer++) {
>                         struct pipe_surface *cbsurf, surf_tmpl;
> +                       void * custom_blend;
>
>                         surf_tmpl.format = rtex->resource.b.b.format;
>                         surf_tmpl.u.tex.level = level;
> @@ -281,10 +282,17 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
>                         surf_tmpl.u.tex.last_layer = layer;
>                         cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl);
>
> +                       if(rtex->fmask.size) {
> +                               custom_blend = sctx->custom_blend_decompress;
> +                       } else if(rtex->dcc_buffer) {
> +                               /* also eliminates the fast clear if necessary */
> +                               custom_blend = sctx->custom_blend_dcc_decompress;
> +                       } else {
> +                               custom_blend = sctx->custom_blend_fastclear;
> +                       }

The order of these is wrong. DCC decompression should be first, which
also automatically invokes FMASK and CMASK decompression. Next should
be FMASK decompression, which automatically invokes CMASK
decompression.

There are also 2 things that need to be changed in this file or r600_texture.c:

1) CMASK fast clear isn't possible with DCC and shouldn't be used. It
should be disallowed in the commit that
enables DCC.

2) Hardware MSAA resolves can't have DCC enabled in the destination.
There are 2 options:
a) use shader-based resolving
b) disable DCC and release the DCC buffer before using a hw resolve


> +
>                         si_blitter_begin(ctx, SI_DECOMPRESS);
> -                       util_blitter_custom_color(sctx->blitter, cbsurf,
> -                               rtex->fmask.size ? sctx->custom_blend_decompress :
> -                                                  sctx->custom_blend_fastclear);
> +                       util_blitter_custom_color(sctx->blitter, cbsurf, custom_blend);
>                         si_blitter_end(ctx);
>
>                         pipe_surface_reference(&cbsurf, NULL);
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
> index 7dbb2e3..a5525ac 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.c
> +++ b/src/gallium/drivers/radeonsi/si_pipe.c
> @@ -67,6 +67,8 @@ static void si_destroy_context(struct pipe_context *context)
>                 sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress);
>         if (sctx->custom_blend_fastclear)
>                 sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fastclear);
> +       if (sctx->custom_blend_dcc_decompress)
> +               sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_dcc_decompress);
>         util_unreference_framebuffer_state(&sctx->framebuffer.state);
>
>         if (sctx->blitter)
> diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
> index d9c7871..66c66c8 100644
> --- a/src/gallium/drivers/radeonsi/si_pipe.h
> +++ b/src/gallium/drivers/radeonsi/si_pipe.h
> @@ -159,6 +159,7 @@ struct si_context {
>         void                            *custom_blend_resolve;
>         void                            *custom_blend_decompress;
>         void                            *custom_blend_fastclear;
> +       void                            *custom_blend_dcc_decompress;
>         void                            *pstipple_sampler_state;
>         struct si_screen                *screen;
>         struct pipe_fence_handle        *last_gfx_fence;
> diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index faef2ee..5c9c866 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -1915,8 +1915,19 @@ static void si_initialize_color_surface(struct si_context *sctx,
>         surf->cb_color_info = color_info;
>         surf->cb_color_attrib = color_attrib;
>
> -       if (sctx->b.chip_class >= VI)
> -               surf->cb_dcc_control = S_028C78_OVERWRITE_COMBINER_DISABLE(1);

OVERWRITE_COMBINER_DISABLE must be set if both blending and MSAA are
enabled. Otherwise, corruption can occur. I'm waiting for an answer if
we can use CB_DCC_CONTROL.OVERWRITE_COMBINER_DISABLE instead. Until
then, it would be nice to add a "TODO" in the commit message.

> +       if (sctx->b.chip_class >= VI) {
> +

Useless empty line.

> +               surf->cb_dcc_control = S_028C78_KEY_CLEAR_ENABLE(1) |
> +                                      S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(2) |
> +                                      S_028C78_INDEPENDENT_64B_BLOCKS(1);

KEY_CLEAR_ENABLE isn't supported on VI as far as I know. Why do you
think it should be set?

> +
> +               if(rtex->dcc_buffer) {
> +                       uint64_t dcc_offset = rtex->surface.level[level].dcc_offset;
> +
> +                       surf->cb_dcc_base = (rtex->dcc_buffer->gpu_address + dcc_offset) >> 8;
> +               }
> +       }
> +

Useless empty line.

Marek


More information about the mesa-dev mailing list