mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
BIG FIFO Commit PART 1! Sometimes you need to write everything from 0, so 10 days later Ive rewrited some parts of the FIFO in Dual Core mode. Is pending use the same code for SC mode.
- Improved the GP Register Status: now this is all the time from the fifo loop. - Improved the Interrupts manage: 1) Removed All UpdateInturrupts from CommandProcessor Writes and Read. 2) now the CP interrupts are schedule from the video thread and the fifo loop waiting until this happens 3) considering Inmediate mode for the CP interrupts 3) Implemented Interrupt CP Cache State 4) Implemented only Overflow interrupt in GatherPipeCheck because this need to be detected quickly. - Implemented Overflow handling like a real HW, when Hiwatermark interrupt happens this write ClearRegister with True en HI and False in LO (FifoIntReset) after that a Control Register is writed and the FIFO is processed to LO Watermark. - Removed all ugly code from LO and HI watermark manage - Removed all ugly code from BP manage - Change >= by == in the BP clauses - Removed speed hack (1024 chunk) for better GP Status Control. - Commented GXSetGPFifo very soon hack - Commented FackWatchDog hack - Commented FIFO_RW_DISTANCE = WritePointer hack This is the beginning and the base for the future., If this broke your favorite game my apologize, only report this and will try solve it. If you have a Overflown don't worry, I've implemented the real solution code using the Overflow Interruption only need continue working for a perfect protection. Why I did it? Because is preferable a accurate and clean fifo instead hack y fifo for improve that. Thanks to DONKO for you awesome Video Plug in and skid for the chatting. PD: I have 7-10 fps more in the star fox video. bye :P git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6554 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -127,13 +127,14 @@ void Fifo_SendFifoData(u8* _uData, u32 len)
|
||||
// Copy new video instructions to videoBuffer for future use in rendering the new picture
|
||||
memcpy(videoBuffer + size, _uData, len);
|
||||
size += len;
|
||||
OpcodeDecoder_Run(g_bSkipCurrentFrame);
|
||||
}
|
||||
|
||||
|
||||
// Description: Main FIFO update loop
|
||||
// Purpose: Keep the Core HW updated about the CPU-GPU distance
|
||||
void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
{
|
||||
|
||||
fifoStateRun = true;
|
||||
SCPFifoStruct &_fifo = CommandProcessor::fifo;
|
||||
s32 distToSend;
|
||||
@ -146,67 +147,48 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
|
||||
// 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)))))
|
||||
CommandProcessor::SetStatus();
|
||||
|
||||
while (!CommandProcessor::interruptWaiting && _fifo.bFF_GPReadEnable &&
|
||||
_fifo.CPReadWriteDistance && !AtBreakpoint())
|
||||
{
|
||||
// while the FIFO is processing data we activate this for sync with emulator thread.
|
||||
CommandProcessor::isFifoBusy = true;
|
||||
|
||||
|
||||
if (!fifoStateRun)
|
||||
break;
|
||||
if (!fifoStateRun) break;
|
||||
|
||||
_fifo.CPCmdIdle = false;
|
||||
|
||||
CommandProcessor::FifoCriticalEnter();
|
||||
// Create pointer to video data and send it to the VideoPlugin
|
||||
u32 readPtr = _fifo.CPReadPointer;
|
||||
u8 *uData = video_initialize.pGetMemoryPointer(readPtr);
|
||||
// DEBUG_LOG(BOOT, "readPtr: %08x uData %08x", readPtr, uData);
|
||||
|
||||
// If we are in BP mode we only send 32B chunks to Video plugin for BP checking
|
||||
if (_fifo.bFF_BPEnable)
|
||||
{
|
||||
if ((readPtr <= _fifo.CPBreakpoint) && (readPtr + 32 > _fifo.CPBreakpoint))
|
||||
{
|
||||
Common::AtomicStore(_fifo.bFF_GPReadEnable, false);
|
||||
Common::AtomicStore(_fifo.bFF_Breakpoint, true);
|
||||
if (_fifo.bFF_BPInt)
|
||||
CommandProcessor::UpdateInterruptsFromVideoPlugin();
|
||||
CommandProcessor::FifoCriticalLeave();
|
||||
CommandProcessor::isFifoBusy = false;
|
||||
break;
|
||||
}
|
||||
distToSend = 32;
|
||||
|
||||
distToSend = 32;
|
||||
if (readPtr >= _fifo.CPEnd)
|
||||
readPtr = _fifo.CPBase;
|
||||
else
|
||||
readPtr += 32;
|
||||
}
|
||||
// If we are not in BP mode we send all the chunk we have to speed up
|
||||
if (readPtr == _fifo.CPEnd)
|
||||
readPtr = _fifo.CPBase;
|
||||
else
|
||||
{
|
||||
distToSend = _fifo.CPReadWriteDistance;
|
||||
// send 1024B chunk max length to have better control over PeekMessages' period
|
||||
distToSend = distToSend > 1024 ? 1024 : distToSend;
|
||||
if (readPtr + distToSend >= _fifo.CPEnd + 32)
|
||||
{
|
||||
distToSend = _fifo.CPEnd + 32 - readPtr;
|
||||
readPtr = _fifo.CPBase;
|
||||
}
|
||||
else
|
||||
readPtr += distToSend;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Common::AtomicStore(_fifo.CPReadPointer, readPtr);
|
||||
Common::AtomicAdd(_fifo.CPReadWriteDistance, -distToSend);
|
||||
|
||||
// Execute new instructions found in uData
|
||||
Fifo_SendFifoData(uData, distToSend);
|
||||
|
||||
|
||||
Fifo_SendFifoData(uData, distToSend);
|
||||
Common::AtomicStore(_fifo.CPReadPointer, readPtr);
|
||||
Common::AtomicAdd(_fifo.CPReadWriteDistance, -distToSend);
|
||||
|
||||
CommandProcessor::isFifoBusy = true;
|
||||
CommandProcessor::SetStatus();
|
||||
|
||||
_fifo.CPCmdIdle = false;
|
||||
|
||||
OpcodeDecoder_Run(g_bSkipCurrentFrame);
|
||||
|
||||
_fifo.CPCmdIdle = true;
|
||||
|
||||
CommandProcessor::isFifoBusy = false;
|
||||
CommandProcessor::FifoCriticalLeave();
|
||||
|
||||
// Those two are pretty important and must be called in the FIFO Loop.
|
||||
@ -214,17 +196,10 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
|
||||
|
||||
VideoFifo_CheckAsyncRequest();
|
||||
CommandProcessor::isFifoBusy = false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!_fifo.CPReadIdle && _fifo.CPReadWriteDistance < _fifo.CPLoWatermark)
|
||||
{
|
||||
Common::AtomicStore(_fifo.CPReadIdle, true);
|
||||
CommandProcessor::UpdateInterruptsFromVideoPlugin();
|
||||
}
|
||||
|
||||
_fifo.CPCmdIdle = true;
|
||||
CommandProcessor::SetFifoIdleFromVideoPlugin();
|
||||
if (EmuRunning)
|
||||
Common::YieldCPU();
|
||||
@ -233,3 +208,9 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AtBreakpoint()
|
||||
{
|
||||
SCPFifoStruct &_fifo = CommandProcessor::fifo;
|
||||
return _fifo.bFF_BPEnable && (_fifo.CPReadPointer == _fifo.CPBreakpoint);
|
||||
}
|
||||
|
Reference in New Issue
Block a user