DX11: Fix ClearScreen properly this time. Should fix quite a few games (or break them :P)

Fixes issue 3399.

Also remove unnecessary stateman/gfxstate applies:
- gfxstate->ApplyState/Reset only need to be called by VertexManager
- stateman->Apply only needs to be called before any Draw/DrawIndexed call

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6309 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
NeoBrainX 2010-10-24 16:53:33 +00:00
parent 52cd3aee95
commit 5cdda90182
2 changed files with 29 additions and 10 deletions

View File

@ -673,6 +673,7 @@ void drawColorQuad(u32 Color, float x1, float y1, float x2, float y2)
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset); context->IASetVertexBuffers(0, 1, &util_vbuf->GetBuffer(), &stride, &offset);
stateman->Apply();
context->Draw(4, cq_offset); context->Draw(4, cq_offset);
} }

View File

@ -75,6 +75,7 @@ static Common::CriticalSection s_criticalScreenshot;
static char s_sScreenshotName[1024]; static char s_sScreenshotName[1024];
ID3D11Buffer* access_efb_cbuf = NULL; ID3D11Buffer* access_efb_cbuf = NULL;
ID3D11BlendState* clearblendstates[4] = {NULL};
ID3D11DepthStencilState* cleardepthstates[2] = {NULL}; ID3D11DepthStencilState* cleardepthstates[2] = {NULL};
ID3D11RasterizerState* clearraststate = NULL; ID3D11RasterizerState* clearraststate = NULL;
ID3D11BlendState* resetblendstate = NULL; ID3D11BlendState* resetblendstate = NULL;
@ -279,6 +280,21 @@ void SetupDeviceObjects()
CHECK(hr==S_OK, "Create blend state for Renderer::ResetAPIState"); CHECK(hr==S_OK, "Create blend state for Renderer::ResetAPIState");
D3D::SetDebugObjectName((ID3D11DeviceChild*)resetblendstate, "blend state for Renderer::ResetAPIState"); D3D::SetDebugObjectName((ID3D11DeviceChild*)resetblendstate, "blend state for Renderer::ResetAPIState");
clearblendstates[0] = resetblendstate;
resetblendstate->AddRef();
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE;
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[1]);
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
blenddesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALPHA;
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[2]);
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
blenddesc.RenderTarget[0].RenderTargetWriteMask = 0;
hr = D3D::device->CreateBlendState(&blenddesc, &clearblendstates[3]);
CHECK(hr==S_OK, "Create blend state for Renderer::ClearScreen");
ddesc.DepthEnable = FALSE; ddesc.DepthEnable = FALSE;
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
ddesc.DepthFunc = D3D11_COMPARISON_LESS; ddesc.DepthFunc = D3D11_COMPARISON_LESS;
@ -301,6 +317,11 @@ void TeardownDeviceObjects()
{ {
g_framebufferManager.Destroy(); g_framebufferManager.Destroy();
SAFE_RELEASE(access_efb_cbuf); SAFE_RELEASE(access_efb_cbuf);
SAFE_RELEASE(clearblendstates[0]);
SAFE_RELEASE(clearblendstates[1]);
SAFE_RELEASE(clearblendstates[2]);
SAFE_RELEASE(clearblendstates[3]);
SAFE_RELEASE(clearblendstates[4]);
SAFE_RELEASE(cleardepthstates[0]); SAFE_RELEASE(cleardepthstates[0]);
SAFE_RELEASE(cleardepthstates[1]); SAFE_RELEASE(cleardepthstates[1]);
SAFE_RELEASE(clearraststate); SAFE_RELEASE(clearraststate);
@ -808,6 +829,8 @@ void UpdateViewport()
// Tino: color is passed in bgra mode so need to convert it to rgba // 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) 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 // Update the view port for clearing the picture
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc); TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(), D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
@ -822,20 +845,18 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
D3D::stateman->PushDepthState(cleardepthstates[zEnable]); D3D::stateman->PushDepthState(cleardepthstates[zEnable]);
D3D::stateman->PushRasterizerState(clearraststate); D3D::stateman->PushRasterizerState(clearraststate);
D3D::stateman->PushBlendState(resetblendstate); if (colorEnable && alphaEnable) D3D::stateman->PushBlendState(clearblendstates[0]);
D3D::stateman->Apply(); else if (colorEnable) D3D::stateman->PushBlendState(clearblendstates[1]);
else if (alphaEnable) D3D::stateman->PushBlendState(clearblendstates[2]);
else D3D::stateman->PushBlendState(clearblendstates[3]);
D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout()); D3D::drawClearQuad(rgbaColor, (z & 0xFFFFFF) / float(0xFFFFFF), PixelShaderCache::GetClearProgram(), VertexShaderCache::GetClearVertexShader(), VertexShaderCache::GetClearInputLayout());
D3D::stateman->PopBlendState(); D3D::stateman->PopBlendState();
D3D::stateman->PopRasterizerState(); D3D::stateman->PopRasterizerState();
D3D::stateman->PopDepthState(); D3D::stateman->PopDepthState();
D3D::stateman->Apply();
D3D::gfxstate->Reset(); RestoreAPIState();
UpdateViewport();
SetScissorRect();
} }
void Renderer::SetBlendMode(bool forceUpdate) void Renderer::SetBlendMode(bool forceUpdate)
@ -1103,11 +1124,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
// ALWAYS call RestoreAPIState for each ResetAPIState call you're doing // ALWAYS call RestoreAPIState for each ResetAPIState call you're doing
void Renderer::ResetAPIState() void Renderer::ResetAPIState()
{ {
D3D::gfxstate->Reset();
D3D::stateman->PushBlendState(resetblendstate); D3D::stateman->PushBlendState(resetblendstate);
D3D::stateman->PushDepthState(resetdepthstate); D3D::stateman->PushDepthState(resetdepthstate);
D3D::stateman->PushRasterizerState(resetraststate); D3D::stateman->PushRasterizerState(resetraststate);
D3D::stateman->Apply();
reset_called = true; reset_called = true;
} }
@ -1122,7 +1141,6 @@ void Renderer::RestoreAPIState()
} }
UpdateViewport(); UpdateViewport();
SetScissorRect(); SetScissorRect();
D3D::gfxstate->ApplyState();
reset_called = false; reset_called = false;
} }