Mesa (master): etnaviv: implement 64bpp clear

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 25 19:24:19 UTC 2019


Module: Mesa
Branch: master
Commit: 5159db60fccf17b00b8da4257dac027b6e2327ef
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=5159db60fccf17b00b8da4257dac027b6e2327ef

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Mon Aug 12 11:43:26 2019 -0400

etnaviv: implement 64bpp clear

At the same time, update etna_clear_blit_pack_rgba to work with integer
formats.

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>

---

 src/gallium/drivers/etnaviv/etnaviv_blt.c        |  7 +++---
 src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 28 ++++++++++++++++++------
 src/gallium/drivers/etnaviv/etnaviv_clear_blit.h |  6 ++---
 src/gallium/drivers/etnaviv/etnaviv_emit.c       |  1 +
 src/gallium/drivers/etnaviv/etnaviv_internal.h   |  1 +
 src/gallium/drivers/etnaviv/etnaviv_resource.h   |  2 +-
 src/gallium/drivers/etnaviv/etnaviv_rs.c         |  8 ++++---
 src/gallium/drivers/etnaviv/etnaviv_state.c      |  1 +
 src/gallium/drivers/etnaviv/etnaviv_surface.c    |  4 +++-
 src/gallium/drivers/etnaviv/etnaviv_texture.c    |  2 +-
 10 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c b/src/gallium/drivers/etnaviv/etnaviv_blt.c
index 7266505eb4f..08f74035c06 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_blt.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c
@@ -215,7 +215,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
 {
    struct etna_context *ctx = etna_context(pctx);
    struct etna_surface *surf = etna_surface(dst);
-   uint32_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color->f);
+   uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color);
 
    struct etna_resource *res = etna_resource(surf->base.texture);
    struct blt_clear_op clr = {};
@@ -232,13 +232,13 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
       clr.dest.ts_addr.offset = 0;
       clr.dest.ts_addr.flags = ETNA_RELOC_WRITE;
       clr.dest.ts_clear_value[0] = new_clear_value;
-      clr.dest.ts_clear_value[1] = new_clear_value;
+      clr.dest.ts_clear_value[1] = new_clear_value >> 32;
       clr.dest.ts_mode = surf->level->ts_mode;
       clr.dest.ts_compress_fmt = surf->level->ts_compress_fmt;
    }
 
    clr.clear_value[0] = new_clear_value;
-   clr.clear_value[1] = new_clear_value;
+   clr.clear_value[1] = new_clear_value >> 32;
    clr.clear_bits[0] = 0xffffffff; /* TODO: Might want to clear only specific channels? */
    clr.clear_bits[1] = 0xffffffff;
    clr.rect_x = 0; /* What about scissors? */
@@ -251,6 +251,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
    /* This made the TS valid */
    if (surf->surf.ts_size) {
       ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
+      ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
       surf->level->ts_valid = true;
       ctx->dirty |= ETNA_DIRTY_TS | ETNA_DIRTY_DERIVE_TS;
    }
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
index 51d16aa19f7..42dc50e2dff 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
@@ -66,15 +66,29 @@ etna_blit_save_state(struct etna_context *ctx)
          ctx->num_fragment_sampler_views, ctx->sampler_view);
 }
 
-uint32_t
-etna_clear_blit_pack_rgba(enum pipe_format format, const float *rgba)
+uint64_t
+etna_clear_blit_pack_rgba(enum pipe_format format, const union pipe_color_union *color)
 {
    union util_color uc;
-   util_pack_color(rgba, format, &uc);
-   if (util_format_get_blocksize(format) == 2)
-      return uc.ui[0] << 16 | (uc.ui[0] & 0xffff);
-   else
-      return uc.ui[0];
+
+   if (util_format_is_pure_uint(format)) {
+      util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1);
+   } else if (util_format_is_pure_sint(format)) {
+      util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1);
+   } else {
+      util_pack_color(color->f, format, &uc);
+   }
+
+   switch (util_format_get_blocksize(format)) {
+   case 1:
+      uc.ui[0] = uc.ui[0] << 8 | (uc.ui[0] & 0xff);
+   case 2:
+      uc.ui[0] =  uc.ui[0] << 16 | (uc.ui[0] & 0xffff);
+   case 4:
+      uc.ui[1] = uc.ui[0];
+   default:
+      return (uint64_t) uc.ui[1] << 32 | uc.ui[0];
+   }
 }
 
 static void
diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h
index 05a7b64a9f8..2249a5b12e0 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.h
@@ -36,7 +36,7 @@ struct etna_surface;
 
 void
 etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
-                          uint32_t clear_value);
+                          uint64_t clear_value);
 
 void
 etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst,
@@ -50,8 +50,8 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst,
 void
 etna_blit_save_state(struct etna_context *ctx);
 
-uint32_t
-etna_clear_blit_pack_rgba(enum pipe_format format, const float *rgba);
+uint64_t
+etna_clear_blit_pack_rgba(enum pipe_format format, const union pipe_color_union *color);
 
 void
 etna_clear_blit_init(struct pipe_context *pctx);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c
index 6d8dd349f84..ba3d8c021e7 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
@@ -545,6 +545,7 @@ etna_emit_state(struct etna_context *ctx)
       /*01664*/ EMIT_STATE_RELOC(TS_DEPTH_STATUS_BASE, &ctx->framebuffer.TS_DEPTH_STATUS_BASE);
       /*01668*/ EMIT_STATE_RELOC(TS_DEPTH_SURFACE_BASE, &ctx->framebuffer.TS_DEPTH_SURFACE_BASE);
       /*0166C*/ EMIT_STATE(TS_DEPTH_CLEAR_VALUE, ctx->framebuffer.TS_DEPTH_CLEAR_VALUE);
