Added support for late swap tearing to the Vulkan renderer

This commit is contained in:
Sam Lantinga 2024-05-13 14:26:56 -07:00
parent 17520c2e6e
commit 5f1e01cce0

View file

@ -2092,7 +2092,7 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
/* Choose a present mode. If vsync is requested, then use VK_PRESENT_MODE_FIFO_KHR which is guaranteed to be supported */ /* Choose a present mode. If vsync is requested, then use VK_PRESENT_MODE_FIFO_KHR which is guaranteed to be supported */
VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR; VkPresentModeKHR presentMode = VK_PRESENT_MODE_FIFO_KHR;
if (!rendererData->vsync) { if (rendererData->vsync <= 0) {
uint32_t presentModeCount = 0; uint32_t presentModeCount = 0;
result = vkGetPhysicalDeviceSurfacePresentModesKHR(rendererData->physicalDevice, rendererData->surface, &presentModeCount, NULL); result = vkGetPhysicalDeviceSurfacePresentModesKHR(rendererData->physicalDevice, rendererData->surface, &presentModeCount, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
@ -2108,21 +2108,30 @@ static VkResult VULKAN_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
return result; return result;
} }
/* If vsync is not requested, in favor these options in order: if (rendererData->vsync == 0) {
VK_PRESENT_MODE_IMMEDIATE_KHR - no v-sync with tearing /* If vsync is not requested, in favor these options in order:
VK_PRESENT_MODE_MAILBOX_KHR - no v-sync without tearing VK_PRESENT_MODE_IMMEDIATE_KHR - no v-sync with tearing
VK_PRESENT_MODE_FIFO_RELAXED_KHR - no v-sync, may tear */ VK_PRESENT_MODE_MAILBOX_KHR - no v-sync without tearing
for (uint32_t i = 0; i < presentModeCount; i++) { VK_PRESENT_MODE_FIFO_RELAXED_KHR - no v-sync, may tear */
if (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) { for (uint32_t i = 0; i < presentModeCount; i++) {
presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; if (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
break; presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
break;
}
else if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
presentMode = VK_PRESENT_MODE_MAILBOX_KHR;
}
else if ((presentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
(presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)) {
presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
}
} }
else if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) { } else if (rendererData->vsync == -1) {
presentMode = VK_PRESENT_MODE_MAILBOX_KHR; for (uint32_t i = 0; i < presentModeCount; i++) {
} if (presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR) {
else if ((presentMode != VK_PRESENT_MODE_MAILBOX_KHR) && presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
(presentModes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)) { break;
presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; }
} }
} }
SDL_free(presentModes); SDL_free(presentModes);
@ -4026,6 +4035,7 @@ static int VULKAN_SetVSync(SDL_Renderer *renderer, const int vsync)
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata; VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata;
switch (vsync) { switch (vsync) {
case -1:
case 0: case 0:
case 1: case 1:
/* Supported */ /* Supported */