etnaviv: implement TS_MODE for GC7000L
authorJonathan Marek <jonathan@marek.ca>
Mon, 1 Jul 2019 20:16:54 +0000 (16:16 -0400)
committerJonathan Marek <jonathan@marek.ca>
Thu, 4 Jul 2019 18:05:18 +0000 (14:05 -0400)
GC7000L has a TS mode with larger tiles, which improves performance.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
src/gallium/drivers/etnaviv/etnaviv_blt.c
src/gallium/drivers/etnaviv/etnaviv_blt.h
src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/etnaviv/etnaviv_emit.c
src/gallium/drivers/etnaviv/etnaviv_internal.h
src/gallium/drivers/etnaviv/etnaviv_resource.c
src/gallium/drivers/etnaviv/etnaviv_resource.h
src/gallium/drivers/etnaviv/etnaviv_state.c
src/gallium/drivers/etnaviv/etnaviv_texture.c
src/gallium/drivers/etnaviv/etnaviv_texture.h

index 5cc6b8dd8b2f7d728a187e73b598a14c2893b2d1..e0274a5b59968659ac03d90e3e2a592525d70359 100644 (file)
@@ -68,7 +68,7 @@ blt_compute_img_config_bits(const struct blt_imginfo *img, bool for_dest)
       tiling_bits |= for_dest ? BLT_IMAGE_CONFIG_TO_SUPER_TILED : BLT_IMAGE_CONFIG_FROM_SUPER_TILED;
    }
 
-   return BLT_IMAGE_CONFIG_TS_MODE(img->cache_mode) |
+   return BLT_IMAGE_CONFIG_TS_MODE(img->ts_mode) |
           COND(img->use_ts, BLT_IMAGE_CONFIG_TS) |
           COND(img->compressed, BLT_IMAGE_CONFIG_COMPRESSION) |
           BLT_IMAGE_CONFIG_COMPRESSION_FORMAT(img->compress_fmt) |
@@ -182,7 +182,7 @@ emit_blt_inplace(struct etna_cmd_stream *stream, const struct blt_inplace_op *op
    etna_cmd_stream_reserve(stream, 64*2); /* Never allow BLT sequences to be broken up */
    etna_set_state(stream, VIVS_BLT_ENABLE, 0x00000001);
    etna_set_state(stream, VIVS_BLT_CONFIG,
-         VIVS_BLT_CONFIG_INPLACE_TS_MODE(op->cache_mode) |
+         VIVS_BLT_CONFIG_INPLACE_TS_MODE(op->ts_mode) |
          VIVS_BLT_CONFIG_INPLACE_BOTH |
          (util_logbase2(op->bpp) << VIVS_BLT_CONFIG_INPLACE_BPP__SHIFT));
    etna_set_state(stream, VIVS_BLT_DEST_TS_CLEAR_VALUE0, op->ts_clear_value[0]);
@@ -216,7 +216,6 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
    clr.dest.compress_fmt = 3;
    */
    clr.dest.tiling = res->layout;
-   clr.dest.cache_mode = TS_MODE_32; /* TODO: cache modes */
 
    if (surf->surf.ts_size) {
       clr.dest.use_ts = 1;
@@ -225,6 +224,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
       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_mode = surf->level->ts_mode;
    }
 
    clr.clear_value[0] = new_clear_value;
@@ -292,7 +292,6 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
    clr.dest.compress_fmt = COLOR_COMPRESSION_FORMAT_D24S8;
 #endif
    clr.dest.tiling = res->layout;
-   clr.dest.cache_mode = TS_MODE_32; /* TODO: cache modes */
 
    if (surf->surf.ts_size) {
       clr.dest.use_ts = 1;
@@ -301,6 +300,7 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
       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_mode = surf->level->ts_mode;
    }
 
    clr.clear_value[0] = new_clear_value;
@@ -434,8 +434,8 @@ etna_try_blt_blit(struct pipe_context *pctx,
       op.ts_addr.flags = ETNA_RELOC_READ;
       op.ts_clear_value[0] = src_lev->clear_value;
       op.ts_clear_value[1] = src_lev->clear_value;
-      op.cache_mode = TS_MODE_32; /* TODO: cache modes */
-      op.num_tiles = src_lev->size / 128; /* TODO: cache modes */
+      op.ts_mode = src_lev->ts_mode;
+      op.num_tiles = DIV_ROUND_UP(src_lev->size, src_lev->ts_mode ? 256 : 128);
       op.bpp = util_format_get_blocksize(src->base.format);
 
       etna_set_state(ctx->stream, VIVS_GL_FLUSH_CACHE, 0x00000c23);
@@ -451,7 +451,6 @@ etna_try_blt_blit(struct pipe_context *pctx,
       op.src.format = translate_blt_format(src_format);
       op.src.stride = src_lev->stride;
       op.src.tiling = src->layout;
-      op.src.cache_mode = TS_MODE_32; /* TODO: cache modes */
       const struct util_format_description *src_format_desc =
          util_format_description(src_format);
       for (unsigned x=0; x<4; ++x)
@@ -464,6 +463,7 @@ etna_try_blt_blit(struct pipe_context *pctx,
          op.src.ts_addr.flags = ETNA_RELOC_READ;
          op.src.ts_clear_value[0] = src_lev->clear_value;
          op.src.ts_clear_value[1] = src_lev->clear_value;
+         op.src.ts_mode = src_lev->ts_mode;
       }
 
       op.dest.addr.bo = dst->bo;
@@ -476,7 +476,6 @@ etna_try_blt_blit(struct pipe_context *pctx,
       op.dest.compress_fmt = 3;
       */
       op.dest.tiling = dst->layout;
-      op.dest.cache_mode = TS_MODE_32; /* TODO cache modes */
       const struct util_format_description *dst_format_desc =
          util_format_description(dst_format);
       for (unsigned x=0; x<4; ++x)
index 868440828ac0bb8219b28b15941f4a10d6601c20..8bbc6c5e87516d3863bf20fc9b58e168f7eb6a9d 100644 (file)
@@ -47,7 +47,7 @@ struct blt_imginfo
    enum etna_surface_layout tiling; /* ETNA_LAYOUT_* */
    uint32_t ts_clear_value[2];
    uint8_t swizzle[4]; /* TEXTURE_SWIZZLE_* */
-   uint8_t cache_mode; /* TS_CACHE_MODE_* */
+   uint8_t ts_mode; /* TS_MODE_* */
    uint8_t endian_mode; /* ENDIAN_MODE_* */
    uint8_t bpp; /* # bytes per pixel 1/2/4/8 - only used for CLEAR_IMAGE */
 };
@@ -89,7 +89,7 @@ struct blt_inplace_op
    struct etna_reloc ts_addr;
    uint32_t ts_clear_value[2];
    uint32_t num_tiles;
-   uint8_t cache_mode; /* TS_CACHE_MODE_* */
+   uint8_t ts_mode; /* TS_MODE_* */
    uint8_t bpp;
 };
 
index b0a56c6c9b99a893bbba424254f787642cc8e7d7..8aabbe6e944cabf5e3df2f48e269bb52323294b1 100644 (file)
@@ -356,7 +356,6 @@ etna_cmd_stream_reset_notify(struct etna_cmd_stream *stream, void *priv)
       etna_set_state(stream, VIVS_RA_UNK00E0C, 0x00000000);
    }
    if (ctx->specs.halti >= 3) { /* Only on HALTI3+ */
-      etna_set_state(stream, VIVS_PE_MEM_CONFIG, 0x00000000); /* TODO: cache modes */
       etna_set_state(stream, VIVS_PS_HALTI3_UNK0103C, 0x76543210);
    }
    if (ctx->specs.halti >= 4) { /* Only on HALTI4+ */
index ee54daabf3ef10cb22a6d52818a92d6ff7454165..7c954732368271364437d471c168af0a4aae61b1 100644 (file)
@@ -531,6 +531,10 @@ etna_emit_state(struct etna_context *ctx)
          /*014A8*/ EMIT_STATE(PE_DITHER(x), blend->PE_DITHER[x]);
       }
    }
