zink: implement fence_get_fd required by EGL android platform

fence_get_fd is required for any kind of surface flush or native fence
sync export on Android. The typical scenarios are:
- eglDupNativeFenceFDANDROID
- eglSwapBuffers*
- eglMakeCurrent
- glFlush/glFinish for front buffer rendering

This change updates zink_flush to handle PIPE_FLUSH_FENCE_FD via a
forced submit to signal an external sync_fd semaphore. fence_get_fd is
implemented to export the sync file from that semaphore.

Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org>
Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18453>
This commit is contained in:
Yiwei Zhang 2022-09-08 03:17:22 +00:00 committed by Marge Bot
parent 6d1e214238
commit 9fdfe43240
2 changed files with 52 additions and 0 deletions

View file

@ -3425,6 +3425,7 @@ zink_flush(struct pipe_context *pctx,
struct zink_fence *fence = NULL;
struct zink_screen *screen = zink_screen(ctx->base.screen);
unsigned submit_count = 0;
VkSemaphore export_sem = VK_NULL_HANDLE;
/* triggering clears will force has_work */
if (!deferred && ctx->clears_enabled)
@ -3437,6 +3438,29 @@ zink_flush(struct pipe_context *pctx,
ctx->needs_present = NULL;
}
if (flags & PIPE_FLUSH_FENCE_FD) {
assert(!deferred && pfence);
const VkExportSemaphoreCreateInfo esci = {
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
};
const VkSemaphoreCreateInfo sci = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = &esci,
};
VkResult result = VKSCR(CreateSemaphore)(screen->dev, &sci, NULL, &export_sem);
if (zink_screen_handle_vkresult(screen, result)) {
assert(!batch->state->signal_semaphore);
batch->state->signal_semaphore = export_sem;
batch->has_work = true;
} else {
mesa_loge("ZINK: vkCreateSemaphore failed (%s)", vk_Result_to_str(result));
/* let flush proceed and ensure a null sem for fence_get_fd to return -1 */
export_sem = VK_NULL_HANDLE;
}
}
if (!batch->has_work) {
if (pfence) {
/* reuse last fence */
@ -3474,6 +3498,7 @@ zink_flush(struct pipe_context *pctx,
}
mfence->fence = fence;
mfence->sem = export_sem;
if (fence)
mfence->submit_count = submit_count;

View file

@ -192,6 +192,32 @@ fence_finish(struct pipe_screen *pscreen, struct pipe_context *pctx,
timeout_ns);
}
static int
fence_get_fd(struct pipe_screen *pscreen, struct pipe_fence_handle *pfence)
{
struct zink_screen *screen = zink_screen(pscreen);
if (screen->device_lost)
return -1;
struct zink_tc_fence *mfence = (struct zink_tc_fence *)pfence;
if (!mfence->sem)
return -1;
const VkSemaphoreGetFdInfoKHR sgfi = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
.semaphore = mfence->sem,
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
};
int fd = -1;
VkResult result = VKSCR(GetSemaphoreFdKHR)(screen->dev, &sgfi, &fd);
if (!zink_screen_handle_vkresult(screen, result)) {
mesa_loge("ZINK: vkGetSemaphoreFdKHR failed (%s)", vk_Result_to_str(result));
return -1;
}
return fd;
}
void
zink_fence_server_signal(struct pipe_context *pctx, struct pipe_fence_handle *pfence)
{
@ -333,4 +359,5 @@ zink_screen_fence_init(struct pipe_screen *pscreen)
{
pscreen->fence_reference = fence_reference;
pscreen->fence_finish = fence_finish;
pscreen->fence_get_fd = fence_get_fd;
}