Skip to content

Commit

Permalink
VulkanRenderManager: Split finish and present (so we can inject a wai…
Browse files Browse the repository at this point in the history
…t in between if desired).
  • Loading branch information
hrydgard committed Aug 10, 2023
1 parent a246df4 commit e06e919
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 24 deletions.
1 change: 1 addition & 0 deletions Common/GPU/Vulkan/VulkanFrameData.h
Expand Up @@ -13,6 +13,7 @@ enum {
};

enum class VKRRunType {
SUBMIT,
PRESENT,
SYNC,
EXIT,
Expand Down
66 changes: 43 additions & 23 deletions Common/GPU/Vulkan/VulkanRenderManager.cpp
Expand Up @@ -1339,7 +1339,7 @@ void VulkanRenderManager::Finish() {
FrameData &frameData = frameData_[curFrame];

VLOG("PUSH: Frame[%d]", curFrame);
VKRRenderThreadTask *task = new VKRRenderThreadTask(VKRRunType::PRESENT);
VKRRenderThreadTask *task = new VKRRenderThreadTask(VKRRunType::SUBMIT);
task->frame = curFrame;
if (useRenderThread_) {
std::unique_lock<std::mutex> lock(pushMutex_);
Expand All @@ -1354,6 +1354,23 @@ void VulkanRenderManager::Finish() {
}

steps_.clear();
}

void VulkanRenderManager::Present() {
int curFrame = vulkan_->GetCurFrame();

VKRRenderThreadTask *task = new VKRRenderThreadTask(VKRRunType::PRESENT);
task->frame = curFrame;
if (useRenderThread_) {
std::unique_lock<std::mutex> lock(pushMutex_);
renderThreadQueue_.push(task);
pushCondVar_.notify_one();
} else {
// Just do it!
Run(*task);
delete task;
}

vulkan_->EndFrame();
insideFrame_ = false;
}
Expand All @@ -1371,6 +1388,30 @@ void VulkanRenderManager::Wipe() {
void VulkanRenderManager::Run(VKRRenderThreadTask &task) {
FrameData &frameData = frameData_[task.frame];

if (task.runType == VKRRunType::PRESENT) {
if (!frameData.skipSwap) {
VkResult res = frameData.QueuePresent(vulkan_, frameDataShared_);
frameTimeData_[frameData.frameId].queuePresent = time_now_d();
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// We clearly didn't get this in vkAcquireNextImageKHR because of the skipSwap check above.
// Do the increment.
outOfDateFrames_++;
} else if (res == VK_SUBOPTIMAL_KHR) {
outOfDateFrames_++;
} else if (res != VK_SUCCESS) {
_assert_msg_(false, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res));
} else {
// Success
outOfDateFrames_ = 0;
}
} else {
// We only get here if vkAcquireNextImage returned VK_ERROR_OUT_OF_DATE.
outOfDateFrames_++;
frameData.skipSwap = false;
}
return;
}

_dbg_assert_(!frameData.hasPresentCommands);

if (!frameTimeData_[frameData.frameId].firstSubmit) {
Expand Down Expand Up @@ -1407,29 +1448,8 @@ void VulkanRenderManager::Run(VKRRenderThreadTask &task) {
}

switch (task.runType) {
case VKRRunType::PRESENT:
case VKRRunType::SUBMIT:
frameData.SubmitPending(vulkan_, FrameSubmitType::Present, frameDataShared_);

if (!frameData.skipSwap) {
VkResult res = frameData.QueuePresent(vulkan_, frameDataShared_);
frameTimeData_[frameData.frameId].queuePresent = time_now_d();
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// We clearly didn't get this in vkAcquireNextImageKHR because of the skipSwap check above.
// Do the increment.
outOfDateFrames_++;
} else if (res == VK_SUBOPTIMAL_KHR) {
outOfDateFrames_++;
} else if (res != VK_SUCCESS) {
_assert_msg_(false, "vkQueuePresentKHR failed! result=%s", VulkanResultToString(res));
} else {
// Success
outOfDateFrames_ = 0;
}
} else {
// We only get here if vkAcquireNextImage returned VK_ERROR_OUT_OF_DATE.
outOfDateFrames_++;
frameData.skipSwap = false;
}
break;

case VKRRunType::SYNC:
Expand Down
3 changes: 2 additions & 1 deletion Common/GPU/Vulkan/VulkanRenderManager.h
Expand Up @@ -187,8 +187,9 @@ class VulkanRenderManager {

// Makes sure that the GPU has caught up enough that we can start writing buffers of this frame again.
void BeginFrame(bool enableProfiling, bool enableLogProfiler);
// Can run on a different thread!
// These can run on a different thread!
void Finish();
void Present();
// Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown.
void Wipe();

Expand Down
1 change: 1 addition & 0 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Expand Up @@ -1116,6 +1116,7 @@ void VKContext::BeginFrame() {

void VKContext::EndFrame() {
renderManager_.Finish();
renderManager_.Present();

// Unbind stuff, to avoid accidentally relying on it across frames (and provide some protection against forgotten unbinds of deleted things).
Invalidate(InvalidationFlags::CACHED_RENDER_STATE);
Expand Down

0 comments on commit e06e919

Please sign in to comment.