+
+   if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER)) && ctx->specs.halti >= 3)
+      /*014BC*/ EMIT_STATE(PE_MEM_CONFIG, ctx->framebuffer.PE_MEM_CONFIG);
+
    if (unlikely(dirty & (ETNA_DIRTY_FRAMEBUFFER | ETNA_DIRTY_TS))) {
       /*01654*/ EMIT_STATE(TS_MEM_CONFIG, ctx->framebuffer.TS_MEM_CONFIG);
       /*01658*/ EMIT_STATE_RELOC(TS_COLOR_STATUS_BASE, &ctx->framebuffer.TS_COLOR_STATUS_BASE);
index e2f701c3bc9de4470fc35369f59e22b7fa318a97..c00101732e2c29c91e97c22e62d7678fee32c623 100644 (file)
@@ -193,6 +193,7 @@ struct compiled_framebuffer_state {
    struct etna_reloc PE_COLOR_ADDR;
    struct etna_reloc PE_PIPE_COLOR_ADDR[ETNA_MAX_PIXELPIPES];
    uint32_t PE_COLOR_STRIDE;
+   uint32_t PE_MEM_CONFIG;
    uint32_t SE_SCISSOR_LEFT;
    uint32_t SE_SCISSOR_TOP;
    uint32_t SE_SCISSOR_RIGHT;
index 6607e792f465de4ac5117ad200e71837de5f398c..3cf45b6c803edb8fbca223685c00cc05022276f7 100644 (file)
@@ -85,11 +85,21 @@ etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
 {
    struct etna_screen *screen = etna_screen(pscreen);
    size_t rt_ts_size, ts_layer_stride;
+   size_t ts_bits_per_tile, bytes_per_tile;
+   uint8_t ts_mode = TS_MODE_128B; /* only used by halti5 */
 
    assert(!rsc->ts_bo);
 
+   if (screen->specs.halti >= 5) {
+      ts_bits_per_tile = 4;
+      bytes_per_tile = ts_mode == TS_MODE_256B ? 256 : 128;
+   } else {
+      ts_bits_per_tile = screen->specs.bits_per_tile;
+      bytes_per_tile = 64;
+   }
+
    ts_layer_stride = align(DIV_ROUND_UP(rsc->levels[0].layer_stride,
-                                        64 * 8 / screen->specs.bits_per_tile),
+                                        bytes_per_tile * 8 / ts_bits_per_tile),
                            0x100 * screen->specs.pixel_pipes);
    rt_ts_size = ts_layer_stride * rsc->base.array_size;
    if (rt_ts_size == 0)
@@ -110,6 +120,7 @@ etna_screen_resource_alloc_ts(struct pipe_screen *pscreen,
    rsc->levels[0].ts_offset = 0;
    rsc->levels[0].ts_layer_stride = ts_layer_stride;
    rsc->levels[0].ts_size = rt_ts_size;
+   rsc->levels[0].ts_mode = ts_mode;
 
    /* It is important to initialize the TS, as random pattern
     * can result in crashes. Do this on the CPU as this only happens once
index 2938ffa9170804464fa2cd508fb6563221ca1977..c2ad10fddc9d48fb36630fe3561c548958fc7e18 100644 (file)
@@ -51,6 +51,7 @@ struct etna_resource_level {
    uint32_t ts_size;
    uint32_t clear_value; /* clear value of resource level (mainly for TS) */
    bool ts_valid;
+   uint8_t ts_mode;
 
    /* keep track if we have done some per block patching */
    bool patched;
index e23722b0d2f1a14a1a6e1a35d99a01583db349d7..a63350993fefea090a71d332938f39b46b15c2af 100644 (file)
@@ -122,6 +122,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
 
    /* Set up TS as well. Warning: this state is used by both the RS and PE */
    uint32_t ts_mem_config = 0;
+   uint32_t pe_mem_config = 0;
 
    if (sv->nr_cbufs > 0) { /* at least one color buffer? */
       struct etna_surface *cbuf = etna_surface(sv->cbufs[0]);
@@ -173,6 +174,8 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
 
          cs->TS_COLOR_SURFACE_BASE = cbuf->reloc[0];
          cs->TS_COLOR_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
+
+         pe_mem_config |= VIVS_PE_MEM_CONFIG_COLOR_TS_MODE(cbuf->level->ts_mode);
       }
 
       /* MSAA */
@@ -239,6 +242,8 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
 
          cs->TS_DEPTH_SURFACE_BASE = zsbuf->reloc[0];
          cs->TS_DEPTH_SURFACE_BASE.flags = ETNA_RELOC_READ | ETNA_RELOC_WRITE;
+
+         pe_mem_config |= VIVS_PE_MEM_CONFIG_DEPTH_TS_MODE(zsbuf->level->ts_mode);
       }
 
       ts_mem_config |= COND(depth_bits == 16, VIVS_TS_MEM_CONFIG_DEPTH_16BPP);
@@ -316,6 +321,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx,
    cs->SE_CLIP_BOTTOM = (sv->height << 16) + ETNA_SE_CLIP_MARGIN_BOTTOM;
 
    cs->TS_MEM_CONFIG = ts_mem_config;
+   cs->PE_MEM_CONFIG = pe_mem_config;
 
    /* Single buffer setup. There is only one switch for this, not a separate
     * one per color buffer / depth buffer. To keep the logic simple always use
index 58cca3c9ffba695d2b72a847f725fabe65c2ba35..6965ee001ea670f21ee1f0b46e7cce698e7a9adb 100644 (file)
@@ -83,6 +83,7 @@ etna_configure_sampler_ts(struct etna_sampler_ts *sts, struct pipe_sampler_view
       struct etna_resource_level *lev = &rsc->levels[0];
       assert(rsc->ts_bo && lev->ts_valid);
 
+      sts->mode = lev->ts_mode;
       sts->TS_SAMPLER_CONFIG =
          VIVS_TS_SAMPLER_CONFIG_ENABLE |
          VIVS_TS_SAMPLER_CONFIG_COMPRESSION_FORMAT(translate_ts_sampler_format(rsc->base.format));
index 4d66a9f39484417bbf645e6d6ee3c6293e8e5626..e982ee551db07276d956b0fec1cc540fb32194a5 100644 (file)
@@ -36,6 +36,7 @@ struct etna_context;
 
 struct etna_sampler_ts {
    unsigned enable:1;
+   unsigned mode:1;
    uint32_t TS_SAMPLER_CONFIG;
    struct etna_reloc TS_SAMPLER_STATUS_BASE;
    uint32_t TS_SAMPLER_CLEAR_VALUE;