diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2022-03-21 13:43:16 +0100 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2022-03-21 13:43:16 +0100 |
| commit | 1502ac263b56502f1fe4287cc4ab1bf848f12a37 (patch) | |
| tree | 2a6c1158c8748ca9c4e73d7fb13056b1bbc7a8ef | |
| parent | bc2133d685c35ff2041aef072fcf6efb2317321c (diff) | |
| parent | a5d0d810d6e07383ac0fe44a554b9733dc41d871 (diff) | |
threaded context cache merge
| -rw-r--r-- | include/vkvg.h | 13 | ||||
| -rw-r--r-- | src/vkvg_context.c | 6 | ||||
| -rw-r--r-- | src/vkvg_device.c | 35 | ||||
| -rw-r--r-- | src/vkvg_device_internal.c | 42 | ||||
| -rw-r--r-- | src/vkvg_device_internal.h | 15 | ||||
| -rw-r--r-- | tests/multithreading/multithreaded.c | 2 |
6 files changed, 96 insertions, 17 deletions
diff --git a/include/vkvg.h b/include/vkvg.h index 7313bd3..27f562c 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -88,6 +88,7 @@ extern "C" { #define VKVG_LOG_INFO_VBO 0x00000020 #define VKVG_LOG_INFO_IBO 0x00000040 #define VKVG_LOG_INFO_VAO (VKVG_LOG_INFO_VBO|VKVG_LOG_INFO_IBO) +#define VKVG_LOG_THREAD 0x00000080 #define VKVG_LOG_DBG_ARRAYS 0x00001000 #define VKVG_LOG_STROKE 0x00010000 #define VKVG_LOG_FULL 0xffffffff @@ -548,7 +549,17 @@ void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy); */ vkvg_public void vkvg_device_set_thread_aware (VkvgDevice dev, uint32_t thread_awayre); - +vkvg_public +/** + * @brief Set maximum cached context count. + * + * The context cache stored destroyed contexts per thread to speed-up new context creation. + * To disable context cache, call this method with maxCount=0. + * + * @param dev A valid vkvg device pointer. + * @param maxCount The maximum count of saved contexts for fast context instanciation. + */ +void vkvg_device_set_context_cache_size (VkvgDevice dev, uint32_t maxCount); /** * @brief Create a new vkvg device. * diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 1fd8078..262cedb 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -62,12 +62,16 @@ void _init_ctx (VkvgContext ctx) { ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height; ctx->renderPassBeginInfo.pClearValues = clearValues; + LOCK_SURFACE (ctx->pSurf) + if (ctx->pSurf->newSurf) ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; else ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; - ctx->pSurf->newSurf = false; + + UNLOCK_SURFACE (ctx->pSurf); + vkvg_surface_reference (ctx->pSurf); if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT) diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 1527cda..adb8abe 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -31,6 +31,22 @@ if (vkh_phyinfo_try_get_extension_properties(pi, #ext, NULL)) \ enabledExts[enabledExtsCount++] = #ext; \ } +void vkvg_device_set_context_cache_size (VkvgDevice dev, uint32_t maxCount) { + if (maxCount == dev->cachedContextMaxCount) + return; + + dev->cachedContextMaxCount = maxCount; + + _cached_ctx* cur = dev->cachedContextLast; + while (cur && dev->cachedContextCount > dev->cachedContextMaxCount) { + _release_context_ressources (cur->ctx); + _cached_ctx* prev = cur; + cur = cur->pNext; + free (prev); + dev->cachedContextCount--; + } + dev->cachedContextLast = cur; +} void _device_init (VkvgDevice dev, VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve) { dev->instance = inst; dev->hdpi = 72; @@ -43,6 +59,8 @@ void _device_init (VkvgDevice dev, VkInstance inst, VkPhysicalDevice phy, VkDevi dev->vkDev = vkdev; dev->phy = phy; + dev->cachedContextMaxCount = VKVG_MAX_CACHED_CONTEXT_COUNT; + #if VKVG_DBG_STATS dev->debug_stats = (vkvg_debug_stats_t) {0}; #endif @@ -249,7 +267,7 @@ const void* vkvg_get_device_requirements (VkPhysicalDeviceFeatures* pEnabledFeat } -VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve) { +VkvgDevice vkvg_device_create (VkSampleCountFlags samples, bool deferredResolve) { LOG(VKVG_LOG_INFO, "CREATE Device\n"); VkvgDevice dev = (vkvg_device*)calloc(1,sizeof(vkvg_device)); if (!dev) { @@ -380,11 +398,22 @@ void vkvg_device_destroy (VkvgDevice dev) } UNLOCK_DEVICE - while (dev->cachedContextCount > 0) - _release_context_ressources (dev->cachedContext[--dev->cachedContextCount]); + + if (dev->cachedContextCount > 0) { + _cached_ctx* cur = dev->cachedContextLast; + while (cur) { + _release_context_ressources (cur->ctx); + _cached_ctx* prev = cur; + cur = cur->pNext; + free (prev); + } + } + LOG(VKVG_LOG_INFO, "DESTROY Device\n"); + vkDeviceWaitIdle (dev->vkDev); + vkh_image_destroy (dev->emptyImg); vkDestroyDescriptorSetLayout (dev->vkDev, dev->dslGrad,NULL); diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 6096297..ab37f2d 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -421,21 +421,49 @@ void _device_wait_and_reset_device_fence (VkvgDevice dev) { bool _device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx) { LOCK_DEVICE - if (dev->cachedContextCount) - *pCtx = dev->cachedContext[--dev->cachedContextCount]; - else - *pCtx = NULL; + if (dev->cachedContextCount) { + thrd_t curThread = thrd_current (); + _cached_ctx* prev = NULL; + _cached_ctx* cur = dev->cachedContextLast; + while (cur) { + if (thrd_equal (cur->thread, curThread)) { + if (prev) + prev->pNext = cur->pNext; + else + dev->cachedContextLast = cur->pNext; - UNLOCK_DEVICE + dev->cachedContextCount--; + + LOG(VKVG_LOG_THREAD,"get cached context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount); - return *pCtx != NULL; + *pCtx = cur->ctx; + free (cur); + UNLOCK_DEVICE + return true; + } + prev = cur; + cur = cur->pNext; + } + } + *pCtx = NULL; + UNLOCK_DEVICE + return false; } void _device_store_context (VkvgContext ctx) { VkvgDevice dev = ctx->dev; LOCK_DEVICE - dev->cachedContext[dev->cachedContextCount++] = ctx; + _cached_ctx* cur = (_cached_ctx*)calloc(1, sizeof(_cached_ctx)); + cur->ctx = ctx; + cur->thread = thrd_current (); + cur->pNext = dev->cachedContextLast; + + dev->cachedContextLast = cur; + dev->cachedContextCount++; + + LOG(VKVG_LOG_THREAD,"store context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount); + ctx->references++; UNLOCK_DEVICE diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index b282094..5503d17 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -30,7 +30,7 @@ #define STENCIL_CLIP_BIT 0x2 #define STENCIL_ALL_BIT 0x3 -#define VKVG_MAX_CACHED_CONTEXT_COUNT 2 +#define VKVG_MAX_CACHED_CONTEXT_COUNT 36 extern PFN_vkCmdBindPipeline CmdBindPipeline; extern PFN_vkCmdBindDescriptorSets CmdBindDescriptorSets; @@ -53,7 +53,13 @@ extern PFN_vkWaitForFences WaitForFences; extern PFN_vkResetFences ResetFences; extern PFN_vkResetCommandBuffer ResetCommandBuffer; -typedef struct _vkvg_device_t{ +typedef struct _cached_ctx{ + thrd_t thread; + VkvgContext ctx; + struct _cached_ctx* pNext; +} _cached_ctx; + +typedef struct _vkvg_device_t { VkDevice vkDev; /**< Vulkan Logical Device */ VkPhysicalDeviceMemoryProperties phyMemProps; /**< Vulkan Physical device memory properties */ VkPhysicalDevice phy; /**< Vulkan Physical device */ @@ -105,8 +111,9 @@ typedef struct _vkvg_device_t{ VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/ - int32_t cachedContextCount; - VkvgContext cachedContext[VKVG_MAX_CACHED_CONTEXT_COUNT]; + int32_t cachedContextMaxCount; /**< Maximum context cache element count.*/ + int32_t cachedContextCount; /**< Current context cache element count.*/ + _cached_ctx* cachedContextLast; /**< Last element of single linked list of saved context for fast reuse.*/ #ifdef VKVG_WIRED_DEBUG VkPipeline pipelineWired; diff --git a/tests/multithreading/multithreaded.c b/tests/multithreading/multithreaded.c index 4981860..05ee038 100644 --- a/tests/multithreading/multithreaded.c +++ b/tests/multithreading/multithreaded.c @@ -5,7 +5,7 @@ #include "test.h" #include "tinycthread.h" -#define THREAD_COUNT 64 +#define THREAD_COUNT 32 static int finishedThreadCount = 0; |