From a91e206926af3ada7268758c69411d0ed97c80d3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 29 Feb 2020 23:40:55 -0800 Subject: [PATCH 1/2] GPU: Add setting to control inflight frame usage. --- Common/Vulkan/VulkanContext.cpp | 8 ++++++++ Common/Vulkan/VulkanContext.h | 2 ++ Core/Config.cpp | 2 ++ Core/Config.h | 1 + Core/FileLoaders/RamCachingFileLoader.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 6 ++++++ GPU/Vulkan/GPU_Vulkan.cpp | 6 +++++- UI/GameSettingsScreen.cpp | 8 ++++++++ ext/native/thin3d/GLRenderManager.cpp | 8 ++++++-- ext/native/thin3d/GLRenderManager.h | 7 +++++++ ext/native/thin3d/VulkanRenderManager.cpp | 4 ++++ ext/native/thin3d/VulkanRenderManager.h | 5 +++++ 12 files changed, 55 insertions(+), 4 deletions(-) diff --git a/Common/Vulkan/VulkanContext.cpp b/Common/Vulkan/VulkanContext.cpp index cb4dc0b33a09..9d5837788bc1 100644 --- a/Common/Vulkan/VulkanContext.cpp +++ b/Common/Vulkan/VulkanContext.cpp @@ -285,6 +285,14 @@ void VulkanContext::EndFrame() { } } +void VulkanContext::UpdateInflightFrames(int n) { + assert(n >= 1 && n <= MAX_INFLIGHT_FRAMES); + inflightFrames_ = n; + if (curFrame_ >= inflightFrames_) { + curFrame_ = 0; + } +} + void VulkanContext::WaitUntilQueueIdle() { // Should almost never be used vkQueueWaitIdle(gfx_queue_); diff --git a/Common/Vulkan/VulkanContext.h b/Common/Vulkan/VulkanContext.h index fccc3dc98e10..40eb6a78e8fb 100644 --- a/Common/Vulkan/VulkanContext.h +++ b/Common/Vulkan/VulkanContext.h @@ -249,6 +249,8 @@ class VulkanContext { int GetInflightFrames() const { return inflightFrames_; } + // Don't call while a frame is in progress. + void UpdateInflightFrames(int n); int GetCurFrame() const { return curFrame_; diff --git a/Core/Config.cpp b/Core/Config.cpp index d73c00276c80..e1bbe8ddbb43 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -772,6 +772,8 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("GfxDebugSplitSubmit", &g_Config.bGfxDebugSplitSubmit, false, false, false), ConfigSetting("LogFrameDrops", &g_Config.bLogFrameDrops, false, true, false), + ConfigSetting("UseInflightFrames", &g_Config.bUseInflightFrames, true, true, true), + ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 68f938be7931..62ee4733d9ff 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -195,6 +195,7 @@ struct Config { std::string sPostShaderName; // Off for off. bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; + bool bUseInflightFrames; // Sound bool bEnableSound; diff --git a/Core/FileLoaders/RamCachingFileLoader.cpp b/Core/FileLoaders/RamCachingFileLoader.cpp index 9ea0c2e61ff9..bc99ad80f00f 100644 --- a/Core/FileLoaders/RamCachingFileLoader.cpp +++ b/Core/FileLoaders/RamCachingFileLoader.cpp @@ -78,7 +78,7 @@ size_t RamCachingFileLoader::ReadAt(s64 absolutePos, size_t bytes, void *data, F size_t bytesFromCache = ReadFromCache(absolutePos + readSize, bytes - readSize, (u8 *)data + readSize); readSize += bytesFromCache; if (bytesFromCache == 0) { - // We can't read any more. + // We can't read any more. break; } } diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 97b0ecf17849..3fa59b525706 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -97,6 +97,9 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) textureCacheGL_->NotifyConfigChanged(); + GLRenderManager *rm = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->UseInflightFrames(g_Config.bUseInflightFrames); + // Load shader cache. std::string discID = g_paramSFO.GetDiscID(); if (discID.size()) { @@ -355,6 +358,9 @@ void GPU_GLES::BeginHostFrame() { GPUCommon::BeginHostFrame(); UpdateCmdInfo(); if (resized_) { + GLRenderManager *rm = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->UseInflightFrames(g_Config.bUseInflightFrames); + CheckGPUFeatures(); framebufferManager_->Resized(); drawEngine_.Resized(); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 3f20ec064210..464adaf0baba 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -28,7 +28,6 @@ #include "Core/Config.h" #include "Core/Debugger/Breakpoints.h" #include "Core/MemMapHelpers.h" -#include "Core/Config.h" #include "Core/Reporting.h" #include "Core/System.h" #include "Core/ELF/ParamSFO.h" @@ -99,6 +98,8 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) if (vulkan_->GetDeviceFeatures().enabled.wideLines) { drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } + VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->UseInflightFrames(g_Config.bUseInflightFrames); // Load shader cache. std::string discID = g_paramSFO.GetDiscID(); @@ -276,6 +277,9 @@ void GPU_Vulkan::BeginHostFrame() { UpdateCmdInfo(); if (resized_) { + VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + rm->UseInflightFrames(g_Config.bUseInflightFrames); + CheckGPUFeatures(); // In case the GPU changed. BuildReportingInfo(); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index a6fae59fa451..26a03290216e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -345,6 +345,14 @@ void GameSettingsScreen::CreateViews() { graphicsSettings->Add(new CheckBox(&g_Config.bVSync, gr->T("VSync"))); #endif + if (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::OPENGL) { + CheckBox *inflightFrames = graphicsSettings->Add(new CheckBox(&g_Config.bUseInflightFrames, gr->T("Buffer graphics commands (faster, input lag)"))); + inflightFrames->OnClick.Add([=](EventParams &e) { + NativeMessageReceived("gpu_resized", ""); + return UI::EVENT_CONTINUE; + }); + } + CheckBox *hwTransform = graphicsSettings->Add(new CheckBox(&g_Config.bHardwareTransform, gr->T("Hardware Transform"))); hwTransform->OnClick.Handle(this, &GameSettingsScreen::OnHardwareTransform); hwTransform->SetDisabledPtr(&g_Config.bSoftwareRendering); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index f3fe9ce65a81..e34168111da4 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -166,7 +166,7 @@ bool GLRenderManager::ThreadFrame() { do { if (nextFrame) { threadFrame_++; - if (threadFrame_ >= MAX_INFLIGHT_FRAMES) + if (threadFrame_ >= inflightFrames_) threadFrame_ = 0; } FrameData &frameData = frameData_[threadFrame_]; @@ -449,7 +449,11 @@ void GLRenderManager::Finish() { frameData.pull_condVar.notify_all(); curFrame_++; - if (curFrame_ >= MAX_INFLIGHT_FRAMES) + if (newInflightFrames_ != -1) { + inflightFrames_ = newInflightFrames_; + newInflightFrames_ = -1; + } + if (curFrame_ >= inflightFrames_) curFrame_ = 0; insideFrame_ = false; diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index d7d6f54b7645..69838cc52f44 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -862,6 +862,10 @@ class GLRenderManager { enum { MAX_INFLIGHT_FRAMES = 3 }; + void UseInflightFrames(bool use) { + newInflightFrames_ = use ? MAX_INFLIGHT_FRAMES : 1; + } + int GetCurFrame() const { return curFrame_; } @@ -988,6 +992,9 @@ class GLRenderManager { std::function swapIntervalFunction_; GLBufferStrategy bufferStrategy_ = GLBufferStrategy::SUBDATA; + int inflightFrames_ = MAX_INFLIGHT_FRAMES; + int newInflightFrames_ = -1; + int swapInterval_ = 0; bool swapIntervalChanged_ = true; diff --git a/ext/native/thin3d/VulkanRenderManager.cpp b/ext/native/thin3d/VulkanRenderManager.cpp index f6c4778c62ae..21dd931fb867 100644 --- a/ext/native/thin3d/VulkanRenderManager.cpp +++ b/ext/native/thin3d/VulkanRenderManager.cpp @@ -914,6 +914,10 @@ void VulkanRenderManager::Finish() { frameData.pull_condVar.notify_all(); } vulkan_->EndFrame(); + if (newInflightFrames_ != -1) { + vulkan_->UpdateInflightFrames(newInflightFrames_); + newInflightFrames_ = -1; + } insideFrame_ = false; } diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index c14c894a72c7..837e0e37b599 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -240,6 +240,10 @@ class VulkanRenderManager { splitSubmit_ = split; } + void UseInflightFrames(bool use) { + newInflightFrames_ = use ? VulkanContext::MAX_INFLIGHT_FRAMES : 1; + } + VulkanContext *GetVulkanContext() { return vulkan_; } @@ -302,6 +306,7 @@ class VulkanRenderManager { }; FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]; + int newInflightFrames_ = -1; // Submission time state int curWidth_ = -1; From 98df4bbec354155427680d29fcc237b1e4722656 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 1 Mar 2020 08:53:46 -0800 Subject: [PATCH 2/2] GPU: Allow choosing number of inflight frames. --- Core/Config.cpp | 2 +- Core/Config.h | 2 +- GPU/GLES/GPU_GLES.cpp | 4 ++-- GPU/Vulkan/GPU_Vulkan.cpp | 4 ++-- UI/GameSettingsScreen.cpp | 5 +++-- ext/native/thin3d/GLRenderManager.h | 4 ++-- ext/native/thin3d/VulkanRenderManager.h | 4 ++-- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index e1bbe8ddbb43..ca38c4ed9bf3 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -772,7 +772,7 @@ static ConfigSetting graphicsSettings[] = { ConfigSetting("GfxDebugSplitSubmit", &g_Config.bGfxDebugSplitSubmit, false, false, false), ConfigSetting("LogFrameDrops", &g_Config.bLogFrameDrops, false, true, false), - ConfigSetting("UseInflightFrames", &g_Config.bUseInflightFrames, true, true, true), + ConfigSetting("InflightFrames", &g_Config.iInflightFrames, 3, true, true), ConfigSetting(false), }; diff --git a/Core/Config.h b/Core/Config.h index 62ee4733d9ff..43e417006e72 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -195,7 +195,7 @@ struct Config { std::string sPostShaderName; // Off for off. bool bGfxDebugOutput; bool bGfxDebugSplitSubmit; - bool bUseInflightFrames; + int iInflightFrames; // Sound bool bEnableSound; diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 3fa59b525706..21523c53ad1b 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -98,7 +98,7 @@ GPU_GLES::GPU_GLES(GraphicsContext *gfxCtx, Draw::DrawContext *draw) textureCacheGL_->NotifyConfigChanged(); GLRenderManager *rm = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - rm->UseInflightFrames(g_Config.bUseInflightFrames); + rm->SetInflightFrames(g_Config.iInflightFrames); // Load shader cache. std::string discID = g_paramSFO.GetDiscID(); @@ -359,7 +359,7 @@ void GPU_GLES::BeginHostFrame() { UpdateCmdInfo(); if (resized_) { GLRenderManager *rm = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - rm->UseInflightFrames(g_Config.bUseInflightFrames); + rm->SetInflightFrames(g_Config.iInflightFrames); CheckGPUFeatures(); framebufferManager_->Resized(); diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 464adaf0baba..3caa3181c706 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -99,7 +99,7 @@ GPU_Vulkan::GPU_Vulkan(GraphicsContext *gfxCtx, Draw::DrawContext *draw) drawEngine_.SetLineWidth(PSP_CoreParameter().renderWidth / 480.0f); } VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - rm->UseInflightFrames(g_Config.bUseInflightFrames); + rm->SetInflightFrames(g_Config.iInflightFrames); // Load shader cache. std::string discID = g_paramSFO.GetDiscID(); @@ -278,7 +278,7 @@ void GPU_Vulkan::BeginHostFrame() { if (resized_) { VulkanRenderManager *rm = (VulkanRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); - rm->UseInflightFrames(g_Config.bUseInflightFrames); + rm->SetInflightFrames(g_Config.iInflightFrames); CheckGPUFeatures(); // In case the GPU changed. diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 26a03290216e..1618361d5fd1 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -346,8 +346,9 @@ void GameSettingsScreen::CreateViews() { #endif if (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::OPENGL) { - CheckBox *inflightFrames = graphicsSettings->Add(new CheckBox(&g_Config.bUseInflightFrames, gr->T("Buffer graphics commands (faster, input lag)"))); - inflightFrames->OnClick.Add([=](EventParams &e) { + static const char *bufferOptions[] = { "No buffer", "Up to 1", "Up to 2" }; + PopupMultiChoice *inflightChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iInflightFrames, gr->T("Buffer graphics commands (faster, input lag)"), bufferOptions, 0, ARRAY_SIZE(bufferOptions), gr->GetName(), screenManager())); + inflightChoice->OnChoice.Add([=](EventParams &e) { NativeMessageReceived("gpu_resized", ""); return UI::EVENT_CONTINUE; }); diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index 69838cc52f44..377344b07319 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -862,8 +862,8 @@ class GLRenderManager { enum { MAX_INFLIGHT_FRAMES = 3 }; - void UseInflightFrames(bool use) { - newInflightFrames_ = use ? MAX_INFLIGHT_FRAMES : 1; + void SetInflightFrames(int f) { + newInflightFrames_ = f < 1 || f > MAX_INFLIGHT_FRAMES ? MAX_INFLIGHT_FRAMES : f; } int GetCurFrame() const { diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 837e0e37b599..27fc2deca9a7 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -240,8 +240,8 @@ class VulkanRenderManager { splitSubmit_ = split; } - void UseInflightFrames(bool use) { - newInflightFrames_ = use ? VulkanContext::MAX_INFLIGHT_FRAMES : 1; + void SetInflightFrames(int f) { + newInflightFrames_ = f < 1 || f > VulkanContext::MAX_INFLIGHT_FRAMES ? VulkanContext::MAX_INFLIGHT_FRAMES : f; } VulkanContext *GetVulkanContext() {