+      /*016BC*/ EMIT_STATE(TS_COLOR_CLEAR_VALUE_EXT, ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT);
    }
    if (unlikely(dirty & (ETNA_DIRTY_SHADER))) {
       /*0381C*/ EMIT_STATE(GL_VARYING_TOTAL_COMPONENTS, ctx->shader_state.GL_VARYING_TOTAL_COMPONENTS);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h
index e5a5b590efa..8655eac53c3 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_internal.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h
@@ -212,6 +212,7 @@ struct compiled_framebuffer_state {
    struct etna_reloc TS_DEPTH_STATUS_BASE;
    struct etna_reloc TS_DEPTH_SURFACE_BASE;
    uint32_t TS_COLOR_CLEAR_VALUE;
+   uint32_t TS_COLOR_CLEAR_VALUE_EXT;
    struct etna_reloc TS_COLOR_STATUS_BASE;
    struct etna_reloc TS_COLOR_SURFACE_BASE;
    uint32_t PE_LOGIC_OP;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h
index 51e54074139..1da0315ab9e 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_resource.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h
@@ -52,7 +52,7 @@ struct etna_resource_level {
    uint32_t ts_offset;
    uint32_t ts_layer_stride;
    uint32_t ts_size;
-   uint32_t clear_value; /* clear value of resource level (mainly for TS) */
+   uint64_t clear_value; /* clear value of resource level (mainly for TS) */
    bool ts_valid;
    uint8_t ts_mode;
    int8_t ts_compress_fmt; /* COLOR_COMPRESSION_FORMAT_* (-1 = disable) */
diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c
index 5c9c45deb86..e3f7fbd8d3b 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_rs.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c
@@ -265,7 +265,7 @@ etna_submit_rs_state(struct etna_context *ctx,
 /* Generate clear command for a surface (non-fast clear case) */
 void
 etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
-                          uint32_t clear_value)
+                          uint64_t clear_value)
 {
    struct etna_resource *dst = etna_resource(surf->base.texture);
    uint32_t format;
@@ -301,7 +301,7 @@ etna_rs_gen_clear_surface(struct etna_context *ctx, struct etna_surface *surf,
       .dither = {0xffffffff, 0xffffffff},
       .width = surf->surf.padded_width, /* These must be padded to 16x4 if !LINEAR, otherwise RS will hang */
       .height = surf->surf.padded_height,
-      .clear_value = {clear_value},
+      .clear_value = {clear_value, clear_value >> 32, clear_value, clear_value >> 32},
       .clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_ENABLED1,
       .clear_bits = 0xffff
    });
@@ -313,10 +313,11 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, struct pipe_surface *dst,
 {
    struct etna_context *ctx = etna_context(pctx);
    struct etna_surface *surf = etna_surface(dst);
-   uint32_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color->f);
+   uint64_t new_clear_value = etna_clear_blit_pack_rgba(surf->base.format, color);
 
    if (surf->surf.ts_size) { /* TS: use precompiled clear command */
       ctx->framebuffer.TS_COLOR_CLEAR_VALUE = new_clear_value;
+      ctx->framebuffer.TS_COLOR_CLEAR_VALUE_EXT = new_clear_value >> 32;
 
       if (VIV_FEATURE(ctx->screen, chipMinorFeatures1, AUTO_DISABLE)) {
          /* Set number of color tiles to be filled */
@@ -742,6 +743,7 @@ etna_try_rs_blit(struct pipe_context *pctx,
       etna_set_state_reloc(ctx->stream, VIVS_TS_COLOR_SURFACE_BASE, &reloc);
 
       etna_set_state(ctx->stream, VIVS_TS_COLOR_CLEAR_VALUE, src_lev->clear_value);
+      etna_set_state(ctx->stream, VIVS_TS_COLOR_CLEAR_VALUE_EXT, src_lev->clear_value >> 32);
 
       source_ts_valid = true;
    } else {
diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c
index 5c8448315f0..f5f5993abc5 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_state.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_state.c
@@ -187,6 +187,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
 
       if (cbuf->surf.ts_size) {
          cs->TS_COLOR_CLEAR_VALUE = cbuf->level->clear_value;
+         cs->TS_COLOR_CLEAR_VALUE_EXT = cbuf->level->clear_value >> 32;
 
          cs->TS_COLOR_STATUS_BASE = cbuf->ts_reloc;
          cs->TS_COLOR_STATUS_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c
index d93519db6df..153ab837246 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_surface.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c
@@ -103,8 +103,10 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
    if (VIV_FEATURE(ctx->screen, chipFeatures, FAST_CLEAR) &&
        VIV_FEATURE(ctx->screen, chipMinorFeatures0, MC20) &&
        !rsc->ts_bo &&
+       /* needs to be RS/BLT compatible for transfer_map/unmap */
        (rsc->levels[level].padded_width & ETNA_RS_WIDTH_MASK) == 0 &&
-       (rsc->levels[level].padded_height & ETNA_RS_HEIGHT_MASK) == 0) {
+       (rsc->levels[level].padded_height & ETNA_RS_HEIGHT_MASK) == 0 &&
+       etna_resource_hw_tileable(ctx->specs.use_blt, prsc)) {
       etna_screen_resource_alloc_ts(pctx->screen, rsc);
    }
 
diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c
index aa4b2534419..f3ca6a736fc 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_texture.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c
@@ -102,7 +102,7 @@ etna_configure_sampler_ts(struct etna_sampler_ts *sts, struct pipe_sampler_view
       COND(lev->ts_compress_fmt >= 0, VIVS_TS_SAMPLER_CONFIG_COMPRESSION) |
       VIVS_TS_SAMPLER_CONFIG_COMPRESSION_FORMAT(lev->ts_compress_fmt);
    sts->TS_SAMPLER_CLEAR_VALUE = lev->clear_value;
-   sts->TS_SAMPLER_CLEAR_VALUE2 = lev->clear_value; /* To handle 64-bit formats this needs a different value */
+   sts->TS_SAMPLER_CLEAR_VALUE2 = lev->clear_value >> 32;
    sts->TS_SAMPLER_STATUS_BASE.bo = rsc->ts_bo;
    sts->TS_SAMPLER_STATUS_BASE.offset = lev->ts_offset;
    sts->TS_SAMPLER_STATUS_BASE.flags = ETNA_RELOC_READ;




More information about the mesa-commit mailing list