diff --git a/vulkan.d b/vulkan.d index 1c02f62..fba8be7 100644 --- a/vulkan.d +++ b/vulkan.d @@ -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); } +