From: Rob Clark Date: Sat, 21 May 2016 00:05:26 +0000 (-0400) Subject: freedreno: push resource tracking down into batch X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9e4561d3c47c2dabce43ce160915fd9bcea05a81;p=mesa.git freedreno: push resource tracking down into batch Signed-off-by: Rob Clark --- diff --git a/src/gallium/drivers/freedreno/freedreno_batch.c b/src/gallium/drivers/freedreno/freedreno_batch.c index c202ff0e942..51a61d96e02 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.c +++ b/src/gallium/drivers/freedreno/freedreno_batch.c @@ -24,10 +24,12 @@ * Rob Clark */ +#include "util/list.h" #include "util/u_string.h" #include "freedreno_batch.h" #include "freedreno_context.h" +#include "freedreno_resource.h" struct fd_batch * fd_batch_create(struct fd_context *ctx) @@ -54,6 +56,8 @@ fd_batch_create(struct fd_context *ctx) fd_ringbuffer_set_parent(batch->draw, batch->gmem); fd_ringbuffer_set_parent(batch->binning, batch->gmem); + list_inithead(&batch->used_resources); + return batch; } @@ -76,7 +80,38 @@ __fd_batch_describe(char* buf, const struct fd_batch *batch) void fd_batch_flush(struct fd_batch *batch) { + struct fd_resource *rsc, *rsc_tmp; + fd_gmem_render_tiles(batch->ctx); + + /* go through all the used resources and clear their reading flag */ + LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &batch->used_resources, list) { + debug_assert(rsc->pending_batch == batch); + debug_assert(rsc->status != 0); + rsc->status = 0; + fd_batch_reference(&rsc->pending_batch, NULL); + list_delinit(&rsc->list); + } + + assert(LIST_IS_EMPTY(&batch->used_resources)); +} + +void +fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, + enum fd_resource_status status) +{ + rsc->status |= status; + + if (rsc->stencil) + rsc->stencil->status |= status; + + /* TODO resources can actually be shared across contexts, + * so I'm not sure a single list-head will do the trick? + */ + debug_assert((rsc->pending_batch == batch) || !rsc->pending_batch); + list_delinit(&rsc->list); + list_addtail(&rsc->list, &batch->used_resources); + fd_batch_reference(&rsc->pending_batch, batch); } void diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h index 2134624f833..69779d8c8f4 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch.h +++ b/src/gallium/drivers/freedreno/freedreno_batch.h @@ -32,6 +32,8 @@ #include "freedreno_util.h" struct fd_context; +struct fd_resource; +enum fd_resource_status; /* A batch tracks everything about a cmdstream batch/submit, including the * ringbuffers used for binning, draw, and gmem cmds, list of associated @@ -48,11 +50,16 @@ struct fd_batch { struct fd_ringbuffer *binning; /** tiling/gmem (IB0) cmdstream: */ struct fd_ringbuffer *gmem; + + /** list of resources used by currently-unsubmitted batch */ + struct list_head used_resources; }; struct fd_batch * fd_batch_create(struct fd_context *ctx); void fd_batch_flush(struct fd_batch *batch); +void fd_batch_resource_used(struct fd_batch *batch, struct fd_resource *rsc, + enum fd_resource_status status); void fd_batch_check_size(struct fd_batch *batch); /* not called directly: */ diff --git a/src/gallium/drivers/freedreno/freedreno_context.c b/src/gallium/drivers/freedreno/freedreno_context.c index d3a631e3a00..3614370bf33 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.c +++ b/src/gallium/drivers/freedreno/freedreno_context.c @@ -45,7 +45,6 @@ void fd_context_render(struct pipe_context *pctx) { struct fd_context *ctx = fd_context(pctx); - struct fd_resource *rsc, *rsc_tmp; DBG("needs_flush: %d", ctx->needs_flush); @@ -61,16 +60,6 @@ fd_context_render(struct pipe_context *pctx) ctx->cleared = ctx->partial_cleared = ctx->restore = ctx->resolve = 0; ctx->gmem_reason = 0; ctx->num_draws = 0; - - /* go through all the used resources and clear their reading flag */ - LIST_FOR_EACH_ENTRY_SAFE(rsc, rsc_tmp, &ctx->used_resources, list) { - debug_assert(rsc->status != 0); - rsc->status = 0; - rsc->pending_ctx = NULL; - list_delinit(&rsc->list); - } - - assert(LIST_IS_EMPTY(&ctx->used_resources)); } static void diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index cdf40146881..88e103ea6c3 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -185,9 +185,6 @@ 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: diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index 26164f2109e..2c76333cf12 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -40,38 +40,19 @@ #include "freedreno_util.h" static void -resource_used(struct fd_context *ctx, struct pipe_resource *prsc, - enum fd_resource_status status) +resource_read(struct fd_context *ctx, struct pipe_resource *prsc) { - struct fd_resource *rsc; - if (!prsc) return; - - rsc = fd_resource(prsc); - rsc->status |= status; - if (rsc->stencil) - rsc->stencil->status |= status; - - /* TODO resources can actually be shared across contexts, - * so I'm not sure a single list-head will do the trick? - */ - debug_assert((rsc->pending_ctx == ctx) || !rsc->pending_ctx); - list_delinit(&rsc->list); - list_addtail(&rsc->list, &ctx->used_resources); - rsc->pending_ctx = ctx; -} - -static void -resource_read(struct fd_context *ctx, struct pipe_resource *prsc) -{ - resource_used(ctx, prsc, FD_PENDING_READ); + fd_batch_resource_used(ctx->batch, fd_resource(prsc), FD_PENDING_READ); } static void resource_written(struct fd_context *ctx, struct pipe_resource *prsc) { - resource_used(ctx, prsc, FD_PENDING_WRITE); + if (!prsc) + return; + fd_batch_resource_used(ctx->batch, fd_resource(prsc), FD_PENDING_WRITE); } static void @@ -300,8 +281,6 @@ 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; diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 41f46a69c3e..eea53c60696 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -109,7 +109,7 @@ realloc_bo(struct fd_resource *rsc, uint32_t size) rsc->bo = fd_bo_new(screen->dev, size, flags); rsc->timestamp = 0; rsc->status = 0; - rsc->pending_ctx = NULL; + fd_batch_reference(&rsc->pending_batch, NULL); list_delinit(&rsc->list); util_range_set_empty(&rsc->valid_buffer_range); } @@ -453,6 +453,7 @@ fd_resource_destroy(struct pipe_screen *pscreen, struct fd_resource *rsc = fd_resource(prsc); if (rsc->bo) fd_bo_del(rsc->bo); + fd_batch_reference(&rsc->pending_batch, NULL); list_delinit(&rsc->list); util_range_destroy(&rsc->valid_buffer_range); FREE(rsc); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index 9a9b0d08244..f8131c774ec 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -33,6 +33,7 @@ #include "util/u_range.h" #include "util/u_transfer.h" +#include "freedreno_batch.h" #include "freedreno_util.h" /* Texture Layout on a3xx: @@ -91,7 +92,7 @@ struct fd_resource { * in the used_resources list. */ struct list_head list; - struct fd_context *pending_ctx; + struct fd_batch *pending_batch; }; static inline struct fd_resource *