swapchain recreate timing fix
continuous-integration/drone/push Build is passing Details

pull/18/head
cosmonaut 2022-03-06 22:20:06 -08:00
parent 83ce2a3619
commit 74c5ac984c
2 changed files with 134 additions and 128 deletions

View File

@ -988,6 +988,7 @@ REFRESHAPI void Refresh_QueueDestroyGraphicsPipeline(
* The area affected by the render pass.
* All load, store and resolve operations are restricted
* to the given rectangle.
* If NULL, a sensible default will be chosen.
* colorAttachmentInfos:
* A pointer to an array of Refresh_ColorAttachmentInfo structures
* that contains render targets and clear values. May be NULL.

View File

@ -169,13 +169,6 @@ typedef enum VulkanResourceAccessType
RESOURCE_ACCESS_TYPES_COUNT
} VulkanResourceAccessType;
typedef enum CreateSwapchainResult
{
CREATE_SWAPCHAIN_FAIL,
CREATE_SWAPCHAIN_SUCCESS,
CREATE_SWAPCHAIN_SURFACE_ZERO,
} CreateSwapchainResult;
/* Conversions */
static const uint8_t DEVICE_PRIORITY[] =
@ -4095,7 +4088,7 @@ static uint8_t VULKAN_INTERNAL_ChooseSwapPresentMode(
return 1;
}
static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
static uint8_t VULKAN_INTERNAL_CreateSwapchain(
VulkanRenderer *renderer,
void *windowHandle
) {
@ -4124,7 +4117,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
"SDL_Vulkan_CreateSurface failed: %s",
SDL_GetError()
);
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
if (!VULKAN_INTERNAL_QuerySwapChainSupport(
@ -4149,7 +4142,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
}
SDL_free(swapchainData);
Refresh_LogError("Device does not support swap chain creation");
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
swapchainData->swapchainFormat = VK_FORMAT_R8G8B8A8_UNORM;
@ -4191,7 +4184,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
}
SDL_free(swapchainData);
Refresh_LogError("Device does not support swap chain format");
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
}
@ -4216,7 +4209,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
}
SDL_free(swapchainData);
Refresh_LogError("Device does not support swap chain present mode");
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
SDL_Vulkan_GetDrawableSize(
@ -4247,7 +4240,8 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
SDL_free(swapchainSupportDetails.presentModes);
}
SDL_free(swapchainData);
return CREATE_SWAPCHAIN_SURFACE_ZERO;
/* Not an error, just Windows minimize behavior! */
return 0;
}
if (swapchainSupportDetails.capabilities.currentExtent.width != UINT32_MAX)
@ -4280,7 +4274,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
}
SDL_free(swapchainData);
Refresh_LogError("No fallback swapchain size available!");
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
}
@ -4353,7 +4347,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
);
SDL_free(swapchainData);
LogVulkanResultAsError("vkCreateSwapchainKHR", vulkanResult);
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
renderer->vkGetSwapchainImagesKHR(
@ -4376,7 +4370,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
NULL
);
SDL_free(swapchainData);
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
swapchainImages = SDL_stack_alloc(VkImage, swapchainData->imageCount);
@ -4424,7 +4418,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
SDL_free(swapchainData->textures);
SDL_free(swapchainData);
LogVulkanResultAsError("vkCreateImageView", vulkanResult);
return CREATE_SWAPCHAIN_FAIL;
return 0;
}
swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE;
@ -4480,26 +4474,16 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain(
renderer->swapchainDatas[renderer->swapchainDataCount] = swapchainData;
renderer->swapchainDataCount += 1;
return CREATE_SWAPCHAIN_SUCCESS;
return 1;
}
static void VULKAN_INTERNAL_RecreateSwapchain(
VulkanRenderer* renderer,
void *windowHandle
) {
CreateSwapchainResult createSwapchainResult;
VULKAN_Wait((Refresh_Renderer*)renderer);
VULKAN_Wait((Refresh_Renderer*) renderer);
VULKAN_INTERNAL_DestroySwapchain(renderer, windowHandle);
createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle);
if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL)
{
return;
}
VULKAN_Wait((Refresh_Renderer*)renderer);
VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle);
}
/* Command Buffers */
@ -8233,13 +8217,24 @@ static void VULKAN_BeginRenderPass(
renderPassBeginInfo.pNext = NULL;
renderPassBeginInfo.renderPass = renderPass;
renderPassBeginInfo.framebuffer = framebuffer->framebuffer;
renderPassBeginInfo.renderArea.extent.width = renderArea->w;
renderPassBeginInfo.renderArea.extent.height = renderArea->h;
renderPassBeginInfo.renderArea.offset.x = renderArea->x;
renderPassBeginInfo.renderArea.offset.y = renderArea->y;
renderPassBeginInfo.pClearValues = clearValues;
renderPassBeginInfo.clearValueCount = clearCount;
if (renderArea != NULL)
{
renderPassBeginInfo.renderArea.extent.width = renderArea->w;
renderPassBeginInfo.renderArea.extent.height = renderArea->h;
renderPassBeginInfo.renderArea.offset.x = renderArea->x;
renderPassBeginInfo.renderArea.offset.y = renderArea->y;
}
else
{
renderPassBeginInfo.renderArea.extent.width = framebufferWidth;
renderPassBeginInfo.renderArea.extent.height = framebufferHeight;
renderPassBeginInfo.renderArea.offset.x = 0;
renderPassBeginInfo.renderArea.offset.y = 0;
}
renderer->vkCmdBeginRenderPass(
vulkanCommandBuffer->commandBuffer,
&renderPassBeginInfo,
@ -8935,6 +8930,25 @@ static Refresh_CommandBuffer* VULKAN_AcquireCommandBuffer(
return (Refresh_CommandBuffer*) commandBuffer;
}
static VulkanSwapchainData* VULKAN_INTERNAL_FetchSwapchainData(
VulkanRenderer *renderer,
void *windowHandle
) {
VulkanSwapchainData *swapchainData = NULL;
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA);
if (swapchainData == NULL)
{
if (VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle))
{
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA);
}
}
return swapchainData;
}
static Refresh_Texture* VULKAN_AcquireSwapchainTexture(
Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer,
@ -8943,35 +8957,39 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture(
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer;
uint32_t swapchainImageIndex;
VulkanSwapchainData *swapchainData = NULL;
CreateSwapchainResult createSwapchainResult = 0;
uint8_t validSwapchainExists = 1;
VulkanSwapchainData *swapchainData;
VkResult acquireResult = VK_SUCCESS;
VulkanTexture *swapchainTexture = NULL;
VulkanPresentData *presentData;
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA);
swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle);
if (swapchainData == NULL)
{
createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowHandle);
if (createSwapchainResult == CREATE_SWAPCHAIN_FAIL)
{
validSwapchainExists = 0;
}
else if (createSwapchainResult == CREATE_SWAPCHAIN_SURFACE_ZERO)
{
validSwapchainExists = 0;
}
else
{
swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA);
}
return NULL;
}
if (validSwapchainExists)
acquireResult = renderer->vkAcquireNextImageKHR(
renderer->logicalDevice,
swapchainData->swapchain,
UINT64_MAX,
swapchainData->imageAvailableSemaphore,
VK_NULL_HANDLE,
&swapchainImageIndex
);
/* Swapchain is suboptimal, let's try to recreate */
if (acquireResult == VK_SUBOPTIMAL_KHR)
{
VULKAN_INTERNAL_RecreateSwapchain(renderer, windowHandle);
swapchainData = VULKAN_INTERNAL_FetchSwapchainData(renderer, windowHandle);
if (swapchainData == NULL)
{
return NULL;
}
acquireResult = renderer->vkAcquireNextImageKHR(
renderer->logicalDevice,
swapchainData->swapchain,
@ -8981,84 +8999,71 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture(
&swapchainImageIndex
);
/* Swapchain is suboptimal, let's try to recreate */
if (acquireResult == VK_SUBOPTIMAL_KHR)
if (acquireResult != VK_SUCCESS)
{
VULKAN_INTERNAL_RecreateSwapchain(renderer, windowHandle);
acquireResult = renderer->vkAcquireNextImageKHR(
renderer->logicalDevice,
swapchainData->swapchain,
UINT64_MAX,
swapchainData->imageAvailableSemaphore,
VK_NULL_HANDLE,
&swapchainImageIndex
);
}
if (acquireResult == VK_SUCCESS)
{
swapchainTexture = &swapchainData->textures[swapchainImageIndex];
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
vulkanCommandBuffer->commandBuffer,
RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
1,
0,
1,
0,
swapchainTexture->image,
&swapchainTexture->resourceAccessType
);
/* Set up present struct */
if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity)
{
vulkanCommandBuffer->presentDataCapacity += 1;
vulkanCommandBuffer->presentDatas = SDL_realloc(
vulkanCommandBuffer->presentDatas,
vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR)
);
}
presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount];
vulkanCommandBuffer->presentDataCount += 1;
presentData->swapchainData = swapchainData;
presentData->swapchainImageIndex = swapchainImageIndex;
/* Set up present semaphores */
if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity)
{
vulkanCommandBuffer->waitSemaphoreCapacity += 1;
vulkanCommandBuffer->waitSemaphores = SDL_realloc(
vulkanCommandBuffer->waitSemaphores,
vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore)
);
}
vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore;
vulkanCommandBuffer->waitSemaphoreCount += 1;
if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity)
{
vulkanCommandBuffer->signalSemaphoreCapacity += 1;
vulkanCommandBuffer->signalSemaphores = SDL_realloc(
vulkanCommandBuffer->signalSemaphores,
vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore)
);
}
vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore;
vulkanCommandBuffer->signalSemaphoreCount += 1;
return NULL;
}
}
swapchainTexture = &swapchainData->textures[swapchainImageIndex];
VULKAN_INTERNAL_ImageMemoryBarrier(
renderer,
vulkanCommandBuffer->commandBuffer,
RESOURCE_ACCESS_COLOR_ATTACHMENT_WRITE,
VK_IMAGE_ASPECT_COLOR_BIT,
0,
1,
0,
1,
0,
swapchainTexture->image,
&swapchainTexture->resourceAccessType
);
/* Set up present struct */
if (vulkanCommandBuffer->presentDataCount == vulkanCommandBuffer->presentDataCapacity)
{
vulkanCommandBuffer->presentDataCapacity += 1;
vulkanCommandBuffer->presentDatas = SDL_realloc(
vulkanCommandBuffer->presentDatas,
vulkanCommandBuffer->presentDataCapacity * sizeof(VkPresentInfoKHR)
);
}
presentData = &vulkanCommandBuffer->presentDatas[vulkanCommandBuffer->presentDataCount];
vulkanCommandBuffer->presentDataCount += 1;
presentData->swapchainData = swapchainData;
presentData->swapchainImageIndex = swapchainImageIndex;
/* Set up present semaphores */
if (vulkanCommandBuffer->waitSemaphoreCount == vulkanCommandBuffer->waitSemaphoreCapacity)
{
vulkanCommandBuffer->waitSemaphoreCapacity += 1;
vulkanCommandBuffer->waitSemaphores = SDL_realloc(
vulkanCommandBuffer->waitSemaphores,
vulkanCommandBuffer->waitSemaphoreCapacity * sizeof(VkSemaphore)
);
}
vulkanCommandBuffer->waitSemaphores[vulkanCommandBuffer->waitSemaphoreCount] = swapchainData->imageAvailableSemaphore;
vulkanCommandBuffer->waitSemaphoreCount += 1;
if (vulkanCommandBuffer->signalSemaphoreCount == vulkanCommandBuffer->signalSemaphoreCapacity)
{
vulkanCommandBuffer->signalSemaphoreCapacity += 1;
vulkanCommandBuffer->signalSemaphores = SDL_realloc(
vulkanCommandBuffer->signalSemaphores,
vulkanCommandBuffer->signalSemaphoreCapacity * sizeof(VkSemaphore)
);
}
vulkanCommandBuffer->signalSemaphores[vulkanCommandBuffer->signalSemaphoreCount] = swapchainData->renderFinishedSemaphore;
vulkanCommandBuffer->signalSemaphoreCount += 1;
return (Refresh_Texture*) swapchainTexture;
}
@ -10337,7 +10342,7 @@ static Refresh_Device* VULKAN_CreateDevice(
renderer->swapchainDataCapacity * sizeof(VulkanSwapchainData*)
);
if (VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle) != CREATE_SWAPCHAIN_SUCCESS)
if (!VULKAN_INTERNAL_CreateSwapchain(renderer, presentationParameters->deviceWindowHandle))
{
Refresh_LogError("Failed to create swapchain");
return NULL;