video_core/vulkan: Explicity check swapchain size when deciding to recreate
Vulkan for whatever reason does not return VK_ERROR_OUT_OF_DATE_KHR when the swapchain is the wrong size. Explicity make sure the size is indeed up to date to workaround this.
This commit is contained in:
parent
d5f53da79d
commit
3cc3176ad6
|
@ -139,23 +139,25 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
||||||
RenderScreenshot(*framebuffer, use_accelerated);
|
RenderScreenshot(*framebuffer, use_accelerated);
|
||||||
|
|
||||||
bool has_been_recreated = false;
|
bool has_been_recreated = false;
|
||||||
const auto recreate_swapchain = [&] {
|
const auto recreate_swapchain = [&](u32 width, u32 height) {
|
||||||
if (!has_been_recreated) {
|
if (!has_been_recreated) {
|
||||||
has_been_recreated = true;
|
has_been_recreated = true;
|
||||||
scheduler.Finish();
|
scheduler.Finish();
|
||||||
}
|
}
|
||||||
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
|
swapchain.Create(width, height, is_srgb);
|
||||||
swapchain.Create(layout.width, layout.height, is_srgb);
|
|
||||||
};
|
};
|
||||||
if (swapchain.NeedsRecreation(is_srgb)) {
|
|
||||||
recreate_swapchain();
|
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
|
||||||
|
if (swapchain.NeedsRecreation(is_srgb) || swapchain.GetWidth() != layout.width ||
|
||||||
|
swapchain.GetHeight() != layout.height) {
|
||||||
|
recreate_swapchain(layout.width, layout.height);
|
||||||
}
|
}
|
||||||
bool is_outdated;
|
bool is_outdated;
|
||||||
do {
|
do {
|
||||||
swapchain.AcquireNextImage();
|
swapchain.AcquireNextImage();
|
||||||
is_outdated = swapchain.IsOutDated();
|
is_outdated = swapchain.IsOutDated();
|
||||||
if (is_outdated) {
|
if (is_outdated) {
|
||||||
recreate_swapchain();
|
recreate_swapchain(layout.width, layout.height);
|
||||||
}
|
}
|
||||||
} while (is_outdated);
|
} while (is_outdated);
|
||||||
if (has_been_recreated) {
|
if (has_been_recreated) {
|
||||||
|
|
|
@ -67,17 +67,19 @@ VkExtent2D ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, u32 wi
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, u32 width,
|
Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_,
|
||||||
u32 height, bool srgb)
|
u32 width_, u32 height_, bool srgb)
|
||||||
: surface{surface_}, device{device_}, scheduler{scheduler_} {
|
: surface{surface_}, device{device_}, scheduler{scheduler_} {
|
||||||
Create(width, height, srgb);
|
Create(width_, height_, srgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
Swapchain::~Swapchain() = default;
|
Swapchain::~Swapchain() = default;
|
||||||
|
|
||||||
void Swapchain::Create(u32 width, u32 height, bool srgb) {
|
void Swapchain::Create(u32 width_, u32 height_, bool srgb) {
|
||||||
is_outdated = false;
|
is_outdated = false;
|
||||||
is_suboptimal = false;
|
is_suboptimal = false;
|
||||||
|
width = width_;
|
||||||
|
height = height_;
|
||||||
|
|
||||||
const auto physical_device = device.GetPhysical();
|
const auto physical_device = device.GetPhysical();
|
||||||
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)};
|
const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)};
|
||||||
|
@ -88,7 +90,7 @@ void Swapchain::Create(u32 width, u32 height, bool srgb) {
|
||||||
device.GetLogical().WaitIdle();
|
device.GetLogical().WaitIdle();
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
CreateSwapchain(capabilities, width, height, srgb);
|
CreateSwapchain(capabilities, srgb);
|
||||||
CreateSemaphores();
|
CreateSemaphores();
|
||||||
CreateImageViews();
|
CreateImageViews();
|
||||||
|
|
||||||
|
@ -148,8 +150,7 @@ void Swapchain::Present(VkSemaphore render_semaphore) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height,
|
void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb) {
|
||||||
bool srgb) {
|
|
||||||
const auto physical_device{device.GetPhysical()};
|
const auto physical_device{device.GetPhysical()};
|
||||||
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)};
|
const auto formats{physical_device.GetSurfaceFormatsKHR(surface)};
|
||||||
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)};
|
const auto present_modes{physical_device.GetSurfacePresentModesKHR(surface)};
|
||||||
|
|
|
@ -80,9 +80,16 @@ public:
|
||||||
return *present_semaphores[frame_index];
|
return *present_semaphores[frame_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetWidth() const {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetHeight() const {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u32 width, u32 height,
|
void CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bool srgb);
|
||||||
bool srgb);
|
|
||||||
void CreateSemaphores();
|
void CreateSemaphores();
|
||||||
void CreateImageViews();
|
void CreateImageViews();
|
||||||
|
|
||||||
|
@ -105,6 +112,9 @@ private:
|
||||||
std::vector<u64> resource_ticks;
|
std::vector<u64> resource_ticks;
|
||||||
std::vector<vk::Semaphore> present_semaphores;
|
std::vector<vk::Semaphore> present_semaphores;
|
||||||
|
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
|
||||||
u32 image_index{};
|
u32 image_index{};
|
||||||
u32 frame_index{};
|
u32 frame_index{};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue