fix xlib differences in vulkan, properly handle swapchain recreations

This commit is contained in:
Matthew 2025-12-04 11:47:13 +11:00
parent 6bd4718063
commit b05d055383

View File

@ -387,7 +387,6 @@ struct Vulkan
u32 semaphore_index;
PlatformHandles platform_handles;
u32 window_h, window_w;
VkDebugUtilsMessengerEXT dbg_msg;
VkInstance instance;
@ -400,6 +399,8 @@ struct Vulkan
VkSurfaceFormatKHR surface_format;
VkPresentModeKHR present_mode;
VkExtent3D swapchain_extent;
f32[2] res;
bool recreate_swapchain;
VkRenderPass render_pass;
VkFramebuffer framebuffer;
@ -666,15 +667,27 @@ BeginFrame(Vulkan* vk)
result = vkResetFences(vk.device, 1, vk.render_fences.ptr + vk.frame_index);
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)
{
RecreateSwapchain(vk);
}
else if(result != VK_SUBOPTIMAL_KHR)
{
VkCheckA("BeginFrame failure: vkAcquireNextImageKHR error", result);
}
for(u64 i = 0; i < 3; i += 1)
{
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 || vk.recreate_swapchain)
{
RecreateSwapchain(vk);
VkSemaphoreCreateInfo sem_info = { sType: VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
vkDestroySemaphore(vk.device, vk.acquire_sems[vk.frame_index], null);
VkResult sem_res = vkCreateSemaphore(vk.device, &sem_info, null, &vk.acquire_sems[vk.frame_index]);
VkCheckA("Recreating swapchain sem reset failure", sem_res);
continue;
}
else if(result != VK_SUBOPTIMAL_KHR)
{
VkCheckA("BeginFrame failure: vkAcquireNextImageKHR error", result);
}
break;
}
result = vkResetCommandBuffer(vk.cmds[vk.frame_index], 0);
VkCheckA("BeginFrame failure: vkResetCommandBuffer failure", result);
@ -830,7 +843,7 @@ SubmitAndPresent(Vulkan* vk)
};
result = vkQueuePresentKHR(vk.queues.gfx_queue, &present_info);
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || vk.recreate_swapchain)
{
RecreateSwapchain(vk);
}
@ -1507,6 +1520,13 @@ Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set, bool compute = false)
);
}
void
SetExtent(Vulkan* vk, u32 x, u32 y)
{
vk.recreate_swapchain = true;
vk.res = [x, y];
}
pragma(inline): void
BindPipeline(Vulkan* vk, VkCommandBuffer cmd, PipelineHandles* pipeline)
{
@ -1538,20 +1558,20 @@ pragma(inline): void
Transition(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout)
{
VkImageMemoryBarrier2 barrier = {
sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
srcStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
srcAccessMask: VK_ACCESS_2_MEMORY_WRITE_BIT,
dstStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
dstStageMask: VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
dstAccessMask: VK_ACCESS_2_MEMORY_WRITE_BIT | VK_ACCESS_2_MEMORY_READ_BIT,
oldLayout: current_layout,
newLayout: new_layout,
image: image,
oldLayout: current_layout,
newLayout: new_layout,
image: image,
subresourceRange: {
aspectMask: new_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT,
baseMipLevel: 0,
levelCount: VK_REMAINING_MIP_LEVELS,
aspectMask: new_layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT,
baseMipLevel: 0,
levelCount: VK_REMAINING_MIP_LEVELS,
baseArrayLayer: 0,
layerCount: VK_REMAINING_ARRAY_LAYERS,
layerCount: VK_REMAINING_ARRAY_LAYERS,
},
};
@ -2198,20 +2218,6 @@ SelectSwapchainFormats(Vulkan* vk)
vk.present_mode = present_mode;
}
void
CheckAndRecreateSwapchain(Vulkan* vk)
{
VkResult result = vkGetSwapchainStatusKHR(vk.device, vk.swapchain);
if(result == VK_ERROR_OUT_OF_DATE_KHR)
{
RecreateSwapchain(vk);
}
else if(result != VK_SUBOPTIMAL_KHR)
{
VkCheckA("BeginFrame failure: vkAcquireNextImageKHR error", result);
}
}
Descriptor
CreateSampler(Vulkan* vk, MipmapMode mode, u32 binding)
{
@ -2275,6 +2281,9 @@ CreateSwapchain(Vulkan* vk)
SelectSwapchainFormats(vk);
}
u32 w = clamp(cast(u32)vk.res[0], cap.minImageExtent.width, cap.maxImageExtent.width);
u32 h = clamp(cast(u32)vk.res[1], cap.minImageExtent.height, cap.maxImageExtent.height);
VkSwapchainCreateInfoKHR info = {
sType: VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
imageArrayLayers: 1,
@ -2287,8 +2296,8 @@ CreateSwapchain(Vulkan* vk)
imageFormat: vk.surface_format.format,
imageColorSpace: vk.surface_format.colorSpace,
imageExtent: {
width: clamp(cast(u32)vk.window_w, cap.minImageExtent.width, cap.maxImageExtent.width),
height: clamp(cast(u32)vk.window_h, cap.minImageExtent.height, cap.maxImageExtent.height),
width: w,
height: h,
},
preTransform: cap.currentTransform,
presentMode: vk.present_mode,
@ -2338,9 +2347,11 @@ CreateSwapchain(Vulkan* vk)
success = VkCheck("vkCreateImageView failure", result);
}
vk.swapchain_extent.width = info.imageExtent.width;
vk.swapchain_extent.height = info.imageExtent.height;
vk.swapchain_extent.depth = 1;
vk.swapchain_extent.width = w;
vk.swapchain_extent.height = h;
vk.swapchain_extent.depth = 1;
Logf("resized swapchain to %s %s", w, h);
if(!initialized && success)
{
@ -2364,6 +2375,8 @@ RecreateSwapchain(Vulkan* vk)
CreateDrawImages(vk);
Write(vk, vk.global_set, &vk.draw_image);
CreateFramebuffer(vk);
vk.recreate_swapchain = false;
}
void
@ -3211,3 +3224,4 @@ unittest
PlatformHandles handles;
Vulkan vk = Init(handles, 10*1000*1000, 10*1000*1000);
}