Skip to content

Commit f648c27

Browse files
committed
disp/vulkan: Fix suboptimal swapchain handling
When vkAcquireNextImage() returns VK_SUBOPTIMAL_KHR it means that a valid usable image was still acquired and that means that the acquire_samaphore is pending and signalled as normal. This means we cannot just recreate the swapchain and reuse it to acquire an image from the new swapchain as VulkanDisplay::display_queued_image() was doing, because the spec states that the semaphore must be unsignaled and not pending. The fix here is to render and display the suboptimal image as normal and set a flag to immediately return swapchain_image_out_of_date to trigger a swapchain recreation on the next frame.
1 parent c8ee20a commit f648c27

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

src/video_display/vulkan/vulkan_context.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,16 +544,23 @@ void VulkanContext::recreate_swapchain(WindowParameters parameters, vk::RenderPa
544544
create_swap_chain(std::move(old_swap_chain));
545545
create_swapchain_views(device, swapchain, swapchain_atributes.format.format, swapchain_images);
546546
create_framebuffers(render_pass);
547+
swapchain_was_suboptimal = false;
547548
}
548549

549-
uint32_t VulkanContext::acquire_next_swapchain_image(vk::Semaphore acquire_semaphore) const {
550+
uint32_t VulkanContext::acquire_next_swapchain_image(vk::Semaphore acquire_semaphore) {
551+
if(swapchain_was_suboptimal){
552+
return swapchain_image_out_of_date;
553+
}
554+
550555
constexpr uint64_t timeout = 1'000'000'000; // 1s = 1 000 000 000 nanoseconds
551556
uint32_t image_index;
552557
auto acquired = device.acquireNextImageKHR(swapchain, timeout, acquire_semaphore, nullptr, &image_index);
553558
switch (acquired) {
554559
case vk::Result::eSuccess:
555560
break;
556-
case vk::Result::eSuboptimalKHR: [[fallthrough]];
561+
case vk::Result::eSuboptimalKHR:
562+
swapchain_was_suboptimal = true;
563+
break;
557564
case vk::Result::eErrorOutOfDateKHR:
558565
image_index = swapchain_image_out_of_date;
559566
break;

src/video_display/vulkan/vulkan_context.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ class VulkanContext {
158158
vk::PresentModeKHR preferred_present_mode{};
159159

160160
vulkan_display::WindowParameters window_parameters;
161+
bool swapchain_was_suboptimal = false;
161162
public:
162163
//getters
163164
uint32_t get_vulkan_version() const { return vulkan_version; }
@@ -199,7 +200,7 @@ class VulkanContext {
199200

200201
void create_framebuffers(vk::RenderPass render_pass);
201202

202-
uint32_t acquire_next_swapchain_image(vk::Semaphore acquire_semaphore) const;
203+
uint32_t acquire_next_swapchain_image(vk::Semaphore acquire_semaphore);
203204

204205
vk::Framebuffer get_framebuffer(uint32_t framebuffer_id) {
205206
return swapchain_images[framebuffer_id].framebuffer;

0 commit comments

Comments
 (0)