From 38ac3eb1526c9282cde29549ad838ae31c932259 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Thu, 27 Jan 2022 05:08:24 +0100 Subject: [PATCH] merge multithreading device guards with cached context --- include/vkvg.h | 4 +- src/vkvg_context.c | 42 ++++----------------- src/vkvg_context_internal.c | 26 +++++++++++++ src/vkvg_context_internal.h | 1 + src/vkvg_device.c | 16 ++++---- src/vkvg_device_internal.c | 53 ++++++++++++++++++++------- src/vkvg_device_internal.h | 8 ++-- tests/multithreading/multithreaded.c | 4 +- tests/multithreading/multithreaded2.c | 4 +- 9 files changed, 93 insertions(+), 65 deletions(-) diff --git a/include/vkvg.h b/include/vkvg.h index 8280658..9508823 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -535,9 +535,9 @@ void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy); * Device holds the font cache so that each time a context draws text, the same cache is used. * * @{ */ -typedef void (*vkvg_queue_guard)(void* user_data); +typedef void (*vkvg_device_guard)(void* user_data); vkvg_public -void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data); +void vkvg_device_set_guards (VkvgDevice dev, vkvg_device_guard lock_callback, vkvg_device_guard unlock_callback, void* user_data); /** * @brief Create a new vkvg device. diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 42fc2d3..c7f5faf 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -89,9 +89,9 @@ void _init_ctx (VkvgContext ctx) { VkvgContext vkvg_create(VkvgSurface surf) { VkvgDevice dev = surf->dev; + VkvgContext ctx = NULL; - if (dev->cachedContextCount) { - VkvgContext ctx = dev->cachedContext[--dev->cachedContextCount]; + if (_vkvg_device_try_get_cached_context (dev, &ctx) ) { ctx->pSurf = surf; if (!surf || surf->status) { @@ -106,7 +106,7 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->status = VKVG_STATUS_SUCCESS; return ctx; } - VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); + ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context)); LOG(VKVG_LOG_INFO, "CREATE Context: ctx = %p; surf = %p\n", ctx, surf); @@ -151,9 +151,9 @@ 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); + ctx->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); + ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev); - ctx->flushFence = vkh_fence_create_signaled ((VkhDevice)ctx->dev); _create_vertices_buff (ctx); _create_gradient_buff (ctx); _create_cmd_buff (ctx); @@ -274,7 +274,7 @@ void vkvg_destroy (VkvgContext ctx) if (ctx->pattern) vkvg_pattern_destroy (ctx->pattern); - VkDevice dev = ctx->dev->vkDev; + _clear_context (ctx); #if VKVG_DBG_STATS vkvg_debug_stats_t* dbgstats = &ctx->pSurf->dev->debug_stats; @@ -294,37 +294,11 @@ void vkvg_destroy (VkvgContext ctx) #endif if (!ctx->status && ctx->dev->cachedContextCount < VKVG_MAX_CACHED_CONTEXT_COUNT) { - ctx->dev->cachedContext[ctx->dev->cachedContextCount++] = ctx; - _clear_context (ctx); - ctx->references++; + _vkvg_device_store_context (ctx); return; } - _clear_context (ctx); - _vkvg_device_destroy_fence (ctx->pSurf->dev, ctx->flushFence); - - vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers); - vkDestroyCommandPool(dev, ctx->cmdPool, NULL); - - VkDescriptorSet dss[] = {ctx->dsFont,ctx->dsSrc, ctx->dsGrad}; - vkFreeDescriptorSets (dev, ctx->descriptorPool, 3, dss); - - vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL); - - vkvg_buffer_destroy (&ctx->uboGrad); - vkvg_buffer_destroy (&ctx->indices); - vkvg_buffer_destroy (&ctx->vertices); - - free(ctx->vertexCache); - free(ctx->indexCache); - - //TODO:check this for source counter - //vkh_image_destroy (ctx->source); - - free(ctx->pathes); - free(ctx->points); - - free(ctx); + _release_context_ressources (ctx); } void vkvg_set_opacity (VkvgContext ctx, float opacity) { if (ctx->status) diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index c5880da..4e1cf77 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -852,6 +852,32 @@ void _init_descriptor_sets (VkvgContext ctx){ descriptorSetAllocateInfo.pSetLayouts = &dev->dslGrad; VK_CHECK_RESULT(vkAllocateDescriptorSets(dev->vkDev, &descriptorSetAllocateInfo, &ctx->dsGrad)); } +void _release_context_ressources (VkvgContext ctx) { + VkDevice dev = ctx->dev->vkDev; + _vkvg_device_destroy_fence (ctx->dev, ctx->flushFence); + vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers); + vkDestroyCommandPool(dev, ctx->cmdPool, NULL); + + VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad}; + vkFreeDescriptorSets (dev, ctx->descriptorPool, 3, dss); + + vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL); + + vkvg_buffer_destroy (&ctx->uboGrad); + vkvg_buffer_destroy (&ctx->indices); + vkvg_buffer_destroy (&ctx->vertices); + + free(ctx->vertexCache); + free(ctx->indexCache); + + //TODO:check this for source counter + //vkh_image_destroy (ctx->source); + + free(ctx->pathes); + free(ctx->points); + + free(ctx); +} //populate vertice buff for stroke bool _build_vb_step (vkvg_context* ctx, float hw, stroke_context_t* str, bool isCurve){ Vertex v = {{0},ctx->curColor, {0,0,-1}}; diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index fd219a8..5f5017c 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -311,6 +311,7 @@ void _init_descriptor_sets (VkvgContext ctx); void _update_descriptor_set (VkvgContext ctx, VkhImage img, VkDescriptorSet ds); void _update_gradient_desc_set(VkvgContext ctx); void _free_ctx_save (vkvg_context_save_t* sav); +void _release_context_ressources (VkvgContext ctx); static inline float vec2_zcross (vec2 v1, vec2 v2){ return v1.x*v2.y-v1.y*v2.x; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index a90ea8b..2691d26 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -22,6 +22,7 @@ #include "vkvg_device_internal.h" #include "vkvg_surface_internal.h" +#include "vkvg_context_internal.h" #include "vkh_queue.h" #include "vkh_phyinfo.h" #include "vk_mem_alloc.h" @@ -260,11 +261,8 @@ void vkvg_device_destroy (VkvgDevice dev) if (dev->references > 0) return; - int32_t cachedCtxCount = dev->cachedContextCount; - dev->cachedContextCount = VKVG_MAX_CACHED_CONTEXT_COUNT; - while (cachedCtxCount > 0) { - vkvg_destroy(dev->cachedContext[--cachedCtxCount]); - } + while (dev->cachedContextCount > 0) + _release_context_ressources (dev->cachedContext[--dev->cachedContextCount]); LOG(VKVG_LOG_INFO, "DESTROY Device\n"); @@ -334,10 +332,10 @@ void vkvg_device_get_dpy (VkvgDevice dev, int* hdpy, int* vdpy) { *hdpy = dev->hdpi; *vdpy = dev->vdpi; } -void vkvg_device_set_queue_guards (VkvgDevice dev, vkvg_queue_guard before_submit, vkvg_queue_guard after_submit, void* user_data) { - dev->gQLockGuard = before_submit; - dev->gQUnlockGuard = after_submit; - dev->gQGuardUserData = user_data; +void vkvg_device_set_guards (VkvgDevice dev, vkvg_device_guard lock_callback, vkvg_device_guard unlock_callback, void* user_data) { + dev->deviceLockGuard = lock_callback; + dev->deviceUnlockGuard = unlock_callback; + dev->deviceGuardUserData = user_data; } #if VKVG_DBG_STATS vkvg_debug_stats_t vkvg_device_get_stats (VkvgDevice dev) { diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 38f6e55..5d08bf1 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -428,45 +428,72 @@ void _wait_and_reset_device_fence (VkvgDevice dev) { } void _vkvg_device_destroy_fence (VkvgDevice dev, VkFence fence) { - if (dev->gQLockGuard) - dev->gQLockGuard (dev->gQGuardUserData); + if (dev->deviceLockGuard) + dev->deviceLockGuard (dev->deviceGuardUserData); if (dev->gQLastFence == fence) dev->gQLastFence = VK_NULL_HANDLE; vkDestroyFence (dev->vkDev, fence, NULL); - if (dev->gQUnlockGuard) - dev->gQUnlockGuard (dev->gQGuardUserData); + if (dev->deviceUnlockGuard) + dev->deviceUnlockGuard (dev->deviceGuardUserData); } void _vkvg_device_reset_fence (VkvgDevice dev, VkFence fence){ - if (dev->gQLockGuard) - dev->gQLockGuard (dev->gQGuardUserData); + if (dev->deviceLockGuard) + dev->deviceLockGuard (dev->deviceGuardUserData); if (dev->gQLastFence == fence) dev->gQLastFence = VK_NULL_HANDLE; ResetFences (dev->vkDev, 1, &fence); - if (dev->gQUnlockGuard) - dev->gQUnlockGuard (dev->gQGuardUserData); + if (dev->deviceUnlockGuard) + dev->deviceUnlockGuard (dev->deviceGuardUserData); } -void _vkvg_device_wait_fence (VkvgDevice dev, VkFence fence){ +void _vkvg_device_wait_fence (VkvgDevice dev, VkFence fence){ } void _vkvg_device_wait_and_reset_fence (VkvgDevice dev, VkFence fence){ } +bool _vkvg_device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx) { + if (dev->deviceLockGuard) + dev->deviceLockGuard (dev->deviceGuardUserData); + if (dev->cachedContextCount) + *pCtx = dev->cachedContext[--dev->cachedContextCount]; + else + *pCtx = NULL; + + if (dev->deviceUnlockGuard) + dev->deviceUnlockGuard (dev->deviceGuardUserData); + + return *pCtx != NULL; +} +void _vkvg_device_store_context (VkvgContext ctx) { + VkvgDevice dev = ctx->dev; + + if (dev->deviceLockGuard) + dev->deviceLockGuard (dev->deviceGuardUserData); + + if (dev->gQLastFence == ctx->flushFence) + dev->gQLastFence = VK_NULL_HANDLE; + dev->cachedContext[dev->cachedContextCount++] = ctx; + ctx->references++; + + if (dev->deviceUnlockGuard) + dev->deviceUnlockGuard (dev->deviceGuardUserData); +} void _submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) { - if (dev->gQLockGuard) - dev->gQLockGuard (dev->gQGuardUserData); + if (dev->deviceLockGuard) + dev->deviceLockGuard (dev->deviceGuardUserData); if (dev->gQLastFence != VK_NULL_HANDLE) WaitForFences (dev->vkDev, 1, &dev->gQLastFence, VK_TRUE, VKVG_FENCE_TIMEOUT); vkh_cmd_submit (dev->gQueue, cmd, fence); dev->gQLastFence = fence; - if (dev->gQUnlockGuard) - dev->gQUnlockGuard (dev->gQGuardUserData); + if (dev->deviceUnlockGuard) + dev->deviceUnlockGuard (dev->deviceGuardUserData); } bool _init_function_pointers (VkvgDevice dev) { diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index c702e1c..db2c3d3 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -65,9 +65,9 @@ typedef struct _vkvg_device_t{ VkFormat pngStagFormat; /**< Supported vulkan image format png write staging img */ VkImageTiling pngStagTiling; /**< tiling for the blit operation */ - vkvg_queue_guard gQLockGuard; - vkvg_queue_guard gQUnlockGuard; - void* gQGuardUserData; + vkvg_device_guard deviceLockGuard; + vkvg_device_guard deviceUnlockGuard; + void* deviceGuardUserData; VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ VkFence gQLastFence; @@ -137,4 +137,6 @@ void _vkvg_device_destroy_fence (VkvgDevice dev, VkFence fence); void _vkvg_device_reset_fence (VkvgDevice dev, VkFence fence); void _vkvg_device_wait_fence (VkvgDevice dev, VkFence fence); void _vkvg_device_wait_and_reset_fence (VkvgDevice dev, VkFence fence); +bool _vkvg_device_try_get_cached_context(VkvgDevice dev, VkvgContext* pCtx); +void _vkvg_device_store_context (VkvgContext ctx); #endif diff --git a/tests/multithreading/multithreaded.c b/tests/multithreading/multithreaded.c index 5e6620a..00e1444 100644 --- a/tests/multithreading/multithreaded.c +++ b/tests/multithreading/multithreaded.c @@ -53,7 +53,7 @@ void fixedSizeRects(){ pmutex = &mutex; mtx_init (pgQMutex, mtx_plain); - vkvg_device_set_queue_guards (device, _before_submit, _after_submit, pgQMutex); + vkvg_device_set_guards (device, _before_submit, _after_submit, pgQMutex); thrd_t threads[THREAD_COUNT]; @@ -72,7 +72,7 @@ void fixedSizeRects(){ mtx_destroy (pmutex); pmutex = NULL; - vkvg_device_set_queue_guards (device, NULL, NULL, NULL); + vkvg_device_set_guards (device, NULL, NULL, NULL); mtx_destroy (pgQMutex); pgQMutex = NULL; } diff --git a/tests/multithreading/multithreaded2.c b/tests/multithreading/multithreaded2.c index ab55761..1b79ecb 100644 --- a/tests/multithreading/multithreaded2.c +++ b/tests/multithreading/multithreaded2.c @@ -42,7 +42,7 @@ void fixedSizeRects(){ pmutex = &mutex; mtx_init (pgQMutex, mtx_plain); - vkvg_device_set_queue_guards (device, _before_submit, _after_submit, pgQMutex); + vkvg_device_set_guards (device, _before_submit, _after_submit, pgQMutex); thrd_t threads[THREAD_COUNT]; @@ -61,7 +61,7 @@ void fixedSizeRects(){ mtx_destroy (pmutex); pmutex = NULL; - vkvg_device_set_queue_guards (device, NULL, NULL, NULL); + vkvg_device_set_guards (device, NULL, NULL, NULL); mtx_destroy (pgQMutex); pgQMutex = NULL; } -- 2.47.3