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