summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Src/CommandProcessor.cpp
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2013-03-12 11:28:56 +0100
committerdegasus <wickmarkus@web.de>2013-03-12 11:28:56 +0100
commit382be2aabdf0635c67f9ec945283f77f8ed9b0c9 (patch)
tree8df3cf8a3539e4b4b1a96772f17c353f99393ed5 /Source/Core/VideoCommon/Src/CommandProcessor.cpp
parente1ca002937cf8915ab9fb04f82e2dc5e68db1fa2 (diff)
parent83fc5f4747f9c8c6066bf002730827ecc17458aa (diff)
Merge branch 'master' into GLSL-master
Conflicts: .gitignore
Diffstat (limited to 'Source/Core/VideoCommon/Src/CommandProcessor.cpp')
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.cpp101
1 files changed, 56 insertions, 45 deletions
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
index a4dddf537f..eb03730fc3 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
@@ -32,6 +32,8 @@
#include "HW/GPFifo.h"
#include "HW/Memmap.h"
#include "DLCache.h"
+#include "HW/SystemTimers.h"
+#include "Core.h"
namespace CommandProcessor
{
@@ -57,12 +59,15 @@ 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 bool waitingForPEInterruptDisable = false;
+volatile u32 VITicks = CommandProcessor::m_cpClockOrigin;
+
bool IsOnThread()
{
return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread;
@@ -88,6 +93,7 @@ void DoState(PointerWrap &p)
p.Do(bProcessFifoToLoWatermark);
p.Do(bProcessFifoAllDistance);
p.Do(isHiWatermarkActive);
+ p.Do(isLoWatermarkActive);
p.Do(isPossibleWaitingSetDrawDone);
p.Do(interruptSet);
p.Do(interruptWaiting);
@@ -119,7 +125,7 @@ void Init()
m_tokenReg = 0;
memset(&fifo,0,sizeof(fifo));
- fifo.CPCmdIdle = 1 ;
+ fifo.CPCmdIdle = 1;
fifo.CPReadIdle = 1;
fifo.bFF_Breakpoint = 0;
fifo.bFF_HiWatermark = 0;
@@ -136,6 +142,7 @@ void Init()
bProcessFifoAllDistance = false;
isPossibleWaitingSetDrawDone = false;
isHiWatermarkActive = false;
+ isLoWatermarkActive = false;
et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper);
}
@@ -294,7 +301,6 @@ void Read16(u16& _rReturnValue, const u32 _Address)
void Write16(const u16 _Value, const u32 _Address)
{
-
INFO_LOG(COMMANDPROCESSOR, "(write16): 0x%04x @ 0x%08x",_Value,_Address);
switch (_Address & 0xFFF)
@@ -405,7 +411,8 @@ void Write16(const u16 _Value, const u32 _Address)
{
GPFifo::ResetGatherPipe();
ResetVideoBuffer();
- }else
+ }
+ else
{
ResetVideoBuffer();
}
@@ -461,7 +468,7 @@ void STACKALIGN GatherPipeBursted()
}
if (IsOnThread())
- SetOverflowStatusFromGatherPipe();
+ SetCpStatus();
// update the fifo-pointer
if (fifo.CPWritePointer >= fifo.CPEnd)
@@ -511,19 +518,6 @@ void AbortFrame()
}
-void SetOverflowStatusFromGatherPipe()
-{
- fifo.bFF_HiWatermark = (fifo.CPReadWriteDistance > fifo.CPHiWatermark);
- isHiWatermarkActive = fifo.bFF_HiWatermark && fifo.bFF_HiWatermarkInt && m_CPCtrlReg.GPReadEnable;
-
- if (isHiWatermarkActive)
- {
- interruptSet = true;
- INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
- ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
- }
-}
-
void SetCpStatus()
{
// overflow & underflow check
@@ -531,30 +525,33 @@ void SetCpStatus()
fifo.bFF_LoWatermark = (fifo.CPReadWriteDistance < fifo.CPLoWatermark);
// breakpoint
- if (fifo.bFF_BPEnable)
- {
- if (fifo.CPBreakpoint == fifo.CPReadPointer)
- {
- if (!fifo.bFF_Breakpoint)
+ if (Core::IsGPUThread())
+ {
+ if (fifo.bFF_BPEnable)
+ {
+ if (fifo.CPBreakpoint == fifo.CPReadPointer)
{
- INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %i", fifo.CPReadPointer);
- fifo.bFF_Breakpoint = true;
- IncrementCheckContextId();
+ 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;
+ 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;
@@ -562,17 +559,27 @@ void SetCpStatus()
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
- isHiWatermarkActive = ovfInt && 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)
+ if(!interrupt || bpInt || undfInt || ovfInt)
{
- interruptWaiting = true;
- CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
+ if (Core::IsGPUThread())
+ {
+ interruptWaiting = true;
+ CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
+ }
+ else if (Core::IsCPUThread())
+ {
+ interruptSet = interrupt;
+ INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
+ ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
+ }
}
}
else
@@ -596,7 +603,7 @@ void ProcessFifoAllDistance()
if (IsOnThread())
{
while (!CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable &&
- fifo.CPReadWriteDistance && !AtBreakpoint() && !PixelEngine::WaitingForPEInterrupt())
+ fifo.CPReadWriteDistance && !AtBreakpoint())
Common::YieldCPU();
}
bProcessFifoAllDistance = false;
@@ -617,15 +624,11 @@ void SetCpStatusRegister()
{
// Here always there is one fifo attached to the GPU
m_CPStatusReg.Breakpoint = fifo.bFF_Breakpoint;
- m_CPStatusReg.ReadIdle = !fifo.CPReadWriteDistance || (fifo.CPReadPointer == fifo.CPWritePointer) || (fifo.CPReadPointer == fifo.CPBreakpoint) ;
- m_CPStatusReg.CommandIdle = !fifo.CPReadWriteDistance;
+ 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;
- // HACK to compensate for slow response to PE interrupts in Time Splitters: Future Perfect
- if (IsOnThread())
- PixelEngine::ResumeWaitingForPEInterrupt();
-
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"
@@ -693,4 +696,12 @@ void SetCpClearRegister()
// }
}
+void Update()
+{
+ while (VITicks > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread())
+ Common::YieldCPU();
+
+ if (fifo.isGpuReadingData)
+ Common::AtomicAdd(VITicks, SystemTimers::GetTicksPerSecond() / 10000);
+}
} // end of namespace CommandProcessor