forked from MoonsideGames/Refresh
fix separate swapchain synchronization
parent
829356d927
commit
b54b7cc42d
|
@ -745,6 +745,10 @@ typedef struct VulkanSwapchainData
|
||||||
VkImageView *views;
|
VkImageView *views;
|
||||||
VulkanResourceAccessType *resourceAccessTypes;
|
VulkanResourceAccessType *resourceAccessTypes;
|
||||||
uint32_t imageCount;
|
uint32_t imageCount;
|
||||||
|
|
||||||
|
/* Synchronization primitives */
|
||||||
|
VkSemaphore imageAvailableSemaphore;
|
||||||
|
VkSemaphore renderFinishedSemaphore;
|
||||||
} VulkanSwapchainData;
|
} VulkanSwapchainData;
|
||||||
|
|
||||||
typedef struct SwapChainSupportDetails
|
typedef struct SwapChainSupportDetails
|
||||||
|
@ -1353,10 +1357,6 @@ typedef struct VulkanRenderer
|
||||||
|
|
||||||
Refresh_PresentMode presentMode;
|
Refresh_PresentMode presentMode;
|
||||||
|
|
||||||
VkSemaphore transferFinishedSemaphore;
|
|
||||||
VkSemaphore imageAvailableSemaphore;
|
|
||||||
VkSemaphore renderFinishedSemaphore;
|
|
||||||
|
|
||||||
VkFence *availableFences;
|
VkFence *availableFences;
|
||||||
uint32_t availableFenceCount;
|
uint32_t availableFenceCount;
|
||||||
uint32_t availableFenceCapacity;
|
uint32_t availableFenceCapacity;
|
||||||
|
@ -2627,6 +2627,18 @@ static void VULKAN_INTERNAL_DestroySwapchain(
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
renderer->vkDestroySemaphore(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
swapchainData->imageAvailableSemaphore,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->vkDestroySemaphore(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
swapchainData->renderFinishedSemaphore,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
for (i = 0; i < renderer->swapchainDataCount; i += 1)
|
for (i = 0; i < renderer->swapchainDataCount; i += 1)
|
||||||
{
|
{
|
||||||
if (windowHandle == renderer->swapchainDatas[i]->windowHandle)
|
if (windowHandle == renderer->swapchainDatas[i]->windowHandle)
|
||||||
|
@ -4188,7 +4200,8 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
|
||||||
VkResult vulkanResult;
|
VkResult vulkanResult;
|
||||||
VulkanSwapchainData *swapchainData;
|
VulkanSwapchainData *swapchainData;
|
||||||
VkSwapchainCreateInfoKHR swapchainCreateInfo;
|
VkSwapchainCreateInfoKHR swapchainCreateInfo;
|
||||||
VkImageViewCreateInfo createInfo;
|
VkImageViewCreateInfo imageViewCreateInfo;
|
||||||
|
VkSemaphoreCreateInfo semaphoreCreateInfo;
|
||||||
SwapChainSupportDetails swapchainSupportDetails;
|
SwapChainSupportDetails swapchainSupportDetails;
|
||||||
int32_t drawableWidth, drawableHeight;
|
int32_t drawableWidth, drawableHeight;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -4488,25 +4501,25 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
|
||||||
swapchainData->images
|
swapchainData->images
|
||||||
);
|
);
|
||||||
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
|
||||||
createInfo.pNext = NULL;
|
imageViewCreateInfo.pNext = NULL;
|
||||||
createInfo.flags = 0;
|
imageViewCreateInfo.flags = 0;
|
||||||
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||||
createInfo.format = swapchainData->surfaceFormat.format;
|
imageViewCreateInfo.format = swapchainData->surfaceFormat.format;
|
||||||
createInfo.components = swapchainData->swapchainSwizzle;
|
imageViewCreateInfo.components = swapchainData->swapchainSwizzle;
|
||||||
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
imageViewCreateInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
createInfo.subresourceRange.baseMipLevel = 0;
|
imageViewCreateInfo.subresourceRange.baseMipLevel = 0;
|
||||||
createInfo.subresourceRange.levelCount = 1;
|
imageViewCreateInfo.subresourceRange.levelCount = 1;
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
imageViewCreateInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
imageViewCreateInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
for (i = 0; i < swapchainData->imageCount; i += 1)
|
for (i = 0; i < swapchainData->imageCount; i += 1)
|
||||||
{
|
{
|
||||||
createInfo.image = swapchainData->images[i];
|
imageViewCreateInfo.image = swapchainData->images[i];
|
||||||
|
|
||||||
vulkanResult = renderer->vkCreateImageView(
|
vulkanResult = renderer->vkCreateImageView(
|
||||||
renderer->logicalDevice,
|
renderer->logicalDevice,
|
||||||
&createInfo,
|
&imageViewCreateInfo,
|
||||||
NULL,
|
NULL,
|
||||||
&swapchainData->views[i]
|
&swapchainData->views[i]
|
||||||
);
|
);
|
||||||
|
@ -4529,6 +4542,24 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
|
||||||
swapchainData->resourceAccessTypes[i] = RESOURCE_ACCESS_NONE;
|
swapchainData->resourceAccessTypes[i] = RESOURCE_ACCESS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
semaphoreCreateInfo.pNext = NULL;
|
||||||
|
semaphoreCreateInfo.flags = 0;
|
||||||
|
|
||||||
|
renderer->vkCreateSemaphore(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
&semaphoreCreateInfo,
|
||||||
|
NULL,
|
||||||
|
&swapchainData->imageAvailableSemaphore
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer->vkCreateSemaphore(
|
||||||
|
renderer->logicalDevice,
|
||||||
|
&semaphoreCreateInfo,
|
||||||
|
NULL,
|
||||||
|
&swapchainData->renderFinishedSemaphore
|
||||||
|
);
|
||||||
|
|
||||||
SDL_SetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData);
|
SDL_SetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA, swapchainData);
|
||||||
|
|
||||||
if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity)
|
if (renderer->swapchainDataCount >= renderer->swapchainDataCapacity)
|
||||||
|
@ -4650,24 +4681,6 @@ static void VULKAN_DestroyDevice(
|
||||||
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyFragmentUniformBuffer->vulkanBuffer);
|
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyFragmentUniformBuffer->vulkanBuffer);
|
||||||
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyComputeUniformBuffer->vulkanBuffer);
|
VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyComputeUniformBuffer->vulkanBuffer);
|
||||||
|
|
||||||
renderer->vkDestroySemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
renderer->transferFinishedSemaphore,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
renderer->vkDestroySemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
renderer->imageAvailableSemaphore,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
renderer->vkDestroySemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
renderer->renderFinishedSemaphore,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
for (i = 0; i < renderer->availableFenceCount; i += 1)
|
for (i = 0; i < renderer->availableFenceCount; i += 1)
|
||||||
{
|
{
|
||||||
renderer->vkDestroyFence(
|
renderer->vkDestroyFence(
|
||||||
|
@ -8565,7 +8578,7 @@ static void VULKAN_QueuePresent(
|
||||||
renderer->logicalDevice,
|
renderer->logicalDevice,
|
||||||
swapchainData->swapchain,
|
swapchainData->swapchain,
|
||||||
UINT64_MAX,
|
UINT64_MAX,
|
||||||
renderer->imageAvailableSemaphore,
|
swapchainData->imageAvailableSemaphore,
|
||||||
VK_NULL_HANDLE,
|
VK_NULL_HANDLE,
|
||||||
&swapchainImageIndex
|
&swapchainImageIndex
|
||||||
);
|
);
|
||||||
|
@ -8668,7 +8681,7 @@ static void VULKAN_INTERNAL_ResetCommandBuffer(
|
||||||
commandPool->inactiveCommandBufferCount += 1;
|
commandPool->inactiveCommandBufferCount += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fence management */
|
/* Synchronization management */
|
||||||
|
|
||||||
static VkFence VULKAN_INTERNAL_AcquireFence(
|
static VkFence VULKAN_INTERNAL_AcquireFence(
|
||||||
VulkanRenderer *renderer
|
VulkanRenderer *renderer
|
||||||
|
@ -8777,56 +8790,74 @@ static void VULKAN_Submit(
|
||||||
Refresh_CommandBuffer **pCommandBuffers
|
Refresh_CommandBuffer **pCommandBuffers
|
||||||
) {
|
) {
|
||||||
VulkanRenderer* renderer = (VulkanRenderer*)driverData;
|
VulkanRenderer* renderer = (VulkanRenderer*)driverData;
|
||||||
VkSubmitInfo submitInfo;
|
VkSubmitInfo *submitInfos;
|
||||||
|
VkPresentInfoKHR *presentInfos;
|
||||||
|
void **presentWindowHandles;
|
||||||
|
uint8_t *needsNewSwapchain;
|
||||||
|
uint32_t presentCount = 0;
|
||||||
VkResult vulkanResult, presentResult = VK_SUCCESS;
|
VkResult vulkanResult, presentResult = VK_SUCCESS;
|
||||||
VulkanCommandBuffer *currentCommandBuffer;
|
VulkanCommandBuffer *currentCommandBuffer;
|
||||||
VkCommandBuffer *commandBuffers;
|
VkCommandBuffer *commandBuffers;
|
||||||
uint32_t i;
|
VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
uint8_t presentCount = 0;
|
|
||||||
VulkanSwapchainData *swapchainData;
|
VulkanSwapchainData *swapchainData;
|
||||||
VkFence fence;
|
VkFence fence;
|
||||||
|
uint32_t i;
|
||||||
VkPipelineStageFlags waitStages[2];
|
|
||||||
VkSemaphore waitSemaphores[2];
|
|
||||||
uint32_t waitSemaphoreCount = 0;
|
|
||||||
VkPresentInfoKHR presentInfo;
|
|
||||||
|
|
||||||
SDL_LockMutex(renderer->submitLock);
|
SDL_LockMutex(renderer->submitLock);
|
||||||
|
|
||||||
commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount);
|
commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount);
|
||||||
|
submitInfos = SDL_stack_alloc(VkSubmitInfo, commandBufferCount);
|
||||||
|
|
||||||
|
/* In the worst case we will need 1 semaphore per CB so let's allocate appropriately. */
|
||||||
|
presentInfos = SDL_stack_alloc(VkPresentInfoKHR, commandBufferCount);
|
||||||
|
presentWindowHandles = SDL_stack_alloc(void*, commandBufferCount);
|
||||||
|
needsNewSwapchain = SDL_stack_alloc(uint8_t, commandBufferCount);
|
||||||
|
|
||||||
for (i = 0; i < commandBufferCount; i += 1)
|
for (i = 0; i < commandBufferCount; i += 1)
|
||||||
{
|
{
|
||||||
currentCommandBuffer = (VulkanCommandBuffer*)pCommandBuffers[i];
|
currentCommandBuffer = (VulkanCommandBuffer*)pCommandBuffers[i];
|
||||||
presentCount += currentCommandBuffer->present;
|
|
||||||
VULKAN_INTERNAL_EndCommandBuffer(renderer, currentCommandBuffer);
|
VULKAN_INTERNAL_EndCommandBuffer(renderer, currentCommandBuffer);
|
||||||
commandBuffers[i] = currentCommandBuffer->commandBuffer;
|
commandBuffers[i] = currentCommandBuffer->commandBuffer;
|
||||||
}
|
|
||||||
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfos[i].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
submitInfo.pNext = NULL;
|
submitInfos[i].pNext = NULL;
|
||||||
submitInfo.commandBufferCount = commandBufferCount;
|
submitInfos[i].commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = commandBuffers;
|
submitInfos[i].pCommandBuffers = &commandBuffers[i];
|
||||||
|
|
||||||
if (presentCount > 0)
|
if (currentCommandBuffer->present)
|
||||||
{
|
{
|
||||||
waitSemaphores[waitSemaphoreCount] = renderer->imageAvailableSemaphore;
|
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(currentCommandBuffer->presentWindowHandle, WINDOW_SWAPCHAIN_DATA);
|
||||||
waitStages[waitSemaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
||||||
waitSemaphoreCount += 1;
|
|
||||||
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
submitInfos[i].pWaitDstStageMask = &waitStage;
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
submitInfos[i].pWaitSemaphores = &swapchainData->imageAvailableSemaphore;
|
||||||
submitInfo.pSignalSemaphores = &renderer->renderFinishedSemaphore;
|
submitInfos[i].waitSemaphoreCount = 1;
|
||||||
|
submitInfos[i].pSignalSemaphores = &swapchainData->renderFinishedSemaphore;
|
||||||
|
submitInfos[i].signalSemaphoreCount = 1;
|
||||||
|
|
||||||
|
presentInfos[presentCount].sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
presentInfos[presentCount].pNext = NULL;
|
||||||
|
presentInfos[presentCount].waitSemaphoreCount = 1;
|
||||||
|
presentInfos[presentCount].pWaitSemaphores = &swapchainData->renderFinishedSemaphore;
|
||||||
|
|
||||||
|
presentInfos[presentCount].swapchainCount = 1;
|
||||||
|
presentInfos[presentCount].pSwapchains = &swapchainData->swapchain;
|
||||||
|
presentInfos[presentCount].pImageIndices = ¤tCommandBuffer->presentSwapchainImageIndex;
|
||||||
|
presentInfos[presentCount].pResults = NULL;
|
||||||
|
|
||||||
|
presentWindowHandles[presentCount] = currentCommandBuffer->presentWindowHandle;
|
||||||
|
needsNewSwapchain[presentCount] = currentCommandBuffer->needNewSwapchain;
|
||||||
|
|
||||||
|
presentCount += 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
submitInfos[i].pWaitDstStageMask = NULL;
|
||||||
submitInfo.signalSemaphoreCount = 0;
|
submitInfos[i].pWaitSemaphores = NULL;
|
||||||
submitInfo.pSignalSemaphores = NULL;
|
submitInfos[i].waitSemaphoreCount = 0;
|
||||||
|
submitInfos[i].pSignalSemaphores = NULL;
|
||||||
|
submitInfos[i].signalSemaphoreCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
submitInfo.waitSemaphoreCount = waitSemaphoreCount;
|
|
||||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
|
||||||
|
|
||||||
if (presentCount > 0)
|
if (presentCount > 0)
|
||||||
{
|
{
|
||||||
|
@ -8880,8 +8911,8 @@ static void VULKAN_Submit(
|
||||||
/* Submit the commands, finally. */
|
/* Submit the commands, finally. */
|
||||||
vulkanResult = renderer->vkQueueSubmit(
|
vulkanResult = renderer->vkQueueSubmit(
|
||||||
renderer->graphicsQueue,
|
renderer->graphicsQueue,
|
||||||
1,
|
commandBufferCount,
|
||||||
&submitInfo,
|
submitInfos,
|
||||||
fence
|
fence
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -8912,36 +8943,24 @@ static void VULKAN_Submit(
|
||||||
|
|
||||||
/* Present, if applicable */
|
/* Present, if applicable */
|
||||||
|
|
||||||
for (i = 0; i < commandBufferCount; i += 1)
|
for (i = 0; i < presentCount; i += 1)
|
||||||
{
|
{
|
||||||
currentCommandBuffer = (VulkanCommandBuffer*) pCommandBuffers[i];
|
|
||||||
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(currentCommandBuffer->presentWindowHandle, WINDOW_SWAPCHAIN_DATA);
|
|
||||||
presentResult = VK_SUCCESS;
|
|
||||||
|
|
||||||
if (currentCommandBuffer->present)
|
|
||||||
{
|
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
||||||
presentInfo.pNext = NULL;
|
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
|
||||||
presentInfo.pWaitSemaphores = &renderer->renderFinishedSemaphore;
|
|
||||||
|
|
||||||
presentInfo.swapchainCount = 1;
|
|
||||||
presentInfo.pSwapchains = &swapchainData->swapchain;
|
|
||||||
presentInfo.pImageIndices = ¤tCommandBuffer->presentSwapchainImageIndex;
|
|
||||||
|
|
||||||
presentResult = renderer->vkQueuePresentKHR(
|
presentResult = renderer->vkQueuePresentKHR(
|
||||||
renderer->presentQueue,
|
renderer->presentQueue,
|
||||||
&presentInfo
|
&presentInfos[i]
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (presentResult != VK_SUCCESS || currentCommandBuffer->needNewSwapchain)
|
if (presentResult != VK_SUCCESS || needsNewSwapchain[i])
|
||||||
{
|
{
|
||||||
VULKAN_INTERNAL_RecreateSwapchain(renderer, currentCommandBuffer->presentWindowHandle);
|
VULKAN_INTERNAL_RecreateSwapchain(renderer, presentWindowHandles[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_stack_free(commandBuffers);
|
SDL_stack_free(commandBuffers);
|
||||||
|
SDL_stack_free(submitInfos);
|
||||||
|
SDL_stack_free(presentInfos);
|
||||||
|
SDL_stack_free(presentWindowHandles);
|
||||||
|
SDL_stack_free(needsNewSwapchain);
|
||||||
|
|
||||||
SDL_UnlockMutex(renderer->submitLock);
|
SDL_UnlockMutex(renderer->submitLock);
|
||||||
}
|
}
|
||||||
|
@ -9621,9 +9640,6 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
VkResult vulkanResult;
|
VkResult vulkanResult;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
/* Variables: Create semaphores */
|
|
||||||
VkSemaphoreCreateInfo semaphoreInfo;
|
|
||||||
|
|
||||||
/* Variables: Descriptor set layouts */
|
/* Variables: Descriptor set layouts */
|
||||||
VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo;
|
VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo;
|
||||||
VkDescriptorSetLayoutBinding vertexParamLayoutBinding;
|
VkDescriptorSetLayoutBinding vertexParamLayoutBinding;
|
||||||
|
@ -9755,53 +9771,6 @@ static Refresh_Device* VULKAN_CreateDevice(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create semaphores
|
|
||||||
*/
|
|
||||||
|
|
||||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
||||||
semaphoreInfo.pNext = NULL;
|
|
||||||
semaphoreInfo.flags = 0;
|
|
||||||
|
|
||||||
vulkanResult = renderer->vkCreateSemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
&semaphoreInfo,
|
|
||||||
NULL,
|
|
||||||
&renderer->transferFinishedSemaphore
|
|
||||||
);
|
|
||||||
|
|
||||||
if (vulkanResult != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LogVulkanResultAsError("vkCreateSemaphore", vulkanResult);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vulkanResult = renderer->vkCreateSemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
&semaphoreInfo,
|
|
||||||
NULL,
|
|
||||||
&renderer->imageAvailableSemaphore
|
|
||||||
);
|
|
||||||
|
|
||||||
if (vulkanResult != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LogVulkanResultAsError("vkCreateSemaphore", vulkanResult);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
vulkanResult = renderer->vkCreateSemaphore(
|
|
||||||
renderer->logicalDevice,
|
|
||||||
&semaphoreInfo,
|
|
||||||
NULL,
|
|
||||||
&renderer->renderFinishedSemaphore
|
|
||||||
);
|
|
||||||
|
|
||||||
if (vulkanResult != VK_SUCCESS)
|
|
||||||
{
|
|
||||||
LogVulkanResultAsError("vkCreateSemaphore", vulkanResult);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Threading */
|
/* Threading */
|
||||||
|
|
||||||
renderer->allocatorLock = SDL_CreateMutex();
|
renderer->allocatorLock = SDL_CreateMutex();
|
||||||
|
|
Loading…
Reference in New Issue