summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-03-04 07:48:04 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-03-04 07:48:04 +0100
commita5d0d810d6e07383ac0fe44a554b9733dc41d871 (patch)
tree4b91a350291526e210c4e76f94721e97e6e5ce8f
parentbec95371279ff65a3fecd5fda10464d91c311048 (diff)
store context in device context cache per thread
-rw-r--r--include/vkvg.h13
-rw-r--r--src/vkvg_context.c5
-rw-r--r--src/vkvg_context_internal.c2
-rw-r--r--src/vkvg_device.c35
-rw-r--r--src/vkvg_device_internal.c45
-rw-r--r--src/vkvg_device_internal.h15
6 files changed, 99 insertions, 16 deletions
diff --git a/include/vkvg.h b/include/vkvg.h
index c38b59f..769a330 100644
--- a/include/vkvg.h
+++ b/include/vkvg.h
@@ -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.
*
diff --git a/src/vkvg_context.c b/src/vkvg_context.c
index 6e5d125..dfcd76e 100644
--- a/src/vkvg_context.c
+++ b/src/vkvg_context.c
@@ -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)
diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c
index 415037a..2eb20d3 100644
--- a/src/vkvg_context_internal.c
+++ b/src/vkvg_context_internal.c
@@ -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);
diff --git a/src/vkvg_device.c b/src/vkvg_device.c
index 4a266cc..eb50287 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;
@@ -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);
diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c
index cbec2c4..87784c2 100644
--- a/src/vkvg_device_internal.c
+++ b/src/vkvg_device_internal.c
@@ -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;
- 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;
@@ -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
diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h
index f776880..eba61a1 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 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;