From 34692ab826abc8f8faa61bdb2280b742424528f1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 7 Dec 2013 15:14:29 -0500 Subject: Remove unnecessary Src/ folders --- Source/Core/VideoCommon/CommandProcessor.cpp | 700 +++++++++++++++++++++++++++ 1 file changed, 700 insertions(+) create mode 100644 Source/Core/VideoCommon/CommandProcessor.cpp (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp new file mode 100644 index 0000000000..4f64d4172c --- /dev/null +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -0,0 +1,700 @@ +// Copyright 2013 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "Common.h" +#include "VideoCommon.h" +#include "VideoConfig.h" +#include "MathUtil.h" +#include "Thread.h" +#include "Atomic.h" +#include "Fifo.h" +#include "ChunkFile.h" +#include "CommandProcessor.h" +#include "PixelEngine.h" +#include "CoreTiming.h" +#include "ConfigManager.h" +#include "HW/ProcessorInterface.h" +#include "HW/GPFifo.h" +#include "HW/Memmap.h" +#include "DLCache.h" +#include "HW/SystemTimers.h" +#include "Core.h" + +namespace CommandProcessor +{ + +int et_UpdateInterrupts; + +// TODO(ector): Warn on bbox read/write + +// STATE_TO_SAVE +SCPFifoStruct fifo; +UCPStatusReg m_CPStatusReg; +UCPCtrlReg m_CPCtrlReg; +UCPClearReg m_CPClearReg; + +int m_bboxleft; +int m_bboxtop; +int m_bboxright; +int m_bboxbottom; +u16 m_tokenReg; + +static bool bProcessFifoToLoWatermark = false; +static bool bProcessFifoAllDistance = false; + +volatile bool isPossibleWaitingSetDrawDone = false; +volatile bool isHiWatermarkActive = false; +volatile bool isLoWatermarkActive = false; +volatile bool interruptSet= false; +volatile bool interruptWaiting= false; +volatile bool interruptTokenWaiting = false; +volatile bool interruptFinishWaiting = false; + +volatile u32 VITicks = CommandProcessor::m_cpClockOrigin; + +bool IsOnThread() +{ + return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; +} + +void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) +{ + UpdateInterrupts(userdata); +} + +void DoState(PointerWrap &p) +{ + p.DoPOD(m_CPStatusReg); + p.DoPOD(m_CPCtrlReg); + p.DoPOD(m_CPClearReg); + p.Do(m_bboxleft); + p.Do(m_bboxtop); + p.Do(m_bboxright); + p.Do(m_bboxbottom); + p.Do(m_tokenReg); + p.Do(fifo); + + p.Do(bProcessFifoToLoWatermark); + p.Do(bProcessFifoAllDistance); + p.Do(isHiWatermarkActive); + p.Do(isLoWatermarkActive); + p.Do(isPossibleWaitingSetDrawDone); + p.Do(interruptSet); + p.Do(interruptWaiting); + p.Do(interruptTokenWaiting); + p.Do(interruptFinishWaiting); +} + +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));} + +inline u16 ReadLow (u32 _reg) {return (u16)(_reg & 0xFFFF);} +inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);} + +void Init() +{ + m_CPStatusReg.Hex = 0; + m_CPStatusReg.CommandIdle = 1; + m_CPStatusReg.ReadIdle = 1; + + m_CPCtrlReg.Hex = 0; + + m_CPClearReg.Hex = 0; + + m_bboxleft = 0; + m_bboxtop = 0; + m_bboxright = 640; + m_bboxbottom = 480; + + m_tokenReg = 0; + + memset(&fifo,0,sizeof(fifo)); + fifo.CPCmdIdle = 1; + fifo.CPReadIdle = 1; + fifo.bFF_Breakpoint = 0; + fifo.bFF_HiWatermark = 0; + fifo.bFF_HiWatermarkInt = 0; + fifo.bFF_LoWatermark = 0; + fifo.bFF_LoWatermarkInt = 0; + + interruptSet = false; + interruptWaiting = false; + interruptFinishWaiting = false; + interruptTokenWaiting = false; + + bProcessFifoToLoWatermark = false; + bProcessFifoAllDistance = false; + isPossibleWaitingSetDrawDone = false; + isHiWatermarkActive = false; + isLoWatermarkActive = false; + + et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper); +} + +void Read16(u16& _rReturnValue, const u32 _Address) +{ + INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address); + switch (_Address & 0xFFF) + { + 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; + case FIFO_BOUNDING_BOX_TOP: _rReturnValue = m_bboxtop; return; + case FIFO_BOUNDING_BOX_BOTTOM: _rReturnValue = m_bboxbottom; return; + + case FIFO_BASE_LO: _rReturnValue = ReadLow (fifo.CPBase); return; + case FIFO_BASE_HI: _rReturnValue = ReadHigh(fifo.CPBase); return; + case FIFO_END_LO: _rReturnValue = ReadLow (fifo.CPEnd); return; + case FIFO_END_HI: _rReturnValue = ReadHigh(fifo.CPEnd); return; + case FIFO_HI_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPHiWatermark); return; + case FIFO_HI_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPHiWatermark); return; + case FIFO_LO_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPLoWatermark); return; + case FIFO_LO_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPLoWatermark); return; + + case FIFO_RW_DISTANCE_LO: + if (IsOnThread()) + { + if(fifo.CPWritePointer >= fifo.SafeCPReadPointer) + _rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer); + else + _rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); + } + else + { + _rReturnValue = ReadLow (fifo.CPReadWriteDistance); + } + DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue); + return; + case FIFO_RW_DISTANCE_HI: + if (IsOnThread()) + { + if(fifo.CPWritePointer >= fifo.SafeCPReadPointer) + _rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer); + else + _rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); + } + else + { + _rReturnValue = ReadHigh(fifo.CPReadWriteDistance); + } + 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); + return; + case FIFO_WRITE_POINTER_HI: + _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); + DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_READ_POINTER_LO : %04x", _rReturnValue); + return; + case FIFO_READ_POINTER_HI: + if (IsOnThread()) + _rReturnValue = ReadHigh (fifo.SafeCPReadPointer); + else + _rReturnValue = ReadHigh (fifo.CPReadPointer); + 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; + + case XF_RASBUSY_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_L: %04x", _rReturnValue); + return; + case XF_RASBUSY_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_H: %04x", _rReturnValue); + return; + + case XF_CLKS_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_L: %04x", _rReturnValue); + return; + case XF_CLKS_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_H: %04x", _rReturnValue); + return; + + case XF_WAIT_IN_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_L: %04x", _rReturnValue); + return; + case XF_WAIT_IN_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_H: %04x", _rReturnValue); + return; + + case XF_WAIT_OUT_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_L: %04x", _rReturnValue); + return; + case XF_WAIT_OUT_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_H: %04x", _rReturnValue); + return; + + case VCACHE_METRIC_CHECK_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_L: %04x", _rReturnValue); + return; + case VCACHE_METRIC_CHECK_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_H: %04x", _rReturnValue); + return; + + case VCACHE_METRIC_MISS_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_L: %04x", _rReturnValue); + return; + case VCACHE_METRIC_MISS_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_H: %04x", _rReturnValue); + return; + + case VCACHE_METRIC_STALL_L: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_L: %04x", _rReturnValue); + return; + case VCACHE_METRIC_STALL_H: + _rReturnValue = 0; // TODO: Figure out the true value + DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_H: %04x", _rReturnValue); + return; + + case CLKS_PER_VTX_OUT: + _rReturnValue = 4; //Number of clocks per vertex.. TODO: Calculate properly + DEBUG_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue); + return; + default: + _rReturnValue = 0; + WARN_LOG(COMMANDPROCESSOR, "(r16) unknown CP reg @ %08x", _Address); + return; + } + + return; +} + +void Write16(const u16 _Value, const u32 _Address) +{ + INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address); + + switch (_Address & 0xFFF) + { + case STATUS_REGISTER: + { + // This should be Read-Only + ERROR_LOG(COMMANDPROCESSOR,"\t write to STATUS_REGISTER : %04x", _Value); + PanicAlert("CommandProcessor:: CPU writes to STATUS_REGISTER!"); + } + break; + + case CTRL_REGISTER: + { + UCPCtrlReg tmpCtrl(_Value); + m_CPCtrlReg.Hex = tmpCtrl.Hex; + INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value); + SetCpControlRegister(); + } + break; + + case CLEAR_REGISTER: + { + UCPClearReg tmpCtrl(_Value); + m_CPClearReg.Hex = tmpCtrl.Hex; + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to CLEAR_REGISTER : %04x", _Value); + SetCpClearRegister(); + } + break; + + case PERF_SELECT: + // Seems to select which set of perf registers should be exposed. + DEBUG_LOG(COMMANDPROCESSOR, "Write to PERF_SELECT: %04x", _Value); + break; + + // Fifo Registers + case FIFO_TOKEN_REGISTER: + 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); + break; + case FIFO_BASE_HI: + WriteHigh((u32 &)fifo.CPBase, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_BASE_HI : %04x", _Value); + break; + + case FIFO_END_LO: + WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_LO : %04x", _Value); + break; + case FIFO_END_HI: + WriteHigh((u32 &)fifo.CPEnd, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_HI : %04x", _Value); + break; + + case FIFO_WRITE_POINTER_LO: + WriteLow ((u32 &)fifo.CPWritePointer, _Value & 0xFFE0); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_LO : %04x", _Value); + break; + case FIFO_WRITE_POINTER_HI: + WriteHigh((u32 &)fifo.CPWritePointer, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_HI : %04x", _Value); + break; + + case FIFO_READ_POINTER_LO: + WriteLow ((u32 &)fifo.CPReadPointer, _Value & 0xFFE0); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_LO : %04x", _Value); + break; + case FIFO_READ_POINTER_HI: + WriteHigh((u32 &)fifo.CPReadPointer, _Value); + fifo.SafeCPReadPointer = fifo.CPReadPointer; + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_HI : %04x", _Value); + break; + + case FIFO_HI_WATERMARK_LO: + WriteLow ((u32 &)fifo.CPHiWatermark, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_LO : %04x", _Value); + break; + case FIFO_HI_WATERMARK_HI: + WriteHigh((u32 &)fifo.CPHiWatermark, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_HI : %04x", _Value); + break; + + case FIFO_LO_WATERMARK_LO: + WriteLow ((u32 &)fifo.CPLoWatermark, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_LO : %04x", _Value); + break; + case FIFO_LO_WATERMARK_HI: + WriteHigh((u32 &)fifo.CPLoWatermark, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_HI : %04x", _Value); + break; + + case FIFO_BP_LO: + 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); + DEBUG_LOG(COMMANDPROCESSOR,"Write to FIFO_BP_HI : %04x", _Value); + break; + + case FIFO_RW_DISTANCE_HI: + WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value); + if (fifo.CPReadWriteDistance == 0) + { + GPFifo::ResetGatherPipe(); + ResetVideoBuffer(); + } + else + { + ResetVideoBuffer(); + } + IncrementCheckContextId(); + DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_HI : %04x", _Value); + break; + case FIFO_RW_DISTANCE_LO: + WriteLow((u32 &)fifo.CPReadWriteDistance, _Value & 0xFFE0); + DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_LO : %04x", _Value); + break; + + default: + WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address); + } + + if (!IsOnThread()) + RunGpu(); +} + +void Read32(u32& _rReturnValue, const u32 _Address) +{ + _rReturnValue = 0; + _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Read32 from CommandProccessor at 0x%08x", _Address); +} + +void Write32(const u32 _Data, const u32 _Address) +{ + _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProccessor at 0x%08x", _Address); +} + +void STACKALIGN GatherPipeBursted() +{ + ProcessFifoEvents(); + // if we aren't linked, we don't care about gather pipe data + if (!m_CPCtrlReg.GPLinkEnable) + { + if (!IsOnThread()) + { + RunGpu(); + } + else + { + // In multibuffer mode is not allowed write in the same FIFO attached to the GPU. + // Fix Pokemon XD in DC mode. + if((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd) && (ProcessorInterface::Fifo_CPUBase == fifo.CPBase) + && fifo.CPReadWriteDistance > 0) + { + ProcessFifoAllDistance(); + } + } + return; + } + + if (IsOnThread()) + SetCpStatus(true); + + // update the fifo pointer + if (fifo.CPWritePointer >= fifo.CPEnd) + fifo.CPWritePointer = fifo.CPBase; + else + fifo.CPWritePointer += GATHER_PIPE_SIZE; + + Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); + + if (!IsOnThread()) + RunGpu(); + + _assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase, + "FIFO is overflowed by GatherPipe !\nCPU thread is too fast!"); + + // check if we are in sync + _assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync"); + _assert_msg_(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase, "FIFOs linked but out of sync"); + _assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync"); +} + +void UpdateInterrupts(u64 userdata) +{ + if (userdata) + { + interruptSet = true; + INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true); + } + else + { + interruptSet = false; + INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared"); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); + } + interruptWaiting = false; +} + +void UpdateInterruptsFromVideoBackend(u64 userdata) +{ + CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); +} + +// This is called by the ProcessorInterface when PI_FIFO_RESET is written to. +void AbortFrame() +{ + +} + +void SetCpStatus(bool isCPUThread) +{ + // overflow & underflow check + fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); + fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); + + // breakpoint + if (!isCPUThread) + { + if (fifo.bFF_BPEnable) + { + if (fifo.CPBreakpoint == fifo.CPReadPointer) + { + if (!fifo.bFF_Breakpoint) + { + INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer); + fifo.bFF_Breakpoint = true; + IncrementCheckContextId(); + } + } + else + { + if (fifo.bFF_Breakpoint) + INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); + fifo.bFF_Breakpoint = false; + } + } + else + { + if (fifo.bFF_Breakpoint) + INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); + fifo.bFF_Breakpoint = false; + } + } + + bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt; + bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt; + bool undfInt = fifo.bFF_LoWatermark && fifo.bFF_LoWatermarkInt; + + bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable; + + isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable; + isLoWatermarkActive = undfInt && m_CPCtrlReg.GPReadEnable; + + if (interrupt != interruptSet && !interruptWaiting) + { + u64 userdata = interrupt?1:0; + if (IsOnThread()) + { + if (!interrupt || bpInt || undfInt || ovfInt) + { + if (!isCPUThread) + { + // GPU thread: + interruptWaiting = true; + CommandProcessor::UpdateInterruptsFromVideoBackend(userdata); + } + else + { + // CPU thread: + interruptSet = interrupt; + INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt); + } + } + } + else + { + CommandProcessor::UpdateInterrupts(userdata); + } + } +} + +void ProcessFifoToLoWatermark() +{ + if (IsOnThread()) + { + while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && + fifo.CPReadWriteDistance > fifo.CPLoWatermark && !AtBreakpoint()) + Common::YieldCPU(); + } + bProcessFifoToLoWatermark = false; +} + +void ProcessFifoAllDistance() +{ + if (IsOnThread()) + { + while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && + fifo.CPReadWriteDistance && !AtBreakpoint()) + Common::YieldCPU(); + } + bProcessFifoAllDistance = false; +} + +void ProcessFifoEvents() +{ + if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting)) + 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.CPReadWriteDistance || AtBreakpoint() || (fifo.CPReadPointer == fifo.CPWritePointer); + m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance || AtBreakpoint() || !fifo.bFF_GPReadEnable; + 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, force an exception check + // This fixes the hang while booting Eternal Darkness + if (!fifo.bFF_GPReadEnable && m_CPCtrlReg.GPReadEnable && !m_CPCtrlReg.BPEnable) + { + CoreTiming::ForceExceptionCheck(0); + } + + 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(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" + ); + +} + +// NOTE: The implementation of this function should be correct, but we intentionally aren't using it at the moment. +// We don't emulate proper GP timing anyway at the moment, so this code would just slow down emulation. +void SetCpClearRegister() +{ +// if (IsOnThread()) +// { +// if (!m_CPClearReg.ClearFifoUnderflow && m_CPClearReg.ClearFifoOverflow) +// bProcessFifoToLoWatermark = true; +// } +} + +void Update() +{ + while (VITicks > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread()) + Common::YieldCPU(); + + if (fifo.isGpuReadingData) + Common::AtomicAdd(VITicks, SystemTimers::GetTicksPerSecond() / 10000); +} +} // end of namespace CommandProcessor -- cgit v1.2.3 From 010a0d481ad0f5dd19182eafc411feec387404db Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 30 Jan 2014 15:51:20 +0100 Subject: VideoCommon: remove Cache Displaylist This option was known to break every second game and only boost a bit. It also seems to be broken because of streaming into pinned memory and buffer storage buffers. v2: also remove dlc_desc --- Source/Core/VideoCommon/CommandProcessor.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 4f64d4172c..b52be51865 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -17,7 +17,6 @@ #include "HW/ProcessorInterface.h" #include "HW/GPFifo.h" #include "HW/Memmap.h" -#include "DLCache.h" #include "HW/SystemTimers.h" #include "Core.h" @@ -409,7 +408,6 @@ void Write16(const u16 _Value, const u32 _Address) { ResetVideoBuffer(); } - IncrementCheckContextId(); DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_HI : %04x", _Value); break; case FIFO_RW_DISTANCE_LO: @@ -527,7 +525,6 @@ void SetCpStatus(bool isCPUThread) { INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer); fifo.bFF_Breakpoint = true; - IncrementCheckContextId(); } } else -- cgit v1.2.3 From 4129b30494757a79daf8a07e6a07ea937ba1c94b Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sun, 2 Feb 2014 14:16:43 +0100 Subject: MMIO: Port the VideoCommon CP MMIOs to the new interface (and provide framework for other video related mappings). --- Source/Core/VideoCommon/CommandProcessor.cpp | 462 ++++++++++----------------- 1 file changed, 174 insertions(+), 288 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index b52be51865..bf4b97b825 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -19,6 +19,7 @@ #include "HW/Memmap.h" #include "HW/SystemTimers.h" #include "Core.h" +#include "HW/MMIO.h" namespace CommandProcessor { @@ -33,10 +34,10 @@ UCPStatusReg m_CPStatusReg; UCPCtrlReg m_CPCtrlReg; UCPClearReg m_CPClearReg; -int m_bboxleft; -int m_bboxtop; -int m_bboxright; -int m_bboxbottom; +u16 m_bboxleft; +u16 m_bboxtop; +u16 m_bboxright; +u16 m_bboxbottom; u16 m_tokenReg; static bool bProcessFifoToLoWatermark = false; @@ -131,307 +132,192 @@ void Init() et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper); } -void Read16(u16& _rReturnValue, const u32 _Address) +void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { - INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address); - switch (_Address & 0xFFF) + struct { + u32 addr; + u16* ptr; + bool readonly; + bool writes_align_to_32_bytes; + } directly_mapped_vars[] = { + { FIFO_TOKEN_REGISTER, &m_tokenReg }, + + // Bounding box registers are read only. + { FIFO_BOUNDING_BOX_LEFT, &m_bboxleft, true }, + { FIFO_BOUNDING_BOX_RIGHT, &m_bboxright, true }, + { FIFO_BOUNDING_BOX_TOP, &m_bboxtop, true }, + { FIFO_BOUNDING_BOX_BOTTOM, &m_bboxbottom, true }, + + // Some FIFO addresses need to be aligned on 32 bytes on write - only + // the high part can be written directly without a mask. + { FIFO_BASE_LO, MMIO::Utils::LowPart(&fifo.CPBase), false, true }, + { FIFO_BASE_HI, MMIO::Utils::HighPart(&fifo.CPBase) }, + { FIFO_END_LO, MMIO::Utils::LowPart(&fifo.CPEnd), false, true }, + { FIFO_END_HI, MMIO::Utils::HighPart(&fifo.CPEnd) }, + { FIFO_HI_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPHiWatermark) }, + { FIFO_HI_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPHiWatermark) }, + { FIFO_LO_WATERMARK_LO, MMIO::Utils::LowPart(&fifo.CPLoWatermark) }, + { FIFO_LO_WATERMARK_HI, MMIO::Utils::HighPart(&fifo.CPLoWatermark) }, + // FIFO_RW_DISTANCE has some complex read code different for + // single/dual core. + { FIFO_WRITE_POINTER_LO, MMIO::Utils::LowPart(&fifo.CPWritePointer), false, true }, + { FIFO_WRITE_POINTER_HI, MMIO::Utils::HighPart(&fifo.CPWritePointer) }, + // FIFO_READ_POINTER has different code for single/dual core. + { FIFO_BP_LO, MMIO::Utils::LowPart(&fifo.CPBreakpoint), false, true }, + { FIFO_BP_HI, MMIO::Utils::HighPart(&fifo.CPBreakpoint) }, + }; + for (auto& mapped_var : directly_mapped_vars) { - 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; - case FIFO_BOUNDING_BOX_TOP: _rReturnValue = m_bboxtop; return; - case FIFO_BOUNDING_BOX_BOTTOM: _rReturnValue = m_bboxbottom; return; - - case FIFO_BASE_LO: _rReturnValue = ReadLow (fifo.CPBase); return; - case FIFO_BASE_HI: _rReturnValue = ReadHigh(fifo.CPBase); return; - case FIFO_END_LO: _rReturnValue = ReadLow (fifo.CPEnd); return; - case FIFO_END_HI: _rReturnValue = ReadHigh(fifo.CPEnd); return; - case FIFO_HI_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPHiWatermark); return; - case FIFO_HI_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPHiWatermark); return; - case FIFO_LO_WATERMARK_LO: _rReturnValue = ReadLow (fifo.CPLoWatermark); return; - case FIFO_LO_WATERMARK_HI: _rReturnValue = ReadHigh(fifo.CPLoWatermark); return; - - case FIFO_RW_DISTANCE_LO: - if (IsOnThread()) - { - if(fifo.CPWritePointer >= fifo.SafeCPReadPointer) - _rReturnValue = ReadLow (fifo.CPWritePointer - fifo.SafeCPReadPointer); - else - _rReturnValue = ReadLow (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); - } - else - { - _rReturnValue = ReadLow (fifo.CPReadWriteDistance); - } - DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_RW_DISTANCE_LO : %04x", _rReturnValue); - return; - case FIFO_RW_DISTANCE_HI: - if (IsOnThread()) - { - if(fifo.CPWritePointer >= fifo.SafeCPReadPointer) - _rReturnValue = ReadHigh (fifo.CPWritePointer - fifo.SafeCPReadPointer); - else - _rReturnValue = ReadHigh (fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); - } - else - { - _rReturnValue = ReadHigh(fifo.CPReadWriteDistance); - } - 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); - return; - case FIFO_WRITE_POINTER_HI: - _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); - DEBUG_LOG(COMMANDPROCESSOR, "Read FIFO_READ_POINTER_LO : %04x", _rReturnValue); - return; - case FIFO_READ_POINTER_HI: - if (IsOnThread()) - _rReturnValue = ReadHigh (fifo.SafeCPReadPointer); - else - _rReturnValue = ReadHigh (fifo.CPReadPointer); - 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; - - case XF_RASBUSY_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_L: %04x", _rReturnValue); - return; - case XF_RASBUSY_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_RASBUSY_H: %04x", _rReturnValue); - return; - - case XF_CLKS_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_L: %04x", _rReturnValue); - return; - case XF_CLKS_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_CLKS_H: %04x", _rReturnValue); - return; - - case XF_WAIT_IN_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_L: %04x", _rReturnValue); - return; - case XF_WAIT_IN_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_IN_H: %04x", _rReturnValue); - return; - - case XF_WAIT_OUT_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_L: %04x", _rReturnValue); - return; - case XF_WAIT_OUT_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from XF_WAIT_OUT_H: %04x", _rReturnValue); - return; - - case VCACHE_METRIC_CHECK_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_L: %04x", _rReturnValue); - return; - case VCACHE_METRIC_CHECK_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_CHECK_H: %04x", _rReturnValue); - return; - - case VCACHE_METRIC_MISS_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_L: %04x", _rReturnValue); - return; - case VCACHE_METRIC_MISS_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_MISS_H: %04x", _rReturnValue); - return; - - case VCACHE_METRIC_STALL_L: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_L: %04x", _rReturnValue); - return; - case VCACHE_METRIC_STALL_H: - _rReturnValue = 0; // TODO: Figure out the true value - DEBUG_LOG(COMMANDPROCESSOR, "Read from VCACHE_METRIC_STALL_H: %04x", _rReturnValue); - return; - - case CLKS_PER_VTX_OUT: - _rReturnValue = 4; //Number of clocks per vertex.. TODO: Calculate properly - DEBUG_LOG(COMMANDPROCESSOR, "Read from CLKS_PER_VTX_OUT: %04x", _rReturnValue); - return; - default: - _rReturnValue = 0; - WARN_LOG(COMMANDPROCESSOR, "(r16) unknown CP reg @ %08x", _Address); - return; + u16 wmask = mapped_var.writes_align_to_32_bytes ? 0xFFE0 : 0xFFFF; + mmio->Register(base | mapped_var.addr, + MMIO::DirectRead(mapped_var.ptr), + mapped_var.readonly + ? MMIO::InvalidWrite() + : MMIO::DirectWrite(mapped_var.ptr, wmask) + ); } - return; -} - -void Write16(const u16 _Value, const u32 _Address) -{ - INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address); - - switch (_Address & 0xFFF) + // Timing and metrics MMIOs are stubbed with fixed values. + struct { + u32 addr; + u16 value; + } metrics_mmios[] = { + { XF_RASBUSY_L, 0 }, + { XF_RASBUSY_H, 0 }, + { XF_CLKS_L, 0 }, + { XF_CLKS_H, 0 }, + { XF_WAIT_IN_L, 0 }, + { XF_WAIT_IN_H, 0 }, + { XF_WAIT_OUT_L, 0 }, + { XF_WAIT_OUT_H, 0 }, + { VCACHE_METRIC_CHECK_L, 0 }, + { VCACHE_METRIC_CHECK_H, 0 }, + { VCACHE_METRIC_MISS_L, 0 }, + { VCACHE_METRIC_MISS_H, 0 }, + { VCACHE_METRIC_STALL_L, 0 }, + { VCACHE_METRIC_STALL_H, 0 }, + { CLKS_PER_VTX_OUT, 4 }, + }; + for (auto& metrics_mmio : metrics_mmios) { - case STATUS_REGISTER: - { - // This should be Read-Only - ERROR_LOG(COMMANDPROCESSOR,"\t write to STATUS_REGISTER : %04x", _Value); - PanicAlert("CommandProcessor:: CPU writes to STATUS_REGISTER!"); - } - break; + mmio->Register(base | metrics_mmio.addr, + MMIO::Constant(metrics_mmio.value), + MMIO::InvalidWrite() + ); + } - case CTRL_REGISTER: - { - UCPCtrlReg tmpCtrl(_Value); - m_CPCtrlReg.Hex = tmpCtrl.Hex; - INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value); + mmio->Register(base | STATUS_REGISTER, + MMIO::ComplexRead([](u32) { + SetCpStatusRegister(); + return m_CPStatusReg.Hex; + }), + MMIO::InvalidWrite() + ); + + mmio->Register(base | CTRL_REGISTER, + MMIO::DirectRead(&m_CPCtrlReg.Hex), + MMIO::ComplexWrite([](u32, u16 val) { + UCPCtrlReg tmp(val); + m_CPCtrlReg.Hex = tmp.Hex; SetCpControlRegister(); - } - break; - - case CLEAR_REGISTER: - { - UCPClearReg tmpCtrl(_Value); - m_CPClearReg.Hex = tmpCtrl.Hex; - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to CLEAR_REGISTER : %04x", _Value); + if (!IsOnThread()) + RunGpu(); + }) + ); + + mmio->Register(base | CLEAR_REGISTER, + MMIO::DirectRead(&m_CPClearReg.Hex), + MMIO::ComplexWrite([](u32, u16 val) { + UCPClearReg tmp(val); + m_CPClearReg.Hex = tmp.Hex; SetCpClearRegister(); - } - break; - - case PERF_SELECT: - // Seems to select which set of perf registers should be exposed. - DEBUG_LOG(COMMANDPROCESSOR, "Write to PERF_SELECT: %04x", _Value); - break; - - // Fifo Registers - case FIFO_TOKEN_REGISTER: - 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); - break; - case FIFO_BASE_HI: - WriteHigh((u32 &)fifo.CPBase, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_BASE_HI : %04x", _Value); - break; - - case FIFO_END_LO: - WriteLow ((u32 &)fifo.CPEnd, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_LO : %04x", _Value); - break; - case FIFO_END_HI: - WriteHigh((u32 &)fifo.CPEnd, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_END_HI : %04x", _Value); - break; - - case FIFO_WRITE_POINTER_LO: - WriteLow ((u32 &)fifo.CPWritePointer, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_LO : %04x", _Value); - break; - case FIFO_WRITE_POINTER_HI: - WriteHigh((u32 &)fifo.CPWritePointer, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_WRITE_POINTER_HI : %04x", _Value); - break; - - case FIFO_READ_POINTER_LO: - WriteLow ((u32 &)fifo.CPReadPointer, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_LO : %04x", _Value); - break; - case FIFO_READ_POINTER_HI: - WriteHigh((u32 &)fifo.CPReadPointer, _Value); - fifo.SafeCPReadPointer = fifo.CPReadPointer; - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_READ_POINTER_HI : %04x", _Value); - break; - - case FIFO_HI_WATERMARK_LO: - WriteLow ((u32 &)fifo.CPHiWatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_LO : %04x", _Value); - break; - case FIFO_HI_WATERMARK_HI: - WriteHigh((u32 &)fifo.CPHiWatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_HI_WATERMARK_HI : %04x", _Value); - break; - - case FIFO_LO_WATERMARK_LO: - WriteLow ((u32 &)fifo.CPLoWatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_LO : %04x", _Value); - break; - case FIFO_LO_WATERMARK_HI: - WriteHigh((u32 &)fifo.CPLoWatermark, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t Write to FIFO_LO_WATERMARK_HI : %04x", _Value); - break; - - case FIFO_BP_LO: - 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); - DEBUG_LOG(COMMANDPROCESSOR,"Write to FIFO_BP_HI : %04x", _Value); - break; - - case FIFO_RW_DISTANCE_HI: - WriteHigh((u32 &)fifo.CPReadWriteDistance, _Value); - if (fifo.CPReadWriteDistance == 0) - { - GPFifo::ResetGatherPipe(); - ResetVideoBuffer(); - } - else - { - ResetVideoBuffer(); - } - DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_HI : %04x", _Value); - break; - case FIFO_RW_DISTANCE_LO: - WriteLow((u32 &)fifo.CPReadWriteDistance, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"Try to write to FIFO_RW_DISTANCE_LO : %04x", _Value); - break; - - default: - WARN_LOG(COMMANDPROCESSOR, "(w16) unknown CP reg write %04x @ %08x", _Value, _Address); - } + if (!IsOnThread()) + RunGpu(); + }) + ); + + mmio->Register(base | PERF_SELECT, + MMIO::InvalidRead(), + MMIO::Nop() + ); + + // Some MMIOs have different handlers for single core vs. dual core mode. + mmio->Register(base | FIFO_RW_DISTANCE_LO, + IsOnThread() + ? MMIO::ComplexRead([](u32) { + if (fifo.CPWritePointer >= fifo.SafeCPReadPointer) + return ReadLow(fifo.CPWritePointer - fifo.SafeCPReadPointer); + else + return ReadLow(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); + }) + : MMIO::DirectRead(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance)), + MMIO::DirectWrite(MMIO::Utils::LowPart(&fifo.CPReadWriteDistance), 0xFFE0) + ); + mmio->Register(base | FIFO_RW_DISTANCE_HI, + IsOnThread() + ? MMIO::ComplexRead([](u32) { + if (fifo.CPWritePointer >= fifo.SafeCPReadPointer) + return ReadHigh(fifo.CPWritePointer - fifo.SafeCPReadPointer); + else + return ReadHigh(fifo.CPEnd - fifo.SafeCPReadPointer + fifo.CPWritePointer - fifo.CPBase + 32); + }) + : MMIO::DirectRead(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)), + MMIO::ComplexWrite([](u32, u16 val) { + WriteHigh(fifo.CPReadWriteDistance, val); + if (fifo.CPReadWriteDistance == 0) + { + GPFifo::ResetGatherPipe(); + ResetVideoBuffer(); + } + else + { + ResetVideoBuffer(); + } + if (!IsOnThread()) + RunGpu(); + }) + ); + mmio->Register(base | FIFO_READ_POINTER_LO, + IsOnThread() + ? MMIO::DirectRead(MMIO::Utils::LowPart(&fifo.SafeCPReadPointer)) + : MMIO::DirectRead(MMIO::Utils::LowPart(&fifo.CPReadPointer)), + MMIO::DirectWrite(MMIO::Utils::LowPart(&fifo.CPReadPointer), 0xFFE0) + ); + mmio->Register(base | FIFO_READ_POINTER_HI, + IsOnThread() + ? MMIO::DirectRead(MMIO::Utils::HighPart(&fifo.SafeCPReadPointer)) + : MMIO::DirectRead(MMIO::Utils::HighPart(&fifo.CPReadPointer)), + IsOnThread() + ? MMIO::ComplexWrite([](u32, u16 val) { + WriteHigh(fifo.CPReadPointer, val); + fifo.SafeCPReadPointer = fifo.CPReadPointer; + }) + : MMIO::DirectWrite(MMIO::Utils::HighPart(&fifo.CPReadPointer)) + ); +} - if (!IsOnThread()) - RunGpu(); +void Read16(u16& _rReturnValue, const u32 _Address) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_Address, _rReturnValue); +} + +void Write16(const u16 _Value, const u32 _Address) +{ + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_Address, _Value); } void Read32(u32& _rReturnValue, const u32 _Address) { - _rReturnValue = 0; - _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Read32 from CommandProccessor at 0x%08x", _Address); + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Read(_Address, _rReturnValue); } void Write32(const u32 _Data, const u32 _Address) { - _dbg_assert_msg_(COMMANDPROCESSOR, 0, "Write32 at CommandProccessor at 0x%08x", _Address); + // HACK: Remove this function when the new MMIO interface is used. + Memory::mmio_mapping->Write(_Address, _Data); } void STACKALIGN GatherPipeBursted() -- cgit v1.2.3 From 92f8d93e969abf942002439ef583d2a25acad019 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Sat, 15 Feb 2014 03:23:35 +0100 Subject: Remove the old MMIO access "interface". --- Source/Core/VideoCommon/CommandProcessor.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index bf4b97b825..ca70a43703 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -296,30 +296,6 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) ); } -void Read16(u16& _rReturnValue, const u32 _Address) -{ - // HACK: Remove this function when the new MMIO interface is used. - Memory::mmio_mapping->Read(_Address, _rReturnValue); -} - -void Write16(const u16 _Value, const u32 _Address) -{ - // HACK: Remove this function when the new MMIO interface is used. - Memory::mmio_mapping->Write(_Address, _Value); -} - -void Read32(u32& _rReturnValue, const u32 _Address) -{ - // HACK: Remove this function when the new MMIO interface is used. - Memory::mmio_mapping->Read(_Address, _rReturnValue); -} - -void Write32(const u32 _Data, const u32 _Address) -{ - // HACK: Remove this function when the new MMIO interface is used. - Memory::mmio_mapping->Write(_Address, _Data); -} - void STACKALIGN GatherPipeBursted() { ProcessFifoEvents(); -- cgit v1.2.3 From 6c4ee1753aa2b9e620138801b479365b0569317c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 16 Feb 2014 15:30:18 -0500 Subject: Fix some vertical alignments ie. uses spaces for alignment. --- Source/Core/VideoCommon/CommandProcessor.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index ca70a43703..e3f6937b0e 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -337,9 +337,9 @@ void STACKALIGN GatherPipeBursted() "FIFO is overflowed by GatherPipe !\nCPU thread is too fast!"); // check if we are in sync - _assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync"); - _assert_msg_(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase, "FIFOs linked but out of sync"); - _assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync"); + _assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == ProcessorInterface::Fifo_CPUWritePointer, "FIFOs linked but out of sync"); + _assert_msg_(COMMANDPROCESSOR, fifo.CPBase == ProcessorInterface::Fifo_CPUBase, "FIFOs linked but out of sync"); + _assert_msg_(COMMANDPROCESSOR, fifo.CPEnd == ProcessorInterface::Fifo_CPUEnd, "FIFOs linked but out of sync"); } void UpdateInterrupts(u64 userdata) @@ -486,11 +486,11 @@ void SetCpStatusRegister() 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" + , 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" ); } @@ -527,12 +527,12 @@ void SetCpControlRegister() } 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" + , 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" ); } -- cgit v1.2.3 From 3fd87a7636ff434118a5d7f7334550be8db55c0b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 16 Feb 2014 23:51:41 -0500 Subject: Second and final pass of clearing out tabs. --- Source/Core/VideoCommon/CommandProcessor.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index e3f6937b0e..3383d7f79a 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -31,8 +31,8 @@ int et_UpdateInterrupts; // STATE_TO_SAVE SCPFifoStruct fifo; UCPStatusReg m_CPStatusReg; -UCPCtrlReg m_CPCtrlReg; -UCPClearReg m_CPClearReg; +UCPCtrlReg m_CPCtrlReg; +UCPClearReg m_CPClearReg; u16 m_bboxleft; u16 m_bboxtop; @@ -541,11 +541,11 @@ void SetCpControlRegister() // We don't emulate proper GP timing anyway at the moment, so this code would just slow down emulation. void SetCpClearRegister() { -// if (IsOnThread()) -// { -// if (!m_CPClearReg.ClearFifoUnderflow && m_CPClearReg.ClearFifoOverflow) -// bProcessFifoToLoWatermark = true; -// } + // if (IsOnThread()) + // { + // if (!m_CPClearReg.ClearFifoUnderflow && m_CPClearReg.ClearFifoOverflow) + // bProcessFifoToLoWatermark = true; + // } } void Update() -- cgit v1.2.3 From 362dec9c7cde65fe446d671a49962888f391e917 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Tue, 18 Feb 2014 12:18:47 +0100 Subject: Dolphin now builds on Linux with only Source/Core as include dir --- Source/Core/VideoCommon/CommandProcessor.cpp | 36 ++++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 3383d7f79a..21955b27a5 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -2,24 +2,24 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "Common.h" -#include "VideoCommon.h" -#include "VideoConfig.h" -#include "MathUtil.h" -#include "Thread.h" -#include "Atomic.h" -#include "Fifo.h" -#include "ChunkFile.h" -#include "CommandProcessor.h" -#include "PixelEngine.h" -#include "CoreTiming.h" -#include "ConfigManager.h" -#include "HW/ProcessorInterface.h" -#include "HW/GPFifo.h" -#include "HW/Memmap.h" -#include "HW/SystemTimers.h" -#include "Core.h" -#include "HW/MMIO.h" +#include "Common/Common.h" +#include "Common/MathUtil.h" +#include "Common/Thread.h" +#include "Common/Atomic.h" +#include "Common/ChunkFile.h" +#include "Core/ConfigManager.h" +#include "Core/Core.h" +#include "Core/CoreTiming.h" +#include "Core/HW/GPFifo.h" +#include "Core/HW/Memmap.h" +#include "Core/HW/MMIO.h" +#include "Core/HW/ProcessorInterface.h" +#include "Core/HW/SystemTimers.h" +#include "VideoCommon/CommandProcessor.h" +#include "VideoCommon/Fifo.h" +#include "VideoCommon/PixelEngine.h" +#include "VideoCommon/VideoCommon.h" +#include "VideoCommon/VideoConfig.h" namespace CommandProcessor { -- cgit v1.2.3 From ffe588cc240745f0a30595c604083d37e791c670 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Wed, 19 Feb 2014 02:27:20 +0100 Subject: Fix more header sorting issues in VideoCommon/ (now check-includes clean). --- Source/Core/VideoCommon/CommandProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 21955b27a5..0ccd251718 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -2,11 +2,11 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#include "Common/Atomic.h" +#include "Common/ChunkFile.h" #include "Common/Common.h" #include "Common/MathUtil.h" #include "Common/Thread.h" -#include "Common/Atomic.h" -#include "Common/ChunkFile.h" #include "Core/ConfigManager.h" #include "Core/Core.h" #include "Core/CoreTiming.h" -- cgit v1.2.3 From 31cfc73a09a8685cbab20502b4bc132e98e2feb5 Mon Sep 17 00:00:00 2001 From: Matthew Parlane Date: Tue, 11 Mar 2014 00:30:55 +1300 Subject: Fixes spacing for "for", "while", "switch" and "if" Also moved && and || to ends of lines instead of start. Fixed misc vertical alignments and some { needed newlining. --- Source/Core/VideoCommon/CommandProcessor.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 0ccd251718..e92e3560f5 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -310,8 +310,9 @@ void STACKALIGN GatherPipeBursted() { // In multibuffer mode is not allowed write in the same FIFO attached to the GPU. // Fix Pokemon XD in DC mode. - if((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd) && (ProcessorInterface::Fifo_CPUBase == fifo.CPBase) - && fifo.CPReadWriteDistance > 0) + if ((ProcessorInterface::Fifo_CPUEnd == fifo.CPEnd) && + (ProcessorInterface::Fifo_CPUBase == fifo.CPBase) && + fifo.CPReadWriteDistance > 0) { ProcessFifoAllDistance(); } @@ -509,17 +510,17 @@ void SetCpControlRegister() fifo.bFF_LoWatermarkInt = m_CPCtrlReg.FifoUnderflowIntEnable; fifo.bFF_GPLinkEnable = m_CPCtrlReg.GPLinkEnable; - if(m_CPCtrlReg.GPReadEnable && 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(fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable) + if (fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable) { fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable; - while(fifo.isGpuReadingData) Common::YieldCPU(); + while (fifo.isGpuReadingData) Common::YieldCPU(); } else { -- cgit v1.2.3 From 0aecd9504e8ccbf52b89032be9d15b25ff14543d Mon Sep 17 00:00:00 2001 From: magumagu Date: Sun, 1 Jun 2014 01:56:09 -0700 Subject: Video backends: remove dead code. --- Source/Core/VideoCommon/CommandProcessor.cpp | 45 ++-------------------------- 1 file changed, 2 insertions(+), 43 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index e92e3560f5..22af52cfad 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -40,12 +40,7 @@ u16 m_bboxright; u16 m_bboxbottom; u16 m_tokenReg; -static bool bProcessFifoToLoWatermark = false; -static bool bProcessFifoAllDistance = false; - volatile bool isPossibleWaitingSetDrawDone = false; -volatile bool isHiWatermarkActive = false; -volatile bool isLoWatermarkActive = false; volatile bool interruptSet= false; volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; @@ -75,10 +70,6 @@ void DoState(PointerWrap &p) p.Do(m_tokenReg); p.Do(fifo); - p.Do(bProcessFifoToLoWatermark); - p.Do(bProcessFifoAllDistance); - p.Do(isHiWatermarkActive); - p.Do(isLoWatermarkActive); p.Do(isPossibleWaitingSetDrawDone); p.Do(interruptSet); p.Do(interruptWaiting); @@ -110,8 +101,6 @@ void Init() m_tokenReg = 0; memset(&fifo,0,sizeof(fifo)); - fifo.CPCmdIdle = 1; - fifo.CPReadIdle = 1; fifo.bFF_Breakpoint = 0; fifo.bFF_HiWatermark = 0; fifo.bFF_HiWatermarkInt = 0; @@ -123,11 +112,7 @@ void Init() interruptFinishWaiting = false; interruptTokenWaiting = false; - bProcessFifoToLoWatermark = false; - bProcessFifoAllDistance = false; isPossibleWaitingSetDrawDone = false; - isHiWatermarkActive = false; - isLoWatermarkActive = false; et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper); } @@ -365,12 +350,6 @@ void UpdateInterruptsFromVideoBackend(u64 userdata) CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); } -// This is called by the ProcessorInterface when PI_FIFO_RESET is written to. -void AbortFrame() -{ - -} - void SetCpStatus(bool isCPUThread) { // overflow & underflow check @@ -411,9 +390,6 @@ void SetCpStatus(bool isCPUThread) bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable; - isHiWatermarkActive = ovfInt && m_CPCtrlReg.GPReadEnable; - isLoWatermarkActive = undfInt && m_CPCtrlReg.GPReadEnable; - if (interrupt != interruptSet && !interruptWaiting) { u64 userdata = interrupt?1:0; @@ -443,17 +419,6 @@ void SetCpStatus(bool isCPUThread) } } -void ProcessFifoToLoWatermark() -{ - if (IsOnThread()) - { - while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && - fifo.CPReadWriteDistance > fifo.CPLoWatermark && !AtBreakpoint()) - Common::YieldCPU(); - } - bProcessFifoToLoWatermark = false; -} - void ProcessFifoAllDistance() { if (IsOnThread()) @@ -462,7 +427,6 @@ void ProcessFifoAllDistance() fifo.CPReadWriteDistance && !AtBreakpoint()) Common::YieldCPU(); } - bProcessFifoAllDistance = false; } void ProcessFifoEvents() @@ -538,15 +502,10 @@ void SetCpControlRegister() } -// NOTE: The implementation of this function should be correct, but we intentionally aren't using it at the moment. -// We don't emulate proper GP timing anyway at the moment, so this code would just slow down emulation. +// NOTE: We intentionally don't emulate this function at the moment. +// We don't emulate proper GP timing anyway at the moment, so it would just slow down emulation. void SetCpClearRegister() { - // if (IsOnThread()) - // { - // if (!m_CPClearReg.ClearFifoUnderflow && m_CPClearReg.ClearFifoOverflow) - // bProcessFifoToLoWatermark = true; - // } } void Update() -- cgit v1.2.3 From 22e1aa5bb4a159d6d66a321f978917614aa36331 Mon Sep 17 00:00:00 2001 From: degasus Date: Tue, 8 Jul 2014 14:29:26 +0200 Subject: mark all local functions as static --- Source/Core/VideoCommon/CommandProcessor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 22af52cfad..c27681ac3c 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -48,12 +48,12 @@ volatile bool interruptFinishWaiting = false; volatile u32 VITicks = CommandProcessor::m_cpClockOrigin; -bool IsOnThread() +static bool IsOnThread() { return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; } -void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) +static void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) { UpdateInterrupts(userdata); } -- cgit v1.2.3 From 6d3f249dcc746cc7845ef88ddb8ce3bcc9221aca Mon Sep 17 00:00:00 2001 From: degasus Date: Tue, 8 Jul 2014 15:58:25 +0200 Subject: mark all local variables as static --- Source/Core/VideoCommon/CommandProcessor.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index c27681ac3c..e42b7227db 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -24,21 +24,21 @@ namespace CommandProcessor { -int et_UpdateInterrupts; +static int et_UpdateInterrupts; // TODO(ector): Warn on bbox read/write // STATE_TO_SAVE SCPFifoStruct fifo; -UCPStatusReg m_CPStatusReg; -UCPCtrlReg m_CPCtrlReg; -UCPClearReg m_CPClearReg; - -u16 m_bboxleft; -u16 m_bboxtop; -u16 m_bboxright; -u16 m_bboxbottom; -u16 m_tokenReg; +static UCPStatusReg m_CPStatusReg; +static UCPCtrlReg m_CPCtrlReg; +static UCPClearReg m_CPClearReg; + +static u16 m_bboxleft; +static u16 m_bboxtop; +static u16 m_bboxright; +static u16 m_bboxbottom; +static u16 m_tokenReg; volatile bool isPossibleWaitingSetDrawDone = false; volatile bool interruptSet= false; -- cgit v1.2.3 From 07c7e6f35e2854d09ab0a05689867c936ab990e6 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Mon, 25 Aug 2014 21:09:26 +0200 Subject: CommandProcessor: mark some functions as static --- Source/Core/VideoCommon/CommandProcessor.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index e42b7227db..9da48f5302 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -77,11 +77,22 @@ void DoState(PointerWrap &p) p.Do(interruptFinishWaiting); } -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));} - -inline u16 ReadLow (u32 _reg) {return (u16)(_reg & 0xFFFF);} -inline u16 ReadHigh (u32 _reg) {return (u16)(_reg >> 16);} +UNUSED static inline void WriteLow(volatile u32& _reg, u16 lowbits) +{ + Common::AtomicStore(_reg, (_reg & 0xFFFF0000) | lowbits); +} +static inline void WriteHigh(volatile u32& _reg, u16 highbits) +{ + Common::AtomicStore(_reg, (_reg & 0x0000FFFF) | ((u32)highbits << 16)); +} +static inline u16 ReadLow(u32 _reg) +{ + return (u16)(_reg & 0xFFFF); +} +static inline u16 ReadHigh(u32 _reg) +{ + return (u16)(_reg >> 16); +} void Init() { -- cgit v1.2.3 From 14125cf9519d3ca17d2ea160e83112cf8b7b27a2 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 24 Aug 2014 16:27:32 -0400 Subject: Refactor SetCpStatus into two functions for from-GPU and from-CPU mode rather than a boolean parameter. This shouldn't affect functionality. I'm not sure if the breakpoint distinction is actually necessary (my commit messages from the old dc-netplay last year claim that breakpoints are broken anyway, but I don't remember why), but I don't actually need to change this part of the code (yet), so I'll stick with the trimmings change for now. --- Source/Core/VideoCommon/CommandProcessor.cpp | 46 ++++++++++++++-------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 9da48f5302..b54e503240 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -317,7 +317,7 @@ void STACKALIGN GatherPipeBursted() } if (IsOnThread()) - SetCpStatus(true); + SetCPStatusFromCPU(); // update the fifo pointer if (fifo.CPWritePointer >= fifo.CPEnd) @@ -361,30 +361,17 @@ void UpdateInterruptsFromVideoBackend(u64 userdata) CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); } -void SetCpStatus(bool isCPUThread) +void SetCPStatusFromGPU() { - // overflow & underflow check - fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); - fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); - // breakpoint - if (!isCPUThread) + if (fifo.bFF_BPEnable) { - if (fifo.bFF_BPEnable) + if (fifo.CPBreakpoint == fifo.CPReadPointer) { - if (fifo.CPBreakpoint == fifo.CPReadPointer) - { - if (!fifo.bFF_Breakpoint) - { - INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer); - fifo.bFF_Breakpoint = true; - } - } - else + if (!fifo.bFF_Breakpoint) { - if (fifo.bFF_Breakpoint) - INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); - fifo.bFF_Breakpoint = false; + INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer); + fifo.bFF_Breakpoint = true; } } else @@ -394,6 +381,20 @@ void SetCpStatus(bool isCPUThread) fifo.bFF_Breakpoint = false; } } + else + { + if (fifo.bFF_Breakpoint) + INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); + fifo.bFF_Breakpoint = false; + } + SetCPStatusFromCPU(); +} + +void SetCPStatusFromCPU() +{ + // overflow & underflow check + fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); + fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt; bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt; @@ -408,15 +409,14 @@ void SetCpStatus(bool isCPUThread) { if (!interrupt || bpInt || undfInt || ovfInt) { - if (!isCPUThread) + if (Core::IsGPUThread()) { - // GPU thread: + // Schedule the interrupt asynchronously interruptWaiting = true; CommandProcessor::UpdateInterruptsFromVideoBackend(userdata); } else { - // CPU thread: interruptSet = interrupt; INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt); -- cgit v1.2.3 From fbc64984ca7de7db10b1a8a4f49002f260c93569 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Sun, 7 Sep 2014 20:06:58 -0500 Subject: Include CommonTypes.h instead of Common.h. --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index b54e503240..aa9f8c4f28 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -4,7 +4,7 @@ #include "Common/Atomic.h" #include "Common/ChunkFile.h" -#include "Common/Common.h" +#include "Common/CommonTypes.h" #include "Common/MathUtil.h" #include "Common/Thread.h" #include "Core/ConfigManager.h" -- cgit v1.2.3 From 8c5e12cf028bfcc873b053e8a7f428a9d52ff333 Mon Sep 17 00:00:00 2001 From: skidau Date: Mon, 22 Sep 2014 16:49:09 +1000 Subject: Moved the linking of the FIFO CPWritePointer near where CPWritePointer gets updated. The CPWritePointer was getting updated while it was in-flight causing Pac-man Party to flicker. Fixes issue 5223. --- Source/Core/VideoCommon/CommandProcessor.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index aa9f8c4f28..4cd1967ce9 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -325,6 +325,13 @@ void STACKALIGN GatherPipeBursted() else fifo.CPWritePointer += GATHER_PIPE_SIZE; + if (m_CPCtrlReg.GPReadEnable && m_CPCtrlReg.GPLinkEnable) + { + ProcessorInterface::Fifo_CPUWritePointer = fifo.CPWritePointer; + ProcessorInterface::Fifo_CPUBase = fifo.CPBase; + ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd; + } + Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); if (!IsOnThread()) @@ -485,13 +492,6 @@ void SetCpControlRegister() 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 (fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable) { fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable; -- cgit v1.2.3 From 65af90669bd5f9e02bbaa994d51d5c83d147b868 Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 27 Aug 2014 22:56:19 -0400 Subject: Add the 'desynced GPU thread' mode. It's a relatively big commit (less big with -w), but it's hard to test any of this separately... The basic problem is that in netplay or movies, the state of the CPU must be deterministic, including when the game receives notification that the GPU has processed FIFO data. Dual core mode notifies the game whenever the GPU thread actually gets around to doing the work, so it isn't deterministic. Single core mode is because it notifies the game 'instantly' (after processing the data synchronously), but it's too slow for many systems and games. My old dc-netplay branch worked as follows: everything worked as normal except the state of the CP registers was a lie, and the CPU thread only delivered results when idle detection triggered (waiting for the GPU if they weren't ready at that point). Usually, a game is idle iff all the work for the frame has been done, except for a small amount of work depending on the GPU result, so neither the CPU or the GPU waiting on the other affected performance much. However, it's possible that the game could be waiting for some earlier interrupt, and any of several games which, for whatever reason, never went into a detectable idle (even when I tried to improve the detection) would never receive results at all. (The current method should have better compatibility, but it also has slightly higher overhead and breaks some other things, so I want to reimplement this, hopefully with less impact on the code, in the future.) With this commit, the basic idea is that the CPU thread acts as if the work has been done instantly, like single core mode, but actually hands it off asynchronously to the GPU thread (after backing up some data that the game might change in memory before it's actually done). Since the work isn't done, any feedback from the GPU to the CPU, such as real XFB/EFB copies (virtual are OK), EFB pokes, performance queries, etc. is broken; but most games work with these options disabled, and there is no need to try to detect what the CPU thread is doing. Technically: when the flag g_use_deterministic_gpu_thread (currently stuck on) is on, the CPU thread calls RunGpu like in single core mode. This function synchronously copies the data from the FIFO to the internal video buffer and updates the CP registers, interrupts, etc. However, instead of the regular ReadDataFromFifo followed by running the opcode decoder, it runs ReadDataFromFifoOnCPU -> OpcodeDecoder_Preprocess, which relatively quickly scans through the FIFO data, detects SetFinish calls etc., which are immediately fired, and saves certain associated data from memory (e.g. display lists) in AuxBuffers (a parallel stream to the main FIFO, which is a bit slow at the moment), before handing the data off to the GPU thread to actually render. That makes up the bulk of this commit. In various circumstances, including the aforementioned EFB pokes and performance queries as well as swap requests (i.e. the end of a frame - we don't want the CPU potentially pumping out frames too quickly and the GPU falling behind*), SyncGPU is called to wait for actual completion. The overhead mainly comes from OpcodeDecoder_Preprocess (which is, again, synchronous), as well as the actual copying. Currently, display lists and such are escrowed from main memory even though they usually won't change over the course of a frame, and textures are not even though they might, resulting in a small chance of graphical glitches. When the texture locking (i.e. fault on write) code lands, I can make this all correct and maybe a little faster. * This suggests an alternate determinism method of just delaying results until a short time before the end of each frame. For all I know this might mostly work - I haven't tried it - but if any significant work hinges on the competion of render to texture etc., the frame will be missed. --- Source/Core/VideoCommon/CommandProcessor.cpp | 44 +++++++++++++++++----------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index aa9f8c4f28..6f8997cc58 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -77,7 +77,7 @@ void DoState(PointerWrap &p) p.Do(interruptFinishWaiting); } -UNUSED static inline void WriteLow(volatile u32& _reg, u16 lowbits) +static inline void WriteLow(volatile u32& _reg, u16 lowbits) { Common::AtomicStore(_reg, (_reg & 0xFFFF0000) | lowbits); } @@ -159,9 +159,8 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { FIFO_WRITE_POINTER_LO, MMIO::Utils::LowPart(&fifo.CPWritePointer), false, true }, { FIFO_WRITE_POINTER_HI, MMIO::Utils::HighPart(&fifo.CPWritePointer) }, // FIFO_READ_POINTER has different code for single/dual core. - { FIFO_BP_LO, MMIO::Utils::LowPart(&fifo.CPBreakpoint), false, true }, - { FIFO_BP_HI, MMIO::Utils::HighPart(&fifo.CPBreakpoint) }, }; + for (auto& mapped_var : directly_mapped_vars) { u16 wmask = mapped_var.writes_align_to_32_bytes ? 0xFFE0 : 0xFFFF; @@ -173,6 +172,19 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) ); } + mmio->Register(base | FIFO_BP_LO, + MMIO::DirectRead(MMIO::Utils::LowPart(&fifo.CPBreakpoint)), + MMIO::ComplexWrite([](u32, u16 val) { + WriteLow(fifo.CPBreakpoint, val & 0xffe0); + }) + ); + mmio->Register(base | FIFO_BP_HI, + MMIO::DirectRead(MMIO::Utils::HighPart(&fifo.CPBreakpoint)), + MMIO::ComplexWrite([](u32, u16 val) { + WriteHigh(fifo.CPBreakpoint, val); + }) + ); + // Timing and metrics MMIOs are stubbed with fixed values. struct { u32 addr; @@ -216,8 +228,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) UCPCtrlReg tmp(val); m_CPCtrlReg.Hex = tmp.Hex; SetCpControlRegister(); - if (!IsOnThread()) - RunGpu(); + RunGpu(); }) ); @@ -227,8 +238,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) UCPClearReg tmp(val); m_CPClearReg.Hex = tmp.Hex; SetCpClearRegister(); - if (!IsOnThread()) - RunGpu(); + RunGpu(); }) ); @@ -260,6 +270,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) : MMIO::DirectRead(MMIO::Utils::HighPart(&fifo.CPReadWriteDistance)), MMIO::ComplexWrite([](u32, u16 val) { WriteHigh(fifo.CPReadWriteDistance, val); + SyncGPU(SYNC_GPU_OTHER); if (fifo.CPReadWriteDistance == 0) { GPFifo::ResetGatherPipe(); @@ -269,8 +280,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) { ResetVideoBuffer(); } - if (!IsOnThread()) - RunGpu(); + RunGpu(); }) ); mmio->Register(base | FIFO_READ_POINTER_LO, @@ -298,11 +308,7 @@ void STACKALIGN GatherPipeBursted() // if we aren't linked, we don't care about gather pipe data if (!m_CPCtrlReg.GPLinkEnable) { - if (!IsOnThread()) - { - RunGpu(); - } - else + if (IsOnThread() && !g_use_deterministic_gpu_thread) { // In multibuffer mode is not allowed write in the same FIFO attached to the GPU. // Fix Pokemon XD in DC mode. @@ -313,6 +319,10 @@ void STACKALIGN GatherPipeBursted() ProcessFifoAllDistance(); } } + else + { + RunGpu(); + } return; } @@ -327,8 +337,7 @@ void STACKALIGN GatherPipeBursted() Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); - if (!IsOnThread()) - RunGpu(); + RunGpu(); _assert_msg_(COMMANDPROCESSOR, fifo.CPReadWriteDistance <= fifo.CPEnd - fifo.CPBase, "FIFO is overflowed by GatherPipe !\nCPU thread is too fast!"); @@ -358,7 +367,8 @@ void UpdateInterrupts(u64 userdata) void UpdateInterruptsFromVideoBackend(u64 userdata) { - CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); + if (!g_use_deterministic_gpu_thread) + CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); } void SetCPStatusFromGPU() -- cgit v1.2.3 From 2eebdff01ba260a5d517a0b208ede697e4d67323 Mon Sep 17 00:00:00 2001 From: comex Date: Tue, 30 Sep 2014 01:22:57 -0400 Subject: Remove useless STACKALIGN macro. It only ever did anything on 32-bit OS X. Anyway, it wasn't even on the right functions, and these days ABI_PushRegistersAndAdjustStack should handle maintaining the ABI correctly. --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 0c74a4614f..8af2af9ccc 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -302,7 +302,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) ); } -void STACKALIGN GatherPipeBursted() +void GatherPipeBursted() { ProcessFifoEvents(); // if we aren't linked, we don't care about gather pipe data -- cgit v1.2.3 From b2c02e216ceaeb51ee4f6c644050e26d4adab566 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 14 Nov 2014 11:46:02 +1100 Subject: Separated out the CPU and GPU thread path to avoid clobbering. Removed the Eternal Darkness check as it is no longer required. Fixes issue 7835. --- Source/Core/VideoCommon/CommandProcessor.cpp | 52 +++++++++++++++++----------- 1 file changed, 31 insertions(+), 21 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 8af2af9ccc..155e4b18ec 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -404,7 +404,33 @@ void SetCPStatusFromGPU() INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); fifo.bFF_Breakpoint = false; } - SetCPStatusFromCPU(); + // overflow & underflow check + fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); + fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); + + bool bpInt = fifo.bFF_Breakpoint && fifo.bFF_BPInt; + bool ovfInt = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt; + bool undfInt = fifo.bFF_LoWatermark && fifo.bFF_LoWatermarkInt; + + bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable; + + if (interrupt != interruptSet && !interruptWaiting) + { + u64 userdata = interrupt ? 1 : 0; + if (IsOnThread()) + { + if (!interrupt || bpInt || undfInt || ovfInt) + { + // Schedule the interrupt asynchronously + interruptWaiting = true; + CommandProcessor::UpdateInterruptsFromVideoBackend(userdata); + } + } + else + { + CommandProcessor::UpdateInterrupts(userdata); + } + } } void SetCPStatusFromCPU() @@ -426,18 +452,9 @@ void SetCPStatusFromCPU() { if (!interrupt || bpInt || undfInt || ovfInt) { - if (Core::IsGPUThread()) - { - // Schedule the interrupt asynchronously - interruptWaiting = true; - CommandProcessor::UpdateInterruptsFromVideoBackend(userdata); - } - else - { - interruptSet = interrupt; - INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt); - } + interruptSet = interrupt; + INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt); } } else @@ -451,7 +468,7 @@ void ProcessFifoAllDistance() { if (IsOnThread()) { - while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && + while (!interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint()) Common::YieldCPU(); } @@ -489,13 +506,6 @@ void SetCpStatusRegister() void SetCpControlRegister() { - // If the new fifo is being attached, force an exception check - // This fixes the hang while booting Eternal Darkness - if (!fifo.bFF_GPReadEnable && m_CPCtrlReg.GPReadEnable && !m_CPCtrlReg.BPEnable) - { - CoreTiming::ForceExceptionCheck(0); - } - fifo.bFF_BPInt = m_CPCtrlReg.BPInt; fifo.bFF_BPEnable = m_CPCtrlReg.BPEnable; fifo.bFF_HiWatermarkInt = m_CPCtrlReg.FifoOverflowIntEnable; -- cgit v1.2.3 From 3d448e49c6b2cb51121e85046ee4b96c18b12e01 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 14 Nov 2014 17:07:11 +1100 Subject: Update CPStatus before processing the FIFO events and force an exception check on interrupts. Added more information into the FIFO unknown opcode error message. --- Source/Core/VideoCommon/CommandProcessor.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 155e4b18ec..899438b9e4 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -304,6 +304,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) void GatherPipeBursted() { + if (IsOnThread()) + SetCPStatusFromCPU(); + ProcessFifoEvents(); // if we aren't linked, we don't care about gather pipe data if (!m_CPCtrlReg.GPLinkEnable) @@ -326,9 +329,6 @@ void GatherPipeBursted() return; } - if (IsOnThread()) - SetCPStatusFromCPU(); - // update the fifo pointer if (fifo.CPWritePointer >= fifo.CPEnd) fifo.CPWritePointer = fifo.CPBase; @@ -369,6 +369,7 @@ void UpdateInterrupts(u64 userdata) INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared"); ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); } + CoreTiming::ForceExceptionCheck(0); interruptWaiting = false; } @@ -404,6 +405,7 @@ void SetCPStatusFromGPU() INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %i", fifo.CPReadPointer); fifo.bFF_Breakpoint = false; } + // overflow & underflow check fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark); fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark); @@ -447,7 +449,7 @@ void SetCPStatusFromCPU() if (interrupt != interruptSet && !interruptWaiting) { - u64 userdata = interrupt?1:0; + u64 userdata = interrupt ? 1 : 0; if (IsOnThread()) { if (!interrupt || bpInt || undfInt || ovfInt) -- cgit v1.2.3 From ca3e5ce5e131c6f820d8fa069bf1b1566c60c844 Mon Sep 17 00:00:00 2001 From: skidau Date: Mon, 17 Nov 2014 16:05:16 +1100 Subject: Added an exception check when the game is close to overflowing. Fixes the fifo overflow that occurs in Battalion Wars 2. Changed the CPEnd loop check to an exact match. --- Source/Core/VideoCommon/CommandProcessor.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 899438b9e4..a47cfa18b1 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -330,7 +330,7 @@ void GatherPipeBursted() } // update the fifo pointer - if (fifo.CPWritePointer >= fifo.CPEnd) + if (fifo.CPWritePointer == fifo.CPEnd) fifo.CPWritePointer = fifo.CPBase; else fifo.CPWritePointer += GATHER_PIPE_SIZE; @@ -342,6 +342,10 @@ void GatherPipeBursted() ProcessorInterface::Fifo_CPUEnd = fifo.CPEnd; } + // If the game is running close to overflowing, make the exception checking more frequent. + if (fifo.bFF_HiWatermark) + CoreTiming::ForceExceptionCheck(0); + Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); RunGpu(); @@ -470,8 +474,7 @@ void ProcessFifoAllDistance() { if (IsOnThread()) { - while (!interruptWaiting && fifo.bFF_GPReadEnable && - fifo.CPReadWriteDistance && !AtBreakpoint()) + while (!interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint()) Common::YieldCPU(); } } -- cgit v1.2.3 From 51b26f3397abb0af239204112be55a08a012afe3 Mon Sep 17 00:00:00 2001 From: Justin Chadwick Date: Sat, 27 Dec 2014 19:03:13 -0500 Subject: Remove AtBreakpoint() from ReadIdle. Fixes Rogue Squadron 2 without Breaking Gladius --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index a47cfa18b1..b53c50fc2e 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -494,7 +494,7 @@ void SetCpStatusRegister() { // Here always there is one fifo attached to the GPU m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint; - m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || AtBreakpoint() || (fifo.CPReadPointer == fifo.CPWritePointer); + m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer); m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance || AtBreakpoint() || !fifo.bFF_GPReadEnable; m_CPStatusReg.UnderflowLoWatermark = fifo.bFF_LoWatermark; m_CPStatusReg.OverflowHiWatermark = fifo.bFF_HiWatermark; -- cgit v1.2.3 From 279c657cda7772a39f318b5df68fb279bb0400b4 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 5 Mar 2015 17:12:24 +0100 Subject: Fifo: Replace busy loop with condition variable --- Source/Core/VideoCommon/CommandProcessor.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index b53c50fc2e..21ef0be2a9 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -322,10 +322,7 @@ void GatherPipeBursted() ProcessFifoAllDistance(); } } - else - { - RunGpu(); - } + RunGpu(); return; } @@ -375,6 +372,7 @@ void UpdateInterrupts(u64 userdata) } CoreTiming::ForceExceptionCheck(0); interruptWaiting = false; + RunGpu(); } void UpdateInterruptsFromVideoBackend(u64 userdata) @@ -551,5 +549,7 @@ void Update() if (fifo.isGpuReadingData) Common::AtomicAdd(VITicks, SystemTimers::GetTicksPerSecond() / 10000); + + RunGpu(); } } // end of namespace CommandProcessor -- cgit v1.2.3 From b020ae1c5db4e2e198d1beea91c75219a251a167 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 5 Mar 2015 21:14:46 +0100 Subject: Fifo: rewrite sync on idle skipping hack Now it's done without a busy loop --- Source/Core/VideoCommon/CommandProcessor.cpp | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 21ef0be2a9..162e3a2d53 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -40,7 +40,6 @@ static u16 m_bboxright; static u16 m_bboxbottom; static u16 m_tokenReg; -volatile bool isPossibleWaitingSetDrawDone = false; volatile bool interruptSet= false; volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; @@ -70,7 +69,6 @@ void DoState(PointerWrap &p) p.Do(m_tokenReg); p.Do(fifo); - p.Do(isPossibleWaitingSetDrawDone); p.Do(interruptSet); p.Do(interruptWaiting); p.Do(interruptTokenWaiting); @@ -123,8 +121,6 @@ void Init() interruptFinishWaiting = false; interruptTokenWaiting = false; - isPossibleWaitingSetDrawDone = false; - et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper); } @@ -319,7 +315,7 @@ void GatherPipeBursted() (ProcessorInterface::Fifo_CPUBase == fifo.CPBase) && fifo.CPReadWriteDistance > 0) { - ProcessFifoAllDistance(); + FlushGpu(); } } RunGpu(); @@ -468,15 +464,6 @@ void SetCPStatusFromCPU() } } -void ProcessFifoAllDistance() -{ - if (IsOnThread()) - { - while (!interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint()) - Common::YieldCPU(); - } -} - void ProcessFifoEvents() { if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting)) @@ -518,7 +505,7 @@ void SetCpControlRegister() if (fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable) { fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable; - while (fifo.isGpuReadingData) Common::YieldCPU(); + FlushGpu(); } else { -- cgit v1.2.3 From d2c62b17445b666b81a19cb3a6c46f9ee2d1388e Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 13 Mar 2015 23:36:31 +0100 Subject: Fifo: only sleep once within every ms of emulated time --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 162e3a2d53..2c6660e1f8 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -45,6 +45,8 @@ volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; volatile bool interruptFinishWaiting = false; +Common::Flag s_gpuMaySleep; + volatile u32 VITicks = CommandProcessor::m_cpClockOrigin; static bool IsOnThread() -- cgit v1.2.3 From cefcb0ace9d363b3679b4e93bcc9ec05f1e5f4f8 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Mon, 18 May 2015 01:08:10 +0200 Subject: Update license headers to GPLv2+ --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 2c6660e1f8..2ae1fcdc41 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -1,5 +1,5 @@ // Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2 +// Licensed under GPLv2+ // Refer to the license.txt file included. #include "Common/Atomic.h" -- cgit v1.2.3 From 30ebb2459eb97ba544547183854775df8460b475 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Sun, 24 May 2015 06:55:12 +0200 Subject: Set copyright year to when a file was created --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 2ae1fcdc41..f682abdeee 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -1,4 +1,4 @@ -// Copyright 2013 Dolphin Emulator Project +// Copyright 2008 Dolphin Emulator Project // Licensed under GPLv2+ // Refer to the license.txt file included. -- cgit v1.2.3 From 1ba3b4e7ac9d53710454c46ac5384ee44a096b70 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Wed, 27 May 2015 03:08:48 -0400 Subject: CommandProcessor: Replace volatile usages with atomics Also remove said variables from being globals. --- Source/Core/VideoCommon/CommandProcessor.cpp | 81 +++++++++++++++++++--------- 1 file changed, 57 insertions(+), 24 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index f682abdeee..449e99982f 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include + #include "Common/Atomic.h" #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" @@ -40,14 +42,14 @@ static u16 m_bboxright; static u16 m_bboxbottom; static u16 m_tokenReg; -volatile bool interruptSet= false; -volatile bool interruptWaiting= false; -volatile bool interruptTokenWaiting = false; -volatile bool interruptFinishWaiting = false; +static std::atomic s_interrupt_set; +static std::atomic s_interrupt_waiting; +static std::atomic s_interrupt_token_waiting; +static std::atomic s_interrupt_finish_waiting; -Common::Flag s_gpuMaySleep; +static std::atomic s_vi_ticks(CommandProcessor::m_cpClockOrigin); -volatile u32 VITicks = CommandProcessor::m_cpClockOrigin; +Common::Flag s_gpuMaySleep; static bool IsOnThread() { @@ -71,10 +73,10 @@ void DoState(PointerWrap &p) p.Do(m_tokenReg); p.Do(fifo); - p.Do(interruptSet); - p.Do(interruptWaiting); - p.Do(interruptTokenWaiting); - p.Do(interruptFinishWaiting); + p.Do(s_interrupt_set); + p.Do(s_interrupt_waiting); + p.Do(s_interrupt_token_waiting); + p.Do(s_interrupt_finish_waiting); } static inline void WriteLow(volatile u32& _reg, u16 lowbits) @@ -118,10 +120,10 @@ void Init() fifo.bFF_LoWatermark = 0; fifo.bFF_LoWatermarkInt = 0; - interruptSet = false; - interruptWaiting = false; - interruptFinishWaiting = false; - interruptTokenWaiting = false; + s_interrupt_set.store(false); + s_interrupt_waiting.store(false); + s_interrupt_finish_waiting.store(false); + s_interrupt_token_waiting.store(false); et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper); } @@ -358,18 +360,18 @@ void UpdateInterrupts(u64 userdata) { if (userdata) { - interruptSet = true; + s_interrupt_set.store(true); INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true); } else { - interruptSet = false; + s_interrupt_set.store(false); INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared"); ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); } CoreTiming::ForceExceptionCheck(0); - interruptWaiting = false; + s_interrupt_waiting.store(false); RunGpu(); } @@ -379,6 +381,21 @@ void UpdateInterruptsFromVideoBackend(u64 userdata) CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata); } +bool IsInterruptWaiting() +{ + return s_interrupt_waiting.load(); +} + +void SetInterruptTokenWaiting(bool waiting) +{ + s_interrupt_token_waiting.store(waiting); +} + +void SetInterruptFinishWaiting(bool waiting) +{ + s_interrupt_finish_waiting.store(waiting); +} + void SetCPStatusFromGPU() { // breakpoint @@ -416,7 +433,7 @@ void SetCPStatusFromGPU() bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable; - if (interrupt != interruptSet && !interruptWaiting) + if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load()) { u64 userdata = interrupt ? 1 : 0; if (IsOnThread()) @@ -424,7 +441,7 @@ void SetCPStatusFromGPU() if (!interrupt || bpInt || undfInt || ovfInt) { // Schedule the interrupt asynchronously - interruptWaiting = true; + s_interrupt_waiting.store(true); CommandProcessor::UpdateInterruptsFromVideoBackend(userdata); } } @@ -447,14 +464,14 @@ void SetCPStatusFromCPU() bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable; - if (interrupt != interruptSet && !interruptWaiting) + if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load()) { u64 userdata = interrupt ? 1 : 0; if (IsOnThread()) { if (!interrupt || bpInt || undfInt || ovfInt) { - interruptSet = interrupt; + s_interrupt_set.store(interrupt); INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt); } @@ -468,7 +485,7 @@ void SetCPStatusFromCPU() void ProcessFifoEvents() { - if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting)) + if (IsOnThread() && (s_interrupt_waiting.load() || s_interrupt_finish_waiting.load() || s_interrupt_token_waiting.load())) CoreTiming::ProcessFifoWaitEvents(); } @@ -533,12 +550,28 @@ void SetCpClearRegister() void Update() { - while (VITicks > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread()) + while (s_vi_ticks.load() > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread()) Common::YieldCPU(); if (fifo.isGpuReadingData) - Common::AtomicAdd(VITicks, SystemTimers::GetTicksPerSecond() / 10000); + s_vi_ticks.fetch_add(SystemTimers::GetTicksPerSecond() / 10000); RunGpu(); } + +u32 GetVITicks() +{ + return s_vi_ticks.load(); +} + +void SetVITicks(u32 ticks) +{ + s_vi_ticks.store(ticks); +} + +void DecrementVITicks(u32 ticks) +{ + s_vi_ticks.fetch_sub(ticks); +} + } // end of namespace CommandProcessor -- cgit v1.2.3 From 02a3a063c346cf0372a51d4f1133dc436e9b22c0 Mon Sep 17 00:00:00 2001 From: degasus Date: Wed, 27 May 2015 20:53:09 +0200 Subject: Fifo: Extract syncing loop It's now a new helper function within common. --- Source/Core/VideoCommon/CommandProcessor.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 449e99982f..88b16afe7e 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -49,8 +49,6 @@ static std::atomic s_interrupt_finish_waiting; static std::atomic s_vi_ticks(CommandProcessor::m_cpClockOrigin); -Common::Flag s_gpuMaySleep; - static bool IsOnThread() { return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; -- cgit v1.2.3 From d31bed8b79a1266d7ac9c7c6f0e45c20d36aaf4c Mon Sep 17 00:00:00 2001 From: degasus Date: Wed, 3 Jun 2015 23:21:46 +0200 Subject: Fifo: Rewrite SyncGpu The new implementation has 3 options: SyncGpuMaxDistance SyncGpuMinDistance SyncGpuOverclock The MaxDistance controlls how many CPU cycles the CPU is allowed to be in front of the GPU. Too low values will slow down extremly, too high values are as unsynchronized and half of the games will crash. The -MinDistance (negative) set how many cycles the GPU is allowed to be in front of the CPU. As we are used to emulate an infinitiv fast GPU, this may be set to any high (negative) number. The last parameter is to hack a faster (>1.0) or slower(<1.0) GPU. As we don't emulate GPU timing very well (eg skip the timings of the pixel stage completely), an overclock factor of ~0.5 is often much more accurate than 1.0 --- Source/Core/VideoCommon/CommandProcessor.cpp | 29 ---------------------------- 1 file changed, 29 deletions(-) (limited to 'Source/Core/VideoCommon/CommandProcessor.cpp') diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 88b16afe7e..e16484de4d 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -16,7 +16,6 @@ #include "Core/HW/Memmap.h" #include "Core/HW/MMIO.h" #include "Core/HW/ProcessorInterface.h" -#include "Core/HW/SystemTimers.h" #include "VideoCommon/CommandProcessor.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/PixelEngine.h" @@ -47,8 +46,6 @@ static std::atomic s_interrupt_waiting; static std::atomic s_interrupt_token_waiting; static std::atomic s_interrupt_finish_waiting; -static std::atomic s_vi_ticks(CommandProcessor::m_cpClockOrigin); - static bool IsOnThread() { return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread; @@ -546,30 +543,4 @@ void SetCpClearRegister() { } -void Update() -{ - while (s_vi_ticks.load() > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread()) - Common::YieldCPU(); - - if (fifo.isGpuReadingData) - s_vi_ticks.fetch_add(SystemTimers::GetTicksPerSecond() / 10000); - - RunGpu(); -} - -u32 GetVITicks() -{ - return s_vi_ticks.load(); -} - -void SetVITicks(u32 ticks) -{ - s_vi_ticks.store(ticks); -} - -void DecrementVITicks(u32 ticks) -{ - s_vi_ticks.fetch_sub(ticks); -} - } // end of namespace CommandProcessor -- cgit v1.2.3