mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2024-11-23 07:19:50 +00: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
@ -96,6 +96,9 @@ zink_reset_batch_state(struct zink_context *ctx, struct zink_batch_state *bs)
|
||||
pipe_resource_reference(&bs->flush_res, NULL);
|
||||
|
||||
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
|
||||
* 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->programs);
|
||||
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->dead_framebuffers, 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;
|
||||
si.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
si.waitSemaphoreCount = 0;
|
||||
si.pWaitSemaphores = NULL;
|
||||
si.signalSemaphoreCount = 0;
|
||||
si.pSignalSemaphores = NULL;
|
||||
si.pWaitDstStageMask = NULL;
|
||||
si.waitSemaphoreCount = util_dynarray_num_elements(&bs->wait_semaphores, VkSemaphore);
|
||||
si.pWaitSemaphores = bs->wait_semaphores.data;
|
||||
si.pWaitDstStageMask = bs->wait_semaphore_stages.data;
|
||||
si.commandBufferCount = bs->has_barriers ? 2 : 1;
|
||||
VkCommandBuffer cmdbufs[2] = {
|
||||
bs->barrier_cmdbuf,
|
||||
@ -381,14 +384,17 @@ submit_queue(void *data, void *gdata, int thread_index)
|
||||
};
|
||||
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};
|
||||
if (bs->have_timelines) {
|
||||
tsi.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
|
||||
si.pNext = &tsi;
|
||||
tsi.signalSemaphoreValueCount = 1;
|
||||
tsi.pSignalSemaphoreValues = &batch_id;
|
||||
si.signalSemaphoreCount = 1;
|
||||
si.pSignalSemaphores = &screen->sem;
|
||||
signals[si.signalSemaphoreCount++] = screen->sem;
|
||||
}
|
||||
|
||||
struct wsi_memory_signal_submit_info mem_signal = {
|
||||
|
@ -68,6 +68,9 @@ struct zink_batch_state {
|
||||
VkCommandPool cmdpool;
|
||||
VkCommandBuffer 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
|
||||
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_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_signal = zink_fence_server_signal;
|
||||
ctx->base.flush = zink_flush;
|
||||
ctx->base.memory_barrier = zink_memory_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;
|
||||
tc_unflushed_batch_token_reference(&mfence->tc_token, NULL);
|
||||
VKSCR(DestroySemaphore)(screen->dev, mfence->sem, NULL);
|
||||
FREE(mfence);
|
||||
}
|
||||
|
||||
@ -196,20 +197,73 @@ fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
|
||||
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
|
||||
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;
|
||||
|
||||
if (mfence->deferred_ctx) {
|
||||
zink_context(pctx)->batch.has_work = true;
|
||||
/* this must be the current batch */
|
||||
pctx->flush(pctx, NULL, 0);
|
||||
mfence->deferred_ctx = pctx;
|
||||
/* this will be applied on the next submit */
|
||||
VkPipelineStageFlags flag = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
|
||||
util_dynarray_append(&ctx->batch.state->wait_semaphores, VkSemaphore, mfence->sem);
|
||||
util_dynarray_append(&ctx->batch.state->wait_semaphore_stages, VkPipelineStageFlags, flag);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
zink_fence_finish(zink_screen(pctx->screen), pctx, mfence, PIPE_TIMEOUT_INFINITE);
|
||||
|
||||
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
|
||||
|
@ -46,6 +46,7 @@ struct zink_tc_fence {
|
||||
struct tc_unflushed_batch_token *tc_token;
|
||||
struct pipe_context *deferred_ctx;
|
||||
struct zink_fence *fence;
|
||||
VkSemaphore sem;
|
||||
};
|
||||
|
||||
struct zink_fence {
|
||||
@ -78,6 +79,10 @@ zink_fence_reference(struct zink_screen *screen,
|
||||
struct zink_tc_fence **ptr,
|
||||
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
|
||||
zink_fence_server_sync(struct pipe_context *pctx, struct pipe_fence_handle *pfence);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user