etnaviv: clear texture cache and flush ts when texture is modified
authorJonathan Marek <jonathan@marek.ca>
Tue, 2 Jul 2019 17:34:02 +0000 (13:34 -0400)
committerJonathan Marek <jonathan@marek.ca>
Fri, 11 Oct 2019 11:26:52 +0000 (07:26 -0400)
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/etnaviv/etnaviv_texture.c
src/gallium/drivers/etnaviv/etnaviv_texture.h

index 9af564440c0bbf7f427b63fa2a8e72830df6de5b..b31b1158303727c1ccf6252f59e8eaebfa2ed8a0 100644 (file)
@@ -263,9 +263,17 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
    resource_read(ctx, indexbuf);
 
    /* Mark textures as being read */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-      if (ctx->sampler_view[i])
-         resource_read(ctx, ctx->sampler_view[i]->texture);
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      if (ctx->sampler_view[i]) {
+          resource_read(ctx, ctx->sampler_view[i]->texture);
+
+         /* if texture was modified since the last update,
+          * we need to clear the texture cache and possibly
+          * resolve/update ts
+          */
+         etna_update_sampler_source(ctx->sampler_view[i], i);
+      }
+   }
 
    list_for_each_entry(struct etna_hw_query, hq, &ctx->active_hw_queries, node)
       resource_written(ctx, hq->prsc);
index 59a0d122d59e01e852ef6861f6f2c6e94408e8af..88ed970d660517516e4e9a207c44e6f4752e45e5 100644 (file)
@@ -73,31 +73,40 @@ etna_bind_sampler_states(struct pipe_context *pctx, enum pipe_shader_type shader
    ctx->dirty |= ETNA_DIRTY_SAMPLERS;
 }
 
-static void
+static bool
 etna_configure_sampler_ts(struct etna_sampler_ts *sts, struct pipe_sampler_view *pview, bool enable)
 {
+   bool dirty = (sts->enable != enable);
+
    assert(sts);
    sts->enable = enable;
-   if (enable) {
-      struct etna_resource *rsc = etna_resource(pview->texture);
-      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 |
-         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_STATUS_BASE.bo = rsc->ts_bo;
-      sts->TS_SAMPLER_STATUS_BASE.offset = lev->ts_offset;
-      sts->TS_SAMPLER_STATUS_BASE.flags = ETNA_RELOC_READ;
-   } else {
+
+   if (!enable) {
       sts->TS_SAMPLER_CONFIG = 0;
       sts->TS_SAMPLER_STATUS_BASE.bo = NULL;
+      return dirty;
    }
-   /* n.b.: relies on caller to mark ETNA_DIRTY_SAMPLER_VIEWS */
+
+   struct etna_resource *rsc = etna_resource(pview->texture);
+   struct etna_resource_level *lev = &rsc->levels[0];
+
+   if (lev->clear_value != sts->TS_SAMPLER_CLEAR_VALUE)
+      dirty = true;
+
+   assert(rsc->ts_bo && lev->ts_valid);
+
+   sts->mode = lev->ts_mode;
+   sts->TS_SAMPLER_CONFIG =
+      VIVS_TS_SAMPLER_CONFIG_ENABLE |
+      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_STATUS_BASE.bo = rsc->ts_bo;
+   sts->TS_SAMPLER_STATUS_BASE.offset = lev->ts_offset;
+   sts->TS_SAMPLER_STATUS_BASE.flags = ETNA_RELOC_READ;
+
+   return dirty;
 }
 
 /* Return true if the GPU can use sampler TS with this sampler view.
@@ -121,6 +130,7 @@ etna_can_use_sampler_ts(struct pipe_sampler_view *view, int num)
      */
    struct etna_resource *rsc = etna_resource(view->texture);
    struct etna_screen *screen = etna_screen(rsc->base.screen);
+
    return VIV_FEATURE(screen, chipMinorFeatures2, TEXTURE_TILED_READ) &&
       num < VIVS_TS_SAMPLER__LEN &&
       rsc->base.target != PIPE_BUFFER &&
@@ -129,7 +139,7 @@ etna_can_use_sampler_ts(struct pipe_sampler_view *view, int num)
       rsc->levels[0].ts_valid;
 }
 
-static void
+void
 etna_update_sampler_source(struct pipe_sampler_view *view, int num)
 {
    struct etna_resource *base = etna_resource(view->texture);
@@ -147,6 +157,7 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num)
       etna_copy_resource(view->context, &to->base, &from->base, 0,
                          view->texture->last_level);
       to->seqno = from->seqno;
+      ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
    } else if ((to == from) && etna_resource_needs_flush(to)) {
       if (ctx->ts_for_sampler_view && etna_can_use_sampler_ts(view, num)) {
          enable_sampler_ts = true;
@@ -156,10 +167,16 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num)
          etna_copy_resource(view->context, &to->base, &from->base, 0,
                             view->texture->last_level);
          to->flush_seqno = from->seqno;
+         ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
       }
+  } else if ((to == from) && (to->flush_seqno < from->seqno)) {
+      to->flush_seqno = from->seqno;
+      ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
    }
-   if (ctx->ts_for_sampler_view) {
-      etna_configure_sampler_ts(ctx->ts_for_sampler_view(view), view, enable_sampler_ts);
+   if (ctx->ts_for_sampler_view &&
+       etna_configure_sampler_ts(ctx->ts_for_sampler_view(view), view, enable_sampler_ts)) {
+      ctx->dirty |= ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_TEXTURE_CACHES;
+      ctx->dirty_sampler_views |= (1 << num);
    }
 }
 
@@ -277,11 +294,6 @@ etna_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader,
 
    ctx->dirty |= ETNA_DIRTY_SAMPLER_VIEWS | ETNA_DIRTY_TEXTURE_CACHES;
 
-   for (unsigned idx = 0; idx < num_views; ++idx) {
-      if (views[idx])
-         etna_update_sampler_source(views[idx], idx);
-   }
-
    switch (shader) {
    case PIPE_SHADER_FRAGMENT:
       etna_fragtex_set_sampler_views(ctx, num_views, views);
index e982ee551db07276d956b0fec1cc540fb32194a5..e2e9d2b51cdc76761d8387b49cfe3da2408523a9 100644 (file)
@@ -61,4 +61,8 @@ etna_texture_handle_incompatible(struct pipe_context *pctx, struct pipe_resource
 uint32_t
 active_samplers_bits(struct etna_context *ctx);
 
+/* update TS / cache for a sampler if required */
+void
+etna_update_sampler_source(struct pipe_sampler_view *view, int num);
+
 #endif