Add 'immediate xfb' which reduces xfb latency at the cost of graphical errors
This commit is contained in:
parent
a71bc9ebbf
commit
7f0834c919
|
@ -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);
|
||||
|
|
|
@ -133,6 +133,7 @@ const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM{{System::GFX, "Hacks", "EFB
|
|||
true};
|
||||
const ConfigInfo<bool> GFX_HACK_SKIP_XFB_COPY_TO_RAM{{System::GFX, "Hacks", "XFBToTextureEnable"},
|
||||
true};
|
||||
const ConfigInfo<bool> GFX_HACK_IMMEDIATE_XFB{{System::GFX, "Hacks", "ImmediateXFBEnable"}, false};
|
||||
const ConfigInfo<bool> GFX_HACK_COPY_EFB_ENABLED{{System::GFX, "Hacks", "EFBScaledCopy"}, true};
|
||||
const ConfigInfo<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES{
|
||||
{System::GFX, "Hacks", "EFBEmulateFormatChanges"}, false};
|
||||
|
|
|
@ -100,6 +100,7 @@ extern const ConfigInfo<bool> GFX_HACK_BBOX_PREFER_STENCIL_IMPLEMENTATION;
|
|||
extern const ConfigInfo<bool> GFX_HACK_FORCE_PROGRESSIVE;
|
||||
extern const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM;
|
||||
extern const ConfigInfo<bool> GFX_HACK_SKIP_XFB_COPY_TO_RAM;
|
||||
extern const ConfigInfo<bool> GFX_HACK_IMMEDIATE_XFB;
|
||||
extern const ConfigInfo<bool> GFX_HACK_COPY_EFB_ENABLED;
|
||||
extern const ConfigInfo<bool> GFX_HACK_EFB_EMULATE_FORMAT_CHANGES;
|
||||
extern const ConfigInfo<bool> GFX_HACK_VERTEX_ROUDING;
|
||||
|
|
|
@ -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}},
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -32,6 +32,7 @@ private:
|
|||
|
||||
// External Framebuffer
|
||||
QCheckBox* m_store_xfb_copies;
|
||||
QCheckBox* m_immediate_xfb;
|
||||
|
||||
// Other
|
||||
QCheckBox* m_fast_depth_calculation;
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -118,6 +118,7 @@ struct VideoConfig final
|
|||
bool bEFBEmulateFormatChanges;
|
||||
bool bSkipEFBCopyToRam;
|
||||
bool bSkipXFBCopyToRam;
|
||||
bool bImmediateXFB;
|
||||
bool bCopyEFBScaled;
|
||||
int iSafeTextureCache_ColorSamples;
|
||||
ProjectionHackConfig phack;
|
||||
|
|
Loading…
Reference in New Issue