Vulkan: Add adaptive vsync support (#17611)

This commit is contained in:
sonninnos 2025-02-21 22:34:32 +02:00 committed by GitHub
parent f7d235f2d6
commit 3c1a1a44ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 47 additions and 9 deletions

View File

@ -1533,7 +1533,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
enum vulkan_wsi_type type,
void *display, void *surface,
unsigned width, unsigned height,
unsigned swap_interval)
int8_t swap_interval)
{
switch (type)
{
@ -1914,7 +1914,7 @@ bool vulkan_is_hdr10_format(VkFormat format)
bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
unsigned width, unsigned height,
unsigned swap_interval)
int8_t swap_interval)
{
unsigned i;
uint32_t format_count;
@ -1932,6 +1932,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
VkCompositeAlphaFlagBitsKHR composite = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
settings_t *settings = config_get_ptr();
bool vsync = settings->bools.video_vsync;
bool adaptive_vsync = settings->bools.video_adaptive_vsync;
format.format = VK_FORMAT_UNDEFINED;
format.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
@ -1951,7 +1952,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
&& (vk->flags & VK_DATA_FLAG_EMULATE_MAILBOX)
&& vsync)
{
swap_interval = 1;
swap_interval = (adaptive_vsync) ? -1 : 1;
vk->flags |= VK_DATA_FLAG_EMULATING_MAILBOX;
}
else
@ -2028,6 +2029,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
vk->context.swap_interval = swap_interval;
for (i = 0; i < present_mode_count; i++)
vk->context.present_modes[i] = present_modes[i];
/* Prefer IMMEDIATE without vsync */
for (i = 0; i < present_mode_count; i++)
{
@ -2038,6 +2042,13 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
swapchain_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR;
break;
}
if ( swap_interval < 0
&& present_modes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
{
swapchain_present_mode = VK_PRESENT_MODE_FIFO_RELAXED_KHR;
break;
}
}
/* If still in FIFO with no swap interval, try MAILBOX */

View File

@ -363,6 +363,7 @@ typedef struct vulkan_context
VkPhysicalDeviceProperties gpu_properties;
VkPhysicalDeviceMemoryProperties memory_properties;
VkPresentModeKHR present_modes[16];
VkImage swapchain_images[VULKAN_MAX_SWAPCHAIN_IMAGES];
VkFence swapchain_fences[VULKAN_MAX_SWAPCHAIN_IMAGES];
VkFormat swapchain_format;
@ -385,9 +386,9 @@ typedef struct vulkan_context
unsigned swapchain_width;
unsigned swapchain_height;
unsigned swap_interval;
unsigned num_recycled_acquire_semaphores;
int8_t swap_interval;
uint8_t flags;
bool swapchain_fences_signalled[VULKAN_MAX_SWAPCHAIN_IMAGES];
@ -723,7 +724,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk,
enum vulkan_wsi_type type,
void *display, void *surface,
unsigned width, unsigned height,
unsigned swap_interval);
int8_t swap_interval);
void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index);
@ -731,7 +732,7 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk);
bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
unsigned width, unsigned height,
unsigned swap_interval);
int8_t swap_interval);
void vulkan_debug_mark_image(VkDevice device, VkImage image);
void vulkan_debug_mark_memory(VkDevice device, VkDeviceMemory memory);

View File

@ -271,10 +271,24 @@ static void *gfx_ctx_w_vk_get_context_data(void *data) { return &win32_vk.contex
static uint32_t gfx_ctx_w_vk_get_flags(void *data)
{
uint32_t flags = 0;
uint32_t flags = 0;
uint8_t present_mode_count = 16;
uint8_t i = 0;
/* Check for FIFO_RELAXED_KHR capability */
for (i = 0; i < present_mode_count; i++)
{
if (win32_vk.context.present_modes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
{
BIT32_SET(flags, GFX_CTX_FLAGS_ADAPTIVE_VSYNC);
break;
}
}
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG);
#endif
return flags;
}

View File

@ -526,8 +526,20 @@ static void *gfx_ctx_x_vk_get_context_data(void *data)
static uint32_t gfx_ctx_x_vk_get_flags(void *data)
{
uint32_t flags = 0;
gfx_ctx_x_vk_data_t *x = (gfx_ctx_x_vk_data_t*)data;
gfx_ctx_x_vk_data_t *x = (gfx_ctx_x_vk_data_t*)data;
uint32_t flags = 0;
uint8_t present_mode_count = 16;
uint8_t i = 0;
/* Check for FIFO_RELAXED_KHR capability */
for (i = 0; i < present_mode_count; i++)
{
if (x->vk.context.present_modes[i] == VK_PRESENT_MODE_FIFO_RELAXED_KHR)
{
BIT32_SET(flags, GFX_CTX_FLAGS_ADAPTIVE_VSYNC);
break;
}
}
#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS)
BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG);