summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/PixelEngine.cpp
diff options
context:
space:
mode:
authorScott Mansell <phiren@gmail.com>2021-11-25 11:01:37 +1300
committerScott Mansell <phiren@gmail.com>2021-11-25 11:11:01 +1300
commitf5c550e9cb8f5bbc6a4f9bd77bc84c077671c480 (patch)
tree9f6f6c9c2ff3ccc59c0865c31f460350905bb8e6 /Source/Core/VideoCommon/PixelEngine.cpp
parent0b81640dd1ce436519368556a69eb7fc650a60fa (diff)
Delay singlecore gpu interrupts
Fixes Bomberman Jetters in single core mode. When single core mode pauses the CPU to execute the GPU FIFO it greedily executes the whole thing. Before this commit, Finish and Token interrupts would happen instantly, not even taking into account how long the current FIFO window has taken to execute. The interrupts would be effectively backdated to the start of this execution window. This commit does two things: It pipes the current FIFO window execution time though to the interrupt scheduling and it enforces a minimum delay of 500 cycles before an interrupt will be fired.
Diffstat (limited to 'Source/Core/VideoCommon/PixelEngine.cpp')
-rw-r--r--Source/Core/VideoCommon/PixelEngine.cpp19
1 files changed, 13 insertions, 6 deletions
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()