summaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-03-21 13:43:16 +0100
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2022-03-21 13:43:16 +0100
commit1502ac263b56502f1fe4287cc4ab1bf848f12a37 (patch)
tree2a6c1158c8748ca9c4e73d7fb13056b1bbc7a8ef
parentbc2133d685c35ff2041aef072fcf6efb2317321c (diff)
parenta5d0d810d6e07383ac0fe44a554b9733dc41d871 (diff)
threaded context cache merge
-rw-r--r--include/vkvg.h13
-rw-r--r--src/vkvg_context.c6
-rw-r--r--src/vkvg_device.c35
-rw-r--r--src/vkvg_device_internal.c42
-rw-r--r--src/vkvg_device_internal.h15
-rw-r--r--tests/multithreading/multithreaded.c2
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;