Skip to content

Commit

Permalink
Merge pull request #7699 from unknownbrackets/d3d9
Browse files Browse the repository at this point in the history
d3d9: Clear the stencil/alpha on buffer reformat (matching GLES)
  • Loading branch information
hrydgard committed Apr 19, 2015
2 parents 49783ed + 2e4d208 commit 9f7554c
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
66 changes: 60 additions & 6 deletions GPU/Directx9/FramebufferDX9.cpp
Expand Up @@ -81,15 +81,15 @@ namespace DX9 {
dxstate.colorMask.set(true, true, true, true);
dxstate.stencilFunc.set(D3DCMP_ALWAYS, 0, 0);
dxstate.stencilMask.set(0xFF);
pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 0, 0);
pD3Ddevice->Clear(0, NULL, D3DCLEAR_STENCIL|D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 0, 0);
}

void FramebufferManagerDX9::ClearDepthBuffer() {
dxstate.scissorTest.disable();
dxstate.depthWrite.set(TRUE);
dxstate.colorMask.set(false, false, false, false);
dxstate.stencilFunc.set(D3DCMP_NEVER, 0, 0);
pD3Ddevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 0, 0);
pD3Ddevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 0, 0);
}

void FramebufferManagerDX9::DisableState() {
Expand Down Expand Up @@ -435,8 +435,7 @@ namespace DX9 {
}
if (vfb->drawnFormat != vfb->format) {
// TODO: Might ultimately combine this with the resize step in DoSetRenderFrameBuffer().
// TODO
//ReformatFramebufferFrom(vfb, vfb->drawnFormat);
ReformatFramebufferFrom(vfb, vfb->drawnFormat);
}

// ugly...
Expand All @@ -453,8 +452,7 @@ namespace DX9 {
if (vfbFormatChanged) {
textureCache_->NotifyFramebuffer(vfb->fb_address, vfb, NOTIFY_FB_UPDATED);
if (vfb->drawnFormat != vfb->format) {
// TODO
//ReformatFramebufferFrom(vfb, vfb->drawnFormat);
ReformatFramebufferFrom(vfb, vfb->drawnFormat);
}
}

Expand All @@ -468,6 +466,62 @@ namespace DX9 {
}
}

void FramebufferManagerDX9::ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old) {
if (!useBufferedRendering_ || !vfb->fbo) {
return;
}

fbo_bind_as_render_target(vfb->fbo);

// Technically, we should at this point re-interpret the bytes of the old format to the new.
// That might get tricky, and could cause unnecessary slowness in some games.
// For now, we just clear alpha/stencil from 565, which fixes shadow issues in Kingdom Hearts.
// (it uses 565 to write zeros to the buffer, than 4444 to actually render the shadow.)
//
// The best way to do this may ultimately be to create a new FBO (combine with any resize?)
// and blit with a shader to that, then replace the FBO on vfb. Stencil would still be complex
// to exactly reproduce in 4444 and 8888 formats.

if (old == GE_FORMAT_565) {
dxstate.scissorTest.disable();
dxstate.depthWrite.set(FALSE);
dxstate.colorMask.set(false, false, false, true);
dxstate.stencilFunc.set(D3DCMP_ALWAYS, 0, 0);
dxstate.stencilMask.set(0xFF);

float coord[20] = {
-1.0f,-1.0f,0, 0,0,
1.0f,-1.0f,0, 0,0,
1.0f,1.0f,0, 0,0,
-1.0f,1.0f,0, 0,0,
};

dxstate.cullMode.set(false, false);
pD3Ddevice->SetVertexDeclaration(pFramebufferVertexDecl);
pD3Ddevice->SetPixelShader(pFramebufferPixelShader);
pD3Ddevice->SetVertexShader(pFramebufferVertexShader);
shaderManager_->DirtyLastShader();
pD3Ddevice->SetTexture(0, nullptr);

D3DVIEWPORT9 vp;
vp.MinZ = 0;
vp.MaxZ = 1;
vp.X = 0;
vp.Y = 0;
vp.Width = vfb->renderWidth;
vp.Height = vfb->renderHeight;
pD3Ddevice->SetViewport(&vp);

// This should clear stencil and alpha without changing the other colors.
HRESULT hr = pD3Ddevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coord, 5 * sizeof(float));
if (FAILED(hr)) {
ERROR_LOG_REPORT(G3D, "ReformatFramebufferFrom() failed: %08x", hr);
}
}

RebindFramebuffer();
}

void FramebufferManagerDX9::BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst) {
if (!src->fbo || !dst->fbo || !useBufferedRendering_) {
return;
Expand Down
1 change: 1 addition & 0 deletions GPU/Directx9/FramebufferDX9.h
Expand Up @@ -70,6 +70,7 @@ class FramebufferManagerDX9 : public FramebufferManagerCommon {
void Resized();
void DeviceLost();
void CopyDisplayToOutput();
void ReformatFramebufferFrom(VirtualFramebuffer *vfb, GEBufferFormat old);

void BlitFramebufferDepth(VirtualFramebuffer *src, VirtualFramebuffer *dst);

Expand Down

0 comments on commit 9f7554c

Please sign in to comment.