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:
parent
a27570326f
commit
da2d8f1078
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue