change how present modes are handled

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

133
vulkan.d
View File

@ -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