X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fdrivers%2Ffreedreno%2Ffreedreno_batch_cache.c;h=b3a6041eead5afe5d7390668860295affb4bc214;hb=d4a5e14fae17c7ea7bb8d1d0d6467fd4e0706dd1;hp=9fea7d68271d94b33c358b42f78db93a3a630ac1;hpb=628e84a58fdb26c63a705861b92f65f242613321;p=mesa.git diff --git a/src/gallium/drivers/freedreno/freedreno_batch_cache.c b/src/gallium/drivers/freedreno/freedreno_batch_cache.c index 9fea7d68271..b3a6041eead 100644 --- a/src/gallium/drivers/freedreno/freedreno_batch_cache.c +++ b/src/gallium/drivers/freedreno/freedreno_batch_cache.c @@ -134,11 +134,12 @@ fd_bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx) hash_table_foreach(cache->ht, entry) { struct fd_batch *batch = NULL; + /* hold a reference since we can drop screen->lock: */ fd_batch_reference_locked(&batch, (struct fd_batch *)entry->data); if (batch->ctx == ctx) { mtx_unlock(&ctx->screen->lock); fd_batch_reference(&last_batch, batch); - fd_batch_flush(batch, false); + fd_batch_flush(batch, false, false); mtx_lock(&ctx->screen->lock); } fd_batch_reference_locked(&batch, NULL); @@ -152,6 +153,30 @@ fd_bc_flush(struct fd_batch_cache *cache, struct fd_context *ctx) } } +/* deferred flush doesn't actually flush, but it marks every other + * batch associated with the context as dependent on the current + * batch. So when the current batch gets flushed, all other batches + * that came before also get flushed. + */ +void +fd_bc_flush_deferred(struct fd_batch_cache *cache, struct fd_context *ctx) +{ + struct fd_batch *current_batch = ctx->batch; + struct hash_entry *entry; + + mtx_lock(&ctx->screen->lock); + + hash_table_foreach(cache->ht, entry) { + struct fd_batch *batch = entry->data; + if (batch == current_batch) + continue; + if (batch->ctx == ctx) + fd_batch_add_dep(current_batch, batch); + } + + mtx_unlock(&ctx->screen->lock); +} + void fd_bc_invalidate_context(struct fd_context *ctx) { @@ -204,7 +229,7 @@ fd_bc_invalidate_batch(struct fd_batch *batch, bool destroy) void fd_bc_invalidate_resource(struct fd_resource *rsc, bool destroy) { - struct fd_screen *screen = fd_screen(rsc->base.b.screen); + struct fd_screen *screen = fd_screen(rsc->base.screen); struct fd_batch *batch; mtx_lock(&screen->lock); @@ -265,7 +290,7 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx) */ mtx_unlock(&ctx->screen->lock); DBG("%p: too many batches! flush forced!", flush_batch); - fd_batch_flush(flush_batch, true); + fd_batch_flush(flush_batch, true, false); mtx_lock(&ctx->screen->lock); /* While the resources get cleaned up automatically, the flush_batch @@ -291,7 +316,7 @@ fd_bc_alloc_batch(struct fd_batch_cache *cache, struct fd_context *ctx) idx--; /* bit zero returns 1 for ffs() */ - batch = fd_batch_create(ctx); + batch = fd_batch_create(ctx, false); if (!batch) goto out;