mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-11 00:40:16 +00:00
EFB Access now works from both Dual Core and Single Core modes. Thread-safe.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3644 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
ae2a5b8587
commit
7a05aafe39
@ -32,6 +32,8 @@
|
||||
volatile u32 g_XFBUpdateRequested = FALSE;
|
||||
extern u8* g_pVideoData;
|
||||
|
||||
volatile bool g_EFBAccessRequested = false;
|
||||
|
||||
namespace {
|
||||
|
||||
static volatile bool fifoStateRun = false;
|
||||
@ -139,6 +141,12 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
|
||||
video_initialize.pPeekMessages();
|
||||
#endif
|
||||
|
||||
if (g_EFBAccessRequested)
|
||||
{
|
||||
Video_OnThreadAccessEFB();
|
||||
g_EFBAccessRequested = false;
|
||||
}
|
||||
|
||||
// Draw XFB if CP/GPfifo isn't used
|
||||
if (g_XFBUpdateRequested)
|
||||
{
|
||||
|
@ -57,6 +57,8 @@ extern SVideoInitialize g_VideoInitialize;
|
||||
// (mb2) for XFB update hack. TODO: find a static better place
|
||||
extern volatile u32 g_XFBUpdateRequested;
|
||||
|
||||
extern volatile bool g_EFBAccessRequested;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
inline u8 *Memory_GetPtr(u32 _uAddress)
|
||||
{
|
||||
|
@ -126,6 +126,7 @@ EXPORT void CALL Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s3
|
||||
// output: response to the access request (ex: peek z data at specified coord)
|
||||
//
|
||||
EXPORT u32 CALL Video_AccessEFB(EFBAccessType type, u32 x, u32 y);
|
||||
void Video_OnThreadAccessEFB(); // TODO: Find a more sympathetic place to place this
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// Function: Video_Screenshot
|
||||
|
@ -87,8 +87,7 @@ _lRestart:
|
||||
else
|
||||
PB.RemLength -= pos[1];
|
||||
|
||||
PB.CurAddr += pos[1] << 1;
|
||||
// There should be a position fraction as well.
|
||||
//PB.CurSampleFrac = TrueSamplePosition & 0xFFFF;
|
||||
}
|
||||
|
||||
|
||||
|
@ -907,7 +907,6 @@ void Renderer::Swap(u32 xfbAddr, u32 srcWidth, u32 srcHeight, s32 yOffset)
|
||||
s_bLastFrameDumped = false;
|
||||
}
|
||||
#endif
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
// Place messages on the picture, then copy it to the screen
|
||||
SwapBuffers();
|
||||
|
@ -96,6 +96,11 @@ int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||
|
||||
static bool s_PluginInitialized = false;
|
||||
|
||||
static volatile u32 s_AccessEFBResult = 0, s_EFBx, s_EFBy;
|
||||
static volatile EFBAccessType s_AccessEFBType;
|
||||
static Common::Event s_AccessEFBDone;
|
||||
static Common::CriticalSection s_criticalEFB;
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
void DllDebugger(HWND _hParent, bool Show)
|
||||
{
|
||||
@ -458,36 +463,36 @@ void Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset
|
||||
}
|
||||
}
|
||||
|
||||
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
|
||||
void Video_OnThreadAccessEFB()
|
||||
{
|
||||
switch (type)
|
||||
s_criticalEFB.Enter();
|
||||
s_AccessEFBResult = 0;
|
||||
|
||||
switch (s_AccessEFBType)
|
||||
{
|
||||
case PEEK_Z:
|
||||
{
|
||||
if (!g_VideoInitialize.bUseDualCore)
|
||||
u32 z = 0;
|
||||
float xScale = Renderer::GetTargetScaleX();
|
||||
float yScale = Renderer::GetTargetScaleY();
|
||||
|
||||
if (g_Config.iMultisampleMode != MULTISAMPLE_OFF)
|
||||
{
|
||||
u32 z = 0;
|
||||
float xScale = Renderer::GetTargetScaleX();
|
||||
float yScale = Renderer::GetTargetScaleY();
|
||||
|
||||
if (g_Config.iMultisampleMode != MULTISAMPLE_OFF)
|
||||
{
|
||||
// Find the proper dimensions
|
||||
TRectangle source, scaledTargetSource;
|
||||
ComputeBackbufferRectangle(&source);
|
||||
source.Scale(xScale, yScale, &scaledTargetSource);
|
||||
// This will resolve and bind to the depth buffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Renderer::ResolveAndGetDepthTarget(scaledTargetSource));
|
||||
}
|
||||
|
||||
// Read the z value! Also adjust the pixel to read to the upscaled EFB resolution
|
||||
// Plus we need to flip the y value as the OGL image is upside down
|
||||
glReadPixels(x*xScale, Renderer::GetTargetHeight() - y*yScale, xScale, yScale, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z);
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// Clamp the 32bits value returned by glReadPixels to a 24bits value (GC uses a 24bits Z-Buffer)
|
||||
return z / 0x100;
|
||||
// Find the proper dimensions
|
||||
TRectangle source, scaledTargetSource;
|
||||
ComputeBackbufferRectangle(&source);
|
||||
source.Scale(xScale, yScale, &scaledTargetSource);
|
||||
// This will resolve and bind to the depth buffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Renderer::ResolveAndGetDepthTarget(scaledTargetSource));
|
||||
}
|
||||
|
||||
// Read the z value! Also adjust the pixel to read to the upscaled EFB resolution
|
||||
// Plus we need to flip the y value as the OGL image is upside down
|
||||
glReadPixels(s_EFBx*xScale, Renderer::GetTargetHeight() - s_EFBy*yScale, xScale, yScale, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z);
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// Clamp the 32bits value returned by glReadPixels to a 24bits value (GC uses a 24bits Z-Buffer)
|
||||
s_AccessEFBResult = z / 0x100;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -503,6 +508,42 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
||||
s_AccessEFBDone.Set();
|
||||
|
||||
s_criticalEFB.Leave();
|
||||
}
|
||||
|
||||
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
|
||||
{
|
||||
u32 result;
|
||||
|
||||
s_criticalEFB.Enter();
|
||||
|
||||
s_AccessEFBType = type;
|
||||
s_EFBx = x;
|
||||
s_EFBy = y;
|
||||
|
||||
if (g_VideoInitialize.bUseDualCore)
|
||||
{
|
||||
g_EFBAccessRequested = true;
|
||||
s_AccessEFBDone.Init();
|
||||
}
|
||||
|
||||
s_criticalEFB.Leave();
|
||||
|
||||
if (g_VideoInitialize.bUseDualCore)
|
||||
s_AccessEFBDone.Wait();
|
||||
else
|
||||
Video_OnThreadAccessEFB();
|
||||
|
||||
s_criticalEFB.Enter();
|
||||
if (g_VideoInitialize.bUseDualCore)
|
||||
s_AccessEFBDone.Shutdown();
|
||||
|
||||
result = s_AccessEFBResult;
|
||||
s_criticalEFB.Leave();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user