[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