1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed depth fill bugs

Fixes depth fills when using resolution scaling and antialiasing.
Adds support for depth fills on NVIDIA GPUs.
See depth issues in Star Wars: Racer.
This commit is contained in:
narzoul 2023-11-11 19:59:26 +01:00
parent a4256483de
commit 6c7882bb6e
4 changed files with 35 additions and 20 deletions

View File

@ -426,7 +426,7 @@ namespace D3dDdi
case D3DDDICAPS_DDRAW:
{
auto& caps = *static_cast<DDRAW_CAPS*>(pData->pData);
caps.Caps |= DDRAW_CAPS_COLORKEY;
caps.Caps |= DDRAW_CAPS_COLORKEY | DDRAW_CAPS_BLTDEPTHFILL;
caps.CKeyCaps = DDRAW_CKEYCAPS_SRCBLT;
caps.FxCaps = DDRAW_FXCAPS_BLTMIRRORLEFTRIGHT | DDRAW_FXCAPS_BLTMIRRORUPDOWN;
break;

View File

@ -351,25 +351,12 @@ namespace D3dDdi
HRESULT Device::pfnDepthFill(const D3DDDIARG_DEPTHFILL* data)
{
flushPrimitives();
auto resource = getResource(data->hResource);
auto customResource = resource->getCustomResource();
auto fi = getFormatInfo(resource->getFixedDesc().Format);
resource->prepareForGpuWrite(0);
m_state.setTempDepthStencil({ customResource ? *customResource : *resource });
RECT rect = data->DstRect;
resource->scaleRect(rect);
D3DDDIARG_CLEAR clear = {};
clear.Flags = D3DCLEAR_ZBUFFER;
clear.FillDepth = getComponentAsFloat(data->Depth, fi.depth);
if (0 != fi.stencil.bitCount)
auto it = m_resources.find(data->hResource);
if (it != m_resources.end())
{
clear.Flags |= D3DCLEAR_STENCIL;
clear.FillStencil = getComponent(data->Depth, fi.stencil);
return it->second->depthFill(*data);
}
return m_origVtable.pfnClear(m_device, &clear, 1, &rect);
return m_origVtable.pfnDepthFill(m_device, data);
}
HRESULT Device::pfnDestroyDevice()

View File

@ -666,6 +666,30 @@ namespace D3dDdi
LOG_RESULT(m_lockResource.get());
}
HRESULT Resource::depthFill(const D3DDDIARG_DEPTHFILL& data)
{
auto& dstResource = prepareForGpuWrite(data.SubResourceIndex);
auto& si = dstResource.getFixedDesc().pSurfList[data.SubResourceIndex];
auto& state = m_device.getState();
state.flush();
state.setTempDepthStencil({ dstResource });
state.setTempViewport({ 0, 0, si.Width, si.Height });
RECT rect = data.DstRect;
scaleRect(rect);
D3DDDIARG_CLEAR clear = {};
clear.Flags = D3DCLEAR_ZBUFFER;
clear.FillDepth = getComponentAsFloat(data.Depth, m_formatInfo.depth);
if (0 != m_formatInfo.stencil.bitCount && 0 != dstResource.m_formatInfo.stencil.bitCount)
{
clear.Flags |= D3DCLEAR_STENCIL;
clear.FillStencil = getComponent(data.Depth, m_formatInfo.stencil);
}
return m_device.getOrigVtable().pfnClear(m_device, &clear, 1, &rect);
}
void Resource::disableClamp()
{
m_isClampable = false;
@ -1114,7 +1138,7 @@ namespace D3dDdi
return *this;
}
void Resource::prepareForGpuWrite(UINT subResourceIndex)
Resource& Resource::prepareForGpuWrite(UINT subResourceIndex)
{
m_isColorKeyedSurfaceUpToDate = false;
if (m_lockResource || m_msaaResolvedSurface.resource)
@ -1124,12 +1148,14 @@ namespace D3dDdi
loadMsaaResource(subResourceIndex);
clearUpToDateFlags(subResourceIndex);
m_lockData[subResourceIndex].isMsaaUpToDate = true;
return *m_msaaSurface.resource;
}
else if (m_msaaResolvedSurface.resource)
{
loadMsaaResolvedResource(subResourceIndex);
clearUpToDateFlags(subResourceIndex);
m_lockData[subResourceIndex].isMsaaResolvedUpToDate = true;
return *m_msaaResolvedSurface.resource;
}
else
{
@ -1138,6 +1164,7 @@ namespace D3dDdi
m_lockData[subResourceIndex].isVidMemUpToDate = true;
}
}
return *this;
}
Resource& Resource::prepareForTextureRead(UINT stage)

View File

@ -41,6 +41,7 @@ namespace D3dDdi
HRESULT colorFill(D3DDDIARG_COLORFILL data);
HRESULT copySubResourceRegion(UINT dstIndex, const RECT& dstRect,
HANDLE src, UINT srcIndex, const RECT& srcRect);
HRESULT depthFill(const D3DDDIARG_DEPTHFILL& data);
void disableClamp();
void* getLockPtr(UINT subResourceIndex);
RECT getRect(UINT subResourceIndex) const;
@ -52,7 +53,7 @@ namespace D3dDdi
void prepareForCpuRead(UINT subResourceIndex);
void prepareForCpuWrite(UINT subResourceIndex);
Resource& prepareForGpuRead(UINT subResourceIndex);
void prepareForGpuWrite(UINT subResourceIndex);
Resource& prepareForGpuWrite(UINT subResourceIndex);
Resource& prepareForTextureRead(UINT stage);
HRESULT presentationBlt(D3DDDIARG_BLT data, Resource* srcResource);
void scaleRect(RECT& rect);