mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Implement pixel data reinterpretation on EFB format change.
Whatever that means, it fixes that stupid Super Mario Sunshine glitch and possibly lots of other stuff, so test as many glitchy games as possible with this ;) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6669 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -134,6 +134,63 @@ void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
}
|
||||
}
|
||||
|
||||
void OnPixelFormatChange(const BPCmd &bp)
|
||||
{
|
||||
/*
|
||||
* When changing the EFB format, the pixel data won't get converted to the new format but stays the same.
|
||||
* Since we are always using an RGBA8 buffer though, this causes issues in some games.
|
||||
* Thus, we reinterpret the old EFB data with the new format here.
|
||||
*/
|
||||
if (!g_ActiveConfig.bEFBEmulateFormatChanges ||
|
||||
!g_ActiveConfig.backend_info.bSupportsFormatReinterpretation)
|
||||
return;
|
||||
|
||||
int new_format = bpmem.zcontrol.pixel_format;
|
||||
int old_format = Renderer::GetPrevPixelFormat();
|
||||
|
||||
// no need to reinterpret pixel data in these cases
|
||||
if (new_format == old_format || old_format == (unsigned int)-1)
|
||||
goto skip;
|
||||
|
||||
int convtype = -1;
|
||||
switch (old_format)
|
||||
{
|
||||
case PIXELFMT_RGB8_Z24:
|
||||
case PIXELFMT_Z24:
|
||||
// Z24 and RGB8_Z24 are treated equal, so just return in this case
|
||||
if (new_format == PIXELFMT_RGB565_Z16 || new_format == PIXELFMT_Z24)
|
||||
goto skip;
|
||||
|
||||
if (new_format == PIXELFMT_RGBA6_Z24)
|
||||
convtype = 0;
|
||||
else if (new_format == PIXELFMT_RGB565_Z16)
|
||||
convtype = 1;
|
||||
break;
|
||||
|
||||
case PIXELFMT_RGBA6_Z24:
|
||||
if (new_format == PIXELFMT_RGB8_Z24 ||
|
||||
new_format == PIXELFMT_Z24)
|
||||
convtype = 2;
|
||||
else if (new_format == PIXELFMT_RGB565_Z16)
|
||||
convtype = 3;
|
||||
break;
|
||||
|
||||
case PIXELFMT_RGB565_Z16:
|
||||
if (new_format == PIXELFMT_RGB8_Z24 ||
|
||||
new_format == PIXELFMT_Z24)
|
||||
convtype = 4;
|
||||
else if (new_format == PIXELFMT_RGB565_Z16)
|
||||
convtype = 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
PanicAlert("Unhandled EFB format change: %d to %d\n", old_format, new_format);
|
||||
goto skip;
|
||||
}
|
||||
g_renderer->ReinterpretPixelData(convtype);
|
||||
skip:
|
||||
Renderer::StorePixelFormat(new_format);
|
||||
}
|
||||
|
||||
void RestoreRenderState(const BPCmd &bp)
|
||||
{
|
||||
|
@ -47,6 +47,7 @@ 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 int &scaleByHalf);
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc);
|
||||
void OnPixelFormatChange(const BPCmd &bp);
|
||||
void RestoreRenderState(const BPCmd &bp);
|
||||
u8 *GetPointer(const u32 &address);
|
||||
bool GetConfig(const int &type);
|
||||
|
@ -422,7 +422,12 @@ void BPWritten(const BPCmd& bp)
|
||||
break;
|
||||
case BPMEM_TEXINVALIDATE: // Used, if game has manual control the Texture Cache, which we don't allow
|
||||
DEBUG_LOG(VIDEO, "BP Texture Invalid: %08x", bp.newvalue);
|
||||
break;
|
||||
|
||||
case BPMEM_ZCOMPARE: // Set the Z-Compare and EFB pixel format
|
||||
OnPixelFormatChange(bp);
|
||||
break;
|
||||
|
||||
case BPMEM_MIPMAP_STRIDE: // MipMap Stride Channel
|
||||
case BPMEM_COPYYSCALE: // Display Copy Y Scale
|
||||
case BPMEM_IREF: /* 24 RID
|
||||
|
@ -77,6 +77,8 @@ int Renderer::s_LastEFBScale;
|
||||
bool Renderer::s_skipSwap;
|
||||
bool Renderer::XFBWrited;
|
||||
|
||||
unsigned int Renderer::prev_efb_format = (unsigned int)-1;
|
||||
|
||||
Renderer::Renderer()
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
@ -84,7 +86,8 @@ Renderer::Renderer()
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
|
||||
// invalidate previous efb format
|
||||
prev_efb_format = (unsigned int)-1;
|
||||
}
|
||||
|
||||
void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma)
|
||||
|
@ -110,6 +110,7 @@ public:
|
||||
virtual void RenderText(const char* pstr, int left, int top, u32 color) = 0;
|
||||
|
||||
virtual void ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z) = 0;
|
||||
virtual void ReinterpretPixelData(unsigned int convtype) = 0;
|
||||
static void RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma = 1.0f);
|
||||
|
||||
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
|
||||
@ -125,6 +126,9 @@ public:
|
||||
|
||||
virtual bool SaveScreenshot(const std::string &filename, const TargetRectangle &rc) = 0;
|
||||
|
||||
static unsigned int GetPrevPixelFormat() { return prev_efb_format; }
|
||||
static void StorePixelFormat(unsigned int new_format) { prev_efb_format = new_format; }
|
||||
|
||||
protected:
|
||||
|
||||
static Common::CriticalSection s_criticalScreenshot;
|
||||
@ -159,6 +163,9 @@ protected:
|
||||
|
||||
static bool s_skipSwap;
|
||||
static bool XFBWrited;
|
||||
|
||||
private:
|
||||
static unsigned int prev_efb_format;
|
||||
};
|
||||
|
||||
extern Renderer *g_renderer;
|
||||
|
@ -109,6 +109,7 @@ void VideoConfig::Load(const char *ini_file)
|
||||
iniFile.Get("Hacks", "EFBToTextureEnable", &bCopyEFBToTexture, false);
|
||||
iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true);
|
||||
iniFile.Get("Hacks", "EFBCopyCacheEnable", &bEFBCopyCacheEnable, false);
|
||||
iniFile.Get("Hacks", "EFBEmulateFormatChanges", &bEFBEmulateFormatChanges, true);
|
||||
iniFile.Get("Hacks", "ProjectionHack", &iPhackvalue, 0);
|
||||
|
||||
iniFile.Get("Hardware", "Adapter", &iAdapter, 0);
|
||||
@ -226,6 +227,7 @@ void VideoConfig::Save(const char *ini_file)
|
||||
iniFile.Set("Hacks", "EFBToTextureEnable", bCopyEFBToTexture);
|
||||
iniFile.Set("Hacks", "EFBScaledCopy", bCopyEFBScaled);
|
||||
iniFile.Set("Hacks", "EFBCopyCacheEnable", bEFBCopyCacheEnable);
|
||||
iniFile.Set("Hacks", "EFBEmulateFormatChanges", bEFBEmulateFormatChanges);
|
||||
iniFile.Set("Hacks", "ProjectionHack", iPhackvalue);
|
||||
|
||||
iniFile.Set("Hardware", "Adapter", iAdapter);
|
||||
|
@ -119,6 +119,7 @@ struct VideoConfig
|
||||
bool bDlistCachingEnable;
|
||||
bool bEFBCopyEnable;
|
||||
bool bEFBCopyCacheEnable;
|
||||
bool bEFBEmulateFormatChanges;
|
||||
bool bOSDHotKey;
|
||||
bool bHack;
|
||||
bool bCopyEFBToTexture;
|
||||
@ -159,6 +160,7 @@ struct VideoConfig
|
||||
bool bSupports3DVision;
|
||||
bool bAllowSignedBytes; // D3D9 doesn't support signed bytes (?)
|
||||
bool bSupportsDualSourceBlend; // only supported by D3D11 and OpenGL
|
||||
bool bSupportsFormatReinterpretation;
|
||||
} backend_info;
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user