change how present modes are handled

This commit is contained in:
Matthew 2025-11-02 14:15:33 +11:00
parent d46741a480
commit 7394604b33

View File

@ -350,6 +350,16 @@ enum DescType : VkDescriptorType
alias DT = DescType; alias DT = DescType;
enum PresentMode : VkPresentModeKHR
{
Vsync = VK_PRESENT_MODE_FIFO_KHR,
NoVsync = VK_PRESENT_MODE_IMMEDIATE_KHR,
VsyncUncapped = VK_PRESENT_MODE_MAILBOX_KHR,
VsyncRelaxed = VK_PRESENT_MODE_RELAXED_KHR,
Max,
}
struct MappedBuffer(T) struct MappedBuffer(T)
{ {
Buffer base; Buffer base;
@ -383,6 +393,8 @@ struct Vulkan
VkSurfaceFormatKHR surface_format; VkSurfaceFormatKHR surface_format;
VkPresentModeKHR present_mode; VkPresentModeKHR present_mode;
VkExtent3D swapchain_extent; VkExtent3D swapchain_extent;
VkPresentModeKHR[] present_modes;
bool swapchain_dirty;
VkRenderPass render_pass; VkRenderPass render_pass;
VkFramebuffer framebuffer; VkFramebuffer framebuffer;
@ -753,7 +765,12 @@ BeginFrame(Vulkan* vk)
VkCheckA("BeginFrame failure: vkResetFences error", result); VkCheckA("BeginFrame failure: vkResetFences error", result);
result = vkAcquireNextImageKHR(vk.device, vk.swapchain, 1000000000, vk.acquire_sems[vk.frame_index], null, &vk.image_index); result = vkAcquireNextImageKHR(vk.device, vk.swapchain, 1000000000, vk.acquire_sems[vk.frame_index], null, &vk.image_index);
if(result == VK_ERROR_OUT_OF_DATE_KHR) if(vk.swapchain_dirty && (result == VK_SUCCESS || result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR))
{
RecreateSwapchain(vk);
vk.swapchain_dirty = false;
}
else if(result == VK_ERROR_OUT_OF_DATE_KHR)
{ {
RecreateSwapchain(vk); RecreateSwapchain(vk);
} }
@ -2626,19 +2643,9 @@ SelectSwapchainFormats(Vulkan* vk)
u32 mode_count; u32 mode_count;
vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, null); vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, null);
VkPresentModeKHR[] modes = Alloc!(VkPresentModeKHR)(arena, mode_count); PresentMode[] vk.present_modes = Alloc!(PresentMode)(arena, mode_count);
vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, modes.ptr); vkGetPhysicalDeviceSurfacePresentModesKHR(vk.physical_device, vk.surface, &mode_count, modes.ptr);
VkPresentModeKHR present_mode = VK_PRESENT_MODE_FIFO_KHR;
foreach(mode; modes)
{
if(mode == VK_PRESENT_MODE_MAILBOX_KHR)
{
present_mode = VK_PRESENT_MODE_MAILBOX_KHR;
break;
}
}
VkSurfaceFormatKHR surface_format = formats[0]; VkSurfaceFormatKHR surface_format = formats[0];
foreach(format; formats) foreach(format; formats)
{ {
@ -2650,7 +2657,39 @@ SelectSwapchainFormats(Vulkan* vk)
} }
vk.surface_format = surface_format; vk.surface_format = surface_format;
vk.present_mode = present_mode; vk.present_mode = PresentMode.Vsync;
}
PresentMode[]
AvailablePresentModes(Vulkan* vk)
{
return vk.present_modes;
}
bool
SetPresentMode(Vulkan* vk, PresentMode mode)
{
bool result = false;
foreach(pm; vk.present_modes)
{
if(pm == mode)
{
result = true;
break;
}
}
if(result)
{
if(vk.present_mode != mode)
{
vk.swapchain_dirty = true;
}
vk.present_mode = mode;
}
return result;
} }
bool bool