diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 55c7dee14c..c1b3fe3dab 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -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 */ diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 714960d632..3a6dc9dd91 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -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); diff --git a/gfx/drivers_context/w_vk_ctx.c b/gfx/drivers_context/w_vk_ctx.c index 8f2d40bf06..2e0b946976 100644 --- a/gfx/drivers_context/w_vk_ctx.c +++ b/gfx/drivers_context/w_vk_ctx.c @@ -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; } diff --git a/gfx/drivers_context/x_vk_ctx.c b/gfx/drivers_context/x_vk_ctx.c index 38e8654a85..b1eb909458 100644 --- a/gfx/drivers_context/x_vk_ctx.c +++ b/gfx/drivers_context/x_vk_ctx.c @@ -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);