]> O.S.I.I.S - jp/vkvg.git/commitdiff
protect graphic queue submissions with mutex
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 11 Oct 2018 14:56:45 +0000 (16:56 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 11 Oct 2018 14:56:45 +0000 (16:56 +0200)
src/cross_mutex.c [new file with mode: 0644]
src/cross_mutex.h [new file with mode: 0644]
src/vkvg_context_internal.c
src/vkvg_device.c
src/vkvg_device_internal.c
src/vkvg_device_internal.h
src/vkvg_fonts.c
src/vkvg_internal.h
src/vkvg_surface.c

diff --git a/src/cross_mutex.c b/src/cross_mutex.c
new file mode 100644 (file)
index 0000000..c8c1cde
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "cross_mutex.h"
+
+int MUTEX_INIT(MUTEX *mutex)
+{
+#ifdef _WIN32
+    *mutex = CreateMutex(0, FALSE, 0);;
+    return (*mutex==0);
+#elif __APPLE__
+#elif __unix__
+    return pthread_mutex_init (mutex, NULL);
+#endif
+    return -1;
+}
+
+int MUTEX_LOCK(MUTEX *mutex)
+{
+#ifdef _WIN32
+    return (WaitForSingleObject(*mutex, INFINITE)==WAIT_FAILED?1:0);
+#elif __APPLE__
+#elif __unix__
+    return pthread_mutex_lock( mutex );
+#endif
+    return -1;
+}
+
+int MUTEX_UNLOCK(MUTEX *mutex)
+{
+#ifdef _WIN32
+    return (ReleaseMutex(*mutex)==0);
+#elif __APPLE__
+#elif __unix__
+    return pthread_mutex_unlock( mutex );
+#endif
+    return -1;
+}
+
+int MUTEX_DESTROY(MUTEX *mutex)
+{
+#ifdef _WIN32
+    return (CloseHandle(*mutex)==0);
+#elif __APPLE__
+#elif __unix__
+    return pthread_mutex_destroy(mutex);
+#endif
+    return -1;
+}
diff --git a/src/cross_mutex.h b/src/cross_mutex.h
new file mode 100644 (file)
index 0000000..b42c488
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef CROSS_MUTEX_H
+#define CROSS_MUTEX_H
+
+//cross platform mutex
+#ifdef _WIN32
+#include "windows.h"
+#include "process.h"
+#define MUTEX HANDLE
+#elif __APPLE__
+#elif __unix__
+#include "pthread.h"
+#define MUTEX pthread_mutex_t
+#endif
+
+int MUTEX_INIT(MUTEX *mutex);
+int MUTEX_LOCK(MUTEX *mutex);
+int MUTEX_UNLOCK(MUTEX *mutex);
+int MUTEX_DESTROY(MUTEX *mutex);
+
+#endif // CROSS_MUTEX_H
index f80f4a9fd71a3492a97d3537d7f30d9e1568aef1..33e04338fb887f0228a975e3d2f418c80e9d86c0 100644 (file)
@@ -196,7 +196,7 @@ void _clear_attachment (VkvgContext ctx) {
 
 }
 inline void _submit_ctx_cmd(VkvgContext ctx){
-    vkh_cmd_submit (ctx->pSurf->dev->gQueue, &ctx->cmd, ctx->flushFence);
+    _submit_cmd (ctx->pSurf->dev, &ctx->cmd, ctx->flushFence);
 }
 void _wait_and_reset_ctx_cmd (VkvgContext ctx){
     if (!ctx->cmdStarted)
index e89ab9e934a4628431bccea51e897485ddf90dc0..d84b929bf86c22fc939a84a3b7f492ed058756bc 100644 (file)
@@ -49,11 +49,13 @@ VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vk
     CmdSetViewport          = vkGetInstanceProcAddr(inst, "vkCmdSetViewport");
     CmdSetScissor           = vkGetInstanceProcAddr(inst, "vkCmdSetScissor");
     CmdPushConstants        = vkGetInstanceProcAddr(inst, "vkCmdPushConstants");
+    CmdPushDescriptorSet    = vkGetInstanceProcAddr(inst, "vkCmdDescriptorSet");
 
     VkhPhyInfo phyInfos = vkh_phyinfo_create (dev->phy, NULL);
 
     dev->phyMemProps = phyInfos->memProps;
     dev->gQueue = vkh_queue_create (dev, qFamIdx, qIndex, phyInfos->queues[qFamIdx].queueFlags);
+    MUTEX_INIT (&dev->gQMutex);
 
     vkh_phyinfo_destroy (phyInfos);
 
@@ -118,6 +120,8 @@ void vkvg_device_destroy (VkvgDevice dev)
 
     vmaDestroyAllocator (dev->allocator);
 
+    MUTEX_DESTROY (dev->gQMutex);
+
     free(dev);
 }
 
index 518741e53fa2348285682dd7cea74846cb3d2996..cca37a6f9680ffc5796468199fa85c2f3dd7277e 100644 (file)
@@ -304,3 +304,9 @@ void _wait_and_reset_device_fence (VkvgDevice dev) {
     vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
     vkResetFences (dev->vkDev, 1, &dev->fence);
 }
+
+void _submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) {
+    MUTEX_LOCK (&dev->gQMutex);
+    vkh_cmd_submit (dev->gQueue, cmd, fence);
+    MUTEX_UNLOCK (&dev->gQMutex);
+}
index ea58bf2623093ea155790c1f8a3c511e61095b9e..bd896a63b7df25b1d99d732a9a1e7505fd6ba942 100644 (file)
@@ -45,6 +45,7 @@ PFN_vkCmdSetViewport            CmdSetViewport;
 PFN_vkCmdSetScissor             CmdSetScissor;
 
 PFN_vkCmdPushConstants          CmdPushConstants;
