zink: create a single fence per batch on startup and then reuse

previously we would be creating a new fence per batch for every submit,
but we can just reset and reuse them if we're careful with it

based on original patch by Antonio Caggiano

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9243>
This commit is contained in:
Mike Blumenkrantz 2021-02-23 21:40:51 -05:00
parent a27570326f
commit da2d8f1078
5 changed files with 34 additions and 24 deletions

View File

@ -20,11 +20,9 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
struct zink_screen *screen = zink_screen(ctx->base.screen);
batch->descs_used = 0;
// cmdbuf hasn't been submitted before without a fence
if (batch->fence) {
// cmdbuf hasn't been submitted before
if (batch->submitted)
zink_fence_finish(screen, batch->fence, PIPE_TIMEOUT_INFINITE);
zink_fence_reference(screen, &batch->fence, NULL);
}
zink_framebuffer_reference(screen, &batch->fb, NULL);
set_foreach(batch->programs, entry) {
@ -69,7 +67,7 @@ zink_reset_batch(struct zink_context *ctx, struct zink_batch *batch)
if (vkResetCommandPool(screen->dev, batch->cmdpool, 0) != VK_SUCCESS)
fprintf(stderr, "vkResetCommandPool failed\n");
batch->has_work = false;
batch->submitted = batch->has_work = false;
}
void
@ -98,10 +96,8 @@ zink_end_batch(struct zink_context *ctx, struct zink_batch *batch)
return;
}
assert(batch->fence == NULL);
batch->fence = zink_create_fence(ctx->base.screen, batch);
if (!batch->fence)
return;
vkResetFences(zink_screen(ctx->base.screen)->dev, 1, &batch->fence->fence);
zink_fence_init(batch->fence, batch);
util_dynarray_foreach(&batch->persistent_resources, struct zink_resource*, res) {
struct zink_screen *screen = zink_screen(ctx->base.screen);
@ -134,6 +130,7 @@ zink_end_batch(struct zink_context *ctx, struct zink_batch *batch)
ctx->reset.reset(ctx->reset.data, PIPE_GUILTY_CONTEXT_RESET);
}
}
batch->submitted = true;
}
/* returns either the compute batch id or 0 (gfx batch id) based on whether a resource

View File

@ -62,6 +62,7 @@ struct zink_batch {
struct set *active_queries; /* zink_query objects which were active at some point in this batch */
bool has_work;
bool submitted;
bool in_rp; //renderpass is currently active
};

View File

@ -1393,9 +1393,8 @@ zink_wait_on_batch(struct zink_context *ctx, int batch_id)
if (batch_id >= 0) {
struct zink_batch *batch = batch_id == ZINK_COMPUTE_BATCH_ID ? &ctx->compute_batch : &ctx->batches[batch_id];
if (batch != zink_curr_batch(ctx)) {
if (!batch->fence) { // this is the compute batch
zink_end_batch(ctx, batch);
zink_start_batch(ctx, batch);
if (!batch->submitted) { // this is the compute batch
zink_flush_compute(ctx);
} else
ctx->base.screen->fence_finish(ctx->base.screen, NULL, (struct pipe_fence_handle*)batch->fence,
PIPE_TIMEOUT_INFINITE);
@ -1776,6 +1775,11 @@ init_batch(struct zink_context *ctx, struct zink_batch *batch, unsigned idx)
return false;
batch->batch_id = idx;
batch->fence = zink_create_fence(ctx->base.screen, batch);
if (!batch->fence)
return false;
batch->max_descs = 1500;
return true;
}

View File

@ -58,20 +58,8 @@ zink_create_fence(struct pipe_screen *pscreen, struct zink_batch *batch)
debug_printf("vkCreateFence failed\n");
goto fail;
}
ret->active_queries = batch->active_queries;
batch->active_queries = NULL;
ret->batch_id = batch->batch_id;
util_dynarray_init(&ret->resources, NULL);
set_foreach(batch->resources, entry) {
/* the fence needs its own reference to ensure it can safely access lifetime-dependent
* resource members
*/
struct pipe_resource *r = NULL, *pres = (struct pipe_resource *)entry->key;
pipe_resource_reference(&r, pres);
util_dynarray_append(&ret->resources, struct pipe_resource*, pres);
}
ret->submitted = true;
pipe_reference_init(&ret->reference, 1);
return ret;
@ -81,6 +69,24 @@ fail:
return NULL;
}
void
zink_fence_init(struct zink_fence *fence, struct zink_batch *batch)
{
assert(!fence->active_queries);
fence->active_queries = batch->active_queries;
batch->active_queries = NULL;
set_foreach(batch->resources, entry) {
/* the fence needs its own reference to ensure it can safely access lifetime-dependent
* resource members
*/
struct pipe_resource *r = NULL, *pres = (struct pipe_resource *)entry->key;
pipe_resource_reference(&r, pres);
util_dynarray_append(&fence->resources, struct pipe_resource*, pres);
}
fence->submitted = true;
}
void
zink_fence_reference(struct zink_screen *screen,
struct zink_fence **ptr,

View File

@ -47,6 +47,8 @@ zink_fence(struct pipe_fence_handle *pfence)
return (struct zink_fence *)pfence;
}
void
zink_fence_init(struct zink_fence *fence, struct zink_batch *batch);
struct zink_fence *
zink_create_fence(struct pipe_screen *pscreen, struct zink_batch *batch);