Fix screen flickering with frameskip on D3D plugin, also fix occasional hang when turning frameskip off
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4194 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
08d3dee74c
commit
5a21d72693
|
@ -231,7 +231,7 @@ void Stop() // - Hammertime!
|
|||
}
|
||||
|
||||
// Video_EnterLoop() should now exit so that EmuThread() will continue concurrently with the rest
|
||||
// of the commands in this function. We no longer rely on Postmessage. */
|
||||
// of the commands in this function. We no longer rely on Postmessage.
|
||||
|
||||
// Close the trace file
|
||||
Core::StopTrace();
|
||||
|
@ -698,7 +698,7 @@ void Callback_VideoCopiedToXFB(bool video_update)
|
|||
|
||||
int TargetVPS = (int)(VideoInterface::TargetRefreshRate + 0.5);
|
||||
|
||||
float Speed = (VPS / TargetVPS) * 100.0f;
|
||||
float Speed = ((VPS > 0 ? VPS : VideoInterface::ActualRefreshRate) / TargetVPS) * 100.0f;
|
||||
|
||||
// Settings are shown the same for both extended and summary info
|
||||
std::string SSettings = StringFromFormat(" | Core: %s %s",
|
||||
|
|
|
@ -77,6 +77,11 @@ void SetFrameSkipping(unsigned int framesToSkip) {
|
|||
g_framesToSkip = (int)framesToSkip;
|
||||
g_frameSkipCounter = 0;
|
||||
|
||||
// Don't forget to re-enable rendering in case it wasn't...
|
||||
// as this won't be changed anymore when frameskip is turned off
|
||||
if (framesToSkip == 0)
|
||||
CPluginManager::GetInstance().GetVideo()->Video_SetRendering(true);
|
||||
|
||||
cs_frameSkip.Leave();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ void SetBlendMode(const BPCmd &bp);
|
|||
void SetDitherMode(const BPCmd &bp);
|
||||
void SetLogicOpMode(const BPCmd &bp);
|
||||
void SetColorMask(const BPCmd &bp);
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const bool &scaleByHalf);
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf);
|
||||
void RenderToXFB(const BPCmd &bp, const EFBRectangle &rc, const float &yScale, const float &xfbLines, u32 xfbAddr, const u32 &dstWidth, const u32 &dstHeight);
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
|
||||
void RestoreRenderState(const BPCmd &bp);
|
||||
|
|
|
@ -204,7 +204,7 @@ void BPWritten(const BPCmd& bp)
|
|||
bpmem.zcontrol.pixel_format == PIXELFMT_Z24,
|
||||
PE_copy.intensity_fmt > 0,
|
||||
((PE_copy.target_pixel_format / 2) + ((PE_copy.target_pixel_format & 1) * 8)),
|
||||
PE_copy.half_scale > 0);
|
||||
PE_copy.half_scale);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -205,7 +205,7 @@ void SetColorMask(const BPCmd &bp)
|
|||
Renderer::SetColorMask();
|
||||
}
|
||||
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const bool &scaleByHalf)
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||
{
|
||||
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "EmuWindow.h"
|
||||
#include "AVIDump.h"
|
||||
#include "OnScreenDisplay.h"
|
||||
#include "Fifo.h"
|
||||
|
||||
#include "debugger/debugger.h"
|
||||
|
||||
|
@ -149,6 +150,9 @@ void formatBufferDump(const char *in, char *out, int w, int h, int p)
|
|||
|
||||
void Renderer::SwapBuffers()
|
||||
{
|
||||
if (g_bSkipCurrentFrame)
|
||||
return;
|
||||
|
||||
// Center window again.
|
||||
if (EmuWindow::GetParentWnd())
|
||||
{
|
||||
|
|
|
@ -266,14 +266,13 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
|||
}
|
||||
|
||||
// EXTREMELY incomplete.
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect)
|
||||
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
|
||||
{
|
||||
int efb_w = source_rect.GetWidth();
|
||||
int efb_h = source_rect.GetHeight();
|
||||
|
||||
int mult = bScaleByHalf ? 2 : 1;
|
||||
int tex_w = (abs(source_rect.GetWidth()) / mult);
|
||||
int tex_h = (abs(source_rect.GetHeight()) / mult);
|
||||
int tex_w = (abs(source_rect.GetWidth()) >> bScaleByHalf);
|
||||
int tex_h = (abs(source_rect.GetHeight()) >> bScaleByHalf);
|
||||
|
||||
TexCache::iterator iter;
|
||||
LPDIRECT3DTEXTURE9 tex;
|
||||
|
@ -282,7 +281,6 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
|||
{
|
||||
if (!iter->second.isRenderTarget)
|
||||
{
|
||||
ERROR_LOG(VIDEO, "Using non-rendertarget texture as render target!!! WTF?", FALSE);
|
||||
// Remove it and recreate it as a render target
|
||||
iter->second.texture->Release();
|
||||
iter->second.texture = 0;
|
||||
|
@ -305,7 +303,6 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
|||
entry.w = tex_w;
|
||||
entry.h = tex_h;
|
||||
|
||||
// TODO(ector): infer this size in some sensible way
|
||||
D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
|
||||
textures[address] = entry;
|
||||
tex = entry.texture;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
static void Shutdown();
|
||||
static void Invalidate(bool shutdown);
|
||||
static TCacheEntry *Load(int stage, u32 address, int width, int height, int format, int tlutaddr, int tlutfmt);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -116,7 +116,7 @@ void SetColorMask(const BPCmd &bp)
|
|||
Renderer::SetColorMask();
|
||||
}
|
||||
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const bool &scaleByHalf)
|
||||
void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const bool &fromZBuffer, const bool &isIntensityFmt, const u32 ©fmt, const int &scaleByHalf)
|
||||
{
|
||||
// bpmem.zcontrol.pixel_format to PIXELFMT_Z24 is when the game wants to copy from ZBuffer (Zbuffer uses 24-bit Format)
|
||||
if (!g_Config.bEFBCopyDisable)
|
||||
|
|
|
@ -199,6 +199,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
|||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
glViewport(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight);
|
||||
|
@ -231,7 +232,7 @@ void EncodeToRamUsingShader(FRAGMENTSHADER& shader, GLuint srcTexture, const Tar
|
|||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle& source)
|
||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle& source)
|
||||
{
|
||||
u32 format = copyfmt;
|
||||
|
||||
|
@ -254,24 +255,15 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
|||
u8 *dest_ptr = Memory_GetPtr(address);
|
||||
|
||||
GLuint source_texture = bFromZBuffer ? g_framebufferManager.ResolveAndGetDepthTarget(source) : g_framebufferManager.ResolveAndGetRenderTarget(source);
|
||||
int width = source.right - source.left;
|
||||
int height = source.bottom - source.top;
|
||||
|
||||
int width = (source.right - source.left) >> bScaleByHalf;
|
||||
int height = (source.bottom - source.top) >> bScaleByHalf;
|
||||
|
||||
int size_in_bytes = TexDecoder_GetTextureSizeInBytes(width, height, format);
|
||||
|
||||
// Invalidate any existing texture covering this memory range.
|
||||
// TODO - don't delete the texture if it already exists, just replace the contents.
|
||||
TextureMngr::InvalidateRange(address, size_in_bytes);
|
||||
|
||||
if (bScaleByHalf)
|
||||
{
|
||||
// Hm. Shouldn't this only scale destination, not source?
|
||||
// The bloom in Beyond Good & Evil is a good test case - due to this problem,
|
||||
// it goes very wrong. Compare by switching back and forth between Copy textures to RAM and GL Texture.
|
||||
// This also affects the shadows in Burnout 2 badly.
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
|
||||
u16 blkW = TexDecoder_GetBlockWidthInTexels(format) - 1;
|
||||
u16 blkH = TexDecoder_GetBlockHeightInTexels(format) - 1;
|
||||
|
@ -297,7 +289,7 @@ void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyf
|
|||
scaledSource.left = 0;
|
||||
scaledSource.right = expandedWidth / samples;
|
||||
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, bScaleByHalf);
|
||||
EncodeToRamUsingShader(texconv_shader, source_texture, scaledSource, dest_ptr, expandedWidth / samples, expandedHeight, bScaleByHalf > 0);
|
||||
}
|
||||
|
||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
|
|
|
@ -30,7 +30,7 @@ void Init();
|
|||
void Shutdown();
|
||||
|
||||
void EncodeToRam(u32 address, bool bFromZBuffer, bool bIsIntensityFmt,
|
||||
u32 copyfmt, bool bScaleByHalf, const EFBRectangle& source);
|
||||
u32 copyfmt, int bScaleByHalf, const EFBRectangle& source);
|
||||
|
||||
void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc,
|
||||
u8* destAddr, int dstWidth, int dstHeight);
|
||||
|
|
|
@ -492,85 +492,84 @@ TextureMngr::TCacheEntry* TextureMngr::Load(int texstage, u32 address, int width
|
|||
}
|
||||
|
||||
|
||||
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source_rect)
|
||||
void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
|
||||
{
|
||||
DVSTARTPROFILE();
|
||||
GL_REPORT_ERRORD();
|
||||
DVSTARTPROFILE();
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
// for intensity values, use Y of YUV format!
|
||||
// for all purposes, treat 4bit equivalents as 8bit (probably just used for compression)
|
||||
// RGBA8 - RGBA8
|
||||
// RGB565 - RGB565
|
||||
// RGB5A3 - RGB5A3
|
||||
// I4,R4,Z4 - I4
|
||||
// IA4,RA4 - IA4
|
||||
// Z8M,G8,I8,A8,Z8,R8,B8,Z8L - I8
|
||||
// Z16,GB8,RG8,Z16L,IA8,RA8 - IA8
|
||||
bool bIsInit = textures.find(address) != textures.end();
|
||||
// for intensity values, use Y of YUV format!
|
||||
// for all purposes, treat 4bit equivalents as 8bit (probably just used for compression)
|
||||
// RGBA8 - RGBA8
|
||||
// RGB565 - RGB565
|
||||
// RGB5A3 - RGB5A3
|
||||
// I4,R4,Z4 - I4
|
||||
// IA4,RA4 - IA4
|
||||
// Z8M,G8,I8,A8,Z8,R8,B8,Z8L - I8
|
||||
// Z16,GB8,RG8,Z16L,IA8,RA8 - IA8
|
||||
bool bIsInit = textures.find(address) != textures.end();
|
||||
|
||||
PRIM_LOG("copytarg: addr=0x%x, fromz=%d, intfmt=%d, copyfmt=%d", address, (int)bFromZBuffer, (int)bIsIntensityFmt,copyfmt);
|
||||
|
||||
TCacheEntry& entry = textures[address];
|
||||
entry.hash = 0;
|
||||
entry.hashoffset = 0;
|
||||
entry.frameCount = frameCount;
|
||||
|
||||
int mult = bScaleByHalf ? 2 : 1;
|
||||
int w = (abs(source_rect.GetWidth()) / mult);
|
||||
int h = (abs(source_rect.GetHeight()) / mult);
|
||||
PRIM_LOG("copytarg: addr=0x%x, fromz=%d, intfmt=%d, copyfmt=%d", address, (int)bFromZBuffer, (int)bIsIntensityFmt,copyfmt);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
TCacheEntry& entry = textures[address];
|
||||
entry.hash = 0;
|
||||
entry.hashoffset = 0;
|
||||
entry.frameCount = frameCount;
|
||||
|
||||
if (!bIsInit)
|
||||
int w = (abs(source_rect.GetWidth()) >> bScaleByHalf);
|
||||
int h = (abs(source_rect.GetHeight()) >> bScaleByHalf);
|
||||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
if (!bIsInit)
|
||||
{
|
||||
glGenTextures(1, (GLuint *)&entry.texture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
else
|
||||
glGenTextures(1, (GLuint *)&entry.texture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
else
|
||||
{
|
||||
_assert_(entry.texture);
|
||||
_assert_(entry.texture);
|
||||
GL_REPORT_ERROR();
|
||||
if (entry.w == w && entry.h == h && entry.isRectangle)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
// for some reason mario sunshine errors here...
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
// for some reason mario sunshine errors here...
|
||||
// Beyond Good and Evil does too, occasionally.
|
||||
GL_REPORT_ERROR();
|
||||
GL_REPORT_ERROR();
|
||||
} else {
|
||||
// Delete existing texture.
|
||||
glDeleteTextures(1,(GLuint *)&entry.texture);
|
||||
glGenTextures(1, (GLuint *)&entry.texture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
}
|
||||
// Delete existing texture.
|
||||
glDeleteTextures(1,(GLuint *)&entry.texture);
|
||||
glGenTextures(1, (GLuint *)&entry.texture);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, entry.texture);
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
}
|
||||
|
||||
if (!bIsInit || !entry.isRenderTarget)
|
||||
if (!bIsInit || !entry.isRenderTarget)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
}
|
||||
|
||||
entry.w = w;
|
||||
entry.h = h;
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
if (glGetError() != GL_NO_ERROR) {
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
}
|
||||
|
||||
entry.w = w;
|
||||
entry.h = h;
|
||||
entry.isRectangle = true;
|
||||
entry.isRenderTarget = true;
|
||||
entry.fmt = copyfmt;
|
||||
entry.isRenderTarget = true;
|
||||
entry.fmt = copyfmt;
|
||||
|
||||
float colmat[16];
|
||||
float fConstAdd[4] = {0};
|
||||
memset(colmat, 0, sizeof(colmat));
|
||||
float colmat[16];
|
||||
float fConstAdd[4] = {0};
|
||||
memset(colmat, 0, sizeof(colmat));
|
||||
|
||||
if (bFromZBuffer)
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
static void InvalidateRange(u32 start_address, u32 size);
|
||||
|
||||
static TCacheEntry* Load(int texstage, u32 address, int width, int height, u32 format, int tlutaddr, int tlutfmt);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, bool bScaleByHalf, const EFBRectangle &source);
|
||||
static void CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source);
|
||||
|
||||
static void DisableStage(int stage); // sets active texture
|
||||
|
||||
|
|
Loading…
Reference in New Issue