D3D: get rid of flickering in various games by changing way and time to flip backbuffer to frontbuffer. Also added some debugging messages. ZTP intro seems to be additionally 10%+ faster now, maybe only for me in windows mode.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4303 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
7a8f6bdd6d
commit
81e7ce9ad2
|
@ -23,6 +23,7 @@
|
|||
#include "VertexManager.h"
|
||||
#include "VertexShaderManager.h"
|
||||
#include "Utils.h"
|
||||
#include "debugger/debugger.h"
|
||||
|
||||
|
||||
bool textureChanged[8];
|
||||
|
@ -209,6 +210,9 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
|||
//TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
//else // To D3D Texture
|
||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_EFB_CMD,false,
|
||||
{printf("EFB to texture: addr = %08X\n",address);});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,8 +233,7 @@ void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
|||
|
||||
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
|
||||
{
|
||||
if (bpmem.blendmode.colorupdate || bpmem.blendmode.alphaupdate)
|
||||
col = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
col = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
clearflags |= D3DCLEAR_TARGET; // set to break animal crossing :p ??
|
||||
}
|
||||
|
||||
|
|
|
@ -402,7 +402,10 @@ void EndFrame()
|
|||
return;
|
||||
}
|
||||
bFrameInProgress = false;
|
||||
}
|
||||
|
||||
void Present()
|
||||
{
|
||||
if (dev)
|
||||
{
|
||||
dev->EndScene();
|
||||
|
|
|
@ -54,6 +54,7 @@ extern bool bFrameInProgress;
|
|||
void Reset();
|
||||
bool BeginFrame();
|
||||
void EndFrame();
|
||||
void Present();
|
||||
void SwitchFullscreen(bool fullscreen);
|
||||
bool IsFullscreen();
|
||||
bool CanUseINTZ();
|
||||
|
|
|
@ -118,32 +118,27 @@ private:
|
|||
};
|
||||
|
||||
enum PauseEvent {
|
||||
NEXT_FRAME,
|
||||
NEXT_FLUSH,
|
||||
NOT_PAUSE = 0,
|
||||
NEXT_FRAME = 1<<0,
|
||||
NEXT_FLUSH = 1<<1,
|
||||
|
||||
NEXT_PIXEL_SHADER_CHANGE,
|
||||
NEXT_VERTEX_SHADER_CHANGE,
|
||||
NEXT_TEXTURE_CHANGE,
|
||||
NEXT_NEW_TEXTURE,
|
||||
NEXT_PIXEL_SHADER_CHANGE = 1<<2,
|
||||
NEXT_VERTEX_SHADER_CHANGE = 1<<3,
|
||||
NEXT_TEXTURE_CHANGE = 1<<4,
|
||||
NEXT_NEW_TEXTURE = 1<<5,
|
||||
|
||||
NEXT_XFB_CMD,
|
||||
NEXT_EFB_CMD,
|
||||
NEXT_XFB_CMD = 1<<6,
|
||||
NEXT_EFB_CMD = 1<<7,
|
||||
|
||||
NEXT_MATRIX_CMD,
|
||||
NEXT_VERTEX_CMD,
|
||||
NEXT_TEXTURE_CMD,
|
||||
NEXT_LIGHT_CMD,
|
||||
NEXT_FOG_CMD,
|
||||
NEXT_MATRIX_CMD = 1<<8,
|
||||
NEXT_VERTEX_CMD = 1<<9,
|
||||
NEXT_TEXTURE_CMD = 1<<10,
|
||||
NEXT_LIGHT_CMD = 1<<11,
|
||||
NEXT_FOG_CMD = 1<<12,
|
||||
|
||||
NEXT_SET_TLUT,
|
||||
NEXT_SET_TLUT = 1<<13,
|
||||
|
||||
NEXT_FIFO,
|
||||
NEXT_DLIST,
|
||||
NEXT_UCODE,
|
||||
|
||||
NEXT_ERROR,
|
||||
|
||||
NOT_PAUSE,
|
||||
NEXT_ERROR = 1<<14,
|
||||
};
|
||||
|
||||
extern volatile bool DX9DebuggerPauseFlag;
|
||||
|
@ -160,13 +155,15 @@ void DX9DebuggerToPause(bool update);
|
|||
|
||||
#ifdef ENABLE_DX_DEBUGGER
|
||||
|
||||
#define DEBUGGER_PAUSE_AT(event,update) {if ((DX9DebuggerToPauseAtNext == event && --DX9DebuggerEventToPauseCount<=0) || DX9DebuggerPauseFlag) DX9DebuggerToPause(update);}
|
||||
#define DEBUGGER_PAUSE_LOG_AT(event,update,dumpfunc) {if ((DX9DebuggerToPauseAtNext == event && --DX9DebuggerEventToPauseCount<=0) || DX9DebuggerPauseFlag) {{dumpfunc};DX9DebuggerToPause(update);}}
|
||||
#define DEBUGGER_PAUSE_AT(event,update) {if (((DX9DebuggerToPauseAtNext & event) && --DX9DebuggerEventToPauseCount<=0) || DX9DebuggerPauseFlag) DX9DebuggerToPause(update);}
|
||||
#define DEBUGGER_PAUSE_LOG_AT(event,update,dumpfunc) {if (((DX9DebuggerToPauseAtNext & event) && --DX9DebuggerEventToPauseCount<=0) || DX9DebuggerPauseFlag) {{dumpfunc};DX9DebuggerToPause(update);}}
|
||||
#define DEBUGGER_LOG_AT(event,dumpfunc) {if (( DX9DebuggerToPauseAtNext & event ) ) {{dumpfunc};}}
|
||||
|
||||
#else
|
||||
// Not to use debugger in release build
|
||||
#define DEBUGGER_PAUSE_AT(event,update)
|
||||
#define DEBUGGER_PAUSE_LOG_AT(event,update,dumpfunc)
|
||||
#define DEBUGGER_LOG_AT(event,dumpfunc)
|
||||
|
||||
#endif ENABLE_DX_DEBUGGER
|
||||
|
||||
|
|
|
@ -157,6 +157,7 @@ void Renderer::Shutdown()
|
|||
{
|
||||
TeardownDeviceObjects();
|
||||
D3D::EndFrame();
|
||||
D3D::Present();
|
||||
D3D::Close();
|
||||
|
||||
if (s_AVIDumping)
|
||||
|
@ -319,6 +320,14 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
|||
D3D::dev->StretchRect(FBManager::GetEFBColorRTSurface(), src_rect.AsRECT(),
|
||||
D3D::GetBackBufferSurface(), dst_rect.AsRECT(),
|
||||
D3DTEXF_LINEAR);
|
||||
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME),
|
||||
{printf("StretchRect, EFB->XFB\n");});
|
||||
DEBUGGER_PAUSE_LOG_AT(
|
||||
(NEXT_XFB_CMD),false,
|
||||
{printf("RenderToXFB: addr = %08X, %d x %d, sourceRc = (%d,%d,%d,%d)\n",
|
||||
xfbAddr, fbWidth, fbHeight,
|
||||
sourceRc.left, sourceRc.top, sourceRc.right, sourceRc.bottom);}
|
||||
);
|
||||
|
||||
// Finish up the current frame, print some stats
|
||||
if (g_ActiveConfig.bOverlayStats)
|
||||
|
@ -335,34 +344,11 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
|||
OSD::DrawMessages();
|
||||
D3D::EndFrame();
|
||||
|
||||
// D3D frame is now over
|
||||
// Clean out old stuff from caches.
|
||||
frameCount++;
|
||||
PixelShaderCache::Cleanup();
|
||||
VertexShaderCache::Cleanup();
|
||||
TextureCache::Cleanup();
|
||||
|
||||
// Make any new configuration settings active.
|
||||
UpdateActiveConfig();
|
||||
|
||||
// TODO: Resize backbuffer if window size has changed. This code crashes, debug it.
|
||||
g_VideoInitialize.pCopiedToXFB(false);
|
||||
|
||||
CheckForResize();
|
||||
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_XFB_CMD,false,{printf("RenderToXFB");});
|
||||
DEBUGGER_PAUSE_AT(NEXT_FRAME,false);
|
||||
|
||||
|
||||
|
||||
// Begin new frame
|
||||
// Set default viewport and scissor, for the clear to work correctly
|
||||
stats.ResetFrame();
|
||||
// u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
D3D::BeginFrame();
|
||||
|
||||
// Clear backbuffer. We probably don't need to do this every frame.
|
||||
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0);
|
||||
// Clear the render target. We probably don't need to do this every frame.
|
||||
//D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0);
|
||||
|
||||
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
|
||||
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
||||
|
@ -376,6 +362,9 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
|||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, false);
|
||||
|
||||
UpdateViewport();
|
||||
|
||||
//Swap(0,FIELD_PROGRESSIVE,0,0); // we used to swap the buffer here, now we will wait
|
||||
// until the XFB pointer is updated by VI
|
||||
}
|
||||
|
||||
bool Renderer::SetScissorRect()
|
||||
|
@ -529,3 +518,33 @@ void UpdateViewport()
|
|||
|
||||
D3D::dev->SetViewport(&vp);
|
||||
}
|
||||
|
||||
void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
// this function is called after the XFB field is changed, not after
|
||||
// EFB is copied to XFB. In this way, flickering is reduced in games
|
||||
// and seems to also give more FPS in ZTP
|
||||
|
||||
// D3D frame is now over
|
||||
// Clean out old stuff from caches.
|
||||
frameCount++;
|
||||
PixelShaderCache::Cleanup();
|
||||
VertexShaderCache::Cleanup();
|
||||
TextureCache::Cleanup();
|
||||
|
||||
// Make any new configuration settings active.
|
||||
UpdateActiveConfig();
|
||||
|
||||
//TODO: Resize backbuffer if window size has changed. This code crashes, debug it.
|
||||
g_VideoInitialize.pCopiedToXFB(false);
|
||||
|
||||
CheckForResize();
|
||||
|
||||
|
||||
// Begin new frame
|
||||
// Set default viewport and scissor, for the clear to work correctly
|
||||
stats.ResetFrame();
|
||||
|
||||
// Flip/present backbuffer to frontbuffer here
|
||||
D3D::Present();
|
||||
}
|
||||
|
|
|
@ -317,4 +317,8 @@ have_texture:
|
|||
srcSurface = FBManager::GetEFBColorRTSurface();
|
||||
D3D::dev->StretchRect(srcSurface, &source_rc, destSurface, &dest_rc, D3DTEXF_LINEAR);
|
||||
destSurface->Release();
|
||||
|
||||
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME|NEXT_NEW_TEXTURE|NEXT_FLUSH),
|
||||
{printf("StretchRect, EFB (%d,%d) -> Texture at 0x%08X (%d,%d)\n",efb_w,efb_h,address,tex_w,tex_h);});
|
||||
DEBUGGER_PAUSE_AT((NEXT_EFB_CMD|NEXT_NEW_TEXTURE),false);
|
||||
}
|
||||
|
|
|
@ -273,7 +273,10 @@ void Flush()
|
|||
PixelShaderManager::SetTexDims(i, tentry->w, tentry->h, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to load texture\n");});
|
||||
ERROR_LOG(VIDEO, "error loading texture");
|
||||
}
|
||||
}
|
||||
}
|
||||
PixelShaderManager::SetTexturesUsed(0);
|
||||
|
@ -285,10 +288,17 @@ void Flush()
|
|||
VertexShaderManager::SetConstants();
|
||||
PixelShaderManager::SetConstants();
|
||||
|
||||
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
|
||||
goto shader_fail;
|
||||
if (!PixelShaderCache::SetShader(false))
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||
goto shader_fail;
|
||||
}
|
||||
if (!VertexShaderCache::SetShader(g_nativeVertexFmt->m_components))
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set vertex shader\n");});
|
||||
goto shader_fail;
|
||||
|
||||
}
|
||||
|
||||
int stride = g_nativeVertexFmt->GetVertexStride();
|
||||
g_nativeVertexFmt->SetupVertexPointers();
|
||||
|
@ -299,7 +309,11 @@ void Flush()
|
|||
{
|
||||
DWORD write = 0;
|
||||
if (!PixelShaderCache::SetShader(true))
|
||||
{
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR,true,{printf("Fail to set pixel shader\n");});
|
||||
goto shader_fail;
|
||||
}
|
||||
|
||||
// update alpha only
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
|
||||
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
|
@ -315,13 +329,12 @@ void Flush()
|
|||
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, write);
|
||||
}
|
||||
DEBUGGER_PAUSE_AT(NEXT_FLUSH,true);
|
||||
}
|
||||
shader_fail:
|
||||
collection = C_NOTHING;
|
||||
VertexManager::s_pCurBufferPointer = fakeVBuffer;
|
||||
DEBUGGER_PAUSE_AT(NEXT_FLUSH,true);
|
||||
}
|
||||
//DX9DEBUGGER_PAUSE_IF(NEXT_FLUSH);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "Thread.h"
|
||||
#include "LogManager.h"
|
||||
#include "GlobalControl.h"
|
||||
#include "debugger/debugger.h"
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "Debugger/Debugger.h"
|
||||
|
@ -52,6 +53,8 @@ GFXDebuggerDX9 *m_DebuggerFrame = NULL;
|
|||
#include "EmuWindow.h"
|
||||
#include "VideoState.h"
|
||||
#include "XFBConvert.h"
|
||||
#include "render.h"
|
||||
|
||||
|
||||
// Having to include this is TERRIBLY ugly. FIXME x100
|
||||
#include "../../../Core/Core/Src/ConfigManager.h" // FIXME
|
||||
|
@ -64,6 +67,14 @@ PLUGIN_GLOBALS* globals = NULL;
|
|||
bool s_initialized;
|
||||
|
||||
static u32 s_efbAccessRequested = FALSE;
|
||||
static bool s_swapRequested = false;
|
||||
static volatile struct
|
||||
{
|
||||
u32 xfbAddr;
|
||||
FieldType field;
|
||||
u32 fbWidth;
|
||||
u32 fbHeight;
|
||||
} s_beginFieldArgs;
|
||||
|
||||
static volatile EFBAccessType s_AccessEFBType;
|
||||
|
||||
|
@ -308,31 +319,54 @@ void Video_SendFifoData(u8* _uData, u32 len)
|
|||
Fifo_SendFifoData(_uData, len);
|
||||
}
|
||||
|
||||
// Run from the graphics thread
|
||||
void VideoFifo_CheckSwapRequest()
|
||||
{
|
||||
// CPU swap unimplemented
|
||||
// CPU swap, not finished, seems to be working fine for dual-core for now
|
||||
|
||||
if (s_swapRequested)
|
||||
{
|
||||
// Flip the backbuffer to front buffer now
|
||||
s_swapRequested = false;
|
||||
if (s_beginFieldArgs.field == FIELD_PROGRESSIVE || s_beginFieldArgs.field == FIELD_LOWER)
|
||||
{
|
||||
Renderer::Swap(0,FIELD_PROGRESSIVE,0,0); // The swap function is not finished
|
||||
// so it is ok to pass dummy parameters for now
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run from the graphics thread
|
||||
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
// CPU swap unimplemented
|
||||
}
|
||||
|
||||
// Run from the CPU thread (from VideoInterface.cpp)
|
||||
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
|
||||
{
|
||||
/*
|
||||
ConvertXFB(tempBuffer, _pXFB, _dwWidth, _dwHeight);
|
||||
s_beginFieldArgs.xfbAddr = xfbAddr;
|
||||
s_beginFieldArgs.field = field;
|
||||
s_beginFieldArgs.fbWidth = fbWidth;
|
||||
s_beginFieldArgs.fbHeight = fbHeight;
|
||||
s_swapRequested = true;
|
||||
|
||||
// blubb
|
||||
static LPDIRECT3DTEXTURE9 pTexture = D3D::CreateTexture2D((BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8);
|
||||
if (s_initialized)
|
||||
{
|
||||
|
||||
D3D::ReplaceTexture2D(pTexture, (BYTE*)tempBuffer, _dwWidth, _dwHeight, _dwWidth, D3DFMT_A8R8G8B8);
|
||||
D3D::dev->SetTexture(0, pTexture);
|
||||
// Make sure previous swap request has made it to the screen
|
||||
if (g_VideoInitialize.bUseDualCore)
|
||||
{
|
||||
// It seems to be working fine in this way for now without using AtomicLoadAcquire
|
||||
// ector, please check here
|
||||
//while (Common::AtomicLoadAcquire(s_swapRequested))
|
||||
// Common::YieldCPU();
|
||||
}
|
||||
else
|
||||
VideoFifo_CheckSwapRequest();
|
||||
|
||||
D3D::quad2d(0,0,(float)Postprocess::GetWidth(),(float)Postprocess::GetHeight(), 0xFFFFFFFF);
|
||||
|
||||
D3D::EndFrame();
|
||||
D3D::BeginFrame();*/
|
||||
}
|
||||
DEBUGGER_LOG_AT(NEXT_XFB_CMD,{printf("Begin Field: %08x, %d x %d\n",xfbAddr,fbWidth,fbHeight);});
|
||||
}
|
||||
|
||||
void Video_EndField()
|
||||
|
|
Loading…
Reference in New Issue