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:
rice1964 2009-09-20 03:29:43 +00:00
parent 7a8f6bdd6d
commit 81e7ce9ad2
8 changed files with 139 additions and 65 deletions

View File

@ -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 ??
}

View File

@ -402,7 +402,10 @@ void EndFrame()
return;
}
bFrameInProgress = false;
}
void Present()
{
if (dev)
{
dev->EndScene();

View File

@ -54,6 +54,7 @@ extern bool bFrameInProgress;
void Reset();
bool BeginFrame();
void EndFrame();
void Present();
void SwitchFullscreen(bool fullscreen);
bool IsFullscreen();
bool CanUseINTZ();

View File

@ -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

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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

View File

@ -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()