From c7ae0eb0d12ae828d02188ca611391c142be9762 Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Thu, 17 Feb 2011 04:25:21 +0000 Subject: [PATCH] Big Fifo Commit Part2: Now the fifo is more stable than my first commit, so is time... - ReImplementing Single Core Mode like Dual Core Mode Style. - Stage 1: My goal is, we have the Fifo, CommandProccessor code the more clear, maintenible and documented possible. When I quit dolphin I want any developer can continue with the work only reading the code. * Big Refactoring: A lot of functions was changed the names, and modularized. Now the FifoLoop and CatchUpGPU does not exist, was replaced by RunGpu() and RunGpuLoop(). The general idea is modeling the code like the real HW. The fifo is only a buffer where the Write Gather Pipe write the commands and from the Graphic Processor read these. * Big Clean UP a lot of obsolete code and comments was deleted, like DcFakeWachDog, "Fifo very soon hack", etc. In the stage 2, I will refactoring more code doing emphasis in the division of CommandProcessor, Fifo, Gpu Emulation. Beside I will comment all functions and variables in the code (Don't worry I will ask for English help for this part ;) ) Please test a lot SC mode and DC mode :) Thank you so much for testing always and the patience. I don't like broke your favorite game but... you must believe me this part is very sensible, I only try to contribute for have a better and stable dolphin emulator. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7185 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/VideoBackendBase.h | 4 +- Source/Core/Core/Src/HW/SystemTimers.cpp | 13 - .../Core/VideoCommon/Src/CommandProcessor.cpp | 452 ++++-------------- .../Core/VideoCommon/Src/CommandProcessor.h | 16 +- Source/Core/VideoCommon/Src/Fifo.cpp | 121 ++--- Source/Core/VideoCommon/Src/Fifo.h | 18 +- Source/Core/VideoCommon/Src/MainBase.cpp | 11 +- .../Core/VideoCommon/Src/OpcodeDecoding.cpp | 8 +- Source/Core/VideoCommon/Src/PixelEngine.cpp | 4 +- Source/Core/VideoCommon/Src/VideoState.cpp | 2 +- .../Plugin_VideoSoftware/Src/SWmain.cpp | 3 - .../Plugin_VideoSoftware/Src/VideoBackend.h | 1 - 12 files changed, 185 insertions(+), 468 deletions(-) diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/Common/Src/VideoBackendBase.h index 3e9c71bfb9..c72a8a2cc9 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/Common/Src/VideoBackendBase.h @@ -72,7 +72,7 @@ struct SCPFifoStruct // for GP watchdog hack volatile u32 Fake_GPWDToken; // cicular incrementer - volatile u32 isFifoProcesingData; + volatile u32 isGpuReadingData; }; class VideoBackend @@ -114,7 +114,6 @@ public: static void Video_GatherPipeBursted(); - virtual void Video_WaitForFrameFinish() = 0; virtual bool Video_IsPossibleWaitingSetDrawDone() = 0; virtual void Video_AbortFrame() = 0; @@ -146,7 +145,6 @@ class VideoBackendHLE : public VideoBackend void Video_SetRendering(bool bEnabled); - void Video_WaitForFrameFinish(); bool Video_IsPossibleWaitingSetDrawDone(); void Video_AbortFrame(); }; diff --git a/Source/Core/Core/Src/HW/SystemTimers.cpp b/Source/Core/Core/Src/HW/SystemTimers.cpp index 702a96eb62..4d921cd18a 100644 --- a/Source/Core/Core/Src/HW/SystemTimers.cpp +++ b/Source/Core/Core/Src/HW/SystemTimers.cpp @@ -224,13 +224,6 @@ u64 GetFakeTimeBase() return CoreTiming::GetFakeTBStartValue() + ((CoreTiming::GetTicks() - CoreTiming::GetFakeTBStartTicks()) / TIMER_RATIO); } -// For DC watchdog hack -void FakeGPWatchdogCallback(u64 userdata, int cyclesLate) -{ - g_video_backend->Video_WaitForFrameFinish(); // lock CPUThread until frame finish - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame() - cyclesLate, et_FakeGPWD); -} - void PatchEngineCallback(u64 userdata, int cyclesLate) { // Patch mem and run the Action Replay @@ -289,8 +282,6 @@ void Init() et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback); et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback); et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback); - // Always register this. Increases chances of DC/SC save state compatibility. - et_FakeGPWD = CoreTiming::RegisterEvent("FakeGPWatchdogCallback", FakeGPWatchdogCallback); et_PatchEngine = CoreTiming::RegisterEvent("PatchEngine", PatchEngineCallback); CoreTiming::ScheduleEvent(AI_PERIOD, et_AI); @@ -299,10 +290,6 @@ void Init() CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_SI); CoreTiming::ScheduleEvent(AUDIO_DMA_PERIOD, et_AudioDMA); - // For DC watchdog hack - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_FakeGPWD); - CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerFrame(), et_PatchEngine); if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii) diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 1391ed657b..ad05a9797e 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -15,58 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ - -// NOTES (mb2): - -// * GP/CPU sync can be done by several way: -// - MP1 use BP (breakpoint) in movie-menus and mostly PEtoken in 3D -// - ZWW as Crazy Taxi: PEfinish (GXSetDrawDone) -// - SMS: BP, PEToken, PEfinish -// - ZTP: seems to use PEfinish only -// - Animal Crossing: PEfinish at start but there's a bug... -// There's tons of HiWmk/LoWmk ping pong -> Another sync fashion? -// - Super Monkey Ball Adventures: PEToken. Oddity: read&check-PEToken-value-loop stays -// in its JITed block (never fall in Advance() until the game-watchdog's stuff). -// That's why we can't let perform the AdvanceCallBack as usual. -// The PEToken is volatile now and in the fifo struct. -// - Super Monkey Ball: PEFinish. This game has the lamest way to deal with fifo sync for our MT's stuff. -// A hack is mandatory. DONE and should be ok for other games. - -// *What I guess (thx to asynchronous DualCore mode): -// PPC have a frame-finish watchdog. Handled by system timming stuff like the decrementer. -// (DualCore mode): I have observed, after ZTP logos, a fifo-recovery start when DECREMENTER_EXCEPTION is throwned. -// The frame setting (by GP) took too much time and didn't finish properly due to this watchdog. -// Faster GX backends required, indeed :p - -// * BPs are needed for some game GP/CPU sync. -// But it could slowdown (MP1 at least) because our GP in DC is faster than "expected" in some area. -// eg: in movie-menus in MP1, BP are reached quickly. -// The bad thing is that involve too much PPC work (int ack, lock GP, reset BP, new BP addr, unlock BP...) hence the slowdown. -// Anyway, emulation should more accurate like this and it emulate some sort of better load balancing. -// Eather way in those area a more accurate GP timing could be done by slowing down the GP or something less stupid. -// Not functional and not used atm (breaks MP2). - -// * funny, in revs before those with this note, BP irq wasn't cleared (a bug indeed) and MP1 menus was faster. -// BP irq was raised and ack just once but never cleared. However it's sufficient for MP1 to work. -// This hack is used atm. Known BPs handling doesn't work well (btw, BP irq clearing might be done by CPIntEnable raising edge). -// The hack seems to be responsible of the movie stutering in MP1 menus. - -// TODO (mb2): -// * raise watermark Ov/Un irq: POINTLESS since emulated GP timings can't be accuratly set. -// Only 3 choices IMHO for a correct emulated load balancing in DC mode: -// - make our own GP watchdog hack that can lock CPU if GP too slow. STARTED -// - hack directly something in PPC timings (dunno how) -// - boost GP so we can consider it as infinitely fast compared to CPU. -// * raise ReadIdle/CmdIdle flags and observe behaviour of MP1 & ZTP (at least) -// * Clean useless comments and debug stuff in Read16, Write16, GatherPipeBursted when sync will be fixed for DC -// * (reminder) do the same in: -// PeripheralInterface.cpp, PixelEngine.cpp, OGL->BPStructs.cpp, fifo.cpp... ok just check change log >> - -// TODO -// * Kick GPU from dispatcher, not from writes -// * Thunking framework -// * Cleanup of messy now unnecessary safety code in jit - #include "Common.h" #include "VideoCommon.h" #include "VideoConfig.h" @@ -90,7 +38,6 @@ namespace CommandProcessor int et_UpdateInterrupts; -// look for 1002 verts, breakpoint there, see why next draw is flushed // TODO(ector): Warn on bbox read/write // STATE_TO_SAVE @@ -105,12 +52,10 @@ int m_bboxright; int m_bboxbottom; u16 m_tokenReg; -static u32 fake_GPWatchdogLastToken = 0; -static Common::EventEx s_fifoIdleEvent; static bool bProcessFifoToLoWatermark = false; static bool bProcessFifoAllDistance = false; -volatile bool isPossibleWaitingSetDrawDone = false; //This state is changed when the FIFO is processing data. +volatile bool isPossibleWaitingSetDrawDone = false; volatile bool interruptSet= false; volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; @@ -150,8 +95,6 @@ void DoState(PointerWrap &p) p.Do(OnOverflow); } -//inline void WriteLow (u32& _reg, u16 lowbits) {_reg = (_reg & 0xFFFF0000) | lowbits;} -//inline void WriteHigh(u32& _reg, u16 highbits) {_reg = (_reg & 0x0000FFFF) | ((u32)highbits << 16);} inline void WriteLow (volatile u32& _reg, u16 lowbits) {Common::AtomicStore(_reg,(_reg & 0xFFFF0000) | lowbits);} inline void WriteHigh(volatile u32& _reg, u16 highbits) {Common::AtomicStore(_reg,(_reg & 0x0000FFFF) | ((u32)highbits << 16));} @@ -173,8 +116,6 @@ void Init() m_tokenReg = 0; - fake_GPWatchdogLastToken = 0; - memset(&fifo,0,sizeof(fifo)); fifo.CPCmdIdle = 1 ; fifo.CPReadIdle = 1; @@ -189,16 +130,9 @@ void Init() interruptFinishWaiting = false; interruptTokenWaiting = false; - s_fifoIdleEvent.Init(); - et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper); } -void Shutdown() -{ - s_fifoIdleEvent.Shutdown(); -} - void Read16(u16& _rReturnValue, const u32 _Address) { @@ -206,45 +140,16 @@ void Read16(u16& _rReturnValue, const u32 _Address) ProcessFifoEvents(); switch (_Address & 0xFFF) { - case STATUS_REGISTER: - - // Here always there is one fifo attached to the GPU - - if (IsOnThread()) - { - m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint; - m_CPStatusReg.ReadIdle = (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint); - m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance; - m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark; - m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark; - } - else - { - // Single Core MODE - m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint; - m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || !fifo.bFF_GPReadEnable; - m_CPStatusReg.CommandIdle = fifo.CPCmdIdle; - m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark; - } - INFO_LOG(COMMANDPROCESSOR,"\t Read from STATUS_REGISTER : %04x", m_CPStatusReg.Hex); - DEBUG_LOG(COMMANDPROCESSOR, "(r) status: iBP %s | fReadIdle %s | fCmdIdle %s | iOvF %s | iUndF %s" - , m_CPStatusReg.Breakpoint ? "ON" : "OFF" - , m_CPStatusReg.ReadIdle ? "ON" : "OFF" - , m_CPStatusReg.CommandIdle ? "ON" : "OFF" - , m_CPStatusReg.OverflowHiWatermark ? "ON" : "OFF" - , m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF" - ); - + case STATUS_REGISTER: + SetCpStatusRegister(); _rReturnValue = m_CPStatusReg.Hex; return; - case CTRL_REGISTER: _rReturnValue = m_CPCtrlReg.Hex; return; case CLEAR_REGISTER: _rReturnValue = m_CPClearReg.Hex; PanicAlert("CommandProcessor:: CPU reads from CLEAR_REGISTER!"); ERROR_LOG(COMMANDPROCESSOR, "(r) clear: 0x%04x", _rReturnValue); return; - case FIFO_TOKEN_REGISTER: _rReturnValue = m_tokenReg; return; case FIFO_BOUNDING_BOX_LEFT: _rReturnValue = m_bboxleft; return; case FIFO_BOUNDING_BOX_RIGHT: _rReturnValue = m_bboxright; return; @@ -260,20 +165,14 @@ void Read16(u16& _rReturnValue, const u32 _Address) case FIFO_LO_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPLoWatermark); return; case FIFO_LO_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPLoWatermark); return; - // TODO: cases cleanup case FIFO_RW_DISTANCE_LO: _rReturnValue = ReadLow (fifo.CPReadWriteDistance); - // hack: CPU will always believe fifo is empty and on idle - //_rReturnValue = 0; DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue); return; case FIFO_RW_DISTANCE_HI: _rReturnValue = ReadHigh(fifo.CPReadWriteDistance); - // hack: CPU will always believe fifo is empty and on idle - //_rReturnValue = 0; DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_RW_DISTANCE_HI : %04x", _rReturnValue); return; - case FIFO_WRITE_POINTER_LO: _rReturnValue = ReadLow (fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_WRITE_POINTER_LO : %04x", _rReturnValue); @@ -282,14 +181,11 @@ void Read16(u16& _rReturnValue, const u32 _Address) _rReturnValue = ReadHigh(fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_WRITE_POINTER_HI : %04x", _rReturnValue); return; - case FIFO_READ_POINTER_LO: if (IsOnThread()) _rReturnValue = ReadLow (fifo.SafeCPReadPointer); else _rReturnValue = ReadLow (fifo.CPReadPointer); - // hack: CPU will always believe fifo is empty and on idle - //_rReturnValue = ReadLow (fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_LO : %04x", _rReturnValue); return; case FIFO_READ_POINTER_HI: @@ -297,15 +193,12 @@ void Read16(u16& _rReturnValue, const u32 _Address) _rReturnValue = ReadHigh (fifo.SafeCPReadPointer); else _rReturnValue = ReadHigh (fifo.CPReadPointer); - // hack: CPU will always believe fifo is empty and on idle - //_rReturnValue = ReadHigh(fifo.CPWritePointer); DEBUG_LOG(COMMANDPROCESSOR, "read FIFO_READ_POINTER_HI : %04x", _rReturnValue); return; case FIFO_BP_LO: _rReturnValue = ReadLow (fifo.CPBreakpoint); return; case FIFO_BP_HI: _rReturnValue = ReadHigh(fifo.CPBreakpoint); return; - // AyuanX: Lots of games read the followings (e.g. Mario Power Tennis) case XF_RASBUSY_L: _rReturnValue = 0; // TODO: Figure out the true value DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_L: %04x", _rReturnValue); @@ -373,7 +266,6 @@ void Read16(u16& _rReturnValue, const u32 _Address) _rReturnValue = 4; //Number of clocks per vertex.. TODO: Calculate properly DEBUG_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue); return; - //add all the other regs here? are they ever read? default: _rReturnValue = 0; WARN_LOG(COMMANDPROCESSOR, "(r16) unknown CP reg @ %08x", _Address); @@ -388,47 +280,6 @@ void Write16(const u16 _Value, const u32 _Address) INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address); - // Force complete fifo flush if we attempt to set/reset the fifo (API GXSetGPFifo or equivalent) - // It's kind of an API hack but it works for lots of games... and I hope it's the same way for every games. - // TODO: HLE for GX fifo's APIs? - // Here is the hack: - // - if (attempt to overwrite CTRL_REGISTER by 0x0000) - // // then we assume CPReadWriteDistance will be overwrited very soon. - // - if (fifo is not empty) - // // (not 100% sure): shouln't happen unless PPC think having trouble with the sync - // // and it attempt a fifo recovery (look for PI_FIFO_RESET in log). - // // If we want to emulate self fifo recovery we need proper GX metrics emulation... yeah sure :p - // - spin until fifo is empty - // - else - // - normal write16 - - if (((_Address&0xFFF) == CTRL_REGISTER) && (_Value == 0)) // API hack - { - // weird MP1 redo that right after linking fifo with GP... hmmm - //_dbg_assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance == 0, - // "WTF! Something went wrong with GP/PPC the sync! -> CPReadWriteDistance: 0x%08X\n" - // " - The fifo is not empty but we are going to lock it anyway.\n" - // " - \"Normaly\", this is due to fifo-hang-so-lets-attempt-recovery.\n" - // " - The bad news is dolphin don't support special recovery features like GXfifo's metric yet.\n" - // " - The good news is, the time you read that message, the fifo should be empty now :p\n" - // " - Anyway, fifo flush will be forced if you press OK and dolphin might continue to work...\n" - // " - We aren't betting on that :)", fifo.CPReadWriteDistance); - - DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************"); - // (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC) - // Touching that game is a no-go so I don't want to take the risk :p - - if (IsOnThread()) - { - - //ProcessFifoAllDistance(); - } - else - { - CatchUpGPU(); - } - } - switch (_Address & 0xFFF) { case STATUS_REGISTER: @@ -443,90 +294,15 @@ void Write16(const u16 _Value, const u32 _Address) { UCPCtrlReg tmpCtrl(_Value); m_CPCtrlReg.Hex = tmpCtrl.Hex; - - // If the new fifo is being attached We make sure there wont be SetFinish event pending. - // This protection fix eternal darkness booting, because the second SetFinish event when it is booting - // seems invalid or has a bug and hang the game. - - // Single Core MODE - if (!IsOnThread()) - { - - Common::AtomicStore(fifo.bFF_Breakpoint, false); - if (tmpCtrl.FifoUnderflowIntEnable) - Common::AtomicStore(fifo.bFF_LoWatermark, false); - - if (tmpCtrl.FifoOverflowIntEnable) - m_CPStatusReg.OverflowHiWatermark = false; - - UpdateInterruptsScMode(); - } - - if (!fifo.bFF_GPReadEnable && tmpCtrl.GPReadEnable && !tmpCtrl.BPEnable) - { - PixelEngine::ResetSetFinish(); - } - - fifo.bFF_BPInt = tmpCtrl.BPInt; - fifo.bFF_BPEnable = tmpCtrl.BPEnable; - fifo.bFF_HiWatermarkInt = tmpCtrl.FifoOverflowIntEnable; - fifo.bFF_LoWatermarkInt = tmpCtrl.FifoUnderflowIntEnable; - fifo.bFF_GPLinkEnable = tmpCtrl.GPLinkEnable; - - if(tmpCtrl.GPReadEnable && tmpCtrl.GPLinkEnable) - { - ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer; - ProcessorInterface::Fifo_CPUBase = fifo.CPBase; - ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd; - } - // If overflown happens process the fifo to LoWatemark - if (bProcessFifoToLoWatermark) - ProcessFifoToLoWatermark(); - - if(fifo.bFF_GPReadEnable && !tmpCtrl.GPReadEnable) - { - fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable; - while(fifo.isFifoProcesingData) Common::YieldCPU(); - } - else - { - fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable; - } - INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value); - DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | BP %s | Int %s | OvF %s | UndF %s | LINK %s" - , fifo.bFF_GPReadEnable ? "ON" : "OFF" - , fifo.bFF_BPEnable ? "ON" : "OFF" - , fifo.bFF_BPInt ? "ON" : "OFF" - , m_CPCtrlReg.FifoOverflowIntEnable ? "ON" : "OFF" - , m_CPCtrlReg.FifoUnderflowIntEnable ? "ON" : "OFF" - , m_CPCtrlReg.GPLinkEnable ? "ON" : "OFF" - ); + SetCpControlRegister(); } break; case CLEAR_REGISTER: { UCPClearReg tmpCtrl(_Value); - - if (IsOnThread()) - { - if (!tmpCtrl.ClearFifoUnderflow && tmpCtrl.ClearFifoOverflow) - bProcessFifoToLoWatermark = true; - - } - else - { - // Single Core MODE - if (tmpCtrl.ClearFifoOverflow) - m_CPStatusReg.OverflowHiWatermark = false; - if (tmpCtrl.ClearFifoUnderflow) - Common::AtomicStore(fifo.bFF_LoWatermark, false); - UpdateInterruptsScMode(); - } - - - + m_CPClearReg.Hex = tmpCtrl.Hex; DEBUG_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x", _Value); } break; @@ -541,7 +317,6 @@ void Write16(const u16 _Value, const u32 _Address) m_tokenReg = _Value; DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_TOKEN_REGISTER : %04x", _Value); break; - case FIFO_BASE_LO: WriteLow ((u32 &)fifo.CPBase, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO : %04x", _Value); @@ -552,7 +327,6 @@ void Write16(const u16 _Value, const u32 _Address) break; case FIFO_END_LO: - // Sometimes this value is not aligned with 32B, e.g. New Super Mario Bros. Wii WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO : %04x", _Value); break; @@ -598,18 +372,14 @@ void Write16(const u16 _Value, const u32 _Address) break; case FIFO_BP_LO: - WriteLow ((u32 &)fifo.CPBreakpoint, _Value & 0xFFE0); + WriteLow ((u32 &)fifo.CPBreakpoint, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"write to FIFO_BP_LO : %04x", _Value); break; case FIFO_BP_HI: - WriteHigh((u32 &)fifo.CPBreakpoint, _Value); + WriteHigh((u32 &)fifo.CPBreakpoint, _Value); DEBUG_LOG(COMMANDPROCESSOR,"write to FIFO_BP_HI : %04x", _Value); break; - // Super monkey try to overwrite CPReadWriteDistance by an old saved RWD value. Which is lame for us. - // hack: We have to force CPU to think fifo is alway empty and on idle. - // When we fall here CPReadWriteDistance should be always null and the game should always want to overwrite it by 0. - // To skip it, comment out the following write. case FIFO_RW_DISTANCE_HI: WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value); DEBUG_LOG(COMMANDPROCESSOR,"try to write to FIFO_RW_DISTANCE_HI : %04x", _Value); @@ -633,7 +403,7 @@ void Write16(const u16 _Value, const u32 _Address) } if (!IsOnThread()) - CatchUpGPU(); + RunGpu(); ProcessFifoEvents(); } @@ -648,25 +418,6 @@ void Write32(const u32 _Data, const u32 _Address) _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProccessor at 0x%08x", _Address); } -// for GP watchdog hack -void IncrementGPWDToken() -{ - Common::AtomicIncrement(fifo.Fake_GPWDToken); -} - -// Check every FAKE_GP_WATCHDOG_PERIOD if a PE-frame-finish occurred -// if not then lock CPUThread until GP finish a frame. -void WaitForFrameFinish() -{ - - //while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance) - //{ - // s_fifoIdleEvent.Wait(); - //} - - //fake_GPWatchdogLastToken = fifo.Fake_GPWDToken; -} - void STACKALIGN GatherPipeBursted() { ProcessFifoEvents(); @@ -674,14 +425,13 @@ void STACKALIGN GatherPipeBursted() if (!m_CPCtrlReg.GPLinkEnable) { if (!IsOnThread()) - CatchUpGPU(); + RunGpu(); return; } if (IsOnThread()) SetOverflowStatusFromGatherPipe(); - // update the fifo-pointer if (fifo.CPWritePointer >= fifo.CPEnd) fifo.CPWritePointer = fifo.CPBase; @@ -690,17 +440,9 @@ void STACKALIGN GatherPipeBursted() Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); - - if (!IsOnThread()) { - CatchUpGPU(); - if (!m_CPStatusReg.OverflowHiWatermark && fifo.CPReadWriteDistance >= fifo.CPHiWatermark) - { - m_CPStatusReg.OverflowHiWatermark = true; - if (m_CPCtrlReg.FifoOverflowIntEnable) - UpdateInterruptsScMode(); - } + RunGpu(); } else { @@ -729,68 +471,6 @@ void STACKALIGN GatherPipeBursted() _assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync"); } - -// This is only used in single core mode -void CatchUpGPU() -{ - // HyperIris: Memory::GetPointer is an expensive call, call it less, run faster - u8 *ptr = Memory::GetPointer(fifo.CPReadPointer); - - // check if we are able to run this buffer - while (fifo.bFF_GPReadEnable && (fifo.CPReadWriteDistance || - (fifo.bFF_BPEnable && ((fifo.CPReadPointer <= fifo.CPBreakpoint) && (fifo.CPReadPointer + 32 > fifo.CPBreakpoint))))) - { - // check if we are on a breakpoint - if (fifo.bFF_BPEnable && ((fifo.CPReadPointer <= fifo.CPBreakpoint) && (fifo.CPReadPointer + 32 > fifo.CPBreakpoint))) - { - //_assert_msg_(POWERPC,0,"BP: %08x",fifo.CPBreakpoint); - Common::AtomicStore(fifo.bFF_GPReadEnable, false); - Common::AtomicStore(fifo.bFF_Breakpoint, true); - if (fifo.bFF_BPInt) - UpdateInterruptsScMode(); - break; - } - - // read the data and send it to the VideoBackend - // We are going to do FP math on the main thread so have to save the current state - SaveSSEState(); - LoadDefaultSSEState(); - Fifo_SendFifoData(ptr,32); - OpcodeDecoder_Run(g_bSkipCurrentFrame); - LoadSSEState(); - - // increase the ReadPtr - if (fifo.CPReadPointer >= fifo.CPEnd) - { - ptr -= fifo.CPReadPointer - fifo.CPBase; - fifo.CPReadPointer = fifo.CPBase; - DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base"); - } - else - { - ptr += 32; - fifo.CPReadPointer += 32; - } - fifo.CPReadWriteDistance -= 32; - } - - if (!fifo.bFF_LoWatermark && fifo.CPReadWriteDistance < fifo.CPLoWatermark) - { - Common::AtomicStore(fifo.bFF_LoWatermark, true); - if (m_CPCtrlReg.FifoUnderflowIntEnable) - UpdateInterruptsScMode(); - } -} - -void UpdateInterruptsScMode() -{ - bool active = (fifo.bFF_BPInt && fifo.bFF_Breakpoint) - || (m_CPCtrlReg.FifoUnderflowIntEnable && fifo.bFF_LoWatermark) - || (m_CPCtrlReg.FifoOverflowIntEnable && m_CPStatusReg.OverflowHiWatermark); - INFO_LOG(COMMANDPROCESSOR, "Fifo Interrupt: %s", (active)? "Asserted" : "Deasserted"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, active); -} - void UpdateInterrupts(u64 userdata) { if (userdata) @@ -813,37 +493,16 @@ void UpdateInterruptsFromVideoBackend(u64 userdata) CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); } -void SetFifoIdleFromVideoBackend() -{ - s_fifoIdleEvent.Set(); -} - // This is called by the ProcessorInterface when PI_FIFO_RESET is written to. -// The general idea is abort all commands in the FIFO. -// This prevents negative fifo.CPReadWriteDistance by changing fifo.CPReadWriteDistance -// to 0 when PI_FIFO_RESET occurs. void AbortFrame() { - //fifo.bFF_GPReadEnable = false; - //while(IsFifoProcesingData()) Common::YieldCPU(); - //GPFifo::ResetGatherPipe(); - //ResetVideoBuffer(); - //fifo.CPReadPointer = fifo.CPWritePointer; - //fifo.CPReadWriteDistance = 0; - //fifo.CPBreakpoint = 0; - //fifo.bFF_Breakpoint = false; - //fifo.CPCmdIdle = false; - //PixelEngine::ResetSetToken(); - //PixelEngine::ResetSetFinish(); - //fifo.bFF_GPReadEnable = true; - //IncrementCheckContextId(); + } void SetOverflowStatusFromGatherPipe() { if (!fifo.bFF_HiWatermarkInt) return; - // overflow check fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); @@ -855,9 +514,9 @@ void SetOverflowStatusFromGatherPipe() } -void SetStatus() +void SetCpStatus() { - // overflow check + // overflow & underflow check fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); @@ -905,8 +564,6 @@ void SetStatus() } else CommandProcessor::UpdateInterrupts(userdata); - - } } @@ -938,5 +595,88 @@ void ProcessFifoEvents() CoreTiming::ProcessFifoWaitEvents(); } +void Shutdown() +{ + +} + +void SetCpStatusRegister() +{ + // Here always there is one fifo attached to the GPU + + m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint; + m_CPStatusReg.ReadIdle = (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint); + m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance; + m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark; + m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark; + + INFO_LOG(COMMANDPROCESSOR,"\t Read from STATUS_REGISTER : %04x", m_CPStatusReg.Hex); + DEBUG_LOG(COMMANDPROCESSOR, "(r) status: iBP %s | fReadIdle %s | fCmdIdle %s | iOvF %s | iUndF %s" + , m_CPStatusReg.Breakpoint ? "ON" : "OFF" + , m_CPStatusReg.ReadIdle ? "ON" : "OFF" + , m_CPStatusReg.CommandIdle ? "ON" : "OFF" + , m_CPStatusReg.OverflowHiWatermark ? "ON" : "OFF" + , m_CPStatusReg.UnderflowLoWatermark ? "ON" : "OFF" + ); +} + +void SetCpControlRegister() +{ + + // If the new fifo is being attached We make sure there wont be SetFinish event pending. + // This protection fix eternal darkness booting, because the second SetFinish event when it is booting + // seems invalid or has a bug and hang the game. + + if (!fifo.bFF_GPReadEnable && m_CPCtrlReg.GPReadEnable && !m_CPCtrlReg.BPEnable) + { + PixelEngine::ResetSetFinish(); + } + + fifo.bFF_BPInt = m_CPCtrlReg.BPInt; + fifo.bFF_BPEnable = m_CPCtrlReg.BPEnable; + fifo.bFF_HiWatermarkInt = m_CPCtrlReg.FifoOverflowIntEnable; + fifo.bFF_LoWatermarkInt = m_CPCtrlReg.FifoUnderflowIntEnable; + fifo.bFF_GPLinkEnable = m_CPCtrlReg.GPLinkEnable; + + if(m_CPCtrlReg.GPReadEnable && m_CPCtrlReg.GPLinkEnable) + { + ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer; + ProcessorInterface::Fifo_CPUBase = fifo.CPBase; + ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd; + } + // If overflown happens process the fifo to LoWatemark + if (bProcessFifoToLoWatermark) + ProcessFifoToLoWatermark(); + + if(fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable) + { + fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable; + while(fifo.isGpuReadingData) Common::YieldCPU(); + } + else + { + fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable; + } + + + DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | BP %s | Int %s | OvF %s | UndF %s | LINK %s" + , fifo.bFF_GPReadEnable ? "ON" : "OFF" + , fifo.bFF_BPEnable ? "ON" : "OFF" + , fifo.bFF_BPInt ? "ON" : "OFF" + , m_CPCtrlReg.FifoOverflowIntEnable ? "ON" : "OFF" + , m_CPCtrlReg.FifoUnderflowIntEnable ? "ON" : "OFF" + , m_CPCtrlReg.GPLinkEnable ? "ON" : "OFF" + ); + +} + +void SetCpClearRegister() +{ + if (IsOnThread()) + { + if (!m_CPClearReg.ClearFifoUnderflow && m_CPClearReg.ClearFifoOverflow) + bProcessFifoToLoWatermark = true; + } +} } // end of namespace CommandProcessor diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index ec1d1234c3..7fb4e5a45f 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -151,25 +151,15 @@ void Write16(const u16 _Data, const u32 _Address); void Read32(u32& _rReturnValue, const u32 _Address); void Write32(const u32 _Data, const u32 _Address); -// for CGPFIFO -void CatchUpGPU(); -void SetStatus(); +void SetCpStatus(); void GatherPipeBursted(); -void UpdateFifoRegister(); void UpdateInterrupts(u64 userdata); void UpdateInterruptsFromVideoBackend(u64 userdata); -void UpdateInterruptsScMode(); -void SetFifoIdleFromVideoBackend(); bool AllowIdleSkipping(); -// for DC GP watchdog hack -void IncrementGPWDToken(); -void WaitForFrameFinish(); - -void FifoCriticalEnter(); -void FifoCriticalLeave(); - +void SetCpControlRegister(); +void SetCpStatusRegister(); void SetOverflowStatusFromGatherPipe(); void ProcessFifoToLoWatermark(); void ProcessFifoAllDistance(); diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 9f0ec05187..d1b497788c 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -31,8 +31,8 @@ extern u8* g_pVideoData; namespace { -static volatile bool fifoStateRun = false; -static volatile bool EmuRunning = false; +static volatile bool GpuRunningState = false; +static volatile bool EmuRunningState = false; static u8 *videoBuffer; // STATE_TO_SAVE static int size = 0; @@ -53,21 +53,21 @@ void Fifo_Init() { videoBuffer = (u8*)AllocateMemoryPages(FIFO_SIZE); size = 0; - fifoStateRun = false; + GpuRunningState = false; } void Fifo_Shutdown() { - if (fifoStateRun) PanicAlert("Fifo shutting down while active"); + if (GpuRunningState) PanicAlert("Fifo shutting down while active"); FreeMemoryPages(videoBuffer, FIFO_SIZE); } -u8* FAKE_GetFifoStartPtr() +u8* GetVideoBufferStartPtr() { return videoBuffer; } -u8* FAKE_GetFifoEndPtr() +u8* GetVideoBufferEndPtr() { return &videoBuffer[size]; } @@ -79,25 +79,25 @@ void Fifo_SetRendering(bool enabled) // May be executed from any thread, even the graphics thread. // Created to allow for self shutdown. -void Fifo_ExitLoop() +void ExitGpuLoop() { // This should break the wait loop in CPU thread CommandProcessor::fifo.bFF_GPReadEnable = false; - SCPFifoStruct &_fifo = CommandProcessor::fifo; - while(_fifo.isFifoProcesingData) Common::YieldCPU(); + SCPFifoStruct &fifo = CommandProcessor::fifo; + while(fifo.isGpuReadingData) Common::YieldCPU(); // Terminate GPU thread loop - fifoStateRun = false; - EmuRunning = true; + GpuRunningState = false; + EmuRunningState = true; } -void Fifo_RunLoop(bool run) +void EmulatorState(bool running) { - EmuRunning = run; + EmuRunningState = running; } -// Description: Fifo_EnterLoop() sends data through this function. -void Fifo_SendFifoData(u8* _uData, u32 len) +// Description: RunGpuLoop() sends data through this function. +void ReadDataFromFifo(u8* _uData, u32 len) { if (size + len >= FIFO_SIZE) { @@ -124,54 +124,45 @@ void ResetVideoBuffer() // Description: Main FIFO update loop // Purpose: Keep the Core HW updated about the CPU-GPU distance -void Fifo_EnterLoop() +void RunGpuLoop() { - fifoStateRun = true; - SCPFifoStruct &_fifo = CommandProcessor::fifo; - s32 distToSend; + GpuRunningState = true; + SCPFifoStruct &fifo = CommandProcessor::fifo; - while (fifoStateRun) + while (GpuRunningState) { g_video_backend->PeekMessages(); VideoFifo_CheckAsyncRequest(); - - // check if we are able to run this buffer - - CommandProcessor::SetStatus(); - - while (!CommandProcessor::interruptWaiting && _fifo.bFF_GPReadEnable && - _fifo.CPReadWriteDistance && (!AtBreakpoint() || CommandProcessor::OnOverflow)) + + CommandProcessor::SetCpStatus(); + // check if we are able to run this buffer + while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && + fifo.CPReadWriteDistance && (!AtBreakpoint() || CommandProcessor::OnOverflow)) { - _fifo.isFifoProcesingData = true; - CommandProcessor::isPossibleWaitingSetDrawDone = _fifo.bFF_GPLinkEnable; + if (!GpuRunningState) break; - if (!fifoStateRun) break; - - // Create pointer to video data and send it to the VideoBackend - u32 readPtr = _fifo.CPReadPointer; + fifo.isGpuReadingData = true; + CommandProcessor::isPossibleWaitingSetDrawDone = fifo.bFF_GPLinkEnable; + + u32 readPtr = fifo.CPReadPointer; u8 *uData = Memory::GetPointer(readPtr); - distToSend = 32; - - if (readPtr == _fifo.CPEnd) - readPtr = _fifo.CPBase; - else - readPtr += 32; + if (readPtr == fifo.CPEnd) readPtr = fifo.CPBase; + else readPtr += 32; - _assert_msg_(COMMANDPROCESSOR, (s32)_fifo.CPReadWriteDistance - distToSend >= 0 , - "Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", _fifo.CPReadWriteDistance - distToSend); + _assert_msg_(COMMANDPROCESSOR, (s32)fifo.CPReadWriteDistance - 32 >= 0 , + "Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", fifo.CPReadWriteDistance - 32); - // Execute new instructions found in uData - Fifo_SendFifoData(uData, distToSend); + ReadDataFromFifo(uData, 32); OpcodeDecoder_Run(g_bSkipCurrentFrame); - Common::AtomicStore(_fifo.CPReadPointer, readPtr); - Common::AtomicAdd(_fifo.CPReadWriteDistance, -distToSend); - if((FAKE_GetFifoEndPtr() - g_pVideoData) == 0) - Common::AtomicStore(_fifo.SafeCPReadPointer, _fifo.CPReadPointer); - CommandProcessor::SetStatus(); + Common::AtomicStore(fifo.CPReadPointer, readPtr); + Common::AtomicAdd(fifo.CPReadWriteDistance, -32); + if((GetVideoBufferEndPtr() - g_pVideoData) == 0) + Common::AtomicStore(fifo.SafeCPReadPointer, fifo.CPReadPointer); + CommandProcessor::SetCpStatus(); // This call is pretty important in DualCore mode and must be called in the FIFO Loop. // If we don't, s_swapRequested or s_efbAccessRequested won't be set to false @@ -180,16 +171,15 @@ void Fifo_EnterLoop() CommandProcessor::isPossibleWaitingSetDrawDone = false; } - _fifo.isFifoProcesingData = false; + fifo.isGpuReadingData = false; - CommandProcessor::SetFifoIdleFromVideoBackend(); - if (EmuRunning) + if (EmuRunningState) Common::YieldCPU(); else { // While the emu is paused, we still handle async request such as Savestates then sleep. - while (!EmuRunning) + while (!EmuRunningState) { g_video_backend->PeekMessages(); VideoFifo_CheckStateRequest(); @@ -202,6 +192,29 @@ void Fifo_EnterLoop() bool AtBreakpoint() { - SCPFifoStruct &_fifo = CommandProcessor::fifo; - return _fifo.bFF_BPEnable && (_fifo.CPReadPointer == _fifo.CPBreakpoint); + SCPFifoStruct &fifo = CommandProcessor::fifo; + return fifo.bFF_BPEnable && (fifo.CPReadPointer == fifo.CPBreakpoint); } + +void RunGpu() +{ + SCPFifoStruct &fifo = CommandProcessor::fifo; + while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint() ) + { + u8 *uData = Memory::GetPointer(fifo.CPReadPointer); + + SaveSSEState(); + LoadDefaultSSEState(); + ReadDataFromFifo(uData, 32); + OpcodeDecoder_Run(g_bSkipCurrentFrame); + LoadSSEState(); + + //DEBUG_LOG(COMMANDPROCESSOR, "Fifo wraps to base"); + + if (fifo.CPReadPointer == fifo.CPEnd) fifo.CPReadPointer = fifo.CPBase; + else fifo.CPReadPointer += 32; + + fifo.CPReadWriteDistance -= 32; + } + CommandProcessor::SetCpStatus(); +} \ No newline at end of file diff --git a/Source/Core/VideoCommon/Src/Fifo.h b/Source/Core/VideoCommon/Src/Fifo.h index 90f0d9ed33..e73434a19f 100644 --- a/Source/Core/VideoCommon/Src/Fifo.h +++ b/Source/Core/VideoCommon/Src/Fifo.h @@ -30,18 +30,18 @@ extern volatile bool g_bSkipCurrentFrame; void Fifo_Init(); void Fifo_Shutdown(); - -void Fifo_SendFifoData(u8* _uData, u32 len); - -// These two are for dual core mode only. -void Fifo_EnterLoop(); -void Fifo_ExitLoop(); -void Fifo_RunLoop(bool run); -bool AtBreakpoint(); void Fifo_DoState(PointerWrap &f); + +void ReadDataFromFifo(u8* _uData, u32 len); + +void RunGpu(); +void RunGpuLoop(); +void ExitGpuLoop(); +void EmulatorState(bool running); +bool AtBreakpoint(); void ResetVideoBuffer(); void Fifo_SetRendering(bool bEnabled); -bool IsFifoProcesingData(); + // Implemented by the Video Backend void VideoFifo_CheckAsyncRequest(); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 485db54f39..9107bb9be1 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -41,18 +41,18 @@ static u32 s_AccessEFBResult = 0; void VideoBackendHLE::EmuStateChange(EMUSTATE_CHANGE newState) { - Fifo_RunLoop((newState == EMUSTATE_CHANGE_PLAY) ? true : false); + EmulatorState((newState == EMUSTATE_CHANGE_PLAY) ? true : false); } // Enter and exit the video loop void VideoBackendHLE::Video_EnterLoop() { - Fifo_EnterLoop(); + RunGpuLoop(); } void VideoBackendHLE::Video_ExitLoop() { - Fifo_ExitLoop(); + ExitGpuLoop(); s_FifoShuttingDown = true; } @@ -233,11 +233,6 @@ void VideoBackend::Video_GatherPipeBursted() CommandProcessor::GatherPipeBursted(); } -void VideoBackendHLE::Video_WaitForFrameFinish() -{ - CommandProcessor::WaitForFrameFinish(); -} - bool VideoBackendHLE::Video_IsPossibleWaitingSetDrawDone() { return CommandProcessor::isPossibleWaitingSetDrawDone; diff --git a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp index f30bfd0b41..bddc31ef40 100644 --- a/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp +++ b/Source/Core/VideoCommon/Src/OpcodeDecoding.cpp @@ -90,8 +90,8 @@ DataReadU32xNfunc DataReadU32xFuncs[16] = { DataReadU32xN<16> }; -extern u8* FAKE_GetFifoStartPtr(); -extern u8* FAKE_GetFifoEndPtr(); +extern u8* GetVideoBufferStartPtr(); +extern u8* GetVideoBufferEndPtr(); static void Decode(); @@ -135,7 +135,7 @@ void ExecuteDisplayList(u32 address, u32 size) bool FifoCommandRunnable() { - u32 buffer_size = (u32)(FAKE_GetFifoEndPtr() - g_pVideoData); + u32 buffer_size = (u32)(GetVideoBufferEndPtr() - g_pVideoData); if (buffer_size == 0) return false; // can't peek @@ -420,7 +420,7 @@ static void DecodeSemiNop() void OpcodeDecoder_Init() { - g_pVideoData = FAKE_GetFifoStartPtr(); + g_pVideoData = GetVideoBufferStartPtr(); #if _M_SSE >= 0x301 if (cpu_info.bSSSE3) diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index b7b95df8dd..2a328de95d 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -367,8 +367,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge) // TODO?: set-token-value and set-token-INT could be merged since set-token-INT own the token value. if (_bSetTokenAcknowledge) // set token INT { - // This seems smelly... - CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack since PEToken seems to be a frame-finish too + Common::AtomicStore(*(volatile u32*)&CommandProcessor::fifo.PEToken, _token); CommandProcessor::interruptTokenWaiting = true; CoreTiming::ScheduleEvent_Threadsafe(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); @@ -389,7 +388,6 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge) // THIS IS EXECUTED FROM VIDEO THREAD (BPStructs.cpp) when a new frame has been drawn void SetFinish() { - CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack CommandProcessor::interruptFinishWaiting = true; CoreTiming::ScheduleEvent_Threadsafe(0, et_SetFinishOnMainThread, 0); INFO_LOG(PIXELENGINE, "VIDEO Set Finish"); diff --git a/Source/Core/VideoCommon/Src/VideoState.cpp b/Source/Core/VideoCommon/Src/VideoState.cpp index d82aaed46f..1a23410fcc 100644 --- a/Source/Core/VideoCommon/Src/VideoState.cpp +++ b/Source/Core/VideoCommon/Src/VideoState.cpp @@ -58,5 +58,5 @@ void VideoCommon_DoState(PointerWrap &p) void VideoCommon_RunLoop(bool enable) { - Fifo_RunLoop(enable); + EmulatorState(enable); } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 15c7417323..7e1dc3ec83 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -174,9 +174,6 @@ void VideoBackend::Video_SetRendering(bool bEnabled) Fifo_SetRendering(bEnabled); } -void VideoBackend::Video_WaitForFrameFinish(void) -{ -} bool VideoBackend::Video_IsPossibleWaitingSetDrawDone(void) { diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h index 8430e681ff..1e02131a48 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h @@ -35,7 +35,6 @@ class VideoBackend : public VideoBackendLLE void Video_SetRendering(bool bEnabled); - void Video_WaitForFrameFinish(); bool Video_IsPossibleWaitingSetDrawDone(); void Video_AbortFrame();