From 7f0834c91992c3726f1ba36f32f85b97aaa1ece2 Mon Sep 17 00:00:00 2001 From: iwubcode Date: Sat, 12 Aug 2017 23:10:21 -0500 Subject: [PATCH] Add 'immediate xfb' which reduces xfb latency at the cost of graphical errors --- Source/Core/Core/Analytics.cpp | 1 + Source/Core/Core/Config/GraphicsSettings.cpp | 1 + Source/Core/Core/Config/GraphicsSettings.h | 1 + Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp | 1 + .../Core/Core/ConfigLoaders/IsSettingSaveable.cpp | 1 + .../Core/Core/ConfigLoaders/MovieConfigLoader.cpp | 2 ++ Source/Core/Core/HotkeyManager.cpp | 1 + Source/Core/Core/HotkeyManager.h | 1 + Source/Core/Core/Movie.cpp | 1 + Source/Core/Core/Movie.h | 3 ++- .../Core/DolphinQt2/Config/Graphics/HacksWidget.cpp | 8 ++++++++ .../Core/DolphinQt2/Config/Graphics/HacksWidget.h | 1 + Source/Core/DolphinQt2/HotkeyScheduler.cpp | 2 ++ Source/Core/DolphinWX/Frame.cpp | 7 +++++++ Source/Core/DolphinWX/VideoConfigDiag.cpp | 10 ++++++++++ Source/Core/VideoCommon/BPStructs.cpp | 13 +++++++++++-- Source/Core/VideoCommon/MainBase.cpp | 2 +- Source/Core/VideoCommon/RenderBase.cpp | 3 +-- Source/Core/VideoCommon/VideoConfig.cpp | 1 + Source/Core/VideoCommon/VideoConfig.h | 1 + 20 files changed, 55 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Analytics.cpp b/Source/Core/Core/Analytics.cpp index 0673b283b9..0a079c3e1f 100644 --- a/Source/Core/Core/Analytics.cpp +++ b/Source/Core/Core/Analytics.cpp @@ -225,6 +225,7 @@ void DolphinAnalytics::MakePerGameBuilder() builder.AddData("cfg-gfx-efb-copy-format-changes", g_Config.bEFBEmulateFormatChanges); builder.AddData("cfg-gfx-efb-copy-ram", !g_Config.bSkipEFBCopyToRam); builder.AddData("cfg-gfx-xfb-copy-ram", !g_Config.bSkipXFBCopyToRam); + builder.AddData("cfg-gfx-immediate-xfb", !g_Config.bImmediateXFB); builder.AddData("cfg-gfx-efb-copy-scaled", g_Config.bCopyEFBScaled); builder.AddData("cfg-gfx-internal-resolution", g_Config.iEFBScale); builder.AddData("cfg-gfx-tc-samples", g_Config.iSafeTextureCache_ColorSamples); diff --git a/Source/Core/Core/Config/GraphicsSettings.cpp b/Source/Core/Core/Config/GraphicsSettings.cpp index cc0aae44a2..d4b85972f6 100644 --- a/Source/Core/Core/Config/GraphicsSettings.cpp +++ b/Source/Core/Core/Config/GraphicsSettings.cpp @@ -133,6 +133,7 @@ const ConfigInfo GFX_HACK_SKIP_EFB_COPY_TO_RAM{{System::GFX, "Hacks", "EFB true}; const ConfigInfo GFX_HACK_SKIP_XFB_COPY_TO_RAM{{System::GFX, "Hacks", "XFBToTextureEnable"}, true}; +const ConfigInfo GFX_HACK_IMMEDIATE_XFB{{System::GFX, "Hacks", "ImmediateXFBEnable"}, false}; const ConfigInfo GFX_HACK_COPY_EFB_ENABLED{{System::GFX, "Hacks", "EFBScaledCopy"}, true}; const ConfigInfo GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{ {System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false}; diff --git a/Source/Core/Core/Config/GraphicsSettings.h b/Source/Core/Core/Config/GraphicsSettings.h index 9ebc299379..34a68e9489 100644 --- a/Source/Core/Core/Config/GraphicsSettings.h +++ b/Source/Core/Core/Config/GraphicsSettings.h @@ -100,6 +100,7 @@ extern const ConfigInfo GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION; extern const ConfigInfo GFX_HACK_FORCE_PROGRESSIVE; extern const ConfigInfo GFX_HACK_SKIP_EFB_COPY_TO_RAM; extern const ConfigInfo GFX_HACK_SKIP_XFB_COPY_TO_RAM; +extern const ConfigInfo GFX_HACK_IMMEDIATE_XFB; extern const ConfigInfo GFX_HACK_COPY_EFB_ENABLED; extern const ConfigInfo GFX_HACK_EFB_EMULATE_FORMAT_CHANGES; extern const ConfigInfo GFX_HACK_VERTEX_ROUDING; diff --git a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp index e409757f53..e6ec7c97bc 100644 --- a/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/GameConfigLoader.cpp @@ -108,6 +108,7 @@ static const INIToLocationMap& GetINIToLocationMap() {{"Video_Hacks", "ForceProgressive"}, {Config::GFX_HACK_FORCE_PROGRESSIVE.location}}, {{"Video_Hacks", "EFBToTextureEnable"}, {Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM.location}}, {{"Video_Hacks", "XFBToTextureEnable"}, {Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM.location}}, + {{"Video_Hacks", "ImmediateXFBEnable"}, {Config::GFX_HACK_IMMEDIATE_XFB.location}}, {{"Video_Hacks", "EFBScaledCopy"}, {Config::GFX_EFB_SCALE.location}}, {{"Video_Hacks", "EFBEmulateFormatChanges"}, {Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES.location}}, diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp index c38bec4e4d..0f5f783e5b 100644 --- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp +++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp @@ -74,6 +74,7 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location) Config::GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION.location, Config::GFX_HACK_FORCE_PROGRESSIVE.location, Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM.location, Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM.location, + Config::GFX_HACK_IMMEDIATE_XFB.location, Config::GFX_HACK_COPY_EFB_ENABLED.location, Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES.location, Config::GFX_HACK_VERTEX_ROUDING.location, diff --git a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp index de008d4046..046bcf6631 100644 --- a/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp +++ b/Source/Core/Core/ConfigLoaders/MovieConfigLoader.cpp @@ -43,6 +43,7 @@ static void LoadFromDTM(Config::Layer* config_layer, Movie::DTMHeader* dtm) config_layer->Set(Config::GFX_HACK_EFB_ACCESS_ENABLE, dtm->bEFBAccessEnable); config_layer->Set(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM, dtm->bSkipEFBCopyToRam); config_layer->Set(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, dtm->bSkipXFBCopyToRam); + config_layer->Set(Config::GFX_HACK_IMMEDIATE_XFB, dtm->bImmediateXFB); config_layer->Set(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES, dtm->bEFBEmulateFormatChanges); } @@ -65,6 +66,7 @@ void SaveToDTM(Movie::DTMHeader* dtm) dtm->bEFBAccessEnable = Config::Get(Config::GFX_HACK_EFB_ACCESS_ENABLE); dtm->bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); dtm->bSkipXFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM); + dtm->bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB); dtm->bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); // This never used the regular config diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 5b1627b53e..d989627ad1 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -73,6 +73,7 @@ const std::string hotkey_labels[] = { _trans("Toggle Aspect Ratio"), _trans("Toggle EFB Copies"), _trans("Toggle XFB Copies"), + _trans("Toggle XFB Immediate Mode"), _trans("Toggle Fog"), _trans("Toggle Texture Dumping"), _trans("Toggle Custom Textures"), diff --git a/Source/Core/Core/HotkeyManager.h b/Source/Core/Core/HotkeyManager.h index 68f07545f4..f8cc2bdc66 100644 --- a/Source/Core/Core/HotkeyManager.h +++ b/Source/Core/Core/HotkeyManager.h @@ -71,6 +71,7 @@ enum Hotkey HK_TOGGLE_AR, HK_TOGGLE_EFBCOPIES, HK_TOGGLE_XFBCOPIES, + HK_TOGGLE_IMMEDIATE_XFB, HK_TOGGLE_FOG, HK_TOGGLE_DUMPTEXTURES, HK_TOGGLE_TEXTURES, diff --git a/Source/Core/Core/Movie.cpp b/Source/Core/Core/Movie.cpp index ac135f086c..75bf23ee43 100644 --- a/Source/Core/Core/Movie.cpp +++ b/Source/Core/Core/Movie.cpp @@ -1368,6 +1368,7 @@ void SetGraphicsConfig() g_Config.bEFBAccessEnable = tmpHeader.bEFBAccessEnable; g_Config.bSkipEFBCopyToRam = tmpHeader.bSkipEFBCopyToRam; g_Config.bSkipXFBCopyToRam = tmpHeader.bSkipXFBCopyToRam; + g_Config.bImmediateXFB = tmpHeader.bImmediateXFB; g_Config.bEFBEmulateFormatChanges = tmpHeader.bEFBEmulateFormatChanges; } diff --git a/Source/Core/Core/Movie.h b/Source/Core/Core/Movie.h index c5b477b4bf..e369c5891a 100644 --- a/Source/Core/Core/Movie.h +++ b/Source/Core/Core/Movie.h @@ -88,6 +88,7 @@ struct DTMHeader bool bEFBCopyEnable; bool bSkipEFBCopyToRam; bool bSkipXFBCopyToRam; + bool bImmediateXFB; bool bEFBCopyCacheEnable; bool bEFBEmulateFormatChanges; u8 memcards; // Memcards inserted (from least to most significant, the bits are slot A and B) @@ -97,7 +98,7 @@ struct DTMHeader bool bNetPlay; bool bPAL60; u8 language; - u8 reserved[12]; // Padding for any new config options + u8 reserved[11]; // Padding for any new config options u8 discChange[40]; // Name of iso file to switch to, for two disc games. u8 revision[20]; // Git hash u32 DSPiromHash; diff --git a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp index 723a177c2e..ec2e4809c5 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp +++ b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.cpp @@ -69,6 +69,8 @@ void HacksWidget::CreateWidgets() m_store_xfb_copies = new GraphicsBool(tr("Store XFB Copies to Texture Only"), Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM); + m_immediate_xfb = new GraphicsBool(tr("Immediately Present XFB"), + Config::GFX_HACK_IMMEDIATE_XFB); xfb_layout->addWidget(m_store_xfb_copies, 1, 0); @@ -174,6 +176,11 @@ void HacksWidget::AddDescriptions() "in a small number of games that need to readback from memory.\n\nEnabled = XFB Copies to Texture\nDisabled = XFB Copies to RAM " "(and Texture)\n\nIf unsure, leave this checked."); + static const char* TR_IMMEDIATE_XFB_DESCRIPTION = QT_TR_NOOP( + "Displays the XFB copies as soon as they are created, without waiting for scanout. Can cause graphical defects " + "in some games if the game doesn't expect all XFB copies to be displayed. However, turning this setting on reduces latency." + "\n\nIf unsure, leave this unchecked."); + static const char* TR_GPU_DECODING_DESCRIPTION = QT_TR_NOOP("Enables texture decoding using the GPU instead of the CPU. This may result in " "performance gains in some scenarios, or on systems where the CPU is the " @@ -196,6 +203,7 @@ void HacksWidget::AddDescriptions() AddDescription(m_store_efb_copies, TR_STORE_EFB_TO_TEXTURE_DESCRIPTION); AddDescription(m_accuracy, TR_ACCUARCY_DESCRIPTION); AddDescription(m_store_xfb_copies, TR_STORE_XFB_TO_TEXTURE_DESCRIPTION); + AddDescription(m_immediate_xfb, TR_STORE_XFB_TO_TEXTURE_DESCRIPTION); AddDescription(m_gpu_texture_decoding, TR_GPU_DECODING_DESCRIPTION); AddDescription(m_fast_depth_calculation, TR_FAST_DEPTH_CALC_DESCRIPTION); AddDescription(m_disable_bounding_box, TR_DISABLE_BOUNDINGBOX_DESCRIPTION); diff --git a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h index 9e83e76415..d612a6adf4 100644 --- a/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h +++ b/Source/Core/DolphinQt2/Config/Graphics/HacksWidget.h @@ -32,6 +32,7 @@ private: // External Framebuffer QCheckBox* m_store_xfb_copies; + QCheckBox* m_immediate_xfb; // Other QCheckBox* m_fast_depth_calculation; diff --git a/Source/Core/DolphinQt2/HotkeyScheduler.cpp b/Source/Core/DolphinQt2/HotkeyScheduler.cpp index f72075c489..547e4676de 100644 --- a/Source/Core/DolphinQt2/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt2/HotkeyScheduler.cpp @@ -226,6 +226,8 @@ void HotkeyScheduler::Run() g_Config.bSkipEFBCopyToRam = !g_Config.bSkipEFBCopyToRam; if (IsHotkey(HK_TOGGLE_XFBCOPIES)) g_Config.bSkipXFBCopyToRam = !g_Config.bSkipXFBCopyToRam; + if (IsHotkey(HK_TOGGLE_IMMEDIATE_XFB)) + g_Config.bImmediateXFB = !g_Config.bImmediateXFB; if (IsHotkey(HK_TOGGLE_FOG)) g_Config.bDisableFog = !g_Config.bDisableFog; if (IsHotkey(HK_TOGGLE_DUMPTEXTURES)) diff --git a/Source/Core/DolphinWX/Frame.cpp b/Source/Core/DolphinWX/Frame.cpp index 5732664293..97c0f38ec9 100644 --- a/Source/Core/DolphinWX/Frame.cpp +++ b/Source/Core/DolphinWX/Frame.cpp @@ -1491,6 +1491,13 @@ void CFrame::ParseHotkeys() Config::SetCurrent(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM, !Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM)); } + if (IsHotkey(HK_TOGGLE_IMMEDIATE_XFB)) + { + OSDChoice = 6; + // Toggle immediate present of xfb + Config::SetCurrent(Config::GFX_HACK_IMMEDIATE_XFB, + !Config::Get(Config::GFX_HACK_IMMEDIATE_XFB)); + } if (IsHotkey(HK_TOGGLE_FOG)) { OSDChoice = 4; diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp index ef888a0dca..07dcfb9cd2 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp @@ -205,6 +205,10 @@ static wxString skip_xfb_copy_to_ram_desc = wxTRANSLATE( "Stores XFB Copies exclusively on the GPU, bypassing system memory. Causes graphical defects " "in a small number of games that need to readback from memory.\n\nEnabled = XFB Copies to Texture\nDisabled = XFB Copies to RAM " "(and Texture)\n\nIf unsure, leave this checked."); +static wxString immediate_xfb_desc = wxTRANSLATE( + "Displays the XFB copies as soon as they are created, without waiting for scanout. Can cause graphical defects " + "in some games if the game doesn't expect all XFB copies to be displayed. However, turning this setting on reduces latency." + "\n\nIf unsure, leave this unchecked."); static wxString stc_desc = wxTRANSLATE("The \"Safe\" setting eliminates the likelihood of the GPU missing texture updates " "from RAM.\nLower accuracies cause in-game text to appear garbled in certain " @@ -786,6 +790,12 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string& title) 0, wxLEFT | wxRIGHT, space5); group_xfb->AddSpacer(space5); + group_xfb->Add(CreateCheckBox(page_hacks, _("Immediately Present XFB"), + wxGetTranslation(immediate_xfb_desc), + Config::GFX_HACK_IMMEDIATE_XFB), + 0, wxLEFT | wxRIGHT, space5); + group_xfb->AddSpacer(space5); + szr_hacks->AddSpacer(space5); szr_hacks->Add(group_xfb, 0, wxEXPAND | wxLEFT | wxRIGHT, space5); } // xfb diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 183f7d4f20..22e808fe90 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -12,6 +12,7 @@ #include "Common/StringUtil.h" #include "Common/Thread.h" #include "Core/ConfigManager.h" +#include "Core/CoreTiming.h" #include "Core/FifoPlayer/FifoPlayer.h" #include "Core/FifoPlayer/FifoRecorder.h" #include "Core/HW/Memmap.h" @@ -266,9 +267,17 @@ static void BPWritten(const BPCmd& bp) // This stays in to signal end of a "frame" g_renderer->RenderToXFB(destAddr, srcRect, destStride, height, s_gammaLUT[PE_copy.gamma]); - if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates()) + if (g_ActiveConfig.bImmediateXFB) { - VideoInterface::FakeVIUpdate(destAddr, srcRect.GetWidth(), height); + // below div two to convert from bytes to pixels - it expects width, not stride + g_renderer->Swap(destAddr, destStride / 2, destStride / 2, height, false, srcRect, CoreTiming::GetTicks(), s_gammaLUT[PE_copy.gamma]); + } + else + { + if (FifoPlayer::GetInstance().IsRunningWithFakeVideoInterfaceUpdates()) + { + VideoInterface::FakeVIUpdate(destAddr, srcRect.GetWidth(), height); + } } } diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp index 652eb15969..38d37113e2 100644 --- a/Source/Core/VideoCommon/MainBase.cpp +++ b/Source/Core/VideoCommon/MainBase.cpp @@ -49,7 +49,7 @@ void VideoBackendBase::Video_ExitLoop() void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, u64 ticks) { - if (m_initialized && g_renderer) + if (m_initialized && g_renderer && !g_ActiveConfig.bImmediateXFB) { Fifo::SyncGPU(Fifo::SyncGPUReason::Swap); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index d0bebe363c..d438951944 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -37,7 +37,6 @@ #include "Core/Config/SYSCONFSettings.h" #include "Core/ConfigManager.h" #include "Core/Core.h" -#include "Core/CoreTiming.h" #include "Core/FifoPlayer/FifoRecorder.h" #include "Core/HW/VideoInterface.h" #include "Core/Host.h" @@ -337,7 +336,7 @@ void Renderer::DrawDebugText() "Speed Limit: Unlimited" : StringFromFormat("Speed Limit: %li%%", std::lround(SConfig::GetInstance().m_EmulationSpeed * 100.f)), - std::string("Copy XFB: ") + xfbcopy_text, + std::string("Copy XFB: ") + xfbcopy_text + (g_ActiveConfig.bImmediateXFB ? " (Immediate)" : ""), }; enum diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index a127e23b18..1f6e5a38c7 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -137,6 +137,7 @@ void VideoConfig::Refresh() bForceProgressive = Config::Get(Config::GFX_HACK_FORCE_PROGRESSIVE); bSkipEFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM); bSkipXFBCopyToRam = Config::Get(Config::GFX_HACK_SKIP_XFB_COPY_TO_RAM); + bImmediateXFB = Config::Get(Config::GFX_HACK_IMMEDIATE_XFB); bCopyEFBScaled = Config::Get(Config::GFX_HACK_COPY_EFB_ENABLED); bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES); bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index 71031eb192..b22d568032 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -118,6 +118,7 @@ struct VideoConfig final bool bEFBEmulateFormatChanges; bool bSkipEFBCopyToRam; bool bSkipXFBCopyToRam; + bool bImmediateXFB; bool bCopyEFBScaled; int iSafeTextureCache_ColorSamples; ProjectionHackConfig phack;