summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2021-12-02 07:21:41 -0500
committerGitHub <noreply@github.com>2021-12-02 07:21:41 -0500
commitc12e4e8ee080e682b515f7990f416db0150e9c02 (patch)
tree677ea2d2b440fb82a88c8fdc4b01afa6fc71acdb /Source/Core
parent26e4e67d4536835cc1fdf09a5c3ce75404dc8d87 (diff)
parentf5c550e9cb8f5bbc6a4f9bd77bc84c077671c480 (diff)
Merge pull request #10244 from phire/ban-timetravel
Delay singlecore gpu interrupts; Fixes Bomberman Jetters in single core mode.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoCommon/BPMemory.h4
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp20
-rw-r--r--Source/Core/VideoCommon/OpcodeDecoding.cpp4
-rw-r--r--Source/Core/VideoCommon/PixelEngine.cpp19
-rw-r--r--Source/Core/VideoCommon/PixelEngine.h4
5 files changed, 29 insertions, 22 deletions
diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h
index 21636224c0..fdd32746a9 100644
--- a/Source/Core/VideoCommon/BPMemory.h
+++ b/Source/Core/VideoCommon/BPMemory.h
@@ -2205,7 +2205,7 @@ struct BPMemory
extern BPMemory bpmem;
-void LoadBPReg(u32 value0);
-void LoadBPRegPreprocess(u32 value0);
+void LoadBPReg(u32 value0, int cycles_into_future);
+void LoadBPRegPreprocess(u32 value0, int cycles_into_future);
std::pair<std::string, std::string> GetBPRegInfo(u8 cmd, u32 cmddata);
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 1ec097fe6e..0fc4ca6785 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -50,7 +50,7 @@ void BPInit()
bpmem.bpMask = 0xFFFFFF;
}
-static void BPWritten(const BPCmd& bp)
+static void BPWritten(const BPCmd& bp, int cycles_into_future)
{
/*
----------------------------------------------------------------------------------------------------------------
@@ -180,7 +180,7 @@ static void BPWritten(const BPCmd& bp)
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
- PixelEngine::SetFinish(); // may generate interrupt
+ PixelEngine::SetFinish(cycles_into_future); // may generate interrupt
DEBUG_LOG_FMT(VIDEO, "GXSetDrawDone SetPEFinish (value: {:#04X})", bp.newvalue & 0xFFFF);
return;
@@ -193,14 +193,14 @@ static void BPWritten(const BPCmd& bp)
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
- PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), false);
+ PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), false, cycles_into_future);
DEBUG_LOG_FMT(VIDEO, "SetPEToken {:#06X}", bp.newvalue & 0xFFFF);
return;
case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
- PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), true);
+ PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), true, cycles_into_future);
DEBUG_LOG_FMT(VIDEO, "SetPEToken + INT {:#06X}", bp.newvalue & 0xFFFF);
return;
@@ -717,7 +717,7 @@ static void BPWritten(const BPCmd& bp)
}
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
-void LoadBPReg(u32 value0)
+void LoadBPReg(u32 value0, int cycles_into_future)
{
int regNum = value0 >> 24;
int oldval = ((u32*)&bpmem)[regNum];
@@ -730,10 +730,10 @@ void LoadBPReg(u32 value0)
if (regNum != BPMEM_BP_MASK)
bpmem.bpMask = 0xFFFFFF;
- BPWritten(bp);
+ BPWritten(bp, cycles_into_future);
}
-void LoadBPRegPreprocess(u32 value0)
+void LoadBPRegPreprocess(u32 value0, int cycles_into_future)
{
int regNum = value0 >> 24;
// masking could hypothetically be a problem
@@ -742,13 +742,13 @@ void LoadBPRegPreprocess(u32 value0)
{
case BPMEM_SETDRAWDONE:
if ((newval & 0xff) == 0x02)
- PixelEngine::SetFinish();
+ PixelEngine::SetFinish(cycles_into_future);
break;
case BPMEM_PE_TOKEN_ID:
- PixelEngine::SetToken(newval & 0xffff, false);
+ PixelEngine::SetToken(newval & 0xffff, false, cycles_into_future);
break;
case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
- PixelEngine::SetToken(newval & 0xffff, true);
+ PixelEngine::SetToken(newval & 0xffff, true, cycles_into_future);
break;
}
}
diff --git a/Source/Core/VideoCommon/OpcodeDecoding.cpp b/Source/Core/VideoCommon/OpcodeDecoding.cpp
index 00f470d5f4..a1abacc4c6 100644
--- a/Source/Core/VideoCommon/OpcodeDecoding.cpp
+++ b/Source/Core/VideoCommon/OpcodeDecoding.cpp
@@ -221,11 +221,11 @@ u8* Run(DataReader src, u32* cycles, bool in_display_list)
const u32 bp_cmd = src.Read<u32>();
if constexpr (is_preprocess)
{
- LoadBPRegPreprocess(bp_cmd);
+ LoadBPRegPreprocess(bp_cmd, total_cycles);
}
else
{
- LoadBPReg(bp_cmd);
+ LoadBPReg(bp_cmd, total_cycles);
INCSTAT(g_stats.this_frame.num_bp_loads);
}
}
diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp
index 87d58eb010..747328b3c6 100644
--- a/Source/Core/VideoCommon/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/PixelEngine.cpp
@@ -277,7 +277,7 @@ static void SetTokenFinish_OnMainThread(u64 userdata, s64 cyclesLate)
// Raise the event handler above on the CPU thread.
// s_token_finish_mutex must be locked.
// THIS IS EXECUTED FROM VIDEO THREAD
-static void RaiseEvent()
+static void RaiseEvent(int cycles_into_future)
{
if (s_event_raised)
return;
@@ -285,14 +285,21 @@ static void RaiseEvent()
s_event_raised = true;
CoreTiming::FromThread from = CoreTiming::FromThread::NON_CPU;
+ s64 cycles = 0; // we don't care about timings for dual core mode.
if (!SConfig::GetInstance().bCPUThread || Fifo::UseDeterministicGPUThread())
+ {
from = CoreTiming::FromThread::CPU;
- CoreTiming::ScheduleEvent(0, et_SetTokenFinishOnMainThread, 0, from);
+
+ // Hack: Dolphin's single-core gpu timings are way too fast. Enforce a minimum delay to give
+ // games time to setup any interrupt state
+ cycles = std::max(500, cycles_into_future);
+ }
+ CoreTiming::ScheduleEvent(cycles, et_SetTokenFinishOnMainThread, 0, from);
}
// SetToken
// THIS IS EXECUTED FROM VIDEO THREAD
-void SetToken(const u16 token, const bool interrupt)
+void SetToken(const u16 token, const bool interrupt, int cycles_into_future)
{
DEBUG_LOG_FMT(PIXELENGINE, "VIDEO Backend raises INT_CAUSE_PE_TOKEN (btw, token: {:04x})", token);
@@ -301,12 +308,12 @@ void SetToken(const u16 token, const bool interrupt)
s_token_pending = token;
s_token_interrupt_pending |= interrupt;
- RaiseEvent();
+ RaiseEvent(cycles_into_future);
}
// SetFinish
// THIS IS EXECUTED FROM VIDEO THREAD (BPStructs.cpp) when a new frame has been drawn
-void SetFinish()
+void SetFinish(int cycles_into_future)
{
DEBUG_LOG_FMT(PIXELENGINE, "VIDEO Set Finish");
@@ -314,7 +321,7 @@ void SetFinish()
s_finish_interrupt_pending |= true;
- RaiseEvent();
+ RaiseEvent(cycles_into_future);
}
UPEAlphaReadReg GetAlphaReadMode()
diff --git a/Source/Core/VideoCommon/PixelEngine.h b/Source/Core/VideoCommon/PixelEngine.h
index afbc8ddbe9..7444ddb3c2 100644
--- a/Source/Core/VideoCommon/PixelEngine.h
+++ b/Source/Core/VideoCommon/PixelEngine.h
@@ -61,8 +61,8 @@ void DoState(PointerWrap& p);
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
// gfx backend support
-void SetToken(const u16 token, const bool interrupt);
-void SetFinish();
+void SetToken(const u16 token, const bool interrupt, int cycle_delay);
+void SetFinish(int cycle_delay);
UPEAlphaReadReg GetAlphaReadMode();
} // namespace PixelEngine