[Mesa-dev] [PATCH] r600g: implement fast color clears on evergreen+

Marek Olšák maraeo at gmail.com
Fri Jun 7 15:40:53 PDT 2013


The idea is good. Now if only it supported multiple colorbuffers and
all colorbuffer formats. It shouldn't be hard. Also the fast clear
shouldn't be used for array, cube, and 3D textures unless all layers
are cleared together.

One more thing. If you don't use piglit, I recommend using it before
sending patches to the mailing list. If you send a patch, I always
assume there are no piglit regressions on your hardware+driver
combination.

Marek

On Fri, Jun 7, 2013 at 9:44 PM, Grigori Goronzy <greg at chown.ath.cx> wrote:
> Allows MSAA colorbuffers, which have a CMASK automatically and don't
> need any further special handling, to be fast cleared. Instead
> of clearing the buffer, set the clear color and the CMASK to the
> cleared state.
> ---
>  src/gallium/drivers/r600/evergreen_state.c |  8 +++++++-
>  src/gallium/drivers/r600/r600_blit.c       | 29 +++++++++++++++++++++++++++++
>  src/gallium/drivers/r600/r600_resource.h   |  3 +++
>  3 files changed, 39 insertions(+), 1 deletion(-)
>
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index 3ebb157..072a365 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -1584,6 +1584,8 @@ void evergreen_init_color_surface(struct r600_context *rctx,
>         surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask_slice_tile_max);
>         surf->cb_color_cmask_slice = S_028C80_TILE_MAX(rtex->cmask_slice_tile_max);
>
> +       surf->cb_color_clear_value = rtex->color_clear_value;
> +
>         surf->color_initialized = true;
>  }
>
> @@ -2178,7 +2180,7 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
>                                                        (struct r600_resource*)cb->base.texture,
>                                                        RADEON_USAGE_READWRITE);
>
> -               r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 11);
> +               r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 15);
>                 r600_write_value(cs, cb->cb_color_base);        /* R_028C60_CB_COLOR0_BASE */
>                 r600_write_value(cs, cb->cb_color_pitch);       /* R_028C64_CB_COLOR0_PITCH */
>                 r600_write_value(cs, cb->cb_color_slice);       /* R_028C68_CB_COLOR0_SLICE */
> @@ -2190,6 +2192,10 @@ static void evergreen_emit_framebuffer_state(struct r600_context *rctx, struct r
>                 r600_write_value(cs, cb->cb_color_cmask_slice); /* R_028C80_CB_COLOR0_CMASK_SLICE */
>                 r600_write_value(cs, cb->cb_color_fmask);       /* R_028C84_CB_COLOR0_FMASK */
>                 r600_write_value(cs, cb->cb_color_fmask_slice); /* R_028C88_CB_COLOR0_FMASK_SLICE */
> +               r600_write_value(cs, cb->cb_color_clear_value); /* R_028C8C_CB_COLOR0_CLEAR_WORD0 */
> +               r600_write_value(cs, 0);                        /* R_028C90_CB_COLOR0_CLEAR_WORD1 */
> +               r600_write_value(cs, 0);                        /* R_028C94_CB_COLOR0_CLEAR_WORD2 */
> +               r600_write_value(cs, 0);                        /* R_028C98_CB_COLOR0_CLEAR_WORD3 */
>
>                 r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C60_CB_COLOR0_BASE */
>                 r600_write_value(cs, reloc);
> diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
> index 058bf81..2b1b49a 100644
> --- a/src/gallium/drivers/r600/r600_blit.c
> +++ b/src/gallium/drivers/r600/r600_blit.c
> @@ -412,6 +412,23 @@ static boolean is_simple_msaa_resolve(const struct pipe_blit_info *info)
>                 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 char value);
> +
> +static void eg_set_clear_color(struct pipe_context *ctx,
> +                              const union pipe_color_union *color)
> +{
> +       struct r600_context *rctx = (struct r600_context *)ctx;
> +       struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
> +       union util_color uc;
> +
> +       memset(&uc, 0, sizeof(uc));
> +       util_pack_color(color->f, fb->cbufs[0]->format, &uc);
> +
> +       /* TODO: color formats with more than 32bpp */
> +       ((struct r600_texture *)fb->cbufs[0]->texture)->color_clear_value = uc.ui;
> +}
> +
>  static void r600_clear(struct pipe_context *ctx, unsigned buffers,
>                        const union pipe_color_union *color,
>                        double depth, unsigned stencil)
> @@ -419,6 +436,18 @@ static void r600_clear(struct pipe_context *ctx, unsigned buffers,
>         struct r600_context *rctx = (struct r600_context *)ctx;
>         struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
>
> +       /* fast color clear on AA framebuffers (EG+) */
> +       /* TODO: multiple color buffers */
> +       if (rctx->chip_class >= EVERGREEN &&
> +                       (buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs == 1 &&
> +                       ((struct r600_texture *)fb->cbufs[0]->texture)->cmask_size) {
> +               struct r600_texture *tex = (struct r600_texture *)fb->cbufs[0]->texture;
> +               eg_set_clear_color(ctx, color);
> +               r600_clear_buffer(ctx, fb->cbufs[0]->texture,
> +                               tex->cmask_offset, tex->cmask_size, 0);
> +               buffers &= ~PIPE_CLEAR_COLOR;
> +       }
> +
>         /* if hyperz enabled just clear hyperz */
>         if (fb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
>                 struct r600_texture *rtex;
> diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
> index d5df633..08a3ba7 100644
> --- a/src/gallium/drivers/r600/r600_resource.h
> +++ b/src/gallium/drivers/r600/r600_resource.h
> @@ -91,6 +91,8 @@ struct r600_texture {
>         struct r600_resource            *htile;
>         /* use htile only for first level */
>         float                           depth_clear;
> +
> +       unsigned                        color_clear_value;
>  };
>
>  #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_038000_ARRAY_LINEAR_ALIGNED)
> @@ -132,6 +134,7 @@ struct r600_surface {
>         unsigned cb_color_cmask;        /* CB_COLORn_CMASK (EG) or CB_COLORn_TILE (r600) */
>         unsigned cb_color_cmask_slice;  /* EG only */
>         unsigned cb_color_mask;         /* R600 only */
> +       unsigned cb_color_clear_value;  /* EG only */
>         struct r600_resource *cb_buffer_fmask; /* Used for FMASK relocations. R600 only */
>         struct r600_resource *cb_buffer_cmask; /* Used for CMASK relocations. R600 only */
>
> --
> 1.8.1.2
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list