etnaviv: avoid using invalid TS
authorLucas Stach <l.stach@pengutronix.de>
Mon, 21 Nov 2016 11:25:29 +0000 (12:25 +0100)
committerLucas Stach <l.stach@pengutronix.de>
Tue, 11 Apr 2017 14:52:01 +0000 (16:52 +0200)
The TS is only valid after it has been initialized by a fast
clear, so it should not be taken into account when blitting
resources that haven't been cleared. Also the blit itself
invalidates the destination TS, as it's not updated and will
retain data from the previous rendering after the blit.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Wladimir J. van der Laan <laanwj@gmail.com>
src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
src/gallium/drivers/etnaviv/etnaviv_resource.h
src/gallium/drivers/etnaviv/etnaviv_surface.c

index 4a03d8294f541aa3db5a221f33ff2ea4fa68c0ce..d555884d3fe3ef8cafe92641a7efa75eadde8018 100644 (file)
@@ -119,6 +119,7 @@ etna_blit_clear_color(struct pipe_context *pctx, struct pipe_surface *dst,
          ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_COLOR_AUTO_DISABLE;
       }
 
+      surf->level->ts_valid = true;
       ctx->dirty |= ETNA_DIRTY_TS;
    } else if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
       /* If clear color changed, re-generate stored command */
@@ -178,6 +179,7 @@ etna_blit_clear_zs(struct pipe_context *pctx, struct pipe_surface *dst,
          ctx->framebuffer.TS_MEM_CONFIG |= VIVS_TS_MEM_CONFIG_DEPTH_AUTO_DISABLE;
       }
 
+      surf->level->ts_valid = true;
       ctx->dirty |= ETNA_DIRTY_TS;
    } else {
       if (unlikely(new_clear_value != surf->level->clear_value)) { /* Queue normal RS clear for non-TS surfaces */
@@ -468,7 +470,8 @@ etna_try_rs_blit(struct pipe_context *pctx,
    }
 
    /* Set up color TS to source surface before blit, if needed */
-   if (src->levels[blit_info->src.level].ts_size) {
+   if (src->levels[blit_info->src.level].ts_size &&
+       src->levels[blit_info->src.level].ts_valid) {
       struct etna_reloc reloc;
       unsigned ts_offset =
          src_lev->ts_offset + blit_info->src.box.z * src_lev->ts_layer_stride;
@@ -521,6 +524,7 @@ etna_try_rs_blit(struct pipe_context *pctx,
    etna_submit_rs_state(ctx, &copy_to_screen);
    resource_written(ctx, &dst->base);
    dst->seqno++;
+   dst->levels[blit_info->dst.level].ts_valid = false;
 
    return TRUE;
 
index a9b288e708be5e7053c32b426bb9a172f8fc4681..a6c6a78269ec6ceec1646313d7347f93e1ac7a97 100644 (file)
@@ -46,6 +46,7 @@ struct etna_resource_level {
    uint32_t ts_layer_stride;
    uint32_t ts_size;
    uint32_t clear_value; /* clear value of resource level (mainly for TS) */
+   bool ts_valid;
 };
 
 /* status of queued up but not flushed reads and write operations.
index a0013a48bcf23e0b11bb62285e73379ecb84d279..db4846aa060de98f2b93a1a3678a8d588c269861 100644 (file)
@@ -107,6 +107,7 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
 
       surf->surf.ts_offset += layer_offset;
       surf->surf.ts_size -= layer_offset;
+      surf->surf.ts_valid = false;
 
       surf->ts_reloc.bo = rsc->ts_bo;
       surf->ts_reloc.offset = surf->surf.ts_offset;