From 7394604b33a95dd37a5f4be9bcb11bea9b4db6e1 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 2 Nov 2025 14:15:33 +1100 Subject: [PATCH] change how present modes are handled --- vulkan.d | 133 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 47 deletions(-) diff --git a/vulkan.d b/vulkan.d index 88efcdb..1af398d 100644 --- a/vulkan.d +++ b/vulkan.d @@ -333,23 +333,33 @@ alias SI = StepInitialized; enum DescType : VkDescriptorType { - Sampler = VK_DESCRIPTOR_TYPE_SAMPLER, + Sampler = VK_DESCRIPTOR_TYPE_SAMPLER, CombinedSampler = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - Image = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - StorageImage = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + Image = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + StorageImage = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, UniformTexelBuf = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, StorageTexelBuf = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, - Uniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - DynamicUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - Storage = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - StorageDynamic = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, - InputAttach = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + Uniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + DynamicUniform = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + Storage = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + StorageDynamic = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + InputAttach = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, Max, } 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) { Buffer base; @@ -361,36 +371,38 @@ struct MappedBuffer(T) struct Vulkan { - Arena arena; - Arena[FRAME_OVERLAP] frame_arenas; + Arena arena; + Arena[FRAME_OVERLAP] frame_arenas; - u32 frame_index; - u32 semaphore_index; + u32 frame_index; + u32 semaphore_index; - SLList!(SI) cleanup_list; + SLList!(SI) cleanup_list; - PlatformHandles platform_handles; - u32 window_h, window_w; + PlatformHandles platform_handles; + u32 window_h, window_w; - VkDebugUtilsMessengerEXT dbg_msg; - VkInstance instance; - VkSurfaceKHR surface; - VkPhysicalDevice physical_device; - VkDevice device; - VmaAllocator vma; - VkSwapchainKHR swapchain; + VkDebugUtilsMessengerEXT dbg_msg; + VkInstance instance; + VkSurfaceKHR surface; + VkPhysicalDevice physical_device; + VkDevice device; + VmaAllocator vma; + VkSwapchainKHR swapchain; - VkSurfaceFormatKHR surface_format; - VkPresentModeKHR present_mode; - VkExtent3D swapchain_extent; + VkSurfaceFormatKHR surface_format; + VkPresentModeKHR present_mode; + VkExtent3D swapchain_extent; + VkPresentModeKHR[] present_modes; + bool swapchain_dirty; - VkRenderPass render_pass; - VkFramebuffer framebuffer; - ImageView[] present_images; - u32 image_index; + VkRenderPass render_pass; + VkFramebuffer framebuffer; + ImageView[] present_images; + u32 image_index; - ImageView draw_image; - ImageView depth_image; + ImageView draw_image; + ImageView depth_image; VkCommandPool[FRAME_OVERLAP] cmd_pools; VkCommandBuffer[FRAME_OVERLAP] cmds; @@ -399,9 +411,9 @@ struct Vulkan VkCommandBuffer comp_cmd; VkFence comp_fence; - VkSemaphore[] submit_sems; - VkSemaphore[FRAME_OVERLAP] acquire_sems; - VkFence[FRAME_OVERLAP] render_fences; + VkSemaphore[] submit_sems; + VkSemaphore[FRAME_OVERLAP] acquire_sems; + VkFence[FRAME_OVERLAP] render_fences; VkCommandPool imm_pool; VkCommandBuffer imm_cmd; @@ -753,7 +765,12 @@ BeginFrame(Vulkan* vk) VkCheckA("BeginFrame failure: vkResetFences error", result); 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); } @@ -2626,19 +2643,9 @@ SelectSwapchainFormats(Vulkan* vk) u32 mode_count; 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); - 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]; foreach(format; formats) { @@ -2650,7 +2657,39 @@ SelectSwapchainFormats(Vulkan* vk) } 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