From 0edcde6d555e806f86f9811c193a4ab22457c2bd Mon Sep 17 00:00:00 2001 From: narzoul Date: Sun, 23 Oct 2016 14:51:41 +0200 Subject: [PATCH] Force CpuOptimized flag on off-screen plain surfaces This flag forces linear (non-swizzled) surface layout on Intel HD drivers. Fixes issues with games that keep writing to unlocked surfaces (e.g. Nox) as well as greatly increases lock performance. --- DDrawCompat/D3dDdi/DeviceFuncs.cpp | 60 +++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/DDrawCompat/D3dDdi/DeviceFuncs.cpp b/DDrawCompat/D3dDdi/DeviceFuncs.cpp index 5448a6e..65c8722 100644 --- a/DDrawCompat/D3dDdi/DeviceFuncs.cpp +++ b/DDrawCompat/D3dDdi/DeviceFuncs.cpp @@ -101,21 +101,79 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIBOX& box) namespace { + D3DDDI_DEVICEFUNCS& getOrigVtable(HANDLE device); + D3DDDI_RESOURCEFLAGS getResourceTypeFlags(); + void modifyCreateResourceFlags(D3DDDI_RESOURCEFLAGS& flags); + + const UINT g_resourceTypeFlags = getResourceTypeFlags().Value; + + HRESULT APIENTRY createResource(HANDLE hDevice, D3DDDIARG_CREATERESOURCE* pResource) + { + modifyCreateResourceFlags(pResource->Flags); + return getOrigVtable(hDevice).pfnCreateResource(hDevice, pResource); + } + + HRESULT APIENTRY createResource2(HANDLE hDevice, D3DDDIARG_CREATERESOURCE2* pResource2) + { + modifyCreateResourceFlags(pResource2->Flags); + return getOrigVtable(hDevice).pfnCreateResource2(hDevice, pResource2); + } + HRESULT APIENTRY destroyDevice(HANDLE hDevice) { - HRESULT result = D3dDdi::DeviceFuncs::s_origVtables.at(hDevice).pfnDestroyDevice(hDevice); + HRESULT result = getOrigVtable(hDevice).pfnDestroyDevice(hDevice); if (SUCCEEDED(result)) { D3dDdi::DeviceFuncs::s_origVtables.erase(hDevice); } return result; } + + D3DDDI_DEVICEFUNCS& getOrigVtable(HANDLE device) + { + return D3dDdi::DeviceFuncs::s_origVtables.at(device); + } + + D3DDDI_RESOURCEFLAGS getResourceTypeFlags() + { + D3DDDI_RESOURCEFLAGS flags = {}; + flags.RenderTarget = 1; + flags.ZBuffer = 1; + flags.DMap = 1; + flags.Points = 1; + flags.RtPatches = 1; + flags.NPatches = 1; + flags.Video = 1; + flags.CaptureBuffer = 1; + flags.Primary = 1; + flags.Texture = 1; + flags.CubeMap = 1; + flags.VertexBuffer = 1; + flags.IndexBuffer = 1; + flags.DecodeRenderTarget = 1; + flags.DecodeCompressedBuffer = 1; + flags.VideoProcessRenderTarget = 1; + flags.Overlay = 1; + flags.TextApi = 1; + return flags; + } + + void modifyCreateResourceFlags(D3DDDI_RESOURCEFLAGS& flags) + { + const bool isOffScreenPlain = 0 == (flags.Value & g_resourceTypeFlags); + if (isOffScreenPlain) + { + flags.CpuOptimized = 1; + } + } } namespace D3dDdi { void DeviceFuncs::setCompatVtable(D3DDDI_DEVICEFUNCS& vtable) { + vtable.pfnCreateResource = &createResource; + vtable.pfnCreateResource2 = &createResource2; vtable.pfnDestroyDevice = &destroyDevice; } }