mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Switch to Video_BeginField; hopefully fix or reduce some video stability problems by using Events.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3740 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -24,7 +24,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
||||
{
|
||||
Video_Prepare = 0;
|
||||
Video_SendFifoData = 0;
|
||||
Video_UpdateXFB = 0;
|
||||
Video_BeginField = 0;
|
||||
Video_EnterLoop = 0;
|
||||
Video_ExitLoop = 0;
|
||||
Video_Screenshot = 0;
|
||||
@ -35,8 +35,8 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
||||
(LoadSymbol("Video_Prepare"));
|
||||
Video_SendFifoData = reinterpret_cast<TVideo_SendFifoData>
|
||||
(LoadSymbol("Video_SendFifoData"));
|
||||
Video_UpdateXFB = reinterpret_cast<TVideo_UpdateXFB>
|
||||
(LoadSymbol("Video_UpdateXFB"));
|
||||
Video_BeginField = reinterpret_cast<TVideo_BeginField>
|
||||
(LoadSymbol("Video_BeginField"));
|
||||
Video_Screenshot = reinterpret_cast<TVideo_Screenshot>
|
||||
(LoadSymbol("Video_Screenshot"));
|
||||
Video_EnterLoop = reinterpret_cast<TVideo_EnterLoop>
|
||||
@ -50,7 +50,7 @@ PluginVideo::PluginVideo(const char *_Filename) : CPlugin(_Filename), validVideo
|
||||
|
||||
if ((Video_Prepare != 0) &&
|
||||
(Video_SendFifoData != 0) &&
|
||||
(Video_UpdateXFB != 0) &&
|
||||
(Video_BeginField != 0) &&
|
||||
(Video_EnterLoop != 0) &&
|
||||
(Video_ExitLoop != 0) &&
|
||||
(Video_Screenshot != 0) &&
|
||||
|
@ -25,7 +25,7 @@ namespace Common {
|
||||
|
||||
typedef void (__cdecl* TVideo_Prepare)();
|
||||
typedef void (__cdecl* TVideo_SendFifoData)(u8*,u32);
|
||||
typedef void (__cdecl* TVideo_UpdateXFB)(u32, u32, u32, s32, bool);
|
||||
typedef void (__cdecl* TVideo_BeginField)(u32, FieldType, u32, u32);
|
||||
typedef bool (__cdecl* TVideo_Screenshot)(const char* filename);
|
||||
typedef void (__cdecl* TVideo_EnterLoop)();
|
||||
typedef void (__cdecl* TVideo_ExitLoop)();
|
||||
@ -43,7 +43,7 @@ public:
|
||||
TVideo_SendFifoData Video_SendFifoData;
|
||||
TVideo_EnterLoop Video_EnterLoop;
|
||||
TVideo_ExitLoop Video_ExitLoop;
|
||||
TVideo_UpdateXFB Video_UpdateXFB;
|
||||
TVideo_BeginField Video_BeginField;
|
||||
TVideo_AccessEFB Video_AccessEFB;
|
||||
|
||||
TVideo_AddMessage Video_AddMessage;
|
||||
|
@ -71,6 +71,18 @@
|
||||
|
||||
namespace Common
|
||||
{
|
||||
|
||||
// MemFence: Neither the compiler nor the CPU can reorder memory accesses
|
||||
// beyond this barrier.
|
||||
__forceinline void MemFence()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MemoryBarrier();
|
||||
#else
|
||||
// TODO: UNIX experts, please implement the memory fence.
|
||||
#endif
|
||||
}
|
||||
|
||||
class CriticalSection
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -987,15 +987,7 @@ void GenerateVIInterrupt(VIInterruptType _VIInterrupt)
|
||||
}
|
||||
}
|
||||
|
||||
u8* GetXFBPointerTop()
|
||||
{
|
||||
if (m_XFBInfoTop.POFF)
|
||||
return Memory::GetPointer(m_XFBInfoTop.FBB << 5);
|
||||
else
|
||||
return Memory::GetPointer(m_XFBInfoTop.FBB);
|
||||
}
|
||||
|
||||
u32 GetXFBPointerTop_GC()
|
||||
u32 GetXFBAddressTop()
|
||||
{
|
||||
if (m_XFBInfoTop.POFF)
|
||||
return m_XFBInfoTop.FBB << 5;
|
||||
@ -1003,16 +995,7 @@ u32 GetXFBPointerTop_GC()
|
||||
return m_XFBInfoTop.FBB;
|
||||
}
|
||||
|
||||
u8* GetXFBPointerBottom()
|
||||
{
|
||||
// POFF for XFB bottom is connected to POFF for XFB top
|
||||
if (m_XFBInfoTop.POFF)
|
||||
return Memory::GetPointer(m_XFBInfoBottom.FBB << 5);
|
||||
else
|
||||
return Memory::GetPointer(m_XFBInfoBottom.FBB);
|
||||
}
|
||||
|
||||
u32 GetXFBPointerBottom_GC()
|
||||
u32 GetXFBAddressBottom()
|
||||
{
|
||||
// POFF for XFB bottom is connected to POFF for XFB top
|
||||
if (m_XFBInfoTop.POFF)
|
||||
@ -1058,6 +1041,25 @@ int getTicksPerLine() {
|
||||
}
|
||||
|
||||
|
||||
static void BeginField(u32 xfbAddr, FieldType field)
|
||||
{
|
||||
static const char* const fieldTypeNames[] = { "Progressive", "Upper", "Lower" };
|
||||
DEBUG_LOG(VIDEOINTERFACE, "(VI->BeginField): addr: %.08X | FieldSteps %u | FbSteps %u | ACV %u | Field %s",
|
||||
xfbAddr, m_HorizontalStepping.FieldSteps, m_HorizontalStepping.FbSteps, m_VerticalTimingRegister.ACV,
|
||||
fieldTypeNames[field]
|
||||
);
|
||||
|
||||
u32 fbWidth = m_HorizontalStepping.FieldSteps * 16;
|
||||
u32 fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
|
||||
|
||||
Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo();
|
||||
if (xfbAddr && video->IsValid())
|
||||
{
|
||||
video->Video_BeginField(xfbAddr, field, fbWidth, fbHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Purpose 1: Send VI interrupt for every screen refresh
|
||||
// Purpose 2: Execute XFB copy in homebrew games
|
||||
// Run when: This is run 7200 times per second on full speed
|
||||
@ -1094,57 +1096,32 @@ void Update()
|
||||
|
||||
if (m_VBeamPos == NextXFBRender)
|
||||
{
|
||||
u32 xfbAddr = 0;
|
||||
int yOffset = 0;
|
||||
|
||||
if (NextXFBRender == 1)
|
||||
{
|
||||
NextXFBRender = LinesPerField;
|
||||
// TODO: proper VI regs typedef and logic for XFB to work.
|
||||
// eg. Animal Crossing gc have smth in TFBL.XOF bitfield.
|
||||
// "XOF - Horizontal Offset of the left-most pixel within the first word of the fetched picture."
|
||||
xfbAddr = GetXFBPointerTop_GC();
|
||||
u32 xfbAddr = GetXFBAddressTop();
|
||||
BeginField(xfbAddr, m_DisplayControlRegister.NIN ? FIELD_PROGRESSIVE : FIELD_UPPER);
|
||||
}
|
||||
else
|
||||
{
|
||||
NextXFBRender = 1;
|
||||
// Previously checked m_XFBInfoTop.POFF then used m_XFBInfoBottom.FBB, try reverting if there are problems
|
||||
xfbAddr = GetXFBPointerBottom_GC();
|
||||
yOffset = -1;
|
||||
}
|
||||
|
||||
Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo();
|
||||
|
||||
if (xfbAddr && video->IsValid())
|
||||
{
|
||||
int fbWidth = m_HorizontalStepping.FieldSteps * 16;
|
||||
int fbHeight = (m_HorizontalStepping.FbSteps / m_HorizontalStepping.FieldSteps) * m_VerticalTimingRegister.ACV;
|
||||
|
||||
DEBUG_LOG(VIDEOINTERFACE, "(VI->XFBUpdate): ptr: %.08X | %ix%i | xoff: %i",
|
||||
xfbAddr, fbWidth, fbHeight, m_XFBInfoTop.XOFF);
|
||||
|
||||
if (Core::GetStartupParameter().bUseDualCore)
|
||||
// scheduled on EmuThread in DC mode
|
||||
video->Video_UpdateXFB(xfbAddr, fbWidth, fbHeight, yOffset, TRUE);
|
||||
else
|
||||
// otherwise do it now from here (CPUthread)
|
||||
video->Video_UpdateXFB(xfbAddr, fbWidth, fbHeight, yOffset, FALSE);
|
||||
u32 xfbAddr = GetXFBAddressBottom();
|
||||
BeginField(xfbAddr, m_DisplayControlRegister.NIN ? FIELD_PROGRESSIVE : FIELD_LOWER);
|
||||
}
|
||||
}
|
||||
|
||||
// check INT_PRERETRACE
|
||||
if (m_InterruptRegister[0].VCT == m_VBeamPos)
|
||||
{
|
||||
m_InterruptRegister[0].IR_INT = 1;
|
||||
UpdateInterrupts();
|
||||
}
|
||||
|
||||
// INT_POSTRETRACE
|
||||
if (m_InterruptRegister[1].VCT == m_VBeamPos)
|
||||
{
|
||||
m_InterruptRegister[1].IR_INT = 1;
|
||||
UpdateInterrupts();
|
||||
}
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (m_InterruptRegister[i].VCT == m_VBeamPos)
|
||||
{
|
||||
m_InterruptRegister[i].IR_INT = 1;
|
||||
UpdateInterrupts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include "Fifo.h"
|
||||
|
||||
|
||||
// TODO (mb2): move/rm this global
|
||||
volatile u32 g_XFBUpdateRequested = FALSE;
|
||||
extern u8* g_pVideoData;
|
||||
|
||||
volatile bool g_EFBAccessRequested = false;
|
||||
@ -63,7 +61,6 @@ void Fifo_Init()
|
||||
videoBuffer = (u8*)AllocateMemoryPages(FIFO_SIZE);
|
||||
fifo_exit_event.Init();
|
||||
fifoStateRun = false;
|
||||
g_XFBUpdateRequested = FALSE;
|
||||
}
|
||||
|
||||
void Fifo_Shutdown()
|
||||
@ -147,10 +144,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
#endif
|
||||
|
||||
// Draw XFB if CP/GPfifo isn't used
|
||||
if (g_XFBUpdateRequested)
|
||||
{
|
||||
Video_UpdateXFB(NULL, 0, 0, 0, FALSE);
|
||||
}
|
||||
VideoFifo_CheckSwapRequest();
|
||||
|
||||
if (g_EFBAccessRequested)
|
||||
{
|
||||
|
@ -37,4 +37,8 @@ void Fifo_ExitLoopNonBlocking();
|
||||
|
||||
void Fifo_DoState(PointerWrap &f);
|
||||
|
||||
// Implemented by the Video Plugin
|
||||
void VideoFifo_CheckSwapRequest();
|
||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user