From dcf8e5a97c66c755dff31307af2bac2f8b5e85d8 Mon Sep 17 00:00:00 2001 From: Frank Praznik 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 2ae62771e0032..1de15fb20f1e8 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -4413,6 +4413,7 @@ static bool VULKAN_INTERNAL_CreateSwapchain( VkSemaphoreCreateInfo semaphoreCreateInfo; SwapchainSupportDetails swapchainSupportDetails; bool hasValidSwapchainComposition, hasValidPresentMode; + VkCompositeAlphaFlagsKHR compositeAlphaFlag = 0; Sint32 drawableWidth, drawableHeight; Uint32 i; SDL_VideoDevice *_this = SDL_GetVideoDevice(); @@ -4584,6 +4585,25 @@ static bool VULKAN_INTERNAL_CreateSwapchain( swapchainData->imageCount = SDL_max(swapchainData->imageCount, 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; @@ -4601,7 +4621,7 @@ static bool VULKAN_INTERNAL_CreateSwapchain( swapchainCreateInfo.queueFamilyIndexCount = 0; swapchainCreateInfo.pQueueFamilyIndices = NULL; swapchainCreateInfo.preTransform = swapchainSupportDetails.capabilities.currentTransform; - swapchainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; + swapchainCreateInfo.compositeAlpha = compositeAlphaFlag; swapchainCreateInfo.presentMode = swapchainData->presentMode; swapchainCreateInfo.clipped = VK_TRUE; swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;