diff --git a/Source/Core/Core/Src/HW/CommandProcessor.cpp b/Source/Core/Core/Src/HW/CommandProcessor.cpp index 7030965cdc..8c3c6d9a01 100644 --- a/Source/Core/Core/Src/HW/CommandProcessor.cpp +++ b/Source/Core/Core/Src/HW/CommandProcessor.cpp @@ -15,6 +15,12 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ + +// TODO +// * Kick GPU from dispatcher, not from writes +// * Thunking framework +// * Cleanup of messy now unnecessary safety code in jit + #include "Common.h" #include "../Plugins/Plugin_Video.h" #include "../PowerPC/PowerPC.h" @@ -218,11 +224,11 @@ void Write16(const u16 _Value, const u32 _Address) ; fifo.bPauseRead = true; } + #ifdef _WIN32 + EnterCriticalSection(&fifo.sync); + #endif } -#ifdef _WIN32 - EnterCriticalSection(&fifo.sync); -#endif switch (_Address & 0xFFF) { case STATUS_REGISTER: @@ -304,7 +310,8 @@ void Write16(const u16 _Value, const u32 _Address) // This will recursively enter fifo.sync, TODO(ector): is this good? UpdateFifoRegister(); #ifdef _WIN32 - LeaveCriticalSection(&fifo.sync); + if (Core::g_CoreStartupParameter.bUseDualCore) + LeaveCriticalSection(&fifo.sync); #endif fifo.bPauseRead = false; // pauseread is not actually used anywhere! TOOD(ector): huh! } @@ -366,6 +373,53 @@ void GatherPipeBursted() } } + + +void CatchUpGPU() +{ + // check if we are able to run this buffer + if ((fifo.bFF_GPReadEnable) && !(fifo.bFF_BPEnable && fifo.bFF_Breakpoint)) + { + while (fifo.CPReadWriteDistance > 0) + { + // check if we are on a breakpoint + if (fifo.bFF_BPEnable) + { + //MessageBox(0,"Breakpoint enabled",0,0); + if ((fifo.CPReadPointer & ~0x1F) == (fifo.CPBreakpoint & ~0x1F)) + { + //_assert_msg_(GEKKO,0,"BP: %08x",fifo.CPBreakpoint); + fifo.bFF_Breakpoint = 1; + m_CPStatusReg.Breakpoint = 1; + //g_VideoInitialize.pUpdateInterrupts(); + UpdateInterrupts(); + break; + } + } + + // read the data and send it to the VideoPlugin + + u8 *ptr = Memory::GetPointer(fifo.CPReadPointer); + fifo.CPReadPointer += 32; + // We are going to do FP math on the main thread so have to save the current state + SaveSSEState(); + LoadDefaultSSEState(); + PluginVideo::Video_SendFifoData(ptr); + LoadSSEState(); + + fifo.CPReadWriteDistance -= 32; + + // increase the ReadPtr + if (fifo.CPReadPointer >= fifo.CPEnd) + { + fifo.CPReadPointer = fifo.CPBase; + LOG(COMMANDPROCESSOR, "BUFFER LOOP"); + // PanicAlert("loop now"); + } + } + } +} + // __________________________________________________________________________________________________ // UpdateFifoRegister // It's no problem if the gfx falls behind a little bit. Better make sure to stop the cpu thread @@ -395,50 +449,7 @@ void UpdateFifoRegister() #ifdef _WIN32 if (Core::g_CoreStartupParameter.bUseDualCore) LeaveCriticalSection(&fifo.sync); #endif - if (!Core::g_CoreStartupParameter.bUseDualCore) - { - // check if we are able to run this buffer - if ((fifo.bFF_GPReadEnable) && !(fifo.bFF_BPEnable && fifo.bFF_Breakpoint)) - { - while(fifo.CPReadWriteDistance > 0) - { - // check if we are on a breakpoint - if (fifo.bFF_BPEnable) - { - //MessageBox(0,"Breakpoint enabled",0,0); - if ((fifo.CPReadPointer & ~0x1F) == (fifo.CPBreakpoint & ~0x1F)) - { - //_assert_msg_(GEKKO,0,"BP: %08x",fifo.CPBreakpoint); - fifo.bFF_Breakpoint = 1; - m_CPStatusReg.Breakpoint = 1; - //g_VideoInitialize.pUpdateInterrupts(); - UpdateInterrupts(); - break; - } - } - - // read the data and send it to the VideoPlugin - - u8 *ptr = Memory::GetPointer(fifo.CPReadPointer); - fifo.CPReadPointer += 32; - // We are going to do FP math on the main thread so have to save the current state - SaveSSEState(); - LoadDefaultSSEState(); - PluginVideo::Video_SendFifoData(ptr); - LoadSSEState(); - - fifo.CPReadWriteDistance -= 32; - - // increase the ReadPtr - if (fifo.CPReadPointer >= fifo.CPEnd) - { - fifo.CPReadPointer = fifo.CPBase; - LOG(COMMANDPROCESSOR, "BUFFER LOOP"); - // MessageBox(NULL, "loop", "now", MB_OK); - } - } - } - } +// if (!Core::g_CoreStartupParameter.bUseDualCore) CatchUpGPU(); } void UpdateInterrupts() diff --git a/Source/Core/Core/Src/HW/CommandProcessor.h b/Source/Core/Core/Src/HW/CommandProcessor.h index 37d7084114..46991c8081 100644 --- a/Source/Core/Core/Src/HW/CommandProcessor.h +++ b/Source/Core/Core/Src/HW/CommandProcessor.h @@ -87,6 +87,7 @@ void HWCALL Read32(u32& _rReturnValue, const u32 _Address); void HWCALL Write32(const u32 _Data, const u32 _Address); // for CGPFIFO +void CatchUpGPU(); void GatherPipeBursted(); void UpdateInterrupts(); void UpdateInterruptsFromVideoPlugin(); diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 023169e910..e37736b1e1 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -23,6 +23,7 @@ #include "../HW/DSP.h" #include "../HW/AudioInterface.h" #include "../HW/VideoInterface.h" +#include "../HW/CommandProcessor.h" #include "../HW/SerialInterface.h" #include "../PowerPC/PowerPC.h" #include "../CoreTiming.h" @@ -59,8 +60,8 @@ int AI_PERIOD = GetTicksPerSecond() / 80, DSP_PERIOD = GetTicksPerSecond() / 250, DSPINT_PERIOD = GetTicksPerSecond() / 230, - HLE_IPC_PERIOD = GetTicksPerSecond() / 250; - + HLE_IPC_PERIOD = GetTicksPerSecond() / 250, + GPU_PERIOD = 10000; u32 GetTicksPerSecond() { @@ -84,7 +85,6 @@ void IPC_HLE_UpdateCallback(u64 userdata, int cyclesLate) CoreTiming::ScheduleEvent(HLE_IPC_PERIOD-cyclesLate, &IPC_HLE_UpdateCallback, "IPC_HLE_UpdateCallback"); } - void VICallback(u64 userdata, int cyclesLate) { VideoInterface::Update(); @@ -112,7 +112,6 @@ void DSPInterruptCallback(u64 userdata, int cyclesLate) CoreTiming::ScheduleEvent(DSPINT_PERIOD-cyclesLate, &DSPInterruptCallback, "DSPInterruptCallback"); } - void DecrementerCallback(u64 userdata, int cyclesLate) { //Why is fakeDec too big here? @@ -121,7 +120,6 @@ void DecrementerCallback(u64 userdata, int cyclesLate) PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; } - void DecrementerSet() { // MessageBox(0, "dec set",0,0); @@ -143,6 +141,11 @@ void AdvanceCallback(int cyclesExecuted) PowerPC::ppcState.spr[SPR_DEC] = (u32)fakeDec / TIMER_RATIO; } +void RunGPUCallback(u64 userdata, int cyclesLate) +{ + CommandProcessor::CatchUpGPU(); + CoreTiming::ScheduleEvent(GPU_PERIOD-cyclesLate, &RunGPUCallback, "RunGPUCallback"); +} // TODO(ector): improve, by using a more accurate timer // calculate the timing over the past 7 frames @@ -215,6 +218,9 @@ void Init() CoreTiming::ScheduleEvent(SI_PERIOD, &SICallback, "SICallback"); CoreTiming::ScheduleEvent(DSPINT_PERIOD, &DSPInterruptCallback, "DSPInterruptCallback"); + if (!Core::GetStartupParameter().bUseDualCore) + CoreTiming::ScheduleEvent(GPU_PERIOD, &RunGPUCallback, "RunGPUCallback"); + if (Core::GetStartupParameter().bWii) { CoreTiming::ScheduleEvent(HLE_IPC_PERIOD, &IPC_HLE_UpdateCallback, "IPC_HLE_UpdateCallback");