From ed020691cc78b4b48e6b510daa70b664fc758068 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 1 Mar 2022 22:21:07 -0800 Subject: [PATCH] add swapchain format query --- include/Refresh.h | 8 +++- src/Refresh.c | 11 ++++++ src/Refresh_Driver.h | 6 +++ src/Refresh_Driver_Vulkan.c | 74 ++++++++++++++++++++++++++++--------- 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index d9b8c16..ddb7f92 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -1242,6 +1242,12 @@ REFRESHAPI Refresh_Texture* Refresh_AcquireSwapchainTexture( void *windowHandle ); +/* Returns the format of the swapchain for the given window. */ +REFRESHAPI Refresh_TextureFormat Refresh_GetSwapchainFormat( + Refresh_Device *device, + void *windowHandle +); + /* Submits all of the enqueued commands. */ REFRESHAPI void Refresh_Submit( Refresh_Device* device, @@ -1249,7 +1255,7 @@ REFRESHAPI void Refresh_Submit( Refresh_CommandBuffer **pCommandBuffers ); -/* Waits for the previous submission to complete. */ +/* Waits for all submissions to complete. */ REFRESHAPI void Refresh_Wait( Refresh_Device *device ); diff --git a/src/Refresh.c b/src/Refresh.c index f6dfe94..c71981e 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -725,6 +725,17 @@ Refresh_Texture* Refresh_AcquireSwapchainTexture( ); } +Refresh_TextureFormat Refresh_GetSwapchainFormat( + Refresh_Device *device, + void *windowHandle +) { + if (device == NULL) { return 0; } + return device->GetSwapchainFormat( + device->driverData, + windowHandle + ); +} + void Refresh_Submit( Refresh_Device *device, uint32_t commandBufferCount, diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 95abaaa..5d1fdfe 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -448,6 +448,11 @@ struct Refresh_Device void *windowHandle ); + Refresh_TextureFormat (*GetSwapchainFormat)( + Refresh_Renderer *driverData, + void *windowHandle + ); + void(*Submit)( Refresh_Renderer *driverData, uint32_t commandBufferCount, @@ -504,6 +509,7 @@ struct Refresh_Device ASSIGN_DRIVER_FUNC(BindComputeTextures, name) \ ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \ ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \ + ASSIGN_DRIVER_FUNC(GetSwapchainFormat, name) \ ASSIGN_DRIVER_FUNC(Submit, name) \ ASSIGN_DRIVER_FUNC(Wait, name) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 94d927f..b199b73 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -3849,7 +3849,6 @@ static uint8_t VULKAN_INTERNAL_ChooseSwapSurfaceFormat( } } - Refresh_LogError("Desired surface format is unavailable."); return 0; } @@ -3961,7 +3960,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( return CREATE_SWAPCHAIN_FAIL; } - swapchainData->swapchainFormat = VK_FORMAT_B8G8R8A8_UNORM; + swapchainData->swapchainFormat = VK_FORMAT_R8G8B8A8_UNORM; swapchainData->swapchainSwizzle.r = VK_COMPONENT_SWIZZLE_IDENTITY; swapchainData->swapchainSwizzle.g = VK_COMPONENT_SWIZZLE_IDENTITY; swapchainData->swapchainSwizzle.b = VK_COMPONENT_SWIZZLE_IDENTITY; @@ -3973,22 +3972,36 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( swapchainSupportDetails.formatsLength, &swapchainData->surfaceFormat )) { - renderer->vkDestroySurfaceKHR( - renderer->instance, - swapchainData->surface, - NULL - ); - if (swapchainSupportDetails.formatsLength > 0) - { - SDL_free(swapchainSupportDetails.formats); + Refresh_LogWarn("RGBA8 swapchain unsupported, falling back to BGRA8 with swizzle"); + swapchainData->swapchainFormat = VK_FORMAT_B8G8R8A8_UNORM; + swapchainData->swapchainSwizzle.r = VK_COMPONENT_SWIZZLE_B; + swapchainData->swapchainSwizzle.g = VK_COMPONENT_SWIZZLE_G; + swapchainData->swapchainSwizzle.b = VK_COMPONENT_SWIZZLE_R; + swapchainData->swapchainSwizzle.a = VK_COMPONENT_SWIZZLE_A; + + if (!VULKAN_INTERNAL_ChooseSwapSurfaceFormat( + swapchainData->swapchainFormat, + swapchainSupportDetails.formats, + swapchainSupportDetails.formatsLength, + &swapchainData->surfaceFormat + )) { + renderer->vkDestroySurfaceKHR( + renderer->instance, + swapchainData->surface, + NULL + ); + if (swapchainSupportDetails.formatsLength > 0) + { + SDL_free(swapchainSupportDetails.formats); + } + if (swapchainSupportDetails.presentModesLength > 0) + { + SDL_free(swapchainSupportDetails.presentModes); + } + SDL_free(swapchainData); + Refresh_LogError("Device does not support swap chain format"); + return CREATE_SWAPCHAIN_FAIL; } - if (swapchainSupportDetails.presentModesLength > 0) - { - SDL_free(swapchainSupportDetails.presentModes); - } - SDL_free(swapchainData); - Refresh_LogError("Device does not support swap chain format"); - return CREATE_SWAPCHAIN_FAIL; } if (!VULKAN_INTERNAL_ChooseSwapPresentMode( @@ -8626,6 +8639,33 @@ static Refresh_Texture* VULKAN_AcquireSwapchainTexture( return (Refresh_Texture*) swapchainTexture; } +static Refresh_TextureFormat VULKAN_GetSwapchainFormat( + Refresh_Renderer *driverData, + void *windowHandle +) { + VulkanSwapchainData *swapchainData = (VulkanSwapchainData*) SDL_GetWindowData(windowHandle, WINDOW_SWAPCHAIN_DATA); + + if (swapchainData == NULL) + { + Refresh_LogWarn("No swapchain for this window!"); + return 0; + } + + if (swapchainData->swapchainFormat == VK_FORMAT_R8G8B8A8_UNORM) + { + return REFRESH_TEXTUREFORMAT_R8G8B8A8; + } + else if (swapchainData->swapchainFormat == VK_FORMAT_B8G8R8A8_UNORM) + { + return REFRESH_TEXTUREFORMAT_B8G8R8A8; + } + else + { + Refresh_LogWarn("Unrecognized swapchain format!"); + return 0; + } +} + /* Synchronization management */ static VkFence VULKAN_INTERNAL_AcquireFence(