freedreno: mark resources as being read so that writes flush the queue
authorIlia Mirkin <imirkin@alum.mit.edu>
Fri, 3 Apr 2015 00:48:44 +0000 (20:48 -0400)
committerRob Clark <robclark@freedesktop.org>
Sun, 5 Apr 2015 20:36:34 +0000 (16:36 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_draw.c
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_resource.h

index bb1b52797a85f82cc7a5d4e50d142a954ba8b46e..5fca57c5a3a9721f60ed6e59bdebff0e153667aa 100644 (file)
@@ -95,6 +95,7 @@ fd_context_render(struct pipe_context *pctx)
 {
        struct fd_context *ctx = fd_context(pctx);
        struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+       struct fd_resource *rsc, *rsc_tmp;
        int i;
 
        DBG("needs_flush: %d", ctx->needs_flush);
@@ -122,6 +123,15 @@ fd_context_render(struct pipe_context *pctx)
                        fd_resource(pfb->cbufs[i]->texture)->dirty = false;
        if (pfb->zsbuf)
                fd_resource(pfb->zsbuf->texture)->dirty = false;
+
+       /* go through all the used resources and clear their reading flag */
+       LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list) {
+               assert(rsc->reading);
+               rsc->reading = false;
+               list_delinit(&rsc->list);
+       }
+
+       assert(LIST_IS_EMPTY(&ctx->used_resources));
 }
 
 static void
index 7b0424e65da2030a3af7e8b1bba4fe1d85f93f81..a648689cefd9af93e8d82dc85ebb9442136c901b 100644 (file)
@@ -165,6 +165,9 @@ struct fd_context {
        struct fd_bo *query_bo;
        uint32_t query_tile_stride;
 
+       /* list of resources used by currently-unsubmitted renders */
+       struct list_head used_resources;
+
        /* table with PIPE_PRIM_MAX entries mapping PIPE_PRIM_x to
         * DI_PT_x value to use for draw initiator.  There are some
         * slight differences between generation:
index 423ae23769c15613a4415dbf548ae35afd9d329c..fed3e64f202404ab3b69ed90b6e99e13c12b6f03 100644 (file)
 #include "freedreno_query_hw.h"
 #include "freedreno_util.h"
 
+static void
+resource_reading(struct fd_context *ctx, struct pipe_resource *prsc)
+{
+       struct fd_resource *rsc;
+
+       if (!prsc)
+               return;
+
+       rsc = fd_resource(prsc);
+       rsc->reading = true;
+       list_delinit(&rsc->list);
+       list_addtail(&rsc->list, &ctx->used_resources);
+}
 
 static void
 fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
@@ -101,6 +114,29 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                        ctx->gmem_reason |= FD_GMEM_BLEND_ENABLED;
        }
 
+       /* 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);
+       }
+
+       /* 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);
+       }
+
+       /* Mark index buffer as being read */
+       resource_reading(ctx, ctx->indexbuf.buffer);
+
+       /* 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);
+       for (i = 0; i < ctx->fragtex.num_textures; i++)
+               if (ctx->fragtex.textures[i])
+                       resource_reading(ctx, ctx->fragtex.textures[i]->texture);
+
        ctx->num_draws++;
 
        ctx->stats.draw_calls++;
@@ -223,6 +259,8 @@ fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
 void
 fd_draw_init(struct pipe_context *pctx)
 {
+       list_inithead(&fd_context(pctx)->used_resources);
+
        pctx->draw_vbo = fd_draw_vbo;
        pctx->clear = fd_clear;
        pctx->clear_render_target = fd_clear_render_target;
index 6e7958d42ddb48f0cbdc4c10967892e49fb889a9..000d1c210af47b92c3fe774a3207a5494a3be14b 100644 (file)
@@ -57,7 +57,8 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
 
        rsc->bo = fd_bo_new(screen->dev, size, flags);
        rsc->timestamp = 0;
-       rsc->dirty = false;
+       rsc->dirty = rsc->reading = false;
+       list_delinit(&rsc->list);
 }
 
 static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
@@ -170,6 +171,7 @@ fd_resource_destroy(struct pipe_screen *pscreen,
        struct fd_resource *rsc = fd_resource(prsc);
        if (rsc->bo)
                fd_bo_del(rsc->bo);
+       list_delinit(&rsc->list);
        FREE(rsc);
 }
 
@@ -277,6 +279,7 @@ fd_resource_create(struct pipe_screen *pscreen,
        *prsc = *tmpl;
 
        pipe_reference_init(&prsc->reference, 1);
+       list_inithead(&rsc->list);
        prsc->screen = pscreen;
 
        rsc->base.vtbl = &fd_resource_vtbl;
@@ -340,6 +343,7 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
        *prsc = *tmpl;
 
        pipe_reference_init(&prsc->reference, 1);
+       list_inithead(&rsc->list);
        prsc->screen = pscreen;
 
        rsc->bo = fd_screen_bo_from_handle(pscreen, handle, &slice->pitch);
index 1f246328969f0216aaabb4facae3dda51e1a2b08..1539fc9ad1a86e2169a7af9e72e571348e4bc4ad 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef FREEDRENO_RESOURCE_H_
 #define FREEDRENO_RESOURCE_H_
 
+#include "util/u_double_list.h"
 #include "util/u_transfer.h"
 
 #include "freedreno_util.h"
@@ -67,6 +68,8 @@ struct fd_resource {
        struct fd_resource_slice slices[MAX_MIP_LEVELS];
        uint32_t timestamp;
        bool dirty, reading;
+
+       struct list_head list;
 };
 
 static INLINE struct fd_resource *