mirror of
https://github.com/libretro/ppsspp.git
synced 2025-03-04 14:37:17 +00:00
Vulkan: Resignal unexecuted fences on thread stop.
When resizing or similar, we may end up with frames we never ran. This also happens on startup. We need them signaled at start so we can wait on them, or we may deadlock.
This commit is contained in:
parent
ebe9dcafde
commit
56d34402ff
@ -189,12 +189,6 @@ void VulkanRenderManager::CreateBackbuffers() {
|
||||
|
||||
// Start the thread.
|
||||
if (useThread) {
|
||||
for (int i = 0; i < vulkan_->GetInflightFrames(); i++) {
|
||||
// Reset all the frameData. Might be dirty from previous thread stop.
|
||||
frameData_[i].readyForRun = false;
|
||||
frameData_[i].readyForFence = true;
|
||||
}
|
||||
|
||||
run_ = true;
|
||||
// Won't necessarily be 0.
|
||||
threadInitFrame_ = vulkan_->GetCurFrame();
|
||||
@ -202,22 +196,37 @@ void VulkanRenderManager::CreateBackbuffers() {
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderManager::DestroyBackbuffers() {
|
||||
if (useThread) {
|
||||
void VulkanRenderManager::StopThread(bool shutdown) {
|
||||
if (useThread && run_) {
|
||||
run_ = false;
|
||||
// Stop the thread.
|
||||
for (int i = 0; i < vulkan_->GetInflightFrames(); i++) {
|
||||
auto &frameData = frameData_[i];
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData_[i].push_mutex);
|
||||
frameData_[i].push_condVar.notify_all();
|
||||
std::unique_lock<std::mutex> lock(frameData.push_mutex);
|
||||
frameData.push_condVar.notify_all();
|
||||
}
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(frameData_[i].pull_mutex);
|
||||
frameData_[i].pull_condVar.notify_all();
|
||||
std::unique_lock<std::mutex> lock(frameData.pull_mutex);
|
||||
frameData.pull_condVar.notify_all();
|
||||
}
|
||||
}
|
||||
thread_.join();
|
||||
|
||||
// Resignal fences for next time around - must be done after join.
|
||||
for (int i = 0; i < vulkan_->GetInflightFrames(); i++) {
|
||||
auto &frameData = frameData_[i];
|
||||
frameData.readyForRun = false;
|
||||
if (!shutdown && !frameData.readyForFence) {
|
||||
vkDestroyFence(vulkan_->GetDevice(), frameData.fence, nullptr);
|
||||
frameData.fence = vulkan_->CreateFence(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VulkanRenderManager::DestroyBackbuffers() {
|
||||
StopThread(false);
|
||||
vulkan_->WaitUntilQueueIdle();
|
||||
|
||||
VkDevice device = vulkan_->GetDevice();
|
||||
@ -237,9 +246,10 @@ void VulkanRenderManager::DestroyBackbuffers() {
|
||||
}
|
||||
|
||||
VulkanRenderManager::~VulkanRenderManager() {
|
||||
run_ = false;
|
||||
VkDevice device = vulkan_->GetDevice();
|
||||
StopThread(true);
|
||||
vulkan_->WaitUntilQueueIdle();
|
||||
|
||||
VkDevice device = vulkan_->GetDevice();
|
||||
vkDestroySemaphore(device, acquireSemaphore_, nullptr);
|
||||
vkDestroySemaphore(device, renderingCompleteSemaphore_, nullptr);
|
||||
for (int i = 0; i < vulkan_->GetInflightFrames(); i++) {
|
||||
|
@ -221,6 +221,8 @@ private:
|
||||
void FlushSync();
|
||||
void EndSyncFrame(int frame);
|
||||
|
||||
void StopThread(bool shutdown);
|
||||
|
||||
// Permanent objects
|
||||
VkSemaphore acquireSemaphore_;
|
||||
VkSemaphore renderingCompleteSemaphore_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user