diff --git a/DDrawCompat/Common/CompatVtable.h b/DDrawCompat/Common/CompatVtable.h index 633db74..c289e3f 100644 --- a/DDrawCompat/Common/CompatVtable.h +++ b/DDrawCompat/Common/CompatVtable.h @@ -41,17 +41,25 @@ public: } } - static void hookDriverVtable(HANDLE context, const Vtable* vtable) + static void hookDriverVtable(HMODULE module, HANDLE context, const Vtable* vtable) { - if (vtable && s_origVtables.find(context) == s_origVtables.end()) + if (!vtable) { - HookVisitor visitor(*vtable, s_origVtables[context]); + return; + } + + if (s_origModuleVtables.find(module) == s_origModuleVtables.end()) + { + HookVisitor visitor(*vtable, s_origModuleVtables[module]); forEach(visitor); } + + s_origVtables[context] = s_origModuleVtables[module]; } static Vtable s_origVtable; static std::map s_origVtables; + static std::map s_origModuleVtables; static const Vtable* s_origVtablePtr; private: @@ -185,6 +193,9 @@ Vtable CompatVtable::s_origVtable = {}; template std::map CompatVtable::s_origVtables; +template +std::map CompatVtable::s_origModuleVtables; + template const Vtable* CompatVtable::s_origVtablePtr = nullptr; diff --git a/DDrawCompat/D3dDdi/AdapterFuncs.cpp b/DDrawCompat/D3dDdi/AdapterFuncs.cpp index 9ed4787..7113aa2 100644 --- a/DDrawCompat/D3dDdi/AdapterFuncs.cpp +++ b/DDrawCompat/D3dDdi/AdapterFuncs.cpp @@ -7,6 +7,7 @@ namespace { std::map g_d3dExtendedCaps; + std::map g_adapterModule; HRESULT APIENTRY closeAdapter(HANDLE hAdapter) { @@ -15,6 +16,7 @@ namespace { D3dDdi::AdapterFuncs::s_origVtables.erase(hAdapter); g_d3dExtendedCaps.erase(hAdapter); + g_adapterModule.erase(hAdapter); } return result; } @@ -26,7 +28,8 @@ namespace hAdapter, pCreateData); if (SUCCEEDED(result)) { - D3dDdi::DeviceFuncs::hookDriverVtable(pCreateData->hDevice, pCreateData->pDeviceFuncs); + D3dDdi::DeviceFuncs::hookDriverVtable( + g_adapterModule[hAdapter], pCreateData->hDevice, pCreateData->pDeviceFuncs); D3dDdi::DeviceFuncs::onCreateDevice(hAdapter, pCreateData->hDevice); } return result; @@ -52,7 +55,7 @@ namespace D3dDdi return it != g_d3dExtendedCaps.end() ? it->second : emptyCaps; } - void AdapterFuncs::onOpenAdapter(HANDLE adapter) + void AdapterFuncs::onOpenAdapter(HMODULE module, HANDLE adapter) { D3DNTHAL_D3DEXTENDEDCAPS d3dExtendedCaps = {}; D3DDDIARG_GETCAPS getCaps = {}; @@ -62,6 +65,7 @@ namespace D3dDdi D3dDdi::AdapterFuncs::s_origVtables.at(adapter).pfnGetCaps(adapter, &getCaps); g_d3dExtendedCaps[adapter] = d3dExtendedCaps; + g_adapterModule[adapter] = module; } void AdapterFuncs::setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable) diff --git a/DDrawCompat/D3dDdi/AdapterFuncs.h b/DDrawCompat/D3dDdi/AdapterFuncs.h index 22bcf82..17c3efd 100644 --- a/DDrawCompat/D3dDdi/AdapterFuncs.h +++ b/DDrawCompat/D3dDdi/AdapterFuncs.h @@ -14,7 +14,7 @@ namespace D3dDdi { public: static const D3DNTHAL_D3DEXTENDEDCAPS& getD3dExtendedCaps(HANDLE adapter); - static void onOpenAdapter(HANDLE adapter); + static void onOpenAdapter(HMODULE module, HANDLE adapter); static void setCompatVtable(D3DDDI_ADAPTERFUNCS& vtable); }; } diff --git a/DDrawCompat/D3dDdi/Device.cpp b/DDrawCompat/D3dDdi/Device.cpp index d80c176..c1ede7b 100644 --- a/DDrawCompat/D3dDdi/Device.cpp +++ b/DDrawCompat/D3dDdi/Device.cpp @@ -162,7 +162,7 @@ namespace D3dDdi if (SUCCEEDED(result)) { m_oversizedResources.emplace(data.hResource, - OversizedResource(m_adapter, m_device, data.Format, origSurfList[0])); + OversizedResource(*m_origVtable, m_adapter, m_device, data.Format, origSurfList[0])); } return result; @@ -191,7 +191,7 @@ namespace D3dDdi if (SUCCEEDED(result) && data.Flags.RenderTarget && !data.Flags.Primary && isVidMemPool(data.Pool)) { m_renderTargetResources.emplace(data.hResource, - RenderTargetResource(m_device, data.hResource, data.Format, data.SurfCount)); + RenderTargetResource(*m_origVtable, m_device, data.hResource, data.Format, data.SurfCount)); } return result; diff --git a/DDrawCompat/D3dDdi/Hooks.cpp b/DDrawCompat/D3dDdi/Hooks.cpp index 0c1daeb..8abaa2f 100644 --- a/DDrawCompat/D3dDdi/Hooks.cpp +++ b/DDrawCompat/D3dDdi/Hooks.cpp @@ -26,6 +26,7 @@ namespace { UINT g_ddiVersion = 0; std::wstring g_hookedUmdFileName; + HMODULE g_hookedUmdModule = nullptr; PFND3DDDI_OPENADAPTER g_origOpenAdapter = nullptr; void hookOpenAdapter(const std::wstring& umdFileName); @@ -35,12 +36,12 @@ namespace void hookOpenAdapter(const std::wstring& umdFileName) { g_hookedUmdFileName = umdFileName; - HMODULE module = LoadLibraryW(umdFileName.c_str()); - if (module) + g_hookedUmdModule = LoadLibraryW(umdFileName.c_str()); + if (g_hookedUmdModule) { - Compat::hookFunction(module, "OpenAdapter", + Compat::hookFunction(g_hookedUmdModule, "OpenAdapter", reinterpret_cast(g_origOpenAdapter), &openAdapter); - FreeLibrary(module); + FreeLibrary(g_hookedUmdModule); } } @@ -58,8 +59,8 @@ namespace hookedUmdFileNames.insert(g_hookedUmdFileName); } g_ddiVersion = min(pOpenData->Version, pOpenData->DriverVersion); - D3dDdi::AdapterFuncs::hookDriverVtable(pOpenData->hAdapter, pOpenData->pAdapterFuncs); - D3dDdi::AdapterFuncs::onOpenAdapter(pOpenData->hAdapter); + D3dDdi::AdapterFuncs::hookDriverVtable(g_hookedUmdModule, pOpenData->hAdapter, pOpenData->pAdapterFuncs); + D3dDdi::AdapterFuncs::onOpenAdapter(g_hookedUmdModule, pOpenData->hAdapter); } return LOG_RESULT(result); } diff --git a/DDrawCompat/D3dDdi/OversizedResource.cpp b/DDrawCompat/D3dDdi/OversizedResource.cpp index 6efa91f..38fa7ec 100644 --- a/DDrawCompat/D3dDdi/OversizedResource.cpp +++ b/DDrawCompat/D3dDdi/OversizedResource.cpp @@ -6,8 +6,10 @@ namespace D3dDdi { OversizedResource::OversizedResource( - HANDLE adapter, HANDLE device, D3DDDIFORMAT format, const D3DDDI_SURFACEINFO& surfaceInfo) - : m_adapter(adapter) + const D3DDDI_DEVICEFUNCS& deviceFuncs, HANDLE adapter, HANDLE device, + D3DDDIFORMAT format, const D3DDDI_SURFACEINFO& surfaceInfo) + : m_deviceFuncs(deviceFuncs) + , m_adapter(adapter) , m_device(device) , m_format(format) , m_surfaceInfo(surfaceInfo) @@ -20,7 +22,7 @@ namespace D3dDdi if (rect.right <= static_cast(caps.dwMaxTextureWidth) && rect.bottom <= static_cast(caps.dwMaxTextureHeight)) { - return D3dDdi::DeviceFuncs::s_origVtables.at(m_device).pfnBlt(m_device, &data); + return m_deviceFuncs.pfnBlt(m_device, &data); } HANDLE origResource = resource; @@ -33,14 +35,13 @@ namespace D3dDdi rect = RECT{ 0, 0, rect.right - rect.left, rect.bottom - rect.top }; } - const auto& deviceFuncs = D3dDdi::DeviceFuncs::s_origVtables.at(m_device); - HRESULT result = deviceFuncs.pfnBlt(m_device, &data); + HRESULT result = m_deviceFuncs.pfnBlt(m_device, &data); if (bltResource) { resource = origResource; rect = origRect; - deviceFuncs.pfnDestroyResource(m_device, bltResource); + m_deviceFuncs.pfnDestroyResource(m_device, bltResource); } return result; @@ -76,14 +77,13 @@ namespace D3dDdi bltResourceData.pSurfList = &bltSurfaceInfo; bltResourceData.SurfCount = 1; - const auto& deviceFuncs = D3dDdi::DeviceFuncs::s_origVtables.at(m_device); - if (deviceFuncs.pfnCreateResource2) + if (m_deviceFuncs.pfnCreateResource2) { - deviceFuncs.pfnCreateResource2(m_device, &bltResourceData); + m_deviceFuncs.pfnCreateResource2(m_device, &bltResourceData); } else { - deviceFuncs.pfnCreateResource(m_device, + m_deviceFuncs.pfnCreateResource(m_device, reinterpret_cast(&bltResourceData)); } return bltResourceData.hResource; diff --git a/DDrawCompat/D3dDdi/OversizedResource.h b/DDrawCompat/D3dDdi/OversizedResource.h index ea2e496..727527f 100644 --- a/DDrawCompat/D3dDdi/OversizedResource.h +++ b/DDrawCompat/D3dDdi/OversizedResource.h @@ -8,7 +8,7 @@ namespace D3dDdi class OversizedResource { public: - OversizedResource(HANDLE adapter, HANDLE device, + OversizedResource(const D3DDDI_DEVICEFUNCS& deviceFuncs, HANDLE adapter, HANDLE device, D3DDDIFORMAT format, const D3DDDI_SURFACEINFO& surfaceInfo); HRESULT bltFrom(D3DDDIARG_BLT data); @@ -20,6 +20,7 @@ namespace D3dDdi HRESULT blt(D3DDDIARG_BLT& data, HANDLE& resource, RECT& rect); HANDLE createBltResource(RECT bltRect); + const D3DDDI_DEVICEFUNCS& m_deviceFuncs; HANDLE m_adapter; HANDLE m_device; D3DDDIFORMAT m_format; diff --git a/DDrawCompat/D3dDdi/RenderTargetResource.cpp b/DDrawCompat/D3dDdi/RenderTargetResource.cpp index 4ab7b90..a0095b7 100644 --- a/DDrawCompat/D3dDdi/RenderTargetResource.cpp +++ b/DDrawCompat/D3dDdi/RenderTargetResource.cpp @@ -4,9 +4,10 @@ namespace D3dDdi { - RenderTargetResource::RenderTargetResource( + RenderTargetResource::RenderTargetResource(const D3DDDI_DEVICEFUNCS& deviceFuncs, HANDLE device, HANDLE resource, D3DDDIFORMAT format, UINT surfaceCount) - : m_device(device) + : m_deviceFuncs(deviceFuncs) + , m_device(device) , m_resource(resource) , m_bytesPerPixel(getBytesPerPixel(format)) , m_subResources(surfaceCount, SubResource(*this)) @@ -17,7 +18,7 @@ namespace D3dDdi { if (data.SubResourceIndex >= m_subResources.size()) { - return D3dDdi::DeviceFuncs::s_origVtables.at(m_device).pfnLock(m_device, &data); + return m_deviceFuncs.pfnLock(m_device, &data); } auto& subResource = m_subResources[data.SubResourceIndex]; @@ -36,7 +37,7 @@ namespace D3dDdi const UINT origFlags = data.Flags.Value; data.Flags.Value = 0; - const HRESULT result = D3dDdi::DeviceFuncs::s_origVtables.at(m_device).pfnLock(m_device, &data); + const HRESULT result = m_deviceFuncs.pfnLock(m_device, &data); data.Flags.Value = origFlags; if (SUCCEEDED(result)) @@ -54,7 +55,7 @@ namespace D3dDdi { if (data.SubResourceIndex >= m_subResources.size()) { - return D3dDdi::DeviceFuncs::s_origVtables.at(m_device).pfnUnlock(m_device, &data); + return m_deviceFuncs.pfnUnlock(m_device, &data); } m_subResources[data.SubResourceIndex].isLocked = false; @@ -88,7 +89,7 @@ namespace D3dDdi D3DDDIARG_UNLOCK data = {}; data.hResource = m_resource; data.SubResourceIndex = subResourceIndex; - D3dDdi::DeviceFuncs::s_origVtables.at(m_device).pfnUnlock(m_device, &data); + m_deviceFuncs.pfnUnlock(m_device, &data); subResource.surfacePtr = nullptr; subResource.pitch = 0; diff --git a/DDrawCompat/D3dDdi/RenderTargetResource.h b/DDrawCompat/D3dDdi/RenderTargetResource.h index 7eee00b..438c63e 100644 --- a/DDrawCompat/D3dDdi/RenderTargetResource.h +++ b/DDrawCompat/D3dDdi/RenderTargetResource.h @@ -11,7 +11,8 @@ namespace D3dDdi class RenderTargetResource { public: - RenderTargetResource(HANDLE device, HANDLE resource, D3DDDIFORMAT format, UINT surfaceCount); + RenderTargetResource(const D3DDDI_DEVICEFUNCS& deviceFuncs, + HANDLE device, HANDLE resource, D3DDDIFORMAT format, UINT surfaceCount); HRESULT lock(D3DDDIARG_LOCK& data); HRESULT unlock(const D3DDDIARG_UNLOCK& data); @@ -33,6 +34,7 @@ namespace D3dDdi void prepareSubResourceForRendering(UINT subResourceIndex); + const D3DDDI_DEVICEFUNCS& m_deviceFuncs; HANDLE m_device; HANDLE m_resource; UINT m_bytesPerPixel;