[Mesa-dev] [PATCH 4/8] radeonsi: Add DCC fast clear.

Marek Olšák maraeo at gmail.com
Wed Sep 23 17:04:50 PDT 2015


On Fri, Sep 4, 2015 at 9:47 PM, Bas Nieuwenhuizen
<bas at basnieuwenhuizen.nl> wrote:
> We cannot use the clear words from the cmask fast clear, so the
> fast clears are somewhat limited.
>
> The clear patterns have been taken from Catalyst traces.
>
> Signed-off-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
> ---
>  src/gallium/drivers/radeon/r600_texture.c | 48 ++++++++++++++++++++++++-------
>  1 file changed, 38 insertions(+), 10 deletions(-)
>
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 017f5e7..6a4bb59 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -1234,6 +1234,24 @@ static void evergreen_set_clear_color(struct r600_texture *rtex,
>         memcpy(rtex->color_clear_value, &uc, 2 * sizeof(uint32_t));
>  }
>
> +static bool vi_is_dcc_clear_allowed(enum pipe_format surface_format,
> +                                   const union pipe_color_union *color,
> +                                   uint32_t* reset_value) {
> +       if (util_format_is_pure_uint(surface_format) ||
> +           util_format_is_pure_sint(surface_format))
> +               return false;

I think int clear will work just fine. The allowed clear values are
equivalent to the floating-point values, so the code below should work
even for int.

> +
> +       if(color->f[0] != 0.0f || color->f[1] != 0.0f || color->f[2] != 0.0f)
> +               return false;
> +
> +       if(color->f[3] != 1.0f && color->f[3] != 0.0f)
> +               return false;
> +
> +       *reset_value = color->f[3] == 1.0f ? 0x40404040U : 0;

My docs say it should be like this:
(0,0,0,0) = 0x20
(0,0,0,1) = 0x60
(1,1,1,0) = 0xa0
(1,1,1,1) = 0xe0

Of course, testing is required.


> +
> +       return true;
> +}
> +
>  void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
>                                    struct pipe_framebuffer_state *fb,
>                                    struct r600_atom *fb_state,
> @@ -1248,6 +1266,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
>         for (i = 0; i < fb->nr_cbufs; i++) {
>                 struct r600_texture *tex;
>                 unsigned clear_bit = PIPE_CLEAR_COLOR0 << i;
> +               uint32_t dcc_reset_value;
>
>                 if (!fb->cbufs[i])
>                         continue;
> @@ -1287,18 +1306,27 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
>                         continue;
>                 }
>
> -               /* ensure CMASK is enabled */
> -               r600_texture_alloc_cmask_separate(rctx->screen, tex);
> -               if (tex->cmask.size == 0) {
> -                       continue;
> -               }
> -
> -               /* Do the fast clear. */
>                 evergreen_set_clear_color(tex, fb->cbufs[i]->format, color);

evergreen_set_clear_color can be called after the clear succeeds, but
it's useless to call it before we know the clear is allowed.

> -               rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
> -                                  tex->cmask.offset, tex->cmask.size, 0, true);
>
> -               tex->dirty_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
> +               if(tex->dcc_buffer && vi_is_dcc_clear_allowed(fb->cbufs[i]->format, color, &dcc_reset_value)) {
> +                       rctx->clear_buffer(&rctx->b, &tex->dcc_buffer->b.b,
> +                                       0, tex->surface.dcc_size, dcc_reset_value, true);
> +
> +                       tex->dcc_compressed_level_mask |= 1 << fb->cbufs[i]->u.tex.level;
> +               } else {
> +                       /* ensure CMASK is enabled */
> +                       r600_texture_alloc_cmask_separate(rctx->screen, tex);
> +                       if (tex->cmask.size == 0) {
> +                               continue;
> +                       }
> +
> +                       /* Do the fast clear. */
> +                       rctx->clear_buffer(&rctx->b, &tex->cmask_buffer->b.b,
> +                                       tex->cmask.offset, tex->cmask.size, 0, true);

As I said at patch 3 and I'm repeating it again just for clarity: the
CMASK clear can't be used if DCC is enabled.

Marek


More information about the mesa-dev mailing list