mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07: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:
parent
c33f46406e
commit
6e8df50fff
@ -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
|
||||
|
@ -466,7 +466,7 @@ void Renderer::SetColorMask()
|
||||
UINT8 color_mask = 0;
|
||||
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
|
||||
color_mask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
|
||||
if (bpmem.blendmode.colorupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24 || bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 || bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16))
|
||||
if (bpmem.blendmode.colorupdate)
|
||||
color_mask |= D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN | D3D11_COLOR_WRITE_ENABLE_BLUE;
|
||||
D3D::gfxstate->SetRenderTargetWriteMask(color_mask);
|
||||
}
|
||||
@ -562,7 +562,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
u32 ret = 0;
|
||||
if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
// if Z is in 16 bit format yo must return a 16 bit integer
|
||||
// if Z is in 16 bit format you must return a 16 bit integer
|
||||
ret = ((u32)(val * 0xffff));
|
||||
}
|
||||
else
|
||||
@ -598,7 +598,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
}
|
||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
ret = RGBA8ToRGB565ToRGB8(ret);
|
||||
ret = RGBA8ToRGB565ToRGBA8(ret);
|
||||
}
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
|
@ -477,7 +477,7 @@ void Renderer::SetColorMask()
|
||||
DWORD color_mask = 0;
|
||||
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
|
||||
color_mask = D3DCOLORWRITEENABLE_ALPHA;
|
||||
if (bpmem.blendmode.colorupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16 || bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24|| bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
|
||||
if (bpmem.blendmode.colorupdate)
|
||||
color_mask |= D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
|
||||
D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
|
||||
}
|
||||
@ -649,7 +649,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||
if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
// if Z is in 16 bit format yo must return a 16 bit integer
|
||||
// if Z is in 16 bit format you must return a 16 bit integer
|
||||
z = ((u32)(val * 0xffff));
|
||||
}
|
||||
else
|
||||
@ -684,8 +684,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
}
|
||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
ret = RGBA8ToRGB565ToRGB8(ret);
|
||||
}
|
||||
ret = RGBA8ToRGB565ToRGBA8(ret);
|
||||
}
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
ret |= 0xFF000000;
|
||||
|
@ -663,13 +663,9 @@ void Renderer::SetColorMask()
|
||||
{
|
||||
// Only enable alpha channel if it's supported by the current EFB format
|
||||
GLenum ColorMask = GL_FALSE, AlphaMask = GL_FALSE;
|
||||
if (bpmem.blendmode.colorupdate &&
|
||||
(bpmem.zcontrol.pixel_format == PIXELFMT_RGB8_Z24 ||
|
||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 ||
|
||||
bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16))
|
||||
if (bpmem.blendmode.colorupdate)
|
||||
ColorMask = GL_TRUE;
|
||||
if (bpmem.blendmode.alphaupdate &&
|
||||
(bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
|
||||
if (bpmem.blendmode.alphaupdate && (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24))
|
||||
AlphaMask = GL_TRUE;
|
||||
glColorMask(ColorMask, ColorMask, ColorMask, AlphaMask);
|
||||
}
|
||||
@ -727,7 +723,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||
if(bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
// if Z is in 16 bit format yo must return a 16 bit integer
|
||||
// if Z is in 16 bit format you must return a 16 bit integer
|
||||
z = z >> 16;
|
||||
}
|
||||
else
|
||||
@ -737,10 +733,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
return z;
|
||||
}
|
||||
|
||||
case POKE_Z:
|
||||
// TODO: Implement
|
||||
break;
|
||||
|
||||
case PEEK_COLOR: // GXPeekARGB
|
||||
{
|
||||
// Although it may sound strange, this really is A8R8G8B8 and not RGBA or 24-bit...
|
||||
@ -775,8 +767,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
}
|
||||
else if (bpmem.zcontrol.pixel_format == PIXELFMT_RGB565_Z16)
|
||||
{
|
||||
color = RGBA8ToRGB565ToRGB8(color);
|
||||
}
|
||||
color = RGBA8ToRGB565ToRGBA8(color);
|
||||
}
|
||||
if(bpmem.zcontrol.pixel_format != PIXELFMT_RGBA6_Z24)
|
||||
{
|
||||
color |= 0xFF000000;
|
||||
@ -787,13 +779,13 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
}
|
||||
|
||||
case POKE_COLOR:
|
||||
case POKE_Z:
|
||||
// TODO: Implement. One way is to draw a tiny pixel-sized rectangle at
|
||||
// the exact location. Note: EFB pokes are susceptible to Z-buffering
|
||||
// and perhaps blending.
|
||||
//WARN_LOG(VIDEOINTERFACE, "This is probably some kind of software rendering");
|
||||
break;
|
||||
|
||||
// TODO: Implement POKE_Z and POKE_COLOR
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user