]> O.S.I.I.S - jp/vkvg.git/commitdiff
store context in device context cache per thread 105/head
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 4 Mar 2022 06:48:04 +0000 (07:48 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 4 Mar 2022 06:48:04 +0000 (07:48 +0100)
include/vkvg.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_device.c
src/vkvg_device_internal.c
src/vkvg_device_internal.h

index c38b59f98450ea5f72e82eebac3597ddede20fe3..769a330c31ffa342c0d2fddbbb7724660b3160a7 100644 (file)
@@ -89,6 +89,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_FULL          0xffffffff
 
@@ -553,7 +554,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.
  *
index 6e5d125fe440baa6ac58cc3bb6bf37b90870eca2..dfcd76eb7c4ad31cc54a21d804703fd980eb712b 100644 (file)
@@ -62,12 +62,17 @@ void _init_ctx (VkvgContext ctx) {
        ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height;
        ctx->renderPassBeginInfo.pClearValues = clearValues;
 
+       LOCK_SURFACE (ctx->pSurf)
+
        if (ctx->pSurf->new)
                ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll;
        else
                ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil;
 
        ctx->pSurf->new = false;
+
+       UNLOCK_SURFACE (ctx->pSurf);
+
        vkvg_surface_reference (ctx->pSurf);
 
        if (ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT)
index 415037a3aae6d8631c20676a1e65f890f4bd880a..2eb20d325315ff91091ad5fe1eb8e16d5cd03c4f 100644 (file)
@@ -873,7 +873,7 @@ void _release_context_ressources (VkvgContext ctx) {
        VkDescriptorSet dss[] = {ctx->dsFont, ctx->dsSrc, ctx->dsGrad};
        vkFreeDescriptorSets    (dev, ctx->descriptorPool, 3, dss);
 
-       vkDestroyDescriptorPool (dev, ctx->descriptorPool,NULL);
+       vkDestroyDescriptorPool (dev, ctx->descriptorPool, NULL);
 
        vkvg_buffer_destroy (&ctx->uboGrad);
        vkvg_buffer_destroy (&ctx->indices);
index 4a266cc90ae8dc541f41d7c17e24782e578baeb9..eb50287b90368b44148faac2b8a23b5d81edb4e5 100644 (file)
 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;
@@ -40,6 +56,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
@@ -205,7 +223,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) {
@@ -337,11 +355,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);
index cbec2c488b899073fbcd29dff25503e0b979100d..87784c2227d49ecf20564f9b6f7e7138508ebbf2 100644 (file)
@@ -414,8 +414,10 @@ void _device_wait_idle (VkvgDevice dev) {
        vkDeviceWaitIdle (dev->vkDev);
 }
 void _device_wait_and_reset_device_fence (VkvgDevice dev) {
+       LOCK_DEVICE
        vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
        _device_reset_fence(dev, dev->fence);
+       UNLOCK_DEVICE
 }
 
 void _device_destroy_fence (VkvgDevice dev, VkFence fence) {
@@ -441,14 +443,33 @@ void _device_reset_fence (VkvgDevice dev, VkFence fence){
 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;
+
+                               dev->cachedContextCount--;
+
+                               LOG(VKVG_LOG_THREAD,"get cached context: %p, thd:%lu cached ctx: %d\n", cur->ctx, cur->thread, dev->cachedContextCount);
+
+                               *pCtx = cur->ctx;
+                               free (cur);
+                               UNLOCK_DEVICE
+                               return true;
+                       }
+                       prev = cur;
+                       cur = cur->pNext;
+               }
+       }
+       *pCtx = NULL;
        UNLOCK_DEVICE
-
-       return *pCtx != NULL;
+       return false;
 }
 void _device_store_context (VkvgContext ctx) {
        VkvgDevice dev = ctx->dev;
@@ -457,7 +478,17 @@ void _device_store_context (VkvgContext ctx) {
 
        if (dev->gQLastFence == ctx->flushFence)
                dev->gQLastFence = VK_NULL_HANDLE;
-       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
index f776880a3d35e21197a040abd87c6b9d3bc2b2a9..eba61a177c9f2513f1696810edd7eb1a9564cea8 100644 (file)
@@ -30,7 +30,7 @@
 #define STENCIL_CLIP_BIT       0x2
 #define STENCIL_ALL_BIT                0x3
 
-#define VKVG_MAX_CACHED_CONTEXT_COUNT 0
+#define VKVG_MAX_CACHED_CONTEXT_COUNT 2
 
 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 */
@@ -106,8 +112,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;