Fix the splash screen (#1378)

Fix swapchain acquire semaphore reuse

Co-authored-by: nmzik <Nmzik@mail.ru>
This commit is contained in:
Ettore Sartori 2026-10-12 13:40:59 +02:00 committed by GitHub
parent dad900c61d
commit 5ce9a52936
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 12 additions and 4 deletions

View File

@ -266,7 +266,7 @@ public:
void Create();
void Recreate(bool surface_lost = false);
[[nodiscard]] bool NeedsResize() const;
[[nodiscard]] Status AcquireNextImage();
[[nodiscard]] Status AcquireNextImage(CommandScheduler& scheduler);
[[nodiscard]] bool PrepareSystemOverlay();
void RecordPresentCommands(CommandBuffer& command, Presenter::Frame* source,
const Presenter::Layer& overlay, bool draw_system_overlay);
@ -301,6 +301,7 @@ private:
std::vector<vk::Image> m_images;
std::vector<vk::ImageView> m_image_views;
std::vector<vk::Semaphore> m_image_acquired;
std::vector<uint64_t> m_image_acquired_ticks;
std::vector<vk::Semaphore> m_render_complete;
std::unique_ptr<SystemOverlay> m_system_overlay;
vk::DescriptorSetLayout m_overlay_descriptors = nullptr;
@ -501,6 +502,7 @@ void Swapchain::Create() {
vk::SemaphoreCreateInfo semaphore_info {};
semaphore_info.sType = vk::StructureType::eSemaphoreCreateInfo;
m_image_acquired.resize(m_images.size());
m_image_acquired_ticks.assign(m_images.size(), 0);
m_render_complete.resize(m_images.size());
for (size_t i = 0; i < m_images.size(); i++) {
RequireVulkanSuccess(
@ -569,6 +571,7 @@ void Swapchain::Destroy() {
m_images.clear();
m_image_views.clear();
m_image_acquired.clear();
m_image_acquired_ticks.clear();
m_render_complete.clear();
}
@ -594,8 +597,11 @@ bool Swapchain::NeedsResize() const {
m_window_extent.height != m_window.graphic_ctx.screen_height;
}
Swapchain::Status Swapchain::AcquireNextImage() {
Swapchain::Status Swapchain::AcquireNextImage(CommandScheduler& scheduler) {
EXIT_IF(m_handle == nullptr || m_frame_index >= m_image_acquired.size());
// Repeated frames can wrap the semaphore ring without acquiring a new source frame.
// Wait for the submission that consumed this slot before signaling it again.
scheduler.Wait(m_image_acquired_ticks[m_frame_index]);
m_image_index = static_cast<uint32_t>(-1);
const auto result = m_window.graphic_ctx.device.acquireNextImageKHR(
m_handle, std::numeric_limits<uint64_t>::max(), m_image_acquired[m_frame_index], nullptr,
@ -867,7 +873,9 @@ uint64_t Swapchain::Submit(CommandScheduler& scheduler) {
SubmitInfo submit;
submit.AddWait(m_image_acquired[m_frame_index], 1, vk::PipelineStageFlagBits::eTransfer);
submit.AddSignal(m_render_complete[m_image_index]);
return scheduler.Submit(submit);
const auto tick = scheduler.Submit(submit);
m_image_acquired_ticks[m_frame_index] = tick;
return tick;
}
Swapchain::Status Swapchain::Present() {
@ -1023,7 +1031,7 @@ void Presenter::Impl::Present() {
RecoverSwapchain(Swapchain::Status::Recreate);
}
for (uint32_t attempt = 0; attempt < 2; attempt++) {
auto status = swapchain.AcquireNextImage();
auto status = swapchain.AcquireNextImage(present_scheduler);
if (status != Swapchain::Status::Success) {
RecoverSwapchain(status);
continue;