From 050248a552f61a8c87365021490ac1bed59ff850 Mon Sep 17 00:00:00 2001 From: narzoul Date: Thu, 7 Jan 2021 01:06:37 +0100 Subject: [PATCH] Moved z-buffer bit depth caps fix to driver level --- DDrawCompat/D3dDdi/AdapterFuncs.cpp | 95 +++++++++++++++++- DDrawCompat/DDrawCompat.vcxproj | 2 - DDrawCompat/DDrawCompat.vcxproj.filters | 6 -- DDrawCompat/Direct3d/DepthBuffer.cpp | 124 ------------------------ DDrawCompat/Direct3d/DepthBuffer.h | 14 --- DDrawCompat/Direct3d/Direct3d.cpp | 63 +----------- DDrawCompat/Direct3d/Direct3dDevice.cpp | 30 ------ 7 files changed, 94 insertions(+), 240 deletions(-) delete mode 100644 DDrawCompat/Direct3d/DepthBuffer.cpp delete mode 100644 DDrawCompat/Direct3d/DepthBuffer.h diff --git a/DDrawCompat/D3dDdi/AdapterFuncs.cpp b/DDrawCompat/D3dDdi/AdapterFuncs.cpp index 85752b3..66e5383 100644 --- a/DDrawCompat/D3dDdi/AdapterFuncs.cpp +++ b/DDrawCompat/D3dDdi/AdapterFuncs.cpp @@ -1,12 +1,32 @@ +#include +#include + #include -#include "D3dDdi/Adapter.h" -#include "D3dDdi/AdapterFuncs.h" -#include "D3dDdi/DeviceCallbacks.h" -#include "D3dDdi/DeviceFuncs.h" +#include +#include +#include +#include namespace { + DWORD getSupportedZBufferBitDepths(HANDLE adapter); + + std::string bitDepthsToString(DWORD bitDepths) + { + std::string result; + if (bitDepths & DDBD_8) { result += ", 8"; } + if (bitDepths & DDBD_16) { result += ", 16"; } + if (bitDepths & DDBD_24) { result += ", 24"; } + if (bitDepths & DDBD_32) { result += ", 32"; } + + if (result.empty()) + { + return "\"\""; + } + return '"' + result.substr(2) + '"'; + } + HRESULT APIENTRY closeAdapter(HANDLE hAdapter) { HRESULT result = D3dDdi::AdapterFuncs::s_origVtablePtr->pfnCloseAdapter(hAdapter); @@ -33,13 +53,78 @@ namespace HRESULT APIENTRY getCaps(HANDLE hAdapter, const D3DDDIARG_GETCAPS* pData) { HRESULT result = D3dDdi::AdapterFuncs::s_origVtablePtr->pfnGetCaps(hAdapter, pData); - if (SUCCEEDED(result) && D3DDDICAPS_DDRAW == pData->Type) + if (FAILED(result)) { + return result; + } + + switch (pData->Type) + { + case D3DDDICAPS_DDRAW: static_cast(pData->pData)->FxCaps = DDRAW_FXCAPS_BLTMIRRORLEFTRIGHT | DDRAW_FXCAPS_BLTMIRRORUPDOWN; + break; + + case D3DDDICAPS_GETD3D3CAPS: + { + auto& caps = static_cast(pData->pData)->hwCaps; + if (caps.dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH) + { + const DWORD supportedZBufferBitDepths = getSupportedZBufferBitDepths(hAdapter); + if (supportedZBufferBitDepths != caps.dwDeviceZBufferBitDepth) + { + LOG_ONCE("Incorrect z-buffer bit depth capabilities detected; changed from " + << bitDepthsToString(caps.dwDeviceZBufferBitDepth) << " to " + << bitDepthsToString(supportedZBufferBitDepths)); + caps.dwDeviceZBufferBitDepth = supportedZBufferBitDepths; + } + } + break; } + } + return result; } + + DWORD getSupportedZBufferBitDepths(HANDLE adapter) + { + UINT formatCount = 0; + D3DDDIARG_GETCAPS caps = {}; + caps.Type = D3DDDICAPS_GETFORMATCOUNT; + caps.pData = &formatCount; + caps.DataSize = sizeof(formatCount); + D3dDdi::AdapterFuncs::s_origVtablePtr->pfnGetCaps(adapter, &caps); + + std::vector formatOp(formatCount); + caps.Type = D3DDDICAPS_GETFORMATDATA; + caps.pData = formatOp.data(); + caps.DataSize = formatCount * sizeof(FORMATOP); + D3dDdi::AdapterFuncs::s_origVtablePtr->pfnGetCaps(adapter, &caps); + + DWORD supportedZBufferBitDepths = 0; + for (UINT i = 0; i < formatCount; ++i) + { + if (formatOp[i].Operations & (FORMATOP_ZSTENCIL | FORMATOP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH)) + { + switch (formatOp[i].Format) + { + case D3DDDIFMT_D16: + supportedZBufferBitDepths |= DDBD_16; + break; + + case D3DDDIFMT_X8D24: + supportedZBufferBitDepths |= DDBD_24; + break; + + case D3DDDIFMT_D32: + supportedZBufferBitDepths |= DDBD_32; + break; + } + } + } + + return supportedZBufferBitDepths; + } } namespace D3dDdi diff --git a/DDrawCompat/DDrawCompat.vcxproj b/DDrawCompat/DDrawCompat.vcxproj index c122075..1effaf6 100644 --- a/DDrawCompat/DDrawCompat.vcxproj +++ b/DDrawCompat/DDrawCompat.vcxproj @@ -193,7 +193,6 @@ - @@ -275,7 +274,6 @@ - diff --git a/DDrawCompat/DDrawCompat.vcxproj.filters b/DDrawCompat/DDrawCompat.vcxproj.filters index 3aa806d..a7116e4 100644 --- a/DDrawCompat/DDrawCompat.vcxproj.filters +++ b/DDrawCompat/DDrawCompat.vcxproj.filters @@ -138,9 +138,6 @@ Header Files\Direct3d - - Header Files\Direct3d - Header Files\Direct3d @@ -455,9 +452,6 @@ Source Files\Direct3d - - Source Files\Direct3d - Source Files\Direct3d diff --git a/DDrawCompat/Direct3d/DepthBuffer.cpp b/DDrawCompat/Direct3d/DepthBuffer.cpp deleted file mode 100644 index 74ca5f7..0000000 --- a/DDrawCompat/Direct3d/DepthBuffer.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include - -#include "Direct3d/DepthBuffer.h" - -namespace -{ - std::string bitDepthsToString(DWORD bitDepths) - { - std::string result; - if (bitDepths & DDBD_8) { result += ", 8"; } - if (bitDepths & DDBD_16) { result += ", 16"; } - if (bitDepths & DDBD_24) { result += ", 24"; } - if (bitDepths & DDBD_32) { result += ", 32"; } - result = '"' + result.substr(2) + '"'; - return result; - } - - HRESULT CALLBACK enumZBufferFormatsCallback(LPDDPIXELFORMAT lpDDPixFmt, LPVOID lpContext) - { - LOG_FUNC("CompatDepthBuffer::enumZBufferFormatsCallback", lpDDPixFmt, lpContext); - if (DDPF_ZBUFFER == lpDDPixFmt->dwFlags && - (static_cast(1) << lpDDPixFmt->dwZBufferBitDepth) - 1 == lpDDPixFmt->dwZBitMask) - { - DWORD& supportedBitDepths = *reinterpret_cast(lpContext); - switch (lpDDPixFmt->dwZBufferBitDepth) - { - case 8: supportedBitDepths |= DDBD_8; break; - case 16: supportedBitDepths |= DDBD_16; break; - case 24: supportedBitDepths |= DDBD_24; break; - case 32: supportedBitDepths |= DDBD_32; break; - } - } - return LOG_RESULT(D3DENUMRET_OK); - } - - GUID getDeviceGuid(const D3DDEVICEDESC& /*desc*/) - { - return IID_IDirect3DHALDevice; - } - - GUID getDeviceGuid(const D3DDEVICEDESC7& desc) - { - return desc.deviceGUID; - } - - template - DWORD getSupportedZBufferBitDepths(CompatPtr d3d, const GUID& deviceGuid) - { - DWORD supportedBitDepths = 0; - if (d3d) - { - d3d->EnumZBufferFormats(d3d, deviceGuid, &enumZBufferFormatsCallback, &supportedBitDepths); - } - return supportedBitDepths; - } - - bool isHardwareZBufferSupported(const D3DDEVICEDESC& desc) - { - return (desc.dwFlags & D3DDD_DEVICEZBUFFERBITDEPTH) && 0 != desc.dwDeviceZBufferBitDepth; - } - - bool isHardwareZBufferSupported(const D3DDEVICEDESC7& desc) - { - return 0 != desc.dwDeviceZBufferBitDepth && - (IID_IDirect3DHALDevice == desc.deviceGUID || IID_IDirect3DTnLHalDevice == desc.deviceGUID); - } - - void logSupportedZBufferBitDepthsChanged( - CompatPtr dd, const GUID& d3dGuid, DWORD oldBitDepths, DWORD newBitDepths) - { - struct DeviceId - { - GUID directDrawGuid; - GUID direct3dGuid; - - bool operator==(const DeviceId& rhs) const - { - return directDrawGuid == rhs.directDrawGuid && direct3dGuid == rhs.direct3dGuid; - } - }; - - DDDEVICEIDENTIFIER2 deviceIdentifier = {}; - dd->GetDeviceIdentifier(dd, &deviceIdentifier, 0); - const DeviceId deviceId = { deviceIdentifier.guidDeviceIdentifier, d3dGuid }; - - static std::vector loggedDevices; - if (loggedDevices.end() != std::find(loggedDevices.begin(), loggedDevices.end(), deviceId)) - { - return; - } - loggedDevices.push_back(deviceId); - - Compat::Log() << "Incorrect z-buffer bit depth capabilities detected for \"" << - deviceIdentifier.szDescription << "\" / " << - (IID_IDirect3DTnLHalDevice == d3dGuid ? "Direct3D T&L HAL" : "Direct3D HAL") << - "; changed from " << bitDepthsToString(oldBitDepths) << " to " << bitDepthsToString(newBitDepths); - } -} - -namespace Direct3d -{ - namespace DepthBuffer - { - template - void fixSupportedZBufferBitDepths( - CompatPtr d3d, TD3dDeviceDesc& desc) - { - if (isHardwareZBufferSupported(desc)) - { - const DWORD supportedBitDepths = getSupportedZBufferBitDepths(d3d, getDeviceGuid(desc)); - if (0 != supportedBitDepths && supportedBitDepths != desc.dwDeviceZBufferBitDepth) - { - logSupportedZBufferBitDepthsChanged( - d3d, getDeviceGuid(desc), desc.dwDeviceZBufferBitDepth, supportedBitDepths); - desc.dwDeviceZBufferBitDepth = supportedBitDepths; - } - } - } - - template void fixSupportedZBufferBitDepths(CompatPtr, D3DDEVICEDESC&); - template void fixSupportedZBufferBitDepths(CompatPtr, D3DDEVICEDESC7&); - } -} diff --git a/DDrawCompat/Direct3d/DepthBuffer.h b/DDrawCompat/Direct3d/DepthBuffer.h deleted file mode 100644 index 1d5c8bb..0000000 --- a/DDrawCompat/Direct3d/DepthBuffer.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "Common/CompatPtr.h" - -namespace Direct3d -{ - namespace DepthBuffer - { - template - void fixSupportedZBufferBitDepths(CompatPtr d3d, TD3dDeviceDesc& desc); - } -} diff --git a/DDrawCompat/Direct3d/Direct3d.cpp b/DDrawCompat/Direct3d/Direct3d.cpp index 008e821..b226713 100644 --- a/DDrawCompat/Direct3d/Direct3d.cpp +++ b/DDrawCompat/Direct3d/Direct3d.cpp @@ -1,19 +1,10 @@ -#include "Common/CompatPtr.h" -#include "Direct3d/DepthBuffer.h" -#include "Direct3d/Direct3d.h" -#include "Direct3d/Direct3dDevice.h" -#include "Direct3d/Types.h" +#include +#include +#include +#include namespace { - template - struct EnumDevicesParams - { - CompatPtr d3d; - typename Direct3d::Types::TD3dEnumDevicesCallback enumDevicesCallback; - void* userArg; - }; - template HRESULT STDMETHODCALLTYPE createDevice( TDirect3d* This, @@ -31,50 +22,6 @@ namespace return result; } - HRESULT CALLBACK d3dEnumDevicesCallback( - GUID* lpGuid, - LPSTR lpDeviceDescription, - LPSTR lpDeviceName, - LPD3DDEVICEDESC lpD3DHWDeviceDesc, - LPD3DDEVICEDESC lpD3DHELDeviceDesc, - LPVOID lpContext) - { - auto& params = *reinterpret_cast*>(lpContext); - Direct3d::DepthBuffer::fixSupportedZBufferBitDepths(params.d3d, *lpD3DHWDeviceDesc); - return params.enumDevicesCallback(lpGuid, lpDeviceDescription, lpDeviceName, - lpD3DHWDeviceDesc, lpD3DHELDeviceDesc, params.userArg); - } - - HRESULT CALLBACK d3dEnumDevicesCallback( - LPSTR lpDeviceDescription, - LPSTR lpDeviceName, - LPD3DDEVICEDESC7 lpD3DDeviceDesc, - LPVOID lpContext) - { - auto& params = *reinterpret_cast*>(lpContext); - Direct3d::DepthBuffer::fixSupportedZBufferBitDepths(params.d3d, *lpD3DDeviceDesc); - return params.enumDevicesCallback(lpDeviceDescription, lpDeviceName, - lpD3DDeviceDesc, params.userArg); - } - - template - HRESULT STDMETHODCALLTYPE enumDevices( - TDirect3d* This, TD3dEnumDevicesCallback lpEnumDevicesCallback, LPVOID lpUserArg) - { - if (!lpEnumDevicesCallback) - { - return CompatVtable>::s_origVtable.EnumDevices( - This, lpEnumDevicesCallback, lpUserArg); - } - - typedef typename Direct3d::Types::TDirect3dHighest TDirect3dHighest; - CompatPtr d3d(Compat::queryInterface(This)); - - EnumDevicesParams params = { d3d, lpEnumDevicesCallback, lpUserArg }; - return CompatVtable>::s_origVtable.EnumDevices( - This, &d3dEnumDevicesCallback, ¶ms); - } - void setCompatVtable2(IDirect3DVtbl& /*vtable*/) { } @@ -91,8 +38,6 @@ namespace Direct3d template void Direct3d::setCompatVtable(Vtable& vtable) { - vtable.EnumDevices = &enumDevices; - // No need to fix FindDevice since it uses EnumDevices setCompatVtable2(vtable); } diff --git a/DDrawCompat/Direct3d/Direct3dDevice.cpp b/DDrawCompat/Direct3d/Direct3dDevice.cpp index 0848545..9c69450 100644 --- a/DDrawCompat/Direct3d/Direct3dDevice.cpp +++ b/DDrawCompat/Direct3d/Direct3dDevice.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -18,34 +17,6 @@ namespace return result; } - template - void fixSupportedZBufferBitDepths(CompatRef d3dDevice, TD3dDeviceDesc& desc) - { - typedef typename Direct3d::Types::TDirect3d TDirect3d; - CompatPtr d3d; - if (SUCCEEDED(CompatVtable>::s_origVtable.GetDirect3D( - &d3dDevice, &d3d.getRef()))) - { - typedef typename Direct3d::Types::TDirect3dHighest TDirect3dHighest; - Direct3d::DepthBuffer::fixSupportedZBufferBitDepths(d3d, desc); - } - } - - template - HRESULT STDMETHODCALLTYPE getCaps( - TDirect3dDevice* This, - TD3dDeviceDesc* lpD3DHWDevDesc, - Params... params) - { - HRESULT result = CompatVtable>::s_origVtable.GetCaps( - This, lpD3DHWDevDesc, params...); - if (SUCCEEDED(result)) - { - fixSupportedZBufferBitDepths(*This, *lpD3DHWDevDesc); - } - return result; - } - void setCompatVtable(IDirect3DDeviceVtbl& vtable) { vtable.Execute = &execute; @@ -63,7 +34,6 @@ namespace Direct3d void Direct3dDevice::setCompatVtable(Vtable& vtable) { ::setCompatVtable(vtable); - vtable.GetCaps = &getCaps; } template Direct3dDevice;