diff --git a/Source/Core/Common/Thread.cpp b/Source/Core/Common/Thread.cpp index ad0436c3ae..29420dd170 100644 --- a/Source/Core/Common/Thread.cpp +++ b/Source/Core/Common/Thread.cpp @@ -136,7 +136,8 @@ void SetCurrentThreadName(const char* szThreadName) #elif defined __FreeBSD__ pthread_set_name_np(pthread_self(), szThreadName); #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 #ifdef USE_VTUNE // VTune uses OS thread names by default but probably supports longer names when set via its own API. diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 7e3dbd6122..340b3b3c09 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -15,10 +15,12 @@ #include "Core/FifoPlayer/FifoPlayer.h" #include "Core/HW/GPFifo.h" #include "Core/HW/Memmap.h" +#include "Core/HW/ProcessorInterface.h" #include "Core/HW/SystemTimers.h" #include "Core/HW/VideoInterface.h" #include "Core/PowerPC/PowerPC.h" #include "VideoCommon/BPMemory.h" +#include "VideoCommon/CommandProcessor.h" bool IsPlayingBackFifologWithBrokenEFBCopies = false; @@ -80,9 +82,6 @@ bool FifoPlayer::Play() if (m_Loop) { m_CurrentFrame = m_FrameRangeStart; - - PowerPC::ppcState.downcount = 0; - CoreTiming::Advance(); } else { @@ -231,6 +230,13 @@ void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& WriteFramePart(position, frame.fifoDataSize, memoryUpdate, frame, info); 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) @@ -298,6 +304,12 @@ void FifoPlayer::WriteFifo(u8* data, u32 start, u32 end) // Write up to 256 bytes at a time while (written < end) { + while (IsHighWatermarkSet()) + { + CoreTiming::Idle(); + CoreTiming::Advance(); + } + u32 burstEnd = std::min(written + 255, lastBurstEnd); while (written < burstEnd) @@ -317,42 +329,42 @@ void FifoPlayer::WriteFifo(u8* data, u32 start, u32 end) void FifoPlayer::SetupFifo() { - WriteCP(0x02, 0); // disable read, BP, interrupts - WriteCP(0x04, 7); // clear overflow, underflow, metrics + WriteCP(CommandProcessor::CTRL_REGISTER, 0); // disable read, BP, interrupts + WriteCP(CommandProcessor::CLEAR_REGISTER, 7); // clear overflow, underflow, metrics const FifoFrameInfo& frame = m_File->GetFrame(m_CurrentFrame); // Set fifo bounds - WriteCP(0x20, frame.fifoStart); - WriteCP(0x22, frame.fifoStart >> 16); - WriteCP(0x24, frame.fifoEnd); - WriteCP(0x26, frame.fifoEnd >> 16); + WriteCP(CommandProcessor::FIFO_BASE_LO, frame.fifoStart); + WriteCP(CommandProcessor::FIFO_BASE_HI, frame.fifoStart >> 16); + WriteCP(CommandProcessor::FIFO_END_LO, frame.fifoEnd); + WriteCP(CommandProcessor::FIFO_END_HI, frame.fifoEnd >> 16); - // Set watermarks - u32 fifoSize = frame.fifoEnd - frame.fifoStart; - WriteCP(0x28, fifoSize); - WriteCP(0x2a, fifoSize >> 16); - WriteCP(0x2c, 0); - WriteCP(0x2e, 0); + // Set watermarks, high at 75%, low at 0% + u32 hi_watermark = (frame.fifoEnd - frame.fifoStart) * 3 / 4; + WriteCP(CommandProcessor::FIFO_HI_WATERMARK_LO, hi_watermark); + WriteCP(CommandProcessor::FIFO_HI_WATERMARK_HI, hi_watermark >> 16); + WriteCP(CommandProcessor::FIFO_LO_WATERMARK_LO, 0); + WriteCP(CommandProcessor::FIFO_LO_WATERMARK_HI, 0); // Set R/W pointers to fifo start - WriteCP(0x30, 0); - WriteCP(0x32, 0); - WriteCP(0x34, frame.fifoStart); - WriteCP(0x36, frame.fifoStart >> 16); - WriteCP(0x38, frame.fifoStart); - WriteCP(0x3a, frame.fifoStart >> 16); + WriteCP(CommandProcessor::FIFO_RW_DISTANCE_LO, 0); + WriteCP(CommandProcessor::FIFO_RW_DISTANCE_HI, 0); + WriteCP(CommandProcessor::FIFO_WRITE_POINTER_LO, frame.fifoStart); + WriteCP(CommandProcessor::FIFO_WRITE_POINTER_HI, frame.fifoStart >> 16); + WriteCP(CommandProcessor::FIFO_READ_POINTER_LO, frame.fifoStart); + WriteCP(CommandProcessor::FIFO_READ_POINTER_HI, frame.fifoStart >> 16); // Set fifo bounds - WritePI(12, frame.fifoStart); - WritePI(16, frame.fifoEnd); + WritePI(ProcessorInterface::PI_FIFO_BASE, frame.fifoStart); + WritePI(ProcessorInterface::PI_FIFO_END, frame.fifoEnd); // Set write pointer - WritePI(20, frame.fifoStart); + WritePI(ProcessorInterface::PI_FIFO_WPTR, frame.fifoStart); 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() @@ -477,3 +489,15 @@ bool FifoPlayer::ShouldLoadBP(u8 address) 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; +} diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h index ff484dc6bb..a61ab7cc86 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h @@ -113,6 +113,9 @@ private: bool ShouldLoadBP(u8 address); + static bool IsIdleSet(); + static bool IsHighWatermarkSet(); + bool m_Loop; u32 m_CurrentFrame; diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp index d48ca8796c..563203cbd8 100644 --- a/Source/Core/Core/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/HW/ProcessorInterface.cpp @@ -15,21 +15,6 @@ 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 u32 m_InterruptCause; u32 m_InterruptMask; diff --git a/Source/Core/Core/HW/ProcessorInterface.h b/Source/Core/Core/HW/ProcessorInterface.h index c8b8448175..3313a0e6a5 100644 --- a/Source/Core/Core/HW/ProcessorInterface.h +++ b/Source/Core/Core/HW/ProcessorInterface.h @@ -34,6 +34,19 @@ enum InterruptCause 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_InterruptMask;