+PFN_vkCmdPushDescriptorSetKHR   CmdPushDescriptorSet;
 
 
 typedef struct _vkvg_device_t{
@@ -54,6 +55,7 @@ typedef struct _vkvg_device_t{
     VmaAllocator            allocator;
 
     VkhQueue                gQueue;
+    MUTEX                   gQMutex;//queue submission has to be externally syncronized
     VkRenderPass                       renderPass;
 
     uint32_t                references;
index 3fdb8f3b198a2e814ed7ca15f203b54f07b144b3..aa0135bd1b7e18ca15fe047ddb708982bbe16b82 100644 (file)
@@ -98,7 +98,7 @@ void _increase_font_tex_array (VkvgDevice dev){
 
     VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
 
-    vkh_cmd_submit      (dev->gQueue, &cache->cmd, cache->uploadFence);
+    _submit_cmd         (dev, &cache->cmd, cache->uploadFence);
     vkWaitForFences     (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
 
     _flush_all_contexes (dev);
@@ -219,7 +219,7 @@ void _flush_chars_to_tex (VkvgDevice dev, _vkvg_font_t* f) {
 
     VK_CHECK_RESULT(vkEndCommandBuffer(cache->cmd));
 
-    vkh_cmd_submit(dev->gQueue,&cache->cmd,cache->uploadFence);
+    _submit_cmd (dev, &cache->cmd, cache->uploadFence);
 
     f->curLine.penX += cache->stagingX;
     cache->stagingX = 0;
index ca351e314c1f89ad506bb050160e259c9e5661b9..e1bced2df81c0830a6e495fa622c11fa29dbba4b 100644 (file)
@@ -28,5 +28,6 @@
 #include <stdint.h>
 #include <stdbool.h>
 #include "vectors.h"
+#include "cross_mutex.h"
 
 #endif
index 75282ceb8d297d4afce9395347576af8a3124291..694895d1d15a40ea003f92a5a3574fa5608e19ca 100644 (file)
@@ -70,7 +70,7 @@ void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect)
     }
     vkh_cmd_end (cmd);
 
-    vkh_cmd_submit (dev->gQueue, &cmd, dev->fence);
+    _submit_cmd (dev, &cmd, dev->fence);
 }
 
 void _init_surface (VkvgSurface surf) {
@@ -105,10 +105,6 @@ void _init_surface (VkvgSurface surf) {
 void vkvg_surface_clear (VkvgSurface surf) {
     _clear_surface(surf, VK_IMAGE_ASPECT_STENCIL_BIT|VK_IMAGE_ASPECT_COLOR_BIT);
 }
-
-void vkvg_surface_test (VkvgSurface* pSurf, VkvgSurface surf) {
-    pSurf = &surf;
-}
 VkvgSurface vkvg_surface_create(VkvgDevice dev, uint32_t width, uint32_t height){
     VkvgSurface surf = (vkvg_surface*)calloc(1,sizeof(vkvg_surface));
 
@@ -190,7 +186,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img,
                           VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 
     vkh_cmd_end     (cmd);
-    vkh_cmd_submit  (dev->gQueue, &cmd, dev->fence);
+    _submit_cmd     (dev, &cmd, dev->fence);
 
     //don't reset fence after completion as this is the last cmd. (signaled idle fence)
     vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
@@ -309,7 +305,7 @@ void vkvg_surface_write_to_png (VkvgSurface surf, const char* path){
                      vkh_image_get_vkimage (stagImg),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
 
     vkh_cmd_end     (cmd);
-    vkh_cmd_submit  (dev->gQueue, &cmd, dev->fence);
+    _submit_cmd     (dev, &cmd, dev->fence);
     vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
 
     void* img = vkh_image_map (stagImg);