mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 11:20:11 +01:00
zink: implement GL semaphores
this is basically just a wrapper around vulkan semaphores, so it maps fairly well the existing fence function was a big ??? and should never have been triggered like it was Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14498>
This commit is contained in:
parent
29285a0e85
commit
32597e116d
5 changed files with 84 additions and 14 deletions
|
|
@ -96,6 +96,9 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
|
||||||
pipe_resource_reference(&bs->flush_res, NULL);
|
pipe_resource_reference(&bs->flush_res, NULL);
|
||||||
|
|
||||||
bs->resource_size = 0;
|
bs->resource_size = 0;
|
||||||
|
bs->signal_semaphore = VK_NULL_HANDLE;
|
||||||
|
util_dynarray_clear(&bs->wait_semaphores);
|
||||||
|
util_dynarray_clear(&bs->wait_semaphore_stages);
|
||||||
|
|
||||||
/* only reset submitted here so that tc fence desync can pick up the 'completed' flag
|
/* only reset submitted here so that tc fence desync can pick up the 'completed' flag
|
||||||
* before the state is reused
|
* before the state is reused
|
||||||
|
|
@ -222,6 +225,8 @@ create_batch_state(struct zink_context *ctx)
|
||||||
SET_CREATE_OR_FAIL(bs->bufferviews);
|
SET_CREATE_OR_FAIL(bs->bufferviews);
|
||||||
SET_CREATE_OR_FAIL(bs->programs);
|
SET_CREATE_OR_FAIL(bs->programs);
|
||||||
SET_CREATE_OR_FAIL(bs->active_queries);
|
SET_CREATE_OR_FAIL(bs->active_queries);
|
||||||
|
util_dynarray_init(&bs->wait_semaphores, NULL);
|
||||||
|
util_dynarray_init(&bs->wait_semaphore_stages, NULL);
|
||||||
util_dynarray_init(&bs->zombie_samplers, NULL);
|
util_dynarray_init(&bs->zombie_samplers, NULL);
|
||||||
util_dynarray_init(&bs->dead_framebuffers, NULL);
|
util_dynarray_init(&bs->dead_framebuffers, NULL);
|
||||||
util_dynarray_init(&bs->persistent_resources, NULL);
|
util_dynarray_init(&bs->persistent_resources, NULL);
|
||||||
|
|
@ -369,11 +374,9 @@ submit_queue(void *data, void *gdata, int thread_index)
|
||||||
|
|
||||||
uint64_t batch_id = bs->fence.batch_id;
|
uint64_t batch_id = bs->fence.batch_id;
|
||||||
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
si.waitSemaphoreCount = 0;
|
si.waitSemaphoreCount = util_dynarray_num_elements(&bs->wait_semaphores, VkSemaphore);
|
||||||
si.pWaitSemaphores = NULL;
|
si.pWaitSemaphores = bs->wait_semaphores.data;
|
||||||
si.signalSemaphoreCount = 0;
|
si.pWaitDstStageMask = bs->wait_semaphore_stages.data;
|
||||||
si.pSignalSemaphores = NULL;
|
|
||||||
si.pWaitDstStageMask = NULL;
|
|
||||||
si.commandBufferCount = bs->has_barriers ? 2 : 1;
|
si.commandBufferCount = bs->has_barriers ? 2 : 1;
|
||||||
VkCommandBuffer cmdbufs[2] = {
|
VkCommandBuffer cmdbufs[2] = {
|
||||||
bs->barrier_cmdbuf,
|
bs->barrier_cmdbuf,
|
||||||
|
|
@ -381,14 +384,17 @@ submit_queue(void *data, void *gdata, int thread_index)
|
||||||
};
|
};
|
||||||
si.pCommandBuffers = bs->has_barriers ? cmdbufs : &cmdbufs[1];
|
si.pCommandBuffers = bs->has_barriers ? cmdbufs : &cmdbufs[1];
|
||||||
|
|
||||||
|
VkSemaphore signals[2];
|
||||||
|
si.signalSemaphoreCount = !!bs->signal_semaphore;
|
||||||
|
signals[0] = bs->signal_semaphore;
|
||||||
|
si.pSignalSemaphores = signals;
|
||||||
VkTimelineSemaphoreSubmitInfo tsi = {0};
|
VkTimelineSemaphoreSubmitInfo tsi = {0};
|
||||||
if (bs->have_timelines) {
|
if (bs->have_timelines) {
|
||||||
tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
|
tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
|
||||||
si.pNext = &tsi;
|
si.pNext = &tsi;
|
||||||
tsi.signalSemaphoreValueCount = 1;
|
tsi.signalSemaphoreValueCount = 1;
|
||||||
tsi.pSignalSemaphoreValues = &batch_id;
|
tsi.pSignalSemaphoreValues = &batch_id;
|
||||||
si.signalSemaphoreCount = 1;
|
signals[si.signalSemaphoreCount++] = screen->sem;
|
||||||
si.pSignalSemaphores = &screen->sem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wsi_memory_signal_submit_info mem_signal = {
|
struct wsi_memory_signal_submit_info mem_signal = {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,9 @@ struct zink_batch_state {
|
||||||
VkCommandPool cmdpool;
|
VkCommandPool cmdpool;
|
||||||
VkCommandBuffer cmdbuf;
|
VkCommandBuffer cmdbuf;
|
||||||
VkCommandBuffer barrier_cmdbuf;
|
VkCommandBuffer barrier_cmdbuf;
|
||||||
|
VkSemaphore signal_semaphore; //external signal semaphore
|
||||||
|
struct util_dynarray wait_semaphores; //external wait semaphores
|
||||||
|
struct util_dynarray wait_semaphore_stages; //external wait semaphores
|
||||||
|
|
||||||
VkQueue queue; //duplicated from batch for threading
|
VkQueue queue; //duplicated from batch for threading
|
||||||
VkSemaphore sem;
|
VkSemaphore sem;
|
||||||
|
|
|
||||||
|
|
@ -4115,7 +4115,9 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||||
ctx->base.clear_render_target = zink_clear_render_target;
|
ctx->base.clear_render_target = zink_clear_render_target;
|
||||||
ctx->base.clear_depth_stencil = zink_clear_depth_stencil;
|
ctx->base.clear_depth_stencil = zink_clear_depth_stencil;
|
||||||
|
|
||||||
|
ctx->base.create_fence_fd = zink_create_fence_fd;
|
||||||
ctx->base.fence_server_sync = zink_fence_server_sync;
|
ctx->base.fence_server_sync = zink_fence_server_sync;
|
||||||
|
ctx->base.fence_server_signal = zink_fence_server_signal;
|
||||||
ctx->base.flush = zink_flush;
|
ctx->base.flush = zink_flush;
|
||||||
ctx->base.memory_barrier = zink_memory_barrier;
|
ctx->base.memory_barrier = zink_memory_barrier;
|
||||||
ctx->base.texture_barrier = zink_texture_barrier;
|
ctx->base.texture_barrier = zink_texture_barrier;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ destroy_fence(struct zink_screen *screen, struct zink_tc_fence *mfence)
|
||||||
{
|
{
|
||||||
mfence->fence = NULL;
|
mfence->fence = NULL;
|
||||||
tc_unflushed_batch_token_reference(&mfence->tc_token, NULL);
|
tc_unflushed_batch_token_reference(&mfence->tc_token, NULL);
|
||||||
|
VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL);
|
||||||
FREE(mfence);
|
FREE(mfence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,20 +197,73 @@ fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
|
||||||
timeout_ns);
|
timeout_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
|
||||||
|
{
|
||||||
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
|
struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence;
|
||||||
|
|
||||||
|
assert(!ctx->batch.state->signal_semaphore);
|
||||||
|
/* this is a deferred flush to reduce overhead */
|
||||||
|
ctx->batch.state->signal_semaphore = mfence->sem;
|
||||||
|
pctx->flush(pctx, NULL, PIPE_FLUSH_ASYNC);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
|
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
|
||||||
{
|
{
|
||||||
struct zink_tc_fence *mfence = zink_tc_fence(pfence);
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
|
struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence;
|
||||||
|
|
||||||
if (mfence->deferred_ctx == pctx)
|
if (mfence->deferred_ctx == pctx || !mfence->sem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mfence->deferred_ctx) {
|
mfence->deferred_ctx = pctx;
|
||||||
zink_context(pctx)->batch.has_work = true;
|
/* this will be applied on the next submit */
|
||||||
/* this must be the current batch */
|
VkPipelineStageFlags flag = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||||
pctx->flush(pctx, NULL, 0);
|
util_dynarray_append(&ctx->batch.state->wait_semaphores, VkSemaphore, mfence->sem);
|
||||||
|
util_dynarray_append(&ctx->batch.state->wait_semaphore_stages, VkPipelineStageFlags, flag);
|
||||||
}
|
}
|
||||||
zink_fence_finish(zink_screen(pctx->screen), pctx, mfence, PIPE_TIMEOUT_INFINITE);
|
|
||||||
|
void
|
||||||
|
zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type)
|
||||||
|
{
|
||||||
|
struct zink_screen *screen = zink_screen(pctx->screen);
|
||||||
|
VkResult ret = VK_ERROR_UNKNOWN;
|
||||||
|
VkSemaphoreCreateInfo sci = {
|
||||||
|
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||||
|
NULL,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
struct zink_tc_fence *mfence = zink_create_tc_fence();
|
||||||
|
VkExternalSemaphoreHandleTypeFlagBits flags[] = {
|
||||||
|
[PIPE_FD_TYPE_NATIVE_SYNC] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||||
|
[PIPE_FD_TYPE_SYNCOBJ] = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT,
|
||||||
|
};
|
||||||
|
VkImportSemaphoreFdInfoKHR sdi = {0};
|
||||||
|
assert(type < ARRAY_SIZE(flags));
|
||||||
|
|
||||||
|
*pfence = NULL;
|
||||||
|
|
||||||
|
if (VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &mfence->sem) != VK_SUCCESS) {
|
||||||
|
FREE(mfence);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdi.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
|
||||||
|
sdi.semaphore = mfence->sem;
|
||||||
|
sdi.handleType = flags[type];
|
||||||
|
sdi.fd = fd;
|
||||||
|
ret = VKSCR(ImportSemaphoreFdKHR)(screen->dev, &sdi);
|
||||||
|
|
||||||
|
if (!zink_screen_handle_vkresult(screen, ret))
|
||||||
|
goto fail;
|
||||||
|
*pfence = (struct pipe_fence_handle *)mfence;
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL);
|
||||||
|
FREE(mfence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ struct zink_tc_fence {
|
||||||
struct tc_unflushed_batch_token *tc_token;
|
struct tc_unflushed_batch_token *tc_token;
|
||||||
struct pipe_context *deferred_ctx;
|
struct pipe_context *deferred_ctx;
|
||||||
struct zink_fence *fence;
|
struct zink_fence *fence;
|
||||||
|
VkSemaphore sem;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_fence {
|
struct zink_fence {
|
||||||
|
|
@ -78,6 +79,10 @@ zink_fence_reference(struct zink_screen *screen,
|
||||||
struct zink_tc_fence **ptr,
|
struct zink_tc_fence **ptr,
|
||||||
struct zink_tc_fence *fence);
|
struct zink_tc_fence *fence);
|
||||||
|
|
||||||
|
void
|
||||||
|
zink_create_fence_fd(struct pipe_context *pctx, struct pipe_fence_handle **pfence, int fd, enum pipe_fd_type type);
|
||||||
|
void
|
||||||
|
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
|
||||||
void
|
void
|
||||||
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
|
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue