summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorMarcos Vitali <marcosvitali@gmail.com>2010-12-13 07:56:54 +0000
committerMarcos Vitali <marcosvitali@gmail.com>2010-12-13 07:56:54 +0000
commit5fd99516499f186c697f0cf2b7a043e215d18b76 (patch)
tree720b2d8681ecdde3124f1f1d7e607c335b8060f0 /Source/Core/VideoCommon
parent3d3411f3a083ac61afa835ee6282bb19756547cc (diff)
- I've implemented cache of interrupt states for PEFINISH and PETOKEN
- I've implemented calling to ProcessFifoEvents when is there is a pending event in the main queue from CP, PE & GP - I've implemented FifoIntReset(TRUE, TRUE) in write Clear Register. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6572 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.cpp25
-rw-r--r--Source/Core/VideoCommon/Src/CommandProcessor.h3
-rw-r--r--Source/Core/VideoCommon/Src/PixelEngine.cpp54
3 files changed, 64 insertions, 18 deletions
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
index 71c408be1c..e6a0589ba5 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp
@@ -111,11 +111,13 @@ static u32 fake_GPWatchdogLastToken = 0;
static Common::EventEx s_fifoIdleEvent;
static Common::CriticalSection sFifoCritical;
static bool bProcessFifoToLoWatemark = false;
+static bool bProcessFifoAllDistance = false;
volatile bool isFifoBusy = false; //This state is changed when the FIFO is processing data.
volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
-
+volatile bool interruptTokenWaiting = false;
+volatile bool interruptFinishWaiting = false;
void FifoCriticalEnter()
{
@@ -177,6 +179,8 @@ void Init()
interruptSet = false;
interruptWaiting = false;
+ interruptFinishWaiting = false;
+ interruptTokenWaiting = false;
s_fifoIdleEvent.Init();
@@ -192,6 +196,7 @@ void Read16(u16& _rReturnValue, const u32 _Address)
{
INFO_LOG(COMMANDPROCESSOR, "(r): 0x%08x", _Address);
+ ProcessFifoEvents();
switch (_Address & 0xFFF)
{
case STATUS_REGISTER:
@@ -458,6 +463,9 @@ void Write16(const u16 _Value, const u32 _Address)
// If overflown happens process the fifo to LoWatemark
if (bProcessFifoToLoWatemark)
ProcessFifoToLoWatemark();
+
+ if (bProcessFifoAllDistance)
+ ProcessFifoAllDistance();
INFO_LOG(COMMANDPROCESSOR,"\t Write to CTRL_REGISTER : %04x", _Value);
DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | BP %s | Int %s | OvF %s | UndF %s | LINK %s"
@@ -479,6 +487,9 @@ void Write16(const u16 _Value, const u32 _Address)
{
if (!tmpCtrl.ClearFifoUnderflow && tmpCtrl.ClearFifoOverflow)
bProcessFifoToLoWatemark = true;
+
+ if (tmpCtrl.ClearFifoUnderflow && tmpCtrl.ClearFifoOverflow)
+ bProcessFifoAllDistance = true;
}
else
{
@@ -590,8 +601,7 @@ void Write16(const u16 _Value, const u32 _Address)
if (!g_VideoInitialize.bOnThread)
CatchUpGPU();
-
-
+ ProcessFifoEvents();
}
void Read32(u32& _rReturnValue, const u32 _Address)
@@ -626,7 +636,7 @@ void WaitForFrameFinish()
void STACKALIGN GatherPipeBursted()
{
-
+ ProcessFifoEvents();
// if we aren't linked, we don't care about gather pipe data
if (!m_CPCtrlReg.GPLinkEnable)
{
@@ -862,6 +872,13 @@ void ProcessFifoAllDistance()
fifo.CPReadWriteDistance && !AtBreakpoint())
Common::YieldCPU();
}
+ bProcessFifoAllDistance = false;
+}
+
+void ProcessFifoEvents()
+{
+ if (g_VideoInitialize.bOnThread || interruptWaiting || interruptFinishWaiting || interruptTokenWaiting)
+ g_VideoInitialize.pProcessFifoEvents();
}
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h
index 68e0f32080..9d98c802d2 100644
--- a/Source/Core/VideoCommon/Src/CommandProcessor.h
+++ b/Source/Core/VideoCommon/Src/CommandProcessor.h
@@ -33,6 +33,8 @@ extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator
extern volatile bool isFifoBusy; //This one is used for sync gfx thread and emulator thread.
extern volatile bool interruptSet;
extern volatile bool interruptWaiting;
+extern volatile bool interruptTokenWaiting;
+extern volatile bool interruptFinishWaiting;
// internal hardware addresses
enum
@@ -170,6 +172,7 @@ void FifoCriticalLeave();
void SetOverflowStatusFromGatherPipe();
void ProcessFifoToLoWatemark();
void ProcessFifoAllDistance();
+void ProcessFifoEvents();
void AbortFrame();
} // namespace CommandProcessor
diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp
index 4913e21cfc..cea6b46774 100644
--- a/Source/Core/VideoCommon/Src/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp
@@ -112,6 +112,9 @@ static bool g_bSignalFinishInterrupt;
static int et_SetTokenOnMainThread;
static int et_SetFinishOnMainThread;
+volatile bool interruptSetToken = false;
+volatile bool interruptSetFinish = false;
+
u16 bbox[4];
bool bbox_active;
@@ -139,7 +142,8 @@ void DoState(PointerWrap &p)
}
void UpdateInterrupts();
-
+void UpdateTokenInterrupt(bool active);
+void UpdateFinishInterrupt(bool active);
void SetToken_OnMainThread(u64 userdata, int cyclesLate);
void SetFinish_OnMainThread(u64 userdata, int cyclesLate);
@@ -161,7 +165,7 @@ void Init()
void Read16(u16& _uReturnValue, const u32 _iAddress)
{
DEBUG_LOG(PIXELENGINE, "(r16) 0x%08x", _iAddress);
-
+ CommandProcessor::ProcessFifoEvents();
switch (_iAddress & 0xFFF)
{
// CPU Direct Access EFB Raster State Config
@@ -226,6 +230,7 @@ void Read16(u16& _uReturnValue, const u32 _iAddress)
_uReturnValue = 1;
break;
}
+
}
void Write16(const u16 _iValue, const u32 _iAddress)
@@ -282,6 +287,8 @@ void Write16(const u16 _iValue, const u32 _iAddress)
WARN_LOG(PIXELENGINE, "(w16) unknown %04x @ %08x", _iValue, _iAddress);
break;
}
+
+ CommandProcessor::ProcessFifoEvents();
}
void Write32(const u32 _iValue, const u32 _iAddress)
@@ -291,22 +298,35 @@ void Write32(const u32 _iValue, const u32 _iAddress)
bool AllowIdleSkipping()
{
- return !g_VideoInitialize.bOnThread|| (!m_Control.PETokenEnable && !m_Control.PEFinishEnable);
+ return !g_VideoInitialize.bOnThread || (!m_Control.PETokenEnable && !m_Control.PEFinishEnable);
}
void UpdateInterrupts()
{
// check if there is a token-interrupt
- if (g_bSignalTokenInterrupt & m_Control.PETokenEnable)
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, true);
- else
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, false);
-
+ UpdateTokenInterrupt((g_bSignalTokenInterrupt & m_Control.PETokenEnable));
+
// check if there is a finish-interrupt
- if (g_bSignalFinishInterrupt & m_Control.PEFinishEnable)
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_FINISH, true);
- else
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_FINISH, false);
+ UpdateFinishInterrupt((g_bSignalFinishInterrupt & m_Control.PEFinishEnable));
+}
+
+void UpdateTokenInterrupt(bool active)
+{
+ if(interruptSetToken != active)
+ {
+ g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, active);
+ interruptSetToken = active;
+ }
+}
+
+void UpdateFinishInterrupt(bool active)
+{
+
+ if(interruptSetFinish != active)
+ {
+ g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_FINISH, active);
+ interruptSetFinish = active;
+ }
}
// TODO(mb2): Refactor SetTokenINT_OnMainThread(u64 userdata, int cyclesLate).
@@ -322,6 +342,7 @@ void SetToken_OnMainThread(u64 userdata, int cyclesLate)
//_dbg_assert_msg_(PIXELENGINE, (CommandProcessor::fifo.PEToken == (userdata&0xFFFF)), "WTF? BPMEM_PE_TOKEN_INT_ID's token != BPMEM_PE_TOKEN_ID's token" );
INFO_LOG(PIXELENGINE, "VIDEO Plugin raises INT_CAUSE_PE_TOKEN (btw, token: %04x)", CommandProcessor::fifo.PEToken);
UpdateInterrupts();
+ CommandProcessor::interruptTokenWaiting = false;
//}
//else
// LOGV(PIXELENGINE, 1, "VIDEO Plugin wrote token: %i", CommandProcessor::fifo.PEToken);
@@ -331,6 +352,7 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
{
g_bSignalFinishInterrupt = 1;
UpdateInterrupts();
+ CommandProcessor::interruptFinishWaiting = false;
}
// SetToken
@@ -342,6 +364,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
{
// This seems smelly...
CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack since PEToken seems to be a frame-finish too
+ CommandProcessor::interruptTokenWaiting = true;
g_VideoInitialize.pScheduleEvent_Threadsafe(
0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
}
@@ -361,6 +384,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
void SetFinish()
{
CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack
+ CommandProcessor::interruptFinishWaiting = true;
g_VideoInitialize.pScheduleEvent_Threadsafe(
0, et_SetFinishOnMainThread, 0);
INFO_LOG(PIXELENGINE, "VIDEO Set Finish");
@@ -373,25 +397,27 @@ void ResetSetFinish()
//remove event from the queque
if (g_bSignalFinishInterrupt)
{
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_FINISH, false);
+ UpdateFinishInterrupt(false);
g_bSignalFinishInterrupt = false;
}else
{
g_VideoInitialize.pRemoveEvent(et_SetFinishOnMainThread);
}
+ CommandProcessor::interruptFinishWaiting = false;
}
void ResetSetToken()
{
if (g_bSignalTokenInterrupt)
{
- g_VideoInitialize.pSetInterrupt(INT_CAUSE_PE_TOKEN, false);
+ UpdateTokenInterrupt(false);
g_bSignalTokenInterrupt = false;
}else
{
g_VideoInitialize.pRemoveEvent(et_SetTokenOnMainThread);
}
+ CommandProcessor::interruptTokenWaiting = false;
}
} // end of namespace PixelEngine