mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 14:19:46 -06:00
Yet another ClearScreen fix, should be the last one now.
Should fix almost all regressions of the recent ClearScreen changes and keep the fixed stuff. The Super Mario Sunshine glitch is caused by another issue and will be addressed in my next commit. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6668 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
@ -25,7 +25,6 @@
|
||||
|
||||
bool textureChanged[8];
|
||||
const bool renderFog = false;
|
||||
int prev_pix_format = -1;
|
||||
namespace BPFunctions
|
||||
{
|
||||
// ----------------------------------------------
|
||||
@ -90,66 +89,49 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||
There's numerous possible formats for the pixel data in the EFB.
|
||||
However, in the HW accelerated plugins we're always using RGBA8
|
||||
for the EFB format, which causes some problems:
|
||||
- We're using an alpha channel although the game doesn't (1)
|
||||
- If the actual EFB format is PIXELFMT_RGBA6_Z24, we are using more bits per channel than the native HW (2)
|
||||
- When doing a z copy EFB copy target format GX_TF_Z24X8 , the native HW don't worry about hthe color efb format because it only uses the depth part
|
||||
- When changing EFB formats the efb must be cleared (3)
|
||||
- Possible other oddities should be noted here as well
|
||||
- We're using an alpha channel although the game doesn't
|
||||
- If the actual EFB format is RGBA6_Z24 or R5G6B5_Z16, we are using more bits per channel than the native HW
|
||||
|
||||
To properly emulate the above points, we're doing the following:
|
||||
(1)
|
||||
- disable alpha channel writing of any kind of rendering if the actual EFB format doesn't use an alpha channel
|
||||
- NOTE: Always make sure that the EFB has been cleared to an alpha value of 0xFF in this case!
|
||||
- in a dition to the previus make sure we always return 0xFF in alpha when reading the efb content if the efb format has no alpha
|
||||
- Same for color channels, these need to be cleared to 0x00 though.
|
||||
(2)
|
||||
- just scale down the RGBA8 color to RGBA6 and upscale it to RGBA8 again
|
||||
(3) - when the pixel format changes:
|
||||
- call ClearScreen using the correct alpha format for the previus pixel format
|
||||
|
||||
|
||||
- convert the RGBA8 color to RGBA6/RGB8/RGB565 and convert it to RGBA8 again
|
||||
- convert the Z24 depth value to Z16 and back to Z24
|
||||
*/
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
{
|
||||
UPE_Copy PE_copy = bpmem.triggerEFBCopy;
|
||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||
bool alphaEnable = bpmem.blendmode.alphaupdate;
|
||||
bool zEnable = bpmem.zmode.updateenable;
|
||||
u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
u32 z = bpmem.clearZValue;
|
||||
if(prev_pix_format == -1)
|
||||
{
|
||||
prev_pix_format = bpmem.zcontrol.pixel_format;
|
||||
}
|
||||
// (1): Disable unused color channels
|
||||
switch (bpmem.zcontrol.pixel_format)
|
||||
{
|
||||
case PIXELFMT_RGB8_Z24:
|
||||
case PIXELFMT_RGB565_Z16:
|
||||
alphaEnable = true;
|
||||
color |= (prev_pix_format == PIXELFMT_RGBA6_Z24)? 0x0 : 0xFF000000;//(3)
|
||||
break;
|
||||
|
||||
case PIXELFMT_Z24:
|
||||
alphaEnable = colorEnable = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
// (1): Disable unused color channels
|
||||
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24 ||
|
||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16 ||
|
||||
bpmem.zcontrol.pixel_format == PIXELFMT_Z24)
|
||||
{
|
||||
alphaEnable = false;
|
||||
}
|
||||
|
||||
if (colorEnable || alphaEnable || zEnable)
|
||||
{
|
||||
u32 color = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
|
||||
u32 z = bpmem.clearZValue;
|
||||
|
||||
// (2) drop additional accuracy
|
||||
if (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
color = RGBA8ToRGBA6ToRGBA8(color);
|
||||
}
|
||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
color = RGBA8ToRGB565ToRGB8(color);
|
||||
color = RGBA8ToRGB565ToRGBA8(color);
|
||||
z = Z24ToZ16ToZ24(z);
|
||||
}
|
||||
g_renderer->ClearScreen(rc, colorEnable, alphaEnable, zEnable, color, z);
|
||||
}
|
||||
prev_pix_format = bpmem.zcontrol.pixel_format;
|
||||
}
|
||||
|
||||
|
||||
|
@ -545,10 +545,6 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
else// alpha
|
||||
{
|
||||
colmat[15] = 1;
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
fConstAdd[3] = 1;
|
||||
}
|
||||
cbufid = 1;
|
||||
}
|
||||
|
||||
@ -575,18 +571,10 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
case 3: // RA8
|
||||
colmat[0] = colmat[4] = colmat[8] = colmat[15] = 1;
|
||||
cbufid = 3;
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
fConstAdd[3] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: // A8
|
||||
colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1;
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = fConstAdd[3] = 1;
|
||||
}
|
||||
cbufid = 4;
|
||||
break;
|
||||
|
||||
@ -620,10 +608,6 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
case 6: // RGBA8
|
||||
colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1;
|
||||
cbufid = 10;
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
fConstAdd[3] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -633,8 +617,6 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const unsigned int tex_w = (abs(source_rect.GetWidth()) >> (int)bScaleByHalf);
|
||||
const unsigned int tex_h = (abs(source_rect.GetHeight()) >> (int)bScaleByHalf);
|
||||
@ -695,4 +677,4 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer,
|
||||
entry->FromRenderTarget(bFromZBuffer, bScaleByHalf, cbufid, colmat, source_rect, bIsIntensityFmt, copyfmt);
|
||||
|
||||
g_renderer->RestoreAPIState();
|
||||
}
|
||||
}
|
@ -163,7 +163,7 @@ inline u32 RGBA8ToRGBA6ToRGBA8(u32 src)
|
||||
return color;
|
||||
}
|
||||
|
||||
inline u32 RGBA8ToRGB565ToRGB8(u32 src)
|
||||
inline u32 RGBA8ToRGB565ToRGBA8(u32 src)
|
||||
{
|
||||
u32 color = src;
|
||||
u32 dstr5 = (color & 0xFF0000) >> 19;
|
||||
@ -172,9 +172,13 @@ inline u32 RGBA8ToRGB565ToRGB8(u32 src)
|
||||
u32 dstr8 = (dstr5 << 3) | (dstr5 >> 2);
|
||||
u32 dstg8 = (dstg6 << 2) | (dstg6 >> 4);
|
||||
u32 dstb8 = (dstb5 << 3) | (dstb5 >> 2);
|
||||
color = (dstr8 << 16) | (dstg8 << 8) | dstb8;
|
||||
color = 0xFF000000 | (dstr8 << 16) | (dstg8 << 8) | dstb8;
|
||||
return color;
|
||||
}
|
||||
|
||||
inline u32 Z24ToZ16ToZ24(u32 src)
|
||||
{
|
||||
return (src & 0xFFFF00) | (src >> 16);
|
||||
}
|
||||
|
||||
#endif // _VIDEOCOMMON_H
|
||||
|
Reference in New Issue
Block a user