Merge pull request #3573 from degasus/fifoplayer

Fifoplayer: Fix dual core
This commit is contained in:
Ryan Houdek 2016-01-29 16:39:32 -05:00
commit ea3a457091
5 changed files with 68 additions and 42 deletions

View File

@ -136,7 +136,8 @@ void SetCurrentThreadName(const char* szThreadName)
#elif defined __FreeBSD__ #elif defined __FreeBSD__
pthread_set_name_np(pthread_self(), szThreadName); pthread_set_name_np(pthread_self(), szThreadName);
#else #else
pthread_setname_np(pthread_self(), szThreadName); // linux doesn't allow to set more than 16 bytes, including \0.
pthread_setname_np(pthread_self(), std::string(szThreadName).substr(0, 15).c_str());
#endif #endif
#ifdef USE_VTUNE #ifdef USE_VTUNE
// VTune uses OS thread names by default but probably supports longer names when set via its own API. // VTune uses OS thread names by default but probably supports longer names when set via its own API.

View File

@ -15,10 +15,12 @@
#include "Core/FifoPlayer/FifoPlayer.h" #include "Core/FifoPlayer/FifoPlayer.h"
#include "Core/HW/GPFifo.h" #include "Core/HW/GPFifo.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/HW/ProcessorInterface.h"
#include "Core/HW/SystemTimers.h" #include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h" #include "Core/HW/VideoInterface.h"
#include "Core/PowerPC/PowerPC.h" #include "Core/PowerPC/PowerPC.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/CommandProcessor.h"
bool IsPlayingBackFifologWithBrokenEFBCopies = false; bool IsPlayingBackFifologWithBrokenEFBCopies = false;
@ -80,9 +82,6 @@ bool FifoPlayer::Play()
if (m_Loop) if (m_Loop)
{ {
m_CurrentFrame = m_FrameRangeStart; m_CurrentFrame = m_FrameRangeStart;
PowerPC::ppcState.downcount = 0;
CoreTiming::Advance();
} }
else else
{ {
@ -231,6 +230,13 @@ void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo&
WriteFramePart(position, frame.fifoDataSize, memoryUpdate, frame, info); WriteFramePart(position, frame.fifoDataSize, memoryUpdate, frame, info);
FlushWGP(); FlushWGP();
// Sleep while the GPU is active
while (!IsIdleSet())
{
CoreTiming::Idle();
CoreTiming::Advance();
}
} }
void FifoPlayer::WriteFramePart(u32 dataStart, u32 dataEnd, u32& nextMemUpdate, const FifoFrameInfo& frame, const AnalyzedFrameInfo& info) void FifoPlayer::WriteFramePart(u32 dataStart, u32 dataEnd, u32& nextMemUpdate, const FifoFrameInfo& frame, const AnalyzedFrameInfo& info)
@ -298,6 +304,12 @@ void FifoPlayer::WriteFifo(u8* data, u32 start, u32 end)
// Write up to 256 bytes at a time // Write up to 256 bytes at a time
while (written < end) while (written < end)
{ {
while (IsHighWatermarkSet())
{
CoreTiming::Idle();
CoreTiming::Advance();
}
u32 burstEnd = std::min(written + 255, lastBurstEnd); u32 burstEnd = std::min(written + 255, lastBurstEnd);
while (written < burstEnd) while (written < burstEnd)
@ -317,42 +329,42 @@ void FifoPlayer::WriteFifo(u8* data, u32 start, u32 end)
void FifoPlayer::SetupFifo() void FifoPlayer::SetupFifo()
{ {
WriteCP(0x02, 0); // disable read, BP, interrupts WriteCP(CommandProcessor::CTRL_REGISTER, 0); // disable read, BP, interrupts
WriteCP(0x04, 7); // clear overflow, underflow, metrics WriteCP(CommandProcessor::CLEAR_REGISTER, 7); // clear overflow, underflow, metrics
const FifoFrameInfo& frame = m_File->GetFrame(m_CurrentFrame); const FifoFrameInfo& frame = m_File->GetFrame(m_CurrentFrame);
// Set fifo bounds // Set fifo bounds
WriteCP(0x20, frame.fifoStart); WriteCP(CommandProcessor::FIFO_BASE_LO, frame.fifoStart);
WriteCP(0x22, frame.fifoStart >> 16); WriteCP(CommandProcessor::FIFO_BASE_HI, frame.fifoStart >> 16);
WriteCP(0x24, frame.fifoEnd); WriteCP(CommandProcessor::FIFO_END_LO, frame.fifoEnd);
WriteCP(0x26, frame.fifoEnd >> 16); WriteCP(CommandProcessor::FIFO_END_HI, frame.fifoEnd >> 16);
// Set watermarks // Set watermarks, high at 75%, low at 0%
u32 fifoSize = frame.fifoEnd - frame.fifoStart; u32 hi_watermark = (frame.fifoEnd - frame.fifoStart) * 3 / 4;
WriteCP(0x28, fifoSize); WriteCP(CommandProcessor::FIFO_HI_WATERMARK_LO, hi_watermark);
WriteCP(0x2a, fifoSize >> 16); WriteCP(CommandProcessor::FIFO_HI_WATERMARK_HI, hi_watermark >> 16);
WriteCP(0x2c, 0); WriteCP(CommandProcessor::FIFO_LO_WATERMARK_LO, 0);
WriteCP(0x2e, 0); WriteCP(CommandProcessor::FIFO_LO_WATERMARK_HI, 0);
// Set R/W pointers to fifo start // Set R/W pointers to fifo start
WriteCP(0x30, 0); WriteCP(CommandProcessor::FIFO_RW_DISTANCE_LO, 0);
WriteCP(0x32, 0); WriteCP(CommandProcessor::FIFO_RW_DISTANCE_HI, 0);
WriteCP(0x34, frame.fifoStart); WriteCP(CommandProcessor::FIFO_WRITE_POINTER_LO, frame.fifoStart);
WriteCP(0x36, frame.fifoStart >> 16); WriteCP(CommandProcessor::FIFO_WRITE_POINTER_HI, frame.fifoStart >> 16);
WriteCP(0x38, frame.fifoStart); WriteCP(CommandProcessor::FIFO_READ_POINTER_LO, frame.fifoStart);
WriteCP(0x3a, frame.fifoStart >> 16); WriteCP(CommandProcessor::FIFO_READ_POINTER_HI, frame.fifoStart >> 16);
// Set fifo bounds // Set fifo bounds
WritePI(12, frame.fifoStart); WritePI(ProcessorInterface::PI_FIFO_BASE, frame.fifoStart);
WritePI(16, frame.fifoEnd); WritePI(ProcessorInterface::PI_FIFO_END, frame.fifoEnd);
// Set write pointer // Set write pointer
WritePI(20, frame.fifoStart); WritePI(ProcessorInterface::PI_FIFO_WPTR, frame.fifoStart);
FlushWGP(); FlushWGP();
WritePI(20, frame.fifoStart); WritePI(ProcessorInterface::PI_FIFO_WPTR, frame.fifoStart);
WriteCP(0x02, 17); // enable read & GP link WriteCP(CommandProcessor::CTRL_REGISTER, 17); // enable read & GP link
} }
void FifoPlayer::LoadMemory() void FifoPlayer::LoadMemory()
@ -477,3 +489,15 @@ bool FifoPlayer::ShouldLoadBP(u8 address)
return true; return true;
} }
} }
bool FifoPlayer::IsIdleSet()
{
CommandProcessor::UCPStatusReg status = PowerPC::Read_U16(0xCC000000 | CommandProcessor::STATUS_REGISTER);
return status.CommandIdle;
}
bool FifoPlayer::IsHighWatermarkSet()
{
CommandProcessor::UCPStatusReg status = PowerPC::Read_U16(0xCC000000 | CommandProcessor::STATUS_REGISTER);
return status.OverflowHiWatermark;
}

