Merge pull request #10244 from phire/ban-timetravel
Delay singlecore gpu interrupts; Fixes Bomberman Jetters in single core mode.
This commit is contained in:
commit
c12e4e8ee0
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue