From bde49abdb7f534be948305b8ff1fa66a56ea8bf0 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 31 Aug 2024 10:13:59 -0400
Subject: [PATCH] GPU: Support swapchain buffer transparency in Vulkan
If the window is flagged with SDL_WINDOW_TRANSPARENT, create the associated swapchain with a composite alpha value that supports blending, if available.
Fixes transparent windows on the Vulkan backend, and prevents possible validation errors by ensuring that the composite alpha value is always a valid bit in VkSurfaceCapabilitiesKHR::supportedCompositeAlpha.
---
src/gpu/vulkan/SDL_gpu_vulkan.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c
index c63c4884b3cfc..9986d48ac62b8 100644
--- a/src/gpu/vulkan/SDL_gpu_vulkan.c
+++ b/src/gpu/vulkan/SDL_gpu_vulkan.c
@@ -4430,6 +4430,7 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
VkSemaphoreCreateInfo semaphoreCreateInfo;
SwapchainSupportDetails swapchainSupportDetails;
bool hasValidSwapchainComposition, hasValidPresentMode;
+ VkCompositeAlphaFlagsKHR compositeAlphaFlag = 0;
Uint32 i;
windowData->frameCounter = 0;
@@ -4570,6 +4571,25 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
requestedImageCount = SDL_max(requestedImageCount, 3);
}
+ // Default to opaque, if available, followed by inherit, and overwrite with a value that supports transparency, if necessary.
+ if (swapchainSupportDetails.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) {
+ compositeAlphaFlag = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ } else if (swapchainSupportDetails.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
+ compositeAlphaFlag = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
+ }
+
+ if ((windowData->window->flags & SDL_WINDOW_TRANSPARENT) || !compositeAlphaFlag) {
+ if (swapchainSupportDetails.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR) {
+ compositeAlphaFlag = VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR;
+ } else if (swapchainSupportDetails.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR) {
+ compositeAlphaFlag = VK_COMPOSITE_ALPHA_POST_MULTIPLIED_BIT_KHR;
+ } else if (swapchainSupportDetails.capabilities.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) {
+ compositeAlphaFlag = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
+ } else {
+ SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "SDL_WINDOW_TRANSPARENT flag set, but no suitable swapchain composite alpha value supported!");
+ }
+ }
+
swapchainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapchainCreateInfo.pNext = NULL;
swapchainCreateInfo.flags = 0;
@@ -4591,7 +4611,7 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
#else
swapchainCreateInfo.preTransform = swapchainSupportDetails.capabilities.currentTransform;
#endif
- swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+ swapchainCreateInfo.compositeAlpha = compositeAlphaFlag;
swapchainCreateInfo.presentMode = SDLToVK_PresentMode[windowData->presentMode];
swapchainCreateInfo.clipped = VK_TRUE;
swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;