freedreno: add resource tracking support for written buffers
[mesa.git] / src / gallium / drivers / freedreno / freedreno_draw.c
index fed3e64f202404ab3b69ed90b6e99e13c12b6f03..ae75b3efdccf1db1ce8733f2ffa2f97ad2ea1742 100644 (file)
@@ -40,7 +40,7 @@
 #include "freedreno_util.h"
 
 static void
-resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
+resource_used(struct fd_context *ctx, struct pipe_resource *prsc, boolean reading)
 {
        struct fd_resource *rsc;
 
@@ -48,7 +48,10 @@ resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
                return;
 
        rsc = fd_resource(prsc);
-       rsc->reading = true;
+       if (reading)
+               rsc->reading = true;
+       else
+               rsc->writing = true;
        list_delinit(&rsc->list);
        list_addtail(&rsc->list, &ctx->used_resources);
 }
@@ -88,8 +91,12 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
        }
 
        if (fd_stencil_enabled(ctx)) {
+               struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
                buffers |= FD_BUFFER_STENCIL;
-               fd_resource(pfb->zsbuf->texture)->dirty = true;
+               if (rsc->stencil)
+                       rsc->stencil->dirty = true;
+               else
+                       rsc->dirty = true;
                ctx->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
        }
 
@@ -116,26 +123,26 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
        /* Skip over buffer 0, that is sent along with the command stream */
        for (i = 1; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-               resource_reading(ctx, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer);
-               resource_reading(ctx, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer);
+               resource_used(ctx, ctx->constbuf[PIPE_SHADER_VERTEX].cb[i].buffer, true);
+               resource_used(ctx, ctx->constbuf[PIPE_SHADER_FRAGMENT].cb[i].buffer, true);
        }
 
        /* Mark VBOs as being read */
        for (i = 0; i < ctx->vtx.vertexbuf.count; i++) {
                assert(!ctx->vtx.vertexbuf.vb[i].user_buffer);
-               resource_reading(ctx, ctx->vtx.vertexbuf.vb[i].buffer);
+               resource_used(ctx, ctx->vtx.vertexbuf.vb[i].buffer, true);
        }
 
        /* Mark index buffer as being read */
-       resource_reading(ctx, ctx->indexbuf.buffer);
+       resource_used(ctx, ctx->indexbuf.buffer, true);
 
        /* Mark textures as being read */
        for (i = 0; i < ctx->verttex.num_textures; i++)
                if (ctx->verttex.textures[i])
-                       resource_reading(ctx, ctx->verttex.textures[i]->texture);
+                       resource_used(ctx, ctx->verttex.textures[i]->texture, true);
        for (i = 0; i < ctx->fragtex.num_textures; i++)
                if (ctx->fragtex.textures[i])
-                       resource_reading(ctx, ctx->fragtex.textures[i]->texture);
+                       resource_used(ctx, ctx->fragtex.textures[i]->texture, true);
 
        ctx->num_draws++;
 
@@ -215,7 +222,12 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
                                fd_resource(pfb->cbufs[i]->texture)->dirty = true;
 
        if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
-               fd_resource(pfb->zsbuf->texture)->dirty = true;
+               struct fd_resource *rsc = fd_resource(pfb->zsbuf->texture);
+               if (rsc->stencil && buffers & PIPE_CLEAR_STENCIL)
+                       rsc->stencil->dirty = true;
+               if (!rsc->stencil || buffers & PIPE_CLEAR_DEPTH)
+                       rsc->dirty = true;
+
                ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL;
        }