View File

@ -113,6 +113,9 @@ private:
bool ShouldLoadBP(u8 address); bool ShouldLoadBP(u8 address);
static bool IsIdleSet();
static bool IsHighWatermarkSet();
bool m_Loop; bool m_Loop;
u32 m_CurrentFrame; u32 m_CurrentFrame;

View File

@ -15,21 +15,6 @@
namespace ProcessorInterface namespace ProcessorInterface
{ {
// Internal hardware addresses
enum
{
PI_INTERRUPT_CAUSE = 0x00,
PI_INTERRUPT_MASK = 0x04,
PI_FIFO_BASE = 0x0C,
PI_FIFO_END = 0x10,
PI_FIFO_WPTR = 0x14,
PI_FIFO_RESET = 0x18, // ??? - GXAbortFrame writes to it
PI_RESET_CODE = 0x24,
PI_FLIPPER_REV = 0x2C,
PI_FLIPPER_UNK = 0x30 // BS1 writes 0x0245248A to it - prolly some bootstrap thing
};
// STATE_TO_SAVE // STATE_TO_SAVE
u32 m_InterruptCause; u32 m_InterruptCause;
u32 m_InterruptMask; u32 m_InterruptMask;

View File

@ -34,6 +34,19 @@ enum InterruptCause
INT_CAUSE_RST_BUTTON = 0x10000 // ResetButtonState (1 = unpressed, 0 = pressed) it's a state, not maskable INT_CAUSE_RST_BUTTON = 0x10000 // ResetButtonState (1 = unpressed, 0 = pressed) it's a state, not maskable
}; };
// Internal hardware addresses
enum
{
PI_INTERRUPT_CAUSE = 0x00,
PI_INTERRUPT_MASK = 0x04,
PI_FIFO_BASE = 0x0C,
PI_FIFO_END = 0x10,
PI_FIFO_WPTR = 0x14,
PI_FIFO_RESET = 0x18, // ??? - GXAbortFrame writes to it
PI_RESET_CODE = 0x24,
PI_FLIPPER_REV = 0x2C,
PI_FLIPPER_UNK = 0x30 // BS1 writes 0x0245248A to it - prolly some bootstrap thing
};
extern u32 m_InterruptCause; extern u32 m_InterruptCause;
extern u32 m_InterruptMask; extern u32 m_InterruptMask;