From 8789e4c138c2833ae90c1394c8665cf7183955f7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Fri, 18 Mar 2022 20:44:23 +0100 Subject: [PATCH] timeline semaphore implementation start for context --- src/vkvg_context.c | 11 ++++++++--- src/vkvg_context_internal.c | 25 +++++++++++++++++++++++++ src/vkvg_context_internal.h | 4 ++++ src/vkvg_device_internal.c | 2 ++ src/vkvg_surface.c | 8 ++++++-- src/vkvg_surface_internal.c | 4 ++++ src/vkvg_surface_internal.h | 6 +++++- vkh | 2 +- 8 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 67e8b1d..a6d4423 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -62,12 +62,12 @@ void _init_ctx (VkvgContext ctx) { ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; ctx->renderPassBeginInfo.pClearValues = clearValues; - if (ctx->pSurf->new) + if (ctx->pSurf->newSurf) ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; else ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; - ctx->pSurf->new = false; + ctx->pSurf->newSurf = false; vkvg_surface_reference (ctx->pSurf); if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT) @@ -83,6 +83,7 @@ void _init_ctx (VkvgContext ctx) { ctx->cmdStarted = false; ctx->curClipState = vkvg_clip_state_none; ctx->vertCount = ctx->indCount = 0; + ctx->timelineStep = 0; } VkvgContext vkvg_create(VkvgSurface surf) @@ -149,7 +150,10 @@ VkvgContext vkvg_create(VkvgSurface surf) //for context to be thread safe, command pool and descriptor pool have to be created in the thread of the context. ctx->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); + +#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev); +#endif _create_vertices_buff (ctx); _create_gradient_buff (ctx); @@ -173,8 +177,9 @@ VkvgContext vkvg_create(VkvgSurface surf) vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)ctx->cmdPool, "CTX Cmd Pool"); vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[0], "CTX Cmd Buff A"); vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)ctx->cmdBuffers[1], "CTX Cmd Buff B"); +#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_FENCE, (uint64_t)ctx->flushFence, "CTX Flush Fence"); - +#endif vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_POOL, (uint64_t)ctx->descriptorPool, "CTX Descriptor Pool"); vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsSrc, "CTX DescSet SOURCE"); vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_DESCRIPTOR_SET, (uint64_t)ctx->dsFont, "CTX DescSet FONT"); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 1b0e301..68684cb 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -420,24 +420,46 @@ void _create_cmd_buff (VkvgContext ctx){ void _clear_attachment (VkvgContext ctx) { } + bool _wait_flush_fence (VkvgContext ctx) { LOG(VKVG_LOG_INFO, "CTX: _wait_flush_fence\n"); +#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + if (vkh_timeline_wait ((VkhDevice)ctx->dev, ctx->pSurf->timeline, ctx->timelineStep) == VK_SUCCESS) + return true; +#else if (WaitForFences (ctx->dev->vkDev, 1, &ctx->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) return true; +#endif LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n"); ctx->status = VKVG_STATUS_TIMEOUT; return false; } + + bool _wait_and_submit_cmd (VkvgContext ctx){ if (!ctx->cmdStarted)//current cmd buff is empty, be aware that wait is also canceled!! return true; LOG(VKVG_LOG_INFO, "CTX: _wait_and_submit_cmd\n"); +#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + VkvgSurface surf = ctx->pSurf; + VkvgDevice dev = surf->dev; + vkh_timeline_wait ((VkhDevice)dev, surf->timeline, surf->timelineStep); + LOCK_SURFACE(surf) + LOCK_DEVICE + vkh_cmd_submit_timelined (dev->gQueue, &ctx->cmd, surf->timeline, surf->timelineStep, surf->timelineStep+1); + surf->timelineStep++; + ctx->timelineStep = surf->timelineStep; + UNLOCK_DEVICE + UNLOCK_SURFACE(surf) +#else + if (!_wait_flush_fence (ctx)) return false; _device_reset_fence(ctx->dev, ctx->flushFence); _device_submit_cmd (ctx->dev, &ctx->cmd, ctx->flushFence); +#endif if (ctx->cmd == ctx->cmdBuffers[0]) ctx->cmd = ctx->cmdBuffers[1]; @@ -866,7 +888,10 @@ void _init_descriptor_sets (VkvgContext ctx){ void _release_context_ressources (VkvgContext ctx) { VkDevice dev = ctx->dev->vkDev; +#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE _device_destroy_fence (ctx->dev, ctx->flushFence); +#endif + vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers); vkDestroyCommandPool(dev, ctx->cmdPool, NULL); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index bd241ec..ee45ca7 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -131,7 +131,11 @@ typedef struct _vkvg_context_t { VkvgDevice dev; VkvgSurface pSurf; //surface bound to context, set on creation of ctx +#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + uint64_t timelineStep; //context cmd last submission timeline id. +#else VkFence flushFence; //context fence +#endif VkhImage source; //source of painting operation VkCommandPool cmdPool; //local pools ensure thread safety diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 86e528b..29709aa 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -455,8 +455,10 @@ void _device_store_context (VkvgContext ctx) { LOCK_DEVICE +#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE if (dev->gQLastFence == ctx->flushFence) dev->gQLastFence = VK_NULL_HANDLE; +#endif dev->cachedContext[dev->cachedContextCount++] = ctx; ctx->references++; diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 05dc8dd..76b4dbc 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -42,7 +42,7 @@ VkvgSurface vkvg_surface_create (VkvgDevice dev, uint32_t width, uint32_t height surf->width = MAX(1, width); surf->height = MAX(1, height); - surf->new = true;//used to clear all attacments on first render pass + surf->newSurf = true;//used to clear all attacments on first render pass _create_surface_images (surf); @@ -156,7 +156,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vkvg_buffer_destroy (&buff); vkh_image_destroy (stagImg); - surf->new = false; + surf->newSurf = false; //create tmp context with rendering pipeline to create the multisample img VkvgContext ctx = vkvg_create (surf); @@ -223,6 +223,10 @@ void vkvg_surface_destroy(VkvgSurface surf) if (surf->dev->threadAware) mtx_destroy (&surf->mutex); +#if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + vkDestroySemaphore (surf->dev->vkDev, surf->timeline, NULL); +#endif + vkvg_device_destroy (surf->dev); free(surf); } diff --git a/src/vkvg_surface_internal.c b/src/vkvg_surface_internal.c index ffa5983..8c575c3 100644 --- a/src/vkvg_surface_internal.c +++ b/src/vkvg_surface_internal.c @@ -186,5 +186,9 @@ VkvgSurface _create_surface (VkvgDevice dev, VkFormat format) { surf->format = format; if (dev->threadAware) mtx_init (&surf->mutex, mtx_plain); + +#if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + surf->timeline = vkh_timeline_create ((VkhDevice)dev, 0); +#endif return surf; } diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index 79b64e3..0b52d4b 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -37,8 +37,12 @@ typedef struct _vkvg_surface_t { VkhImage img; VkhImage imgMS; VkhImage stencil; - bool new; + bool newSurf; mtx_t mutex; +#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE + VkSemaphore timeline; /**< Timeline semaphore */ + uint64_t timelineStep; +#endif }vkvg_surface; #define LOCK_SURFACE(surf) \ diff --git a/vkh b/vkh index 2a19489..16a129f 160000 --- a/vkh +++ b/vkh @@ -1 +1 @@ -Subproject commit 2a194890dfed6eb82d3a92fd56ecc46f47735d29 +Subproject commit 16a129f586060d7bd2608989e9b70242d0e6d023 -- 2.47.3