--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
}
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)
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);
vmaDestroyAllocator (dev->allocator);
+ MUTEX_DESTROY (dev->gQMutex);
+
free(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);
+}
PFN_vkCmdSetScissor CmdSetScissor;
PFN_vkCmdPushConstants CmdPushConstants;
+PFN_vkCmdPushDescriptorSetKHR CmdPushDescriptorSet;
typedef struct _vkvg_device_t{
VmaAllocator allocator;
VkhQueue gQueue;
+ MUTEX gQMutex;//queue submission has to be externally syncronized
VkRenderPass renderPass;
uint32_t references;
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);
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;
#include <stdint.h>
#include <stdbool.h>
#include "vectors.h"
+#include "cross_mutex.h"
#endif
}
vkh_cmd_end (cmd);
- vkh_cmd_submit (dev->gQueue, &cmd, dev->fence);
+ _submit_cmd (dev, &cmd, dev->fence);
}
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));
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);
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);