mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Moved z-buffer bit depth caps fix to driver level
This commit is contained in:
parent
f3718272cd
commit
050248a552
@ -1,12 +1,32 @@
|
||||
#include <guiddef.h>
|
||||
#include <d3dnthal.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "D3dDdi/Adapter.h"
|
||||
#include "D3dDdi/AdapterFuncs.h"
|
||||
#include "D3dDdi/DeviceCallbacks.h"
|
||||
#include "D3dDdi/DeviceFuncs.h"
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/AdapterFuncs.h>
|
||||
#include <D3dDdi/DeviceCallbacks.h>
|
||||
#include <D3dDdi/DeviceFuncs.h>
|
||||
|
||||
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<DDRAW_CAPS*>(pData->pData)->FxCaps =
|
||||
DDRAW_FXCAPS_BLTMIRRORLEFTRIGHT | DDRAW_FXCAPS_BLTMIRRORUPDOWN;
|
||||
break;
|
||||
|
||||
case D3DDDICAPS_GETD3D3CAPS:
|
||||
{
|
||||
auto& caps = static_cast<D3DNTHAL_GLOBALDRIVERDATA*>(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> 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
|
||||
|
@ -193,7 +193,6 @@
|
||||
<ClInclude Include="DDraw\Visitors\DirectDrawPaletteVtblVisitor.h" />
|
||||
<ClInclude Include="DDraw\Visitors\DirectDrawSurfaceVtblVisitor.h" />
|
||||
<ClInclude Include="DDraw\Visitors\DirectDrawVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\DepthBuffer.h" />
|
||||
<ClInclude Include="Direct3d\Direct3d.h" />
|
||||
<ClInclude Include="Direct3d\Direct3dDevice.h" />
|
||||
<ClInclude Include="Direct3d\Direct3dExecuteBuffer.h" />
|
||||
@ -275,7 +274,6 @@
|
||||
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
|
||||
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
|
||||
<ClCompile Include="DDraw\Surfaces\SurfaceImpl.cpp" />
|
||||
<ClCompile Include="Direct3d\DepthBuffer.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3d.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3dDevice.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3dExecuteBuffer.cpp" />
|
||||
|
@ -138,9 +138,6 @@
|
||||
<ClInclude Include="Direct3d\Direct3dDevice.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3d\DepthBuffer.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3d\Types.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
@ -455,9 +452,6 @@
|
||||
<ClCompile Include="Direct3d\Direct3dDevice.cpp">
|
||||
<Filter>Source Files\Direct3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Direct3d\DepthBuffer.cpp">
|
||||
<Filter>Source Files\Direct3d</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Direct3d\Hooks.cpp">
|
||||
<Filter>Source Files\Direct3d</Filter>
|
||||
</ClCompile>
|
||||
|
@ -1,124 +0,0 @@
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#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<uint64_t>(1) << lpDDPixFmt->dwZBufferBitDepth) - 1 == lpDDPixFmt->dwZBitMask)
|
||||
{
|
||||
DWORD& supportedBitDepths = *reinterpret_cast<DWORD*>(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 <typename TDirect3d>
|
||||
DWORD getSupportedZBufferBitDepths(CompatPtr<TDirect3d> 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<IDirectDraw7> 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<DeviceId> 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 <typename TDirect3d, typename TD3dDeviceDesc>
|
||||
void fixSupportedZBufferBitDepths(
|
||||
CompatPtr<TDirect3d> 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<IDirect3D3>, D3DDEVICEDESC&);
|
||||
template void fixSupportedZBufferBitDepths(CompatPtr<IDirect3D7>, D3DDEVICEDESC7&);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <guiddef.h>
|
||||
|
||||
#include "Common/CompatPtr.h"
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
namespace DepthBuffer
|
||||
{
|
||||
template <typename TDirect3d, typename TD3dDeviceDesc>
|
||||
void fixSupportedZBufferBitDepths(CompatPtr<TDirect3d> d3d, TD3dDeviceDesc& desc);
|
||||
}
|
||||
}
|
@ -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 <Common/CompatPtr.h>
|
||||
#include <Direct3d/Direct3d.h>
|
||||
#include <Direct3d/Direct3dDevice.h>
|
||||
#include <Direct3d/Types.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename TDirect3d>
|
||||
struct EnumDevicesParams
|
||||
{
|
||||
CompatPtr<TDirect3d> d3d;
|
||||
typename Direct3d::Types<TDirect3d>::TD3dEnumDevicesCallback enumDevicesCallback;
|
||||
void* userArg;
|
||||
};
|
||||
|
||||
template <typename TDirect3d, typename TDirectDrawSurface, typename TDirect3dDevice, typename... Params>
|
||||
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<EnumDevicesParams<IDirect3D3>*>(lpContext);
|
||||
Direct3d::DepthBuffer::fixSupportedZBufferBitDepths<IDirect3D3>(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<EnumDevicesParams<IDirect3D7>*>(lpContext);
|
||||
Direct3d::DepthBuffer::fixSupportedZBufferBitDepths<IDirect3D7>(params.d3d, *lpD3DDeviceDesc);
|
||||
return params.enumDevicesCallback(lpDeviceDescription, lpDeviceName,
|
||||
lpD3DDeviceDesc, params.userArg);
|
||||
}
|
||||
|
||||
template <typename TDirect3d, typename TD3dEnumDevicesCallback>
|
||||
HRESULT STDMETHODCALLTYPE enumDevices(
|
||||
TDirect3d* This, TD3dEnumDevicesCallback lpEnumDevicesCallback, LPVOID lpUserArg)
|
||||
{
|
||||
if (!lpEnumDevicesCallback)
|
||||
{
|
||||
return CompatVtable<Vtable<TDirect3d>>::s_origVtable.EnumDevices(
|
||||
This, lpEnumDevicesCallback, lpUserArg);
|
||||
}
|
||||
|
||||
typedef typename Direct3d::Types<TDirect3d>::TDirect3dHighest TDirect3dHighest;
|
||||
CompatPtr<TDirect3dHighest> d3d(Compat::queryInterface<TDirect3dHighest>(This));
|
||||
|
||||
EnumDevicesParams<TDirect3dHighest> params = { d3d, lpEnumDevicesCallback, lpUserArg };
|
||||
return CompatVtable<Vtable<TDirect3d>>::s_origVtable.EnumDevices(
|
||||
This, &d3dEnumDevicesCallback, ¶ms);
|
||||
}
|
||||
|
||||
void setCompatVtable2(IDirect3DVtbl& /*vtable*/)
|
||||
{
|
||||
}
|
||||
@ -91,8 +38,6 @@ namespace Direct3d
|
||||
template <typename TDirect3d>
|
||||
void Direct3d<TDirect3d>::setCompatVtable(Vtable<TDirect3d>& vtable)
|
||||
{
|
||||
vtable.EnumDevices = &enumDevices;
|
||||
// No need to fix FindDevice since it uses EnumDevices
|
||||
setCompatVtable2(vtable);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/CompatRef.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <Direct3d/DepthBuffer.h>
|
||||
#include <Direct3d/Direct3dDevice.h>
|
||||
#include <Direct3d/Types.h>
|
||||
|
||||
@ -18,34 +17,6 @@ namespace
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirect3dDevice, typename TD3dDeviceDesc>
|
||||
void fixSupportedZBufferBitDepths(CompatRef<TDirect3dDevice> d3dDevice, TD3dDeviceDesc& desc)
|
||||
{
|
||||
typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3d TDirect3d;
|
||||
CompatPtr<TDirect3d> d3d;
|
||||
if (SUCCEEDED(CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetDirect3D(
|
||||
&d3dDevice, &d3d.getRef())))
|
||||
{
|
||||
typedef typename Direct3d::Types<TDirect3dDevice>::TDirect3dHighest TDirect3dHighest;
|
||||
Direct3d::DepthBuffer::fixSupportedZBufferBitDepths<TDirect3dHighest>(d3d, desc);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TDirect3dDevice, typename TD3dDeviceDesc, typename... Params>
|
||||
HRESULT STDMETHODCALLTYPE getCaps(
|
||||
TDirect3dDevice* This,
|
||||
TD3dDeviceDesc* lpD3DHWDevDesc,
|
||||
Params... params)
|
||||
{
|
||||
HRESULT result = CompatVtable<Vtable<TDirect3dDevice>>::s_origVtable.GetCaps(
|
||||
This, lpD3DHWDevDesc, params...);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
fixSupportedZBufferBitDepths<TDirect3dDevice>(*This, *lpD3DHWDevDesc);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void setCompatVtable(IDirect3DDeviceVtbl& vtable)
|
||||
{
|
||||
vtable.Execute = &execute;
|
||||
@ -63,7 +34,6 @@ namespace Direct3d
|
||||
void Direct3dDevice<TDirect3dDevice>::setCompatVtable(Vtable<TDirect3dDevice>& vtable)
|
||||
{
|
||||
::setCompatVtable(vtable);
|
||||
vtable.GetCaps = &getCaps;
|
||||
}
|
||||
|
||||
template Direct3dDevice<IDirect3DDevice>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user