diff --git a/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp index 2fa0a862be..f7428935f7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/BPFunctions.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 97055dedf4..14092c80ad 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -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(); } diff --git a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp index c9522efe4e..178c0e4e63 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/BPFunctions.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 96795e81fe..91052cecf1 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -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) diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp index 723d3d0b30..690e2ecdfd 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPFunctions.cpp @@ -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;