mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Merge pull request #22178 from saboten731/pr/libretro-vulkan-presentation-handoff
Libretro Vulkan: wait for presentation handoff completion
This commit is contained in:
4 files changed
+28
-10
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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_; });
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user