From bda1354aac9d32e236048af4d353d5530f644c34 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Sun, 26 Jul 2015 13:30:26 -0400 Subject: [PATCH] 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 --- .../drivers/freedreno/freedreno_context.c | 3 ++- .../drivers/freedreno/freedreno_draw.c | 19 +++++++++++-------- .../drivers/freedreno/freedreno_resource.c | 5 +++-- .../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 127fb5f5aa0..02613dcdbdb 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 c9e317c7dc9..ae75b3efdcc 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 20495779d50..de3cb64ed5b 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 9833b30e17f..e7f127edca4 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; -- 2.30.2