Merge pull request #22178 from saboten731/pr/libretro-vulkan-presentation-handoff

Libretro Vulkan: wait for presentation handoff completion
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2026-08-31 09:54:58 +02:00
commit f4b0c604cd
4 files changed
+28 -10

No files matched your search

+5
View File
@@ -31,6 +31,11 @@ public:
// Mirrors vkQueuePresentKHR: hands the finished image back, waiting on waitSemaphore first.
virtual VkResult QueuePresent(VulkanContext *vulkan, VkQueue queue, uint32_t imageIndex, VkSemaphore waitSemaphore) = 0;
// Called around a queued presentation. Hosts that hand an image to another thread can use this
// to keep the caller from invoking its video callback until QueuePresent has completed.
virtual void BeginPresent() {}
virtual void EndPresent() {}
virtual uint32_t GetImageCount() const = 0;
virtual VkImage GetImage(uint32_t index) const = 0;
virtual VkExtent2D GetExtent() const = 0;
@@ -1620,6 +1620,9 @@ void VulkanRenderManager::Finish() {
void VulkanRenderManager::Present() {
int curFrame = vulkan_->GetCurFrame();
if (VulkanPresentation *presentation = vulkan_->GetPresentation()) {
presentation->BeginPresent();
}
VKRRenderThreadTask *task = new VKRRenderThreadTask(VKRRunType::PRESENT);
task->frame = curFrame;
@@ -1671,6 +1674,9 @@ void VulkanRenderManager::Run(VKRRenderThreadTask &task) {
}
frameData.skipSwap = false;
}
if (VulkanPresentation *presentation = vulkan_->GetPresentation()) {
presentation->EndPresent();
}
return;
}
+14 -8
View File
@@ -106,8 +106,8 @@ void LibretroVulkanPresentation::Destroy(VulkanContext *context) {
images_.clear();
syncIndexMask_ = 0;
std::lock_guard<std::mutex> lock(mutex_);
currentIndex_ = -1;
everPresented_ = false;
presentPending_ = false;
condVar_.notify_all();
}
bool LibretroVulkanPresentation::NeedsRecreate() const {
@@ -138,13 +138,21 @@ VkResult LibretroVulkanPresentation::QueuePresent(VulkanContext *vulkan, VkQueue
return VK_ERROR_OUT_OF_DATE_KHR;
}
std::unique_lock<std::mutex> lock(mutex_);
currentIndex_ = (int)imageIndex;
vulkan_->set_image(vulkan_->handle, &images_[imageIndex].retroImage, 0, nullptr, vulkan_->queue_index);
everPresented_ = true;
condVar_.notify_all();
return VK_SUCCESS;
}
void LibretroVulkanPresentation::BeginPresent() {
std::lock_guard<std::mutex> lock(mutex_);
presentPending_ = true;
}
void LibretroVulkanPresentation::EndPresent() {
std::lock_guard<std::mutex> lock(mutex_);
presentPending_ = false;
condVar_.notify_all();
}
void LibretroVulkanPresentation::LockQueue() {
vulkan_->lock_queue(vulkan_->handle);
}
@@ -162,7 +170,5 @@ void LibretroVulkanPresentation::PrepareSubmit(VkSubmitInfo &submitInfo) {
void LibretroVulkanPresentation::WaitForPresentation() {
std::unique_lock<std::mutex> lock(mutex_);
if (everPresented_ && currentIndex_ < 0) {
condVar_.wait(lock);
}
condVar_.wait(lock, [this] { return !presentPending_; });
}
+3 -2
View File
@@ -30,6 +30,8 @@ public:
VkResult AcquireNextImage(VulkanContext *vulkan, VkSemaphore signalSemaphore, uint32_t *imageIndex) override;
VkResult QueuePresent(VulkanContext *vulkan, VkQueue queue, uint32_t imageIndex, VkSemaphore waitSemaphore) override;
void BeginPresent() override;
void EndPresent() override;
uint32_t GetImageCount() const override { return (uint32_t)images_.size(); }
VkImage GetImage(uint32_t index) const override { return images_[index].image; }
@@ -65,8 +67,7 @@ private:
std::mutex mutex_;
std::condition_variable condVar_;
int currentIndex_ = -1;
bool everPresented_ = false;
bool presentPending_ = false;
static uint32_t ImageCountFromMask(uint32_t mask);
bool IsValidImageIndex(uint32_t imageIndex) const;