mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
DX9/DX11: Fix and simplify ClearScreen. At least fixes a small glitch in Super Mario Sunshine with DX11, might fix several other things as well in both plugins though (so test this, please!)
Explanation of this commit: We only have to care about four BP registers in ClearScreen, the remaining API state should be reset. The colorEnable and alphaEnable parameters are obsolete, for some reason directly using them caused the SMS glitch with DX11 (because of that bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 check in BPFunctions.cpp, is this one actually correct?) The comment in BPFunctions.cpp was at least misleading (if not even wrong), so I removed it. For what it's worth, someone needs to port this to the OpenGL and Software plugins (unless they're doing this properly already) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6327 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
b75a805859
commit
48859da6e3
@ -86,9 +86,6 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
{
|
||||
// it seems that the GC is able to alpha blend on color-fill
|
||||
// we cant do that so if alpha is != 255 we skip it
|
||||
|
||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||
bool zEnable = bpmem.zmode.updateenable;
|
||||
|
@ -77,8 +77,7 @@ static char s_sScreenshotName[1024];
|
||||
|
||||
ID3D11Buffer* access_efb_cbuf = NULL;
|
||||
ID3D11BlendState* clearblendstates[4] = {NULL};
|
||||
ID3D11DepthStencilState* cleardepthstates[2] = {NULL};
|
||||
ID3D11RasterizerState* clearraststate = NULL;
|
||||
ID3D11DepthStencilState* cleardepthstates[3] = {NULL};
|
||||
ID3D11BlendState* resetblendstate = NULL;
|
||||
ID3D11DepthStencilState* resetdepthstate = NULL;
|
||||
ID3D11RasterizerState* resetraststate = NULL;
|
||||
@ -257,14 +256,12 @@ void SetupDeviceObjects()
|
||||
ddesc.DepthEnable = TRUE;
|
||||
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
|
||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
|
||||
hr = D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[2]);
|
||||
CHECK(hr==S_OK, "Create depth state for Renderer::ClearScreen");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled)");
|
||||
|
||||
// TODO: once multisampling gets implemented, this might need to be changed
|
||||
D3D11_RASTERIZER_DESC rdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, true, false, false);
|
||||
hr = D3D::device->CreateRasterizerState(&rdesc, &clearraststate);
|
||||
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ClearScreen");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)clearraststate, "rasterizer state for Renderer::ClearScreen");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled, writing enabled)");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[2], "depth state for Renderer::ClearScreen (depth buffer enabled, writing disabled)");
|
||||
|
||||
D3D11_BLEND_DESC blenddesc;
|
||||
blenddesc.AlphaToCoverageEnable = FALSE;
|
||||
@ -309,7 +306,7 @@ void SetupDeviceObjects()
|
||||
// this might need to be changed once multisampling support gets added
|
||||
D3D11_RASTERIZER_DESC rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);
|
||||
hr = D3D::device->CreateRasterizerState(&rastdesc, &resetraststate);
|
||||
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ClearScreen");
|
||||
CHECK(hr==S_OK, "Create rasterizer state for Renderer::ResetAPIState");
|
||||
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetraststate, "rasterizer state for Renderer::ResetAPIState");
|
||||
}
|
||||
|
||||
@ -324,7 +321,7 @@ void TeardownDeviceObjects()
|
||||
SAFE_RELEASE(clearblendstates[3]);
|
||||
SAFE_RELEASE(cleardepthstates[0]);
|
||||
SAFE_RELEASE(cleardepthstates[1]);
|
||||
SAFE_RELEASE(clearraststate);
|
||||
SAFE_RELEASE(cleardepthstates[2]);
|
||||
SAFE_RELEASE(resetblendstate);
|
||||
SAFE_RELEASE(resetdepthstate);
|
||||
SAFE_RELEASE(resetraststate);
|
||||
@ -833,35 +830,30 @@ void UpdateViewport()
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
}
|
||||
|
||||
// Tino: color is passed in bgra mode so need to convert it to rgba
|
||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
ResetAPIState();
|
||||
|
||||
// Update the view port for clearing the picture
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
|
||||
0.f,
|
||||
1.f);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
|
||||
D3D::context->RSSetScissorRects(1, &sirc);
|
||||
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
||||
|
||||
D3D::stateman->PushDepthState(cleardepthstates[zEnable]);
|
||||
D3D::stateman->PushRasterizerState(clearraststate);
|
||||
if (colorEnable && alphaEnable) D3D::stateman->PushBlendState(clearblendstates[0]);
|
||||
else if (colorEnable) D3D::stateman->PushBlendState(clearblendstates[1]);
|
||||
else if (alphaEnable) D3D::stateman->PushBlendState(clearblendstates[2]);
|
||||
if (bpmem.blendmode.colorupdate && bpmem.blendmode.alphaupdate) D3D::stateman->PushBlendState(clearblendstates[0]);
|
||||
else if (bpmem.blendmode.colorupdate) D3D::stateman->PushBlendState(clearblendstates[1]);
|
||||
else if (bpmem.blendmode.alphaupdate) D3D::stateman->PushBlendState(clearblendstates[2]);
|
||||
else D3D::stateman->PushBlendState(clearblendstates[3]);
|
||||
|
||||
if (!bpmem.zmode.testenable) D3D::stateman->PushDepthState(cleardepthstates[0]);
|
||||
else if (bpmem.zmode.updateenable) D3D::stateman->PushDepthState(cleardepthstates[1]);
|
||||
else /*if (!bpmem.zmode.updateenable)*/ D3D::stateman->PushDepthState(cleardepthstates[2]);
|
||||
|
||||
// Update the view port for clearing the picture
|
||||
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
|
||||
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), 0.f, 1.f);
|
||||
D3D::context->RSSetViewports(1, &vp);
|
||||
|
||||
// Color is passed in bgra mode so we need to convert it to rgba
|
||||
u32 rgbaColor = (color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000);
|
||||
D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout());
|
||||
|
||||
D3D::stateman->PopBlendState();
|
||||
D3D::stateman->PopRasterizerState();
|
||||
D3D::stateman->PopDepthState();
|
||||
D3D::stateman->PopBlendState();
|
||||
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
@ -91,9 +91,6 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
{
|
||||
// it seems that the GC is able to alpha blend on color-fill
|
||||
// we cant do that so if alpha is != 255 we skip it
|
||||
|
||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||
bool zEnable = bpmem.zmode.updateenable;
|
||||
|
@ -990,7 +990,15 @@ void UpdateViewport()
|
||||
|
||||
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
|
||||
{
|
||||
// Update the view port for clearing the picture
|
||||
// Reset rendering pipeline while keeping color masks and depth buffer settings
|
||||
ResetAPIState();
|
||||
SetDepthMode();
|
||||
SetColorMask();
|
||||
|
||||
if (zEnable) // other depth functions don't make sense here
|
||||
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
|
||||
|
||||
// Update the view port for clearing the whole EFB texture
|
||||
TargetRectangle targetRc = ConvertEFBRectangle(rc);
|
||||
D3DVIEWPORT9 vp;
|
||||
vp.X = targetRc.left;
|
||||
@ -1000,23 +1008,8 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
|
||||
vp.MinZ = 0.0;
|
||||
vp.MaxZ = 1.0;
|
||||
D3D::dev->SetViewport(&vp);
|
||||
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
RECT sicr;
|
||||
sicr.left = targetRc.left;
|
||||
sicr.top = targetRc.top;
|
||||
sicr.right = targetRc.right;
|
||||
sicr.bottom = targetRc.bottom;
|
||||
D3D::dev->SetScissorRect(&sicr);
|
||||
D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
if (zEnable)
|
||||
D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
|
||||
D3D::drawClearQuad(color, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader());
|
||||
if (zEnable)
|
||||
D3D::RefreshRenderState(D3DRS_ZFUNC);
|
||||
D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE);
|
||||
UpdateViewport();
|
||||
SetScissorRect();
|
||||
RestoreAPIState();
|
||||
}
|
||||
|
||||
void Renderer::SetBlendMode(bool forceUpdate)
|
||||
|
@ -89,9 +89,6 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
|
||||
|
||||
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
|
||||
{
|
||||
// it seems that the GC is able to alpha blend on color-fill
|
||||
// we cant do that so if alpha is != 255 we skip it
|
||||
|
||||
bool colorEnable = bpmem.blendmode.colorupdate;
|
||||
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);
|
||||
bool zEnable = bpmem.zmode.updateenable;
|
||||
|
Loading…
Reference in New Issue
Block a user