From: Jean-Philippe Bruyère Date: Thu, 11 Oct 2018 14:56:45 +0000 (+0200) Subject: protect graphic queue submissions with mutex X-Git-Tag: v0.1-alpha~107^2~8 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=7f534c43ba735c51ad28957b39ec7f0bdc4d72a8;p=jp%2Fvkvg.git protect graphic queue submissions with mutex --- diff --git a/src/cross_mutex.c b/src/cross_mutex.c new file mode 100644 index 0000000..c8c1cde --- /dev/null +++ b/src/cross_mutex.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018 Jean-Philippe Bruyère + * + * 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 index 0000000..b42c488 --- /dev/null +++ b/src/cross_mutex.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018 Jean-Philippe Bruyère + * + * 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 diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index f80f4a9..33e0433 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -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) diff --git a/src/vkvg_device.c b/src/vkvg_device.c index e89ab9e..d84b929 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -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); } diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 518741e..cca37a6 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -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); +} diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index ea58bf2..bd896a6 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -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; diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 3fdb8f3..aa0135b 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -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; diff --git a/src/vkvg_internal.h b/src/vkvg_internal.h index ca351e3..e1bced2 100644 --- a/src/vkvg_internal.h +++ b/src/vkvg_internal.h @@ -28,5 +28,6 @@ #include #include #include "vectors.h" +#include "cross_mutex.h" #endif diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 75282ce..694895d 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -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);