2010-06-09 01:37:08 +00:00
|
|
|
// Copyright (C) 2003 Dolphin Project.
|
|
|
|
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, version 2.0.
|
|
|
|
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License 2.0 for more details.
|
|
|
|
|
|
|
|
// A copy of the GPL 2.0 should have been included with the program.
|
|
|
|
// If not, see http://www.gnu.org/licenses/
|
|
|
|
|
|
|
|
// Official SVN repository and contact information can be found at
|
|
|
|
// http://code.google.com/p/dolphin-emu/
|
|
|
|
|
|
|
|
|
|
|
|
// http://developer.nvidia.com/object/General_FAQ.html#t6 !!!!!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "Common.h"
|
|
|
|
#include "VideoCommon.h"
|
|
|
|
#include "ChunkFile.h"
|
|
|
|
#include "Atomic.h"
|
2011-01-31 01:28:32 +00:00
|
|
|
#include "CoreTiming.h"
|
|
|
|
#include "ConfigManager.h"
|
2010-06-09 01:37:08 +00:00
|
|
|
|
|
|
|
#include "PixelEngine.h"
|
|
|
|
#include "CommandProcessor.h"
|
2011-01-31 01:28:32 +00:00
|
|
|
#include "HW/ProcessorInterface.h"
|
2011-02-08 12:00:41 +00:00
|
|
|
#include "DLCache.h"
|
2011-10-15 11:19:42 +00:00
|
|
|
#include "State.h"
|
2010-06-09 01:37:08 +00:00
|
|
|
namespace PixelEngine
|
|
|
|
{
|
|
|
|
|
|
|
|
union UPEZConfReg
|
|
|
|
{
|
|
|
|
u16 Hex;
|
|
|
|
struct
|
|
|
|
{
|
2010-09-27 05:16:11 +00:00
|
|
|
u16 ZCompEnable : 1; // Z Comparator Enable
|
|
|
|
u16 Function : 3;
|
|
|
|
u16 ZUpdEnable : 1;
|
|
|
|
u16 : 11;
|
2010-06-09 01:37:08 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
union UPEAlphaConfReg
|
|
|
|
{
|
|
|
|
u16 Hex;
|
|
|
|
struct
|
|
|
|
{
|
2010-09-27 05:16:11 +00:00
|
|
|
u16 BMMath : 1; // GX_BM_BLEND || GX_BM_SUBSTRACT
|
|
|
|
u16 BMLogic : 1; // GX_BM_LOGIC
|
|
|
|
u16 Dither : 1;
|
|
|
|
u16 ColorUpdEnable : 1;
|
|
|
|
u16 AlphaUpdEnable : 1;
|
|
|
|
u16 DstFactor : 3;
|
|
|
|
u16 SrcFactor : 3;
|
|
|
|
u16 Substract : 1; // Additive mode by default
|
|
|
|
u16 BlendOperator : 4;
|
2010-06-09 01:37:08 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
union UPEDstAlphaConfReg
|
|
|
|
{
|
|
|
|
u16 Hex;
|
|
|
|
struct
|
|
|
|
{
|
2010-09-27 05:16:11 +00:00
|
|
|
u16 DstAlpha : 8;
|
|
|
|
u16 Enable : 1;
|
|
|
|
u16 : 7;
|
2010-06-09 01:37:08 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
union UPEAlphaModeConfReg
|
|
|
|
{
|
|
|
|
u16 Hex;
|
|
|
|
struct
|
|
|
|
{
|
2010-09-27 05:16:11 +00:00
|
|
|
u16 Threshold : 8;
|
|
|
|
u16 CompareMode : 8;
|
2010-06-09 01:37:08 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// fifo Control Register
|
|
|
|
union UPECtrlReg
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
2010-09-27 05:16:11 +00:00
|
|
|
u16 PETokenEnable : 1;
|
|
|
|
u16 PEFinishEnable : 1;
|
|
|
|
u16 PEToken : 1; // write only
|
|
|
|
u16 PEFinish : 1; // write only
|
|
|
|
u16 : 12;
|
2010-06-09 01:37:08 +00:00
|
|
|
};
|
|
|
|
u16 Hex;
|
|
|
|
UPECtrlReg() {Hex = 0; }
|
|
|
|
UPECtrlReg(u16 _hex) {Hex = _hex; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// STATE_TO_SAVE
|
|
|
|
static UPEZConfReg m_ZConf;
|
|
|
|
static UPEAlphaConfReg m_AlphaConf;
|
|
|
|
static UPEDstAlphaConfReg m_DstAlphaConf;
|
|
|
|
static UPEAlphaModeConfReg m_AlphaModeConf;
|
|
|
|
static UPEAlphaReadReg m_AlphaRead;
|
|
|
|
static UPECtrlReg m_Control;
|
|
|
|
//static u16 m_Token; // token value most recently encountered
|
|
|
|
|
|
|
|
static bool g_bSignalTokenInterrupt;
|
|
|
|
static bool g_bSignalFinishInterrupt;
|
|
|
|
|
|
|
|
static int et_SetTokenOnMainThread;
|
|
|
|
static int et_SetFinishOnMainThread;
|
|
|
|
|
2010-12-13 07:56:54 +00:00
|
|
|
volatile bool interruptSetToken = false;
|
|
|
|
volatile bool interruptSetFinish = false;
|
|
|
|
|
2010-06-09 01:37:08 +00:00
|
|
|
u16 bbox[4];
|
|
|
|
bool bbox_active;
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
INT_CAUSE_PE_TOKEN = 0x200, // GP Token
|
|
|
|
INT_CAUSE_PE_FINISH = 0x400, // GP Finished
|
|
|
|
};
|
|
|
|
|
|
|
|
void DoState(PointerWrap &p)
|
|
|
|
{
|
|
|
|
p.Do(m_ZConf);
|
|
|
|
p.Do(m_AlphaConf);
|
|
|
|
p.Do(m_DstAlphaConf);
|
|
|
|
p.Do(m_AlphaModeConf);
|
|
|
|
p.Do(m_AlphaRead);
|
|
|
|
p.Do(m_Control);
|
|
|
|
|
|
|
|
p.Do(g_bSignalTokenInterrupt);
|
|
|
|
p.Do(g_bSignalFinishInterrupt);
|
2011-02-15 09:07:55 +00:00
|
|
|
p.Do(interruptSetToken);
|
|
|
|
p.Do(interruptSetFinish);
|
2010-06-09 01:37:08 +00:00
|
|
|
|
|
|
|
p.Do(bbox);
|
|
|
|
p.Do(bbox_active);
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateInterrupts();
|
2010-12-13 07:56:54 +00:00
|
|
|
void UpdateTokenInterrupt(bool active);
|
|
|
|
void UpdateFinishInterrupt(bool active);
|
2010-06-09 01:37:08 +00:00
|
|
|
void SetToken_OnMainThread(u64 userdata, int cyclesLate);
|
|
|
|
void SetFinish_OnMainThread(u64 userdata, int cyclesLate);
|
|
|
|
|
|
|
|
void Init()
|
|
|
|
{
|
|
|
|
m_Control.Hex = 0;
|
2012-01-02 10:20:22 +00:00
|
|
|
m_ZConf.Hex = 0;
|
|
|
|
m_AlphaConf.Hex = 0;
|
|
|
|
m_DstAlphaConf.Hex = 0;
|
|
|
|
m_AlphaModeConf.Hex = 0;
|
|
|
|
m_AlphaRead.Hex = 0;
|
|
|
|
|
|
|
|
g_bSignalTokenInterrupt = false;
|
|
|
|
g_bSignalFinishInterrupt = false;
|
|
|
|
interruptSetToken = false;
|
|
|
|
interruptSetFinish = false;
|
2010-06-09 01:37:08 +00:00
|
|
|
|
2011-01-31 01:28:32 +00:00
|
|
|
et_SetTokenOnMainThread = CoreTiming::RegisterEvent("SetToken", SetToken_OnMainThread);
|
|
|
|
et_SetFinishOnMainThread = CoreTiming::RegisterEvent("SetFinish", SetFinish_OnMainThread);
|
2010-06-09 01:37:08 +00:00
|
|
|
|
|
|
|
bbox[0] = 0x80;
|
|
|
|
bbox[1] = 0xA0;
|
|
|
|
bbox[2] = 0x80;
|
|
|
|
bbox[3] = 0xA0;
|
|
|
|
|
|
|
|
bbox_active = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Read16(u16& _uReturnValue, const u32 _iAddress)
|
|
|
|
{
|
|
|
|
DEBUG_LOG(PIXELENGINE, "(r16) 0x%08x", _iAddress);
|
|
|
|
switch (_iAddress & 0xFFF)
|
|
|
|
{
|
|
|
|
// CPU Direct Access EFB Raster State Config
|
|
|
|
case PE_ZCONF:
|
|
|
|
_uReturnValue = m_ZConf.Hex;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) ZCONF");
|
|
|
|
break;
|
|
|
|
case PE_ALPHACONF:
|
|
|
|
// Most games read this early. no idea why.
|
|
|
|
_uReturnValue = m_AlphaConf.Hex;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) ALPHACONF");
|
|
|
|
break;
|
|
|
|
case PE_DSTALPHACONF:
|
|
|
|
_uReturnValue = m_DstAlphaConf.Hex;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) DSTALPHACONF");
|
|
|
|
break;
|
|
|
|
case PE_ALPHAMODE:
|
|
|
|
_uReturnValue = m_AlphaModeConf.Hex;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) ALPHAMODE");
|
|
|
|
break;
|
|
|
|
case PE_ALPHAREAD:
|
|
|
|
_uReturnValue = m_AlphaRead.Hex;
|
|
|
|
WARN_LOG(PIXELENGINE, "(r16) ALPHAREAD");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PE_CTRL_REGISTER:
|
|
|
|
_uReturnValue = m_Control.Hex;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) CTRL_REGISTER : %04x", _uReturnValue);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PE_TOKEN_REG:
|
|
|
|
_uReturnValue = CommandProcessor::fifo.PEToken;
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) TOKEN_REG : %04x", _uReturnValue);
|
|
|
|
break;
|
|
|
|
|
2011-10-28 20:12:12 +00:00
|
|
|
case PE_BBOX_LEFT:
|
|
|
|
{
|
|
|
|
// Left must be even and 606px max
|
|
|
|
_uReturnValue = std::min((u16) 606, bbox[0]) & ~1;
|
|
|
|
|
|
|
|
INFO_LOG(PIXELENGINE, "R: BBOX_LEFT = %i", _uReturnValue);
|
|
|
|
bbox_active = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PE_BBOX_RIGHT:
|
|
|
|
{
|
|
|
|
// Right must be odd and 607px max
|
|
|
|
_uReturnValue = std::min((u16) 607, bbox[1]) | 1;
|
|
|
|
|
|
|
|
INFO_LOG(PIXELENGINE, "R: BBOX_RIGHT = %i", _uReturnValue);
|
|
|
|
bbox_active = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PE_BBOX_TOP:
|
|
|
|
{
|
|
|
|
// Top must be even and 478px max
|
|
|
|
_uReturnValue = std::min((u16) 478, bbox[2]) & ~1;
|
|
|
|
|
|
|
|
INFO_LOG(PIXELENGINE, "R: BBOX_TOP = %i", _uReturnValue);
|
|
|
|
bbox_active = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PE_BBOX_BOTTOM:
|
|
|
|
{
|
|
|
|
// Bottom must be odd and 479px max
|
|
|
|
_uReturnValue = std::min((u16) 479, bbox[3]) | 1;
|
|
|
|
|
|
|
|
INFO_LOG(PIXELENGINE, "R: BBOX_BOTTOM = %i", _uReturnValue);
|
|
|
|
bbox_active = false;
|
|
|
|
break;
|
|
|
|
}
|
2010-06-09 01:37:08 +00:00
|
|
|
|
|
|
|
case PE_PERF_0L:
|
|
|
|
case PE_PERF_0H:
|
|
|
|
case PE_PERF_1L:
|
|
|
|
case PE_PERF_1H:
|
|
|
|
case PE_PERF_2L:
|
|
|
|
case PE_PERF_2H:
|
|
|
|
case PE_PERF_3L:
|
|
|
|
case PE_PERF_3H:
|
|
|
|
case PE_PERF_4L:
|
|
|
|
case PE_PERF_4H:
|
|
|
|
case PE_PERF_5L:
|
|
|
|
case PE_PERF_5H:
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) perf counter @ %08x", _iAddress);
|
2012-03-08 04:08:14 +00:00
|
|
|
// git r90a2096a24f4 (svn r3663) added the PE_PERF cases, without setting
|
|
|
|
// _uReturnValue to anything, this reverts to the previous behaviour which allows
|
|
|
|
// The timer in SMS:Scrubbing Serena Beach to countdown correctly
|
|
|
|
_uReturnValue = 1;
|
2010-06-09 01:37:08 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
INFO_LOG(PIXELENGINE, "(r16) unknown @ %08x", _iAddress);
|
|
|
|
_uReturnValue = 1;
|
|
|
|
break;
|
|
|
|
}
|
2010-12-13 07:56:54 +00:00
|
|
|
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Write16(const u16 _iValue, const u32 _iAddress)
|
|
|
|
{
|
|
|
|
switch (_iAddress & 0xFFF)
|
|
|
|
{
|
|
|
|
// CPU Direct Access EFB Raster State Config
|
|
|
|
case PE_ZCONF:
|
|
|
|
m_ZConf.Hex = _iValue;
|
|
|
|
INFO_LOG(PIXELENGINE, "(w16) ZCONF: %02x", _iValue);
|
|
|
|
break;
|
|
|
|
case PE_ALPHACONF:
|
|
|
|
m_AlphaConf.Hex = _iValue;
|
|
|
|
INFO_LOG(PIXELENGINE, "(w16) ALPHACONF: %02x", _iValue);
|
|
|
|
break;
|
|
|
|
case PE_DSTALPHACONF:
|
|
|
|
m_DstAlphaConf.Hex = _iValue;
|
|
|
|
INFO_LOG(PIXELENGINE, "(w16) DSTALPHACONF: %02x", _iValue);
|
|
|
|
break;
|
|
|
|
case PE_ALPHAMODE:
|
|
|
|
m_AlphaModeConf.Hex = _iValue;
|
|
|
|
INFO_LOG(PIXELENGINE, "(w16) ALPHAMODE: %02x", _iValue);
|
|
|
|
break;
|
|
|
|
case PE_ALPHAREAD:
|
|
|
|
m_AlphaRead.Hex = _iValue;
|
|
|
|
INFO_LOG(PIXELENGINE, "(w16) ALPHAREAD: %02x", _iValue);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PE_CTRL_REGISTER:
|
|
|
|
{
|
|
|
|
UPECtrlReg tmpCtrl(_iValue);
|
|
|
|
|
|
|
|
if (tmpCtrl.PEToken) g_bSignalTokenInterrupt = false;
|
|
|
|
if (tmpCtrl.PEFinish) g_bSignalFinishInterrupt = false;
|
|
|
|
|
|
|
|
m_Control.PETokenEnable = tmpCtrl.PETokenEnable;
|
|
|
|
m_Control.PEFinishEnable = tmpCtrl.PEFinishEnable;
|
|
|
|
m_Control.PEToken = 0; // this flag is write only
|
|
|
|
m_Control.PEFinish = 0; // this flag is write only
|
|
|
|
|
|
|
|
DEBUG_LOG(PIXELENGINE, "(w16) CTRL_REGISTER: 0x%04x", _iValue);
|
|
|
|
UpdateInterrupts();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PE_TOKEN_REG:
|
|
|
|
PanicAlert("(w16) WTF? PowerPC program wrote token: %i", _iValue);
|
|
|
|
//only the gx pipeline is supposed to be able to write here
|
|
|
|
//g_token = _iValue;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
WARN_LOG(PIXELENGINE, "(w16) unknown %04x @ %08x", _iValue, _iAddress);
|
|
|
|
break;
|
|
|
|
}
|
2010-12-13 07:56:54 +00:00
|
|
|
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Write32(const u32 _iValue, const u32 _iAddress)
|
|
|
|
{
|
|
|
|
WARN_LOG(PIXELENGINE, "(w32) 0x%08x @ 0x%08x IGNORING...",_iValue,_iAddress);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AllowIdleSkipping()
|
|
|
|
{
|
2011-01-31 01:28:32 +00:00
|
|
|
return !SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || (!m_Control.PETokenEnable && !m_Control.PEFinishEnable);
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateInterrupts()
|
|
|
|
{
|
|
|
|
// check if there is a token-interrupt
|
2010-12-13 07:56:54 +00:00
|
|
|
UpdateTokenInterrupt((g_bSignalTokenInterrupt & m_Control.PETokenEnable));
|
|
|
|
|
2010-06-09 01:37:08 +00:00
|
|
|
// check if there is a finish-interrupt
|
2010-12-13 07:56:54 +00:00
|
|
|
UpdateFinishInterrupt((g_bSignalFinishInterrupt & m_Control.PEFinishEnable));
|
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateTokenInterrupt(bool active)
|
|
|
|
{
|
2013-02-03 07:05:46 +00:00
|
|
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN, active);
|
|
|
|
interruptSetToken = active;
|
2010-12-13 07:56:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void UpdateFinishInterrupt(bool active)
|
|
|
|
{
|
2013-02-03 07:05:46 +00:00
|
|
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH, active);
|
|
|
|
interruptSetFinish = active;
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(mb2): Refactor SetTokenINT_OnMainThread(u64 userdata, int cyclesLate).
|
|
|
|
// Think about the right order between tokenVal and tokenINT... one day maybe.
|
|
|
|
// Cleanup++
|
|
|
|
|
|
|
|
// Called only if BPMEM_PE_TOKEN_INT_ID is ack by GP
|
|
|
|
void SetToken_OnMainThread(u64 userdata, int cyclesLate)
|
|
|
|
{
|
2013-02-03 07:05:46 +00:00
|
|
|
INFO_LOG(PIXELENGINE, "VIDEO Backend raises INT_CAUSE_PE_TOKEN (btw, token: %04x)", CommandProcessor::fifo.PEToken);
|
|
|
|
UpdateInterrupts();
|
|
|
|
CommandProcessor::interruptTokenWaiting = false;
|
|
|
|
IncrementCheckContextId();
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
|
|
|
|
{
|
|
|
|
UpdateInterrupts();
|
2010-12-13 07:56:54 +00:00
|
|
|
CommandProcessor::interruptFinishWaiting = false;
|
2011-02-10 04:47:02 +00:00
|
|
|
CommandProcessor::isPossibleWaitingSetDrawDone = false;
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetToken
|
|
|
|
// THIS IS EXECUTED FROM VIDEO THREAD
|
|
|
|
void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
|
|
|
|
{
|
2013-02-03 07:05:46 +00:00
|
|
|
// we do it directly from videoThread because of
|
|
|
|
// Super Monkey Ball
|
|
|
|
// XXX: No 16-bit atomic store available, so cheat and use 32-bit.
|
|
|
|
// That's what we've always done. We're counting on fifo.PEToken to be
|
|
|
|
// 4-byte padded.
|
|
|
|
Common::AtomicStore(*(volatile u32*)&CommandProcessor::fifo.PEToken, _token);
|
|
|
|
|
2010-06-09 01:37:08 +00:00
|
|
|
if (_bSetTokenAcknowledge) // set token INT
|
|
|
|
{
|
2010-12-13 07:56:54 +00:00
|
|
|
CommandProcessor::interruptTokenWaiting = true;
|
2011-01-31 01:28:32 +00:00
|
|
|
CoreTiming::ScheduleEvent_Threadsafe(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
|
2013-02-03 07:05:46 +00:00
|
|
|
g_bSignalTokenInterrupt = true;
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
2013-02-03 07:05:46 +00:00
|
|
|
|
2011-02-08 12:00:41 +00:00
|
|
|
IncrementCheckContextId();
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetFinish
|
|
|
|
// THIS IS EXECUTED FROM VIDEO THREAD (BPStructs.cpp) when a new frame has been drawn
|
|
|
|
void SetFinish()
|
|
|
|
{
|
2010-12-13 07:56:54 +00:00
|
|
|
CommandProcessor::interruptFinishWaiting = true;
|
2011-01-31 01:28:32 +00:00
|
|
|
CoreTiming::ScheduleEvent_Threadsafe(0, et_SetFinishOnMainThread, 0);
|
2013-02-03 07:05:46 +00:00
|
|
|
g_bSignalFinishInterrupt = true;
|
2010-06-09 01:37:08 +00:00
|
|
|
INFO_LOG(PIXELENGINE, "VIDEO Set Finish");
|
2011-02-08 12:00:41 +00:00
|
|
|
IncrementCheckContextId();
|
2010-06-09 01:37:08 +00:00
|
|
|
}
|
|
|
|
|
2010-07-28 02:57:17 +00:00
|
|
|
//This function is used in CommandProcessor when write CTRL_REGISTER and the new fifo is attached.
|
|
|
|
void ResetSetFinish()
|
|
|
|
{
|
|
|
|
//if SetFinish happened but PE_CTRL_REGISTER not, I reset the interrupt else
|
|
|
|
//remove event from the queque
|
|
|
|
if (g_bSignalFinishInterrupt)
|
|
|
|
{
|
2010-12-13 07:56:54 +00:00
|
|
|
UpdateFinishInterrupt(false);
|
2010-07-28 02:57:17 +00:00
|
|
|
g_bSignalFinishInterrupt = false;
|
2011-01-31 01:28:32 +00:00
|
|
|
}
|
|
|
|
else
|
2010-07-28 02:57:17 +00:00
|
|
|
{
|
2011-01-31 01:28:32 +00:00
|
|
|
CoreTiming::RemoveEvent(et_SetFinishOnMainThread);
|
2010-07-28 02:57:17 +00:00
|
|
|
}
|
2010-12-13 07:56:54 +00:00
|
|
|
CommandProcessor::interruptFinishWaiting = false;
|
2010-07-28 02:57:17 +00:00
|
|
|
}
|
|
|
|
|
2010-08-10 07:25:35 +00:00
|
|
|
void ResetSetToken()
|
|
|
|
{
|
|
|
|
if (g_bSignalTokenInterrupt)
|
|
|
|
{
|
2010-12-13 07:56:54 +00:00
|
|
|
UpdateTokenInterrupt(false);
|
2010-08-10 07:25:35 +00:00
|
|
|
g_bSignalTokenInterrupt = false;
|
2011-01-31 01:28:32 +00:00
|
|
|
}
|
|
|
|
else
|
2010-08-10 07:25:35 +00:00
|
|
|
{
|
2011-01-31 01:28:32 +00:00
|
|
|
CoreTiming::RemoveEvent(et_SetTokenOnMainThread);
|
2010-08-10 07:25:35 +00:00
|
|
|
}
|
2010-12-13 07:56:54 +00:00
|
|
|
CommandProcessor::interruptTokenWaiting = false;
|
2010-08-10 07:25:35 +00:00
|
|
|
}
|
- I've fixed possibles random hangs in DC mode.
- I've fixed hangs in DC mode in (Simpsons, Monkey Island, Pokemon XD, etc)
- I've implemented accurate manage of Pixel Engine Interrupts, now the GPU loop is stopped when a PE Interrupt needs to be managed and resume when Pixel Engine finish,
I think now, the Fifo in DC mode is more accurate than SC mode. :)
Time to close the big fifo Issue 3694 (snif), please if you have a possible fifo issue report this like a game issue.
I was working with Skid_AU together, especially thanks for him.
Test a lot all games, and compare the performance with the master maybe this accuracy has a cost (not a lot).
I think now the fifo is very stable, overflow fixed, random hang fixed, if you have a game with a hang with this rev and not in master please report this.
2012-03-08 05:47:55 +00:00
|
|
|
|
|
|
|
bool WaitingForPEInterrupt()
|
|
|
|
{
|
2012-03-19 01:54:58 +00:00
|
|
|
return !CommandProcessor::waitingForPEInterruptDisable && (CommandProcessor::interruptFinishWaiting || CommandProcessor::interruptTokenWaiting || interruptSetFinish || interruptSetToken);
|
- I've fixed possibles random hangs in DC mode.
- I've fixed hangs in DC mode in (Simpsons, Monkey Island, Pokemon XD, etc)
- I've implemented accurate manage of Pixel Engine Interrupts, now the GPU loop is stopped when a PE Interrupt needs to be managed and resume when Pixel Engine finish,
I think now, the Fifo in DC mode is more accurate than SC mode. :)
Time to close the big fifo Issue 3694 (snif), please if you have a possible fifo issue report this like a game issue.
I was working with Skid_AU together, especially thanks for him.
Test a lot all games, and compare the performance with the master maybe this accuracy has a cost (not a lot).
I think now the fifo is very stable, overflow fixed, random hang fixed, if you have a game with a hang with this rev and not in master please report this.
2012-03-08 05:47:55 +00:00
|
|
|
}
|
2010-06-09 01:37:08 +00:00
|
|
|
} // end of namespace PixelEngine
|