Mesa (master): freedreno: add resource tracking support for written buffers

Rob Clark robclark at kemper.freedesktop.org
Mon Jul 27 17:51:14 UTC 2015


Module: Mesa
Branch: master
Commit: bda1354aac9d32e236048af4d353d5530f644c34
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bda1354aac9d32e236048af4d353d5530f644c34

Author: Rob Clark <robclark at freedesktop.org>
Date:   Sun Jul 26 13:30:26 2015 -0400

freedreno: add resource tracking support for written buffers

With stream-out (transform-feedback) we have the case where resources
are *written* by the gpu, which needs basically the same tracking to
figure out when rendering must be flushed.

Signed-off-by: Rob Clark <robclark at freedesktop.org>

---

 src/gallium/drivers/freedreno/freedreno_context.c  |    3 ++-
 src/gallium/drivers/freedreno/freedreno_draw.c     |   19 +++++++++++--------
 src/gallium/drivers/freedreno/freedreno_resource.c |    5 +++--
 src/gallium/drivers/freedreno/freedreno_resource.h |    2 +-
 4 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c
index 127fb5f..02613dc 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.c
+++ b/src/gallium/drivers/freedreno/freedreno_context.c
@@ -130,8 +130,9 @@ fd_context_render(struct pipe_context *pctx)
 
 	/* 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);
+		assert(rsc->reading || rsc->writing);
 		rsc->reading = false;
+		rsc->writing = false;
 		list_delinit(&rsc->list);
 	}
 
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index c9e317c..ae75b3e 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -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);
 }
@@ -120,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++;
 
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 2049577..de3cb64 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -97,7 +97,7 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
 
 	rsc->bo = fd_bo_new(screen->dev, size, flags);
 	rsc->timestamp = 0;
-	rsc->dirty = rsc->reading = false;
+	rsc->dirty = rsc->reading = rsc->writing = false;
 	list_delinit(&rsc->list);
 	util_range_set_empty(&rsc->valid_buffer_range);
 }
@@ -239,7 +239,8 @@ fd_resource_transfer_map(struct pipe_context *pctx,
 		 * resource and we're trying to write to it, flush the renders.
 		 */
 		if (rsc->dirty || (rsc->stencil && rsc->stencil->dirty) ||
-			((ptrans->usage & PIPE_TRANSFER_WRITE) && rsc->reading))
+			((ptrans->usage & PIPE_TRANSFER_WRITE) && rsc->reading) ||
+			((ptrans->usage & PIPE_TRANSFER_READ) && rsc->writing))
 			fd_context_render(pctx);
 
 		/* The GPU keeps track of how the various bo's are being used, and
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h
index 9833b30..e7f127e 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.h
+++ b/src/gallium/drivers/freedreno/freedreno_resource.h
@@ -68,7 +68,7 @@ struct fd_resource {
 	uint32_t layer_size;
 	struct fd_resource_slice slices[MAX_MIP_LEVELS];
 	uint32_t timestamp;
-	bool dirty, reading;
+	bool dirty, reading, writing;
 	/* buffer range that has been initialized */
 	struct util_range valid_buffer_range;
 




More information about the mesa-commit mailing list