From 553b209b552aacb25cef5e40895c8fd4368c792b Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Tue, 28 Feb 2023 01:16:53 -0600 Subject: [PATCH 1/4] Add VS project --- atelier-sync-fix.sln | 25 +++++++++++ atelier-sync-fix.vcxproj | 97 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 atelier-sync-fix.sln create mode 100644 atelier-sync-fix.vcxproj diff --git a/atelier-sync-fix.sln b/atelier-sync-fix.sln new file mode 100644 index 0000000..9dae6b3 --- /dev/null +++ b/atelier-sync-fix.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.4.33205.214 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "atelier-sync-fix", "atelier-sync-fix.vcxproj", "{CE4B1C78-E0CD-4DE8-80F9-58929657E541}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CE4B1C78-E0CD-4DE8-80F9-58929657E541}.Debug|x64.ActiveCfg = Debug|x64 + {CE4B1C78-E0CD-4DE8-80F9-58929657E541}.Debug|x64.Build.0 = Debug|x64 + {CE4B1C78-E0CD-4DE8-80F9-58929657E541}.Release|x64.ActiveCfg = Release|x64 + {CE4B1C78-E0CD-4DE8-80F9-58929657E541}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8432BF76-4884-4C65-9A0B-3A0D65E71A4B} + EndGlobalSection +EndGlobal diff --git a/atelier-sync-fix.vcxproj b/atelier-sync-fix.vcxproj new file mode 100644 index 0000000..e788672 --- /dev/null +++ b/atelier-sync-fix.vcxproj @@ -0,0 +1,97 @@ + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {ce4b1c78-e0cd-4de8-80f9-58929657e541} + atelier-sync-fix + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + d3d11 + + + + Level3 + _CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0xa00;NOMINMAX;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + stdcpp17 + + + Windows + true + false + d3d11.def + + + + + true + _DEBUG;%(PreprocessorDefinitions) + + + + + true + true + true + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file From b8c997257fa6aee0fea458876ebecc837adc5580 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Tue, 28 Feb 2023 01:16:31 -0600 Subject: [PATCH 2/4] Add windows support Windows ID3D11DeviceContext likes rewriting its own vtable pointers, so we can't hook it that way --- impl.cpp | 595 ++++++++++++++++++++++++++++--------------------------- impl.h | 2 +- main.cpp | 4 +- 3 files changed, 309 insertions(+), 292 deletions(-) diff --git a/impl.cpp b/impl.cpp index 85f7a56..13956f6 100644 --- a/impl.cpp +++ b/impl.cpp @@ -11,6 +11,7 @@ using PFN_ID3D11Device_CreateBuffer = HRESULT (STDMETHODCALLTYPE *) (ID3D11Devic const D3D11_BUFFER_DESC*, const D3D11_SUBRESOURCE_DATA*, ID3D11Buffer**); using PFN_ID3D11Device_CreateDeferredContext = HRESULT (STDMETHODCALLTYPE *) (ID3D11Device*, UINT, ID3D11DeviceContext**); +using PFN_ID3D11Device_GetImmediateContext = void(STDMETHODCALLTYPE*) (ID3D11Device*, ID3D11DeviceContext**); using PFN_ID3D11Device_CreateTexture1D = HRESULT (STDMETHODCALLTYPE *) (ID3D11Device*, const D3D11_TEXTURE1D_DESC*, const D3D11_SUBRESOURCE_DATA*, ID3D11Texture1D**); using PFN_ID3D11Device_CreateTexture2D = HRESULT (STDMETHODCALLTYPE *) (ID3D11Device*, @@ -18,61 +19,21 @@ using PFN_ID3D11Device_CreateTexture2D = HRESULT (STDMETHODCALLTYPE *) (ID3D11De using PFN_ID3D11Device_CreateTexture3D = HRESULT (STDMETHODCALLTYPE *) (ID3D11Device*, const D3D11_TEXTURE3D_DESC*, const D3D11_SUBRESOURCE_DATA*, ID3D11Texture3D**); -using PFN_ID3D11DeviceContext_ClearRenderTargetView = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11RenderTargetView*, const FLOAT[4]); -using PFN_ID3D11DeviceContext_ClearUnorderedAccessViewFloat = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11UnorderedAccessView*, const FLOAT[4]); -using PFN_ID3D11DeviceContext_ClearUnorderedAccessViewUint = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11UnorderedAccessView*, const UINT[4]); -using PFN_ID3D11DeviceContext_CopyResource = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11Resource*, ID3D11Resource*); -using PFN_ID3D11DeviceContext_CopySubresourceRegion = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11Resource*, UINT, UINT, UINT, UINT, ID3D11Resource*, UINT, const D3D11_BOX*); -using PFN_ID3D11DeviceContext_CopyStructureCount = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11Buffer*, UINT, ID3D11UnorderedAccessView*); -using PFN_ID3D11DeviceContext_Dispatch = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - UINT, UINT, UINT); -using PFN_ID3D11DeviceContext_DispatchIndirect = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11Buffer*, UINT); -using PFN_ID3D11DeviceContext_OMSetRenderTargets = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - UINT, ID3D11RenderTargetView* const*, ID3D11DepthStencilView*); -using PFN_ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - UINT, ID3D11RenderTargetView* const*, ID3D11DepthStencilView*, UINT, UINT, ID3D11UnorderedAccessView* const*, const UINT*); -using PFN_ID3D11DeviceContext_UpdateSubresource = void (STDMETHODCALLTYPE *) (ID3D11DeviceContext*, - ID3D11Resource*, UINT, const D3D11_BOX*, const void*, UINT, UINT); - struct DeviceProcs { PFN_ID3D11Device_CreateBuffer CreateBuffer = nullptr; PFN_ID3D11Device_CreateDeferredContext CreateDeferredContext = nullptr; + PFN_ID3D11Device_GetImmediateContext GetImmediateContext = nullptr; PFN_ID3D11Device_CreateTexture1D CreateTexture1D = nullptr; PFN_ID3D11Device_CreateTexture2D CreateTexture2D = nullptr; PFN_ID3D11Device_CreateTexture3D CreateTexture3D = nullptr; }; -struct ContextProcs { - PFN_ID3D11DeviceContext_ClearRenderTargetView ClearRenderTargetView = nullptr; - PFN_ID3D11DeviceContext_ClearUnorderedAccessViewFloat ClearUnorderedAccessViewFloat = nullptr; - PFN_ID3D11DeviceContext_ClearUnorderedAccessViewUint ClearUnorderedAccessViewUint = nullptr; - PFN_ID3D11DeviceContext_CopyResource CopyResource = nullptr; - PFN_ID3D11DeviceContext_CopySubresourceRegion CopySubresourceRegion = nullptr; - PFN_ID3D11DeviceContext_CopyStructureCount CopyStructureCount = nullptr; - PFN_ID3D11DeviceContext_Dispatch Dispatch = nullptr; - PFN_ID3D11DeviceContext_DispatchIndirect DispatchIndirect = nullptr; - PFN_ID3D11DeviceContext_OMSetRenderTargets OMSetRenderTargets = nullptr; - PFN_ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews OMSetRenderTargetsAndUnorderedAccessViews = nullptr; - PFN_ID3D11DeviceContext_UpdateSubresource UpdateSubresource = nullptr; -}; - static mutex g_hookMutex; static mutex g_globalMutex; DeviceProcs g_deviceProcs; -ContextProcs g_immContextProcs; -ContextProcs g_defContextProcs; constexpr uint32_t HOOK_DEVICE = (1u << 0); -constexpr uint32_t HOOK_IMM_CTX = (1u << 1); -constexpr uint32_t HOOK_DEF_CTX = (1u << 2); uint32_t g_installedHooks = 0u; @@ -80,12 +41,6 @@ const DeviceProcs* getDeviceProcs(ID3D11Device* pDevice) { return &g_deviceProcs; } -const ContextProcs* getContextProcs(ID3D11DeviceContext* pContext) { - return pContext->GetType() == D3D11_DEVICE_CONTEXT_IMMEDIATE - ? &g_immContextProcs - : &g_defContextProcs; -} - /** Metadata */ static const GUID IID_StagingShadowResource = {0xe2728d91,0x9fdd,0x40d0,{0x87,0xa8,0x09,0xb6,0x2d,0xf3,0x14,0x9a}}; @@ -263,8 +218,6 @@ bool isCpuReadableResource( ID3D11Resource* createShadowResourceLocked( ID3D11DeviceContext* pContext, ID3D11Resource* pBaseResource) { - auto procs = getContextProcs(pContext); - ID3D11Device* device = nullptr; pContext->GetDevice(&device); @@ -358,7 +311,7 @@ ID3D11Resource* createShadowResourceLocked( } if (SUCCEEDED(hr)) { - procs->CopyResource(pContext, shadowResource, pBaseResource); + pContext->CopyResource(shadowResource, pBaseResource); pBaseResource->SetPrivateDataInterface(IID_StagingShadowResource, shadowResource); } else log("Failed to create shadow resource, hr ", std::hex, hr); @@ -399,7 +352,6 @@ ID3D11Resource* getOrCreateShadowResource( void updateViewShadowResource( ID3D11DeviceContext* pContext, ID3D11View* pView) { - auto procs = getContextProcs(pContext); ID3D11Resource* baseResource; pView->GetResource(&baseResource); @@ -493,7 +445,7 @@ void updateViewShadowResource( for (uint32_t i = 0; i < layerCount; i++) { uint32_t subresource = D3D11CalcSubresource(mipLevel, layerIndex + i, resourceInfo.Mips); - procs->CopySubresourceRegion(pContext, + pContext->CopySubresourceRegion( shadowResource, subresource, 0, 0, 0, baseResource, subresource, nullptr); } @@ -547,6 +499,14 @@ HRESULT STDMETHODCALLTYPE ID3D11Device_CreateBuffer( return procs->CreateBuffer(pDevice, pDesc, pData, ppBuffer); } +void STDMETHODCALLTYPE ID3D11Device_GetImmediateContext( + ID3D11Device* pDevice, + ID3D11DeviceContext** ppImmediateContext) { + auto procs = getDeviceProcs(pDevice); + procs->GetImmediateContext(pDevice, ppImmediateContext); + *ppImmediateContext = hookContext(*ppImmediateContext); +} + HRESULT STDMETHODCALLTYPE ID3D11Device_CreateDeferredContext( ID3D11Device* pDevice, UINT Flags, @@ -555,8 +515,7 @@ HRESULT STDMETHODCALLTYPE ID3D11Device_CreateDeferredContext( HRESULT hr = procs->CreateDeferredContext(pDevice, Flags, ppDeferredContext); if (SUCCEEDED(hr) && ppDeferredContext) - hookContext(*ppDeferredContext); - + *ppDeferredContext = hookContext(*ppDeferredContext); return hr; } @@ -611,39 +570,6 @@ HRESULT STDMETHODCALLTYPE ID3D11Device_CreateTexture3D( return procs->CreateTexture3D(pDevice, pDesc, pData, ppTexture); } -void STDMETHODCALLTYPE ID3D11DeviceContext_ClearRenderTargetView( - ID3D11DeviceContext* pContext, - ID3D11RenderTargetView* pRTV, - const FLOAT pColor[4]) { - auto procs = getContextProcs(pContext); - procs->ClearRenderTargetView(pContext, pRTV, pColor); - - if (pRTV) - updateViewShadowResource(pContext, pRTV); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_ClearUnorderedAccessViewFloat( - ID3D11DeviceContext* pContext, - ID3D11UnorderedAccessView* pUAV, - const FLOAT pColor[4]) { - auto procs = getContextProcs(pContext); - procs->ClearUnorderedAccessViewFloat(pContext, pUAV, pColor); - - if (pUAV) - updateViewShadowResource(pContext, pUAV); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_ClearUnorderedAccessViewUint( - ID3D11DeviceContext* pContext, - ID3D11UnorderedAccessView* pUAV, - const UINT pColor[4]) { - auto procs = getContextProcs(pContext); - procs->ClearUnorderedAccessViewUint(pContext, pUAV, pColor); - - if (pUAV) - updateViewShadowResource(pContext, pUAV); -} - HRESULT tryCpuCopy( ID3D11DeviceContext* pContext, ID3D11Resource* pDstResource, @@ -766,181 +692,6 @@ HRESULT tryCpuCopy( return S_OK; } -void STDMETHODCALLTYPE ID3D11DeviceContext_CopyResource( - ID3D11DeviceContext* pContext, - ID3D11Resource* pDstResource, - ID3D11Resource* pSrcResource) { - auto procs = getContextProcs(pContext); - - ID3D11Resource* dstShadow = getShadowResource(pDstResource); - - bool needsBaseCopy = true; - bool needsShadowCopy = true; - - if (isImmediatecontext(pContext)) { - HRESULT hr = tryCpuCopy(pContext, pDstResource, - 0, 0, 0, 0, pSrcResource, 0, nullptr); - needsBaseCopy = FAILED(hr); - - if (!needsBaseCopy && dstShadow) { - hr = tryCpuCopy(pContext, dstShadow, - 0, 0, 0, 0, pSrcResource, 0, nullptr); - needsShadowCopy = FAILED(hr); - } - } - - if (needsBaseCopy) - procs->CopyResource(pContext, pDstResource, pSrcResource); - - if (dstShadow) { - if (needsShadowCopy) - procs->CopyResource(pContext, dstShadow, pSrcResource); - - dstShadow->Release(); - } -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_CopySubresourceRegion( - ID3D11DeviceContext* pContext, - ID3D11Resource* pDstResource, - UINT DstSubresource, - UINT DstX, - UINT DstY, - UINT DstZ, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - const D3D11_BOX* pSrcBox) { - auto procs = getContextProcs(pContext); - - ID3D11Resource* dstShadow = getShadowResource(pDstResource); - - bool needsBaseCopy = true; - bool needsShadowCopy = true; - - if (isImmediatecontext(pContext)) { - HRESULT hr = tryCpuCopy(pContext, - pDstResource, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox); - needsBaseCopy = FAILED(hr); - - if (!needsBaseCopy && dstShadow) { - hr = tryCpuCopy(pContext, - dstShadow, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox); - needsShadowCopy = FAILED(hr); - } - } - - if (needsBaseCopy) { - procs->CopySubresourceRegion(pContext, - pDstResource, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox); - } - - if (dstShadow) { - if (needsShadowCopy) { - ATFIX_RESOURCE_INFO srcInfo = { }; - getResourceInfo(pSrcResource, &srcInfo); - - procs->CopySubresourceRegion(pContext, - dstShadow, DstSubresource, DstX, DstY, DstZ, - pSrcResource, SrcSubresource, pSrcBox); - } - - dstShadow->Release(); - } -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_CopyStructureCount( - ID3D11DeviceContext* pContext, - ID3D11Buffer* pDstBuffer, - UINT DstOffset, - ID3D11UnorderedAccessView* pSrcUav) { - auto procs = getContextProcs(pContext); - procs->CopyStructureCount(pContext, pDstBuffer, DstOffset, pSrcUav); - - ID3D11Resource* shadowResource = getShadowResource(pDstBuffer); - ID3D11Buffer* shadowBuffer = nullptr; - - if (shadowResource) { - shadowResource->QueryInterface(IID_PPV_ARGS(&shadowBuffer)); - shadowResource->Release(); - - procs->CopyStructureCount(pContext, shadowBuffer, DstOffset, pSrcUav); - shadowBuffer->Release(); - } -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_Dispatch( - ID3D11DeviceContext* pContext, - UINT X, - UINT Y, - UINT Z) { - auto procs = getContextProcs(pContext); - procs->Dispatch(pContext, X, Y, Z); - - updateUavShadowResources(pContext); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_DispatchIndirect( - ID3D11DeviceContext* pContext, - ID3D11Buffer* pParameterBuffer, - UINT pParameterOffset) { - auto procs = getContextProcs(pContext); - procs->DispatchIndirect(pContext, pParameterBuffer, pParameterOffset); - - updateUavShadowResources(pContext); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_OMSetRenderTargets( - ID3D11DeviceContext* pContext, - UINT RTVCount, - ID3D11RenderTargetView* const* ppRTVs, - ID3D11DepthStencilView* pDSV) { - auto procs = getContextProcs(pContext); - updateRtvShadowResources(pContext); - - procs->OMSetRenderTargets(pContext, RTVCount, ppRTVs, pDSV); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_OMSetRenderTargetsAndUnorderedAccessViews( - ID3D11DeviceContext* pContext, - UINT RTVCount, - ID3D11RenderTargetView* const* ppRTVs, - ID3D11DepthStencilView* pDSV, - UINT UAVIndex, - UINT UAVCount, - ID3D11UnorderedAccessView* const* ppUAVs, - const UINT* pUAVClearValues) { - auto procs = getContextProcs(pContext); - updateRtvShadowResources(pContext); - - procs->OMSetRenderTargetsAndUnorderedAccessViews(pContext, - RTVCount, ppRTVs, pDSV, UAVIndex, UAVCount, ppUAVs, pUAVClearValues); -} - -void STDMETHODCALLTYPE ID3D11DeviceContext_UpdateSubresource( - ID3D11DeviceContext* pContext, - ID3D11Resource* pResource, - UINT Subresource, - const D3D11_BOX* pBox, - const void* pData, - UINT RowPitch, - UINT SlicePitch) { - auto procs = getContextProcs(pContext); - - procs->UpdateSubresource(pContext, pResource, - Subresource, pBox, pData, RowPitch, SlicePitch); - - ID3D11Resource* shadowResource = getShadowResource(pResource); - - if (shadowResource) { - procs->UpdateSubresource(pContext, shadowResource, - Subresource, pBox, pData, RowPitch, SlicePitch); - shadowResource->Release(); - } -} - #define HOOK_PROC(iface, object, table, index, proc) \ hookProc(object, #iface "::" #proc, &table->proc, &iface ## _ ## proc, index) @@ -979,6 +730,7 @@ void hookDevice(ID3D11Device* pDevice) { DeviceProcs* procs = &g_deviceProcs; HOOK_PROC(ID3D11Device, pDevice, procs, 3, CreateBuffer); HOOK_PROC(ID3D11Device, pDevice, procs, 27, CreateDeferredContext); + HOOK_PROC(ID3D11Device, pDevice, procs, 40, GetImmediateContext); HOOK_PROC(ID3D11Device, pDevice, procs, 4, CreateTexture1D); HOOK_PROC(ID3D11Device, pDevice, procs, 5, CreateTexture2D); HOOK_PROC(ID3D11Device, pDevice, procs, 6, CreateTexture3D); @@ -986,39 +738,304 @@ void hookDevice(ID3D11Device* pDevice) { g_installedHooks |= HOOK_DEVICE; } -void hookContext(ID3D11DeviceContext* pContext) { - std::lock_guard lock(g_hookMutex); +class ContextWrapper final : public ID3D11DeviceContext { + LONG refcnt; + ID3D11DeviceContext* ctx; + +public: + ContextWrapper(ID3D11DeviceContext* ctx_) : refcnt(1), ctx(ctx_) {} + + // IUnknown + HRESULT QueryInterface(REFIID riid, void** ppvObject) override { + LPOLESTR iidstr; + if (StringFromIID(riid, &iidstr) == S_OK) { + char buf[64] = {}; + WideCharToMultiByte(CP_UTF8, 0, iidstr, -1, buf, sizeof(buf), nullptr, nullptr); + log("ID3D11DeviceContext QueryInterface ", buf); + CoTaskMemFree(iidstr); + } else { + log("ID3D11DeviceContext QueryInterface "); + } + return ctx->QueryInterface(riid, ppvObject); + } + ULONG AddRef() override { return InterlockedAdd(&refcnt, 1); } + ULONG Release() override { + ULONG res = InterlockedAdd(&refcnt, -1); + if (res == 0) { + ctx->Release(); + delete this; + } + return res; + } - uint32_t flag = HOOK_IMM_CTX; - ContextProcs* procs = &g_immContextProcs; + // ID3D11DeviceChild + void STDMETHODCALLTYPE GetDevice(ID3D11Device** ppDevice) override { ctx->GetDevice(ppDevice); } + HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT* pDataSize, void* pData) override { return ctx->GetPrivateData(guid, pDataSize, pData); } + HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void* pData) override { return ctx->SetPrivateData(guid, DataSize, pData); } + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) override { return ctx->SetPrivateDataInterface(guid, pData); } + + // ID3D11DeviceContext + void VSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->VSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void PSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->PSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void PSSetShader(ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->PSSetShader(pPixelShader, ppClassInstances, NumClassInstances); } + void PSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->PSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void VSSetShader(ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->VSSetShader(pVertexShader, ppClassInstances, NumClassInstances); } + void DrawIndexed(UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) override { ctx->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation); } + void Draw(UINT VertexCount, UINT StartVertexLocation) override { ctx->Draw(VertexCount, StartVertexLocation); } + HRESULT Map(ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) override { return ctx->Map(pResource, Subresource, MapType, MapFlags, pMappedResource); } + void Unmap(ID3D11Resource* pResource, UINT Subresource) override { ctx->Unmap(pResource, Subresource); } + void PSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->PSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void IASetInputLayout(ID3D11InputLayout* pInputLayout) override { ctx->IASetInputLayout(pInputLayout); } + void IASetVertexBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppVertexBuffers, const UINT* pStrides, const UINT* pOffsets) override { ctx->IASetVertexBuffers(StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); } + void IASetIndexBuffer(ID3D11Buffer* pIndexBuffer, DXGI_FORMAT Format, UINT Offset) override { ctx->IASetIndexBuffer(pIndexBuffer, Format, Offset); } + void DrawIndexedInstanced(UINT IndexCountPerInstance, UINT InstanceCount, UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) override { ctx->DrawIndexedInstanced(IndexCountPerInstance, InstanceCount, StartIndexLocation, BaseVertexLocation, StartInstanceLocation); } + void DrawInstanced(UINT VertexCountPerInstance, UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) override { ctx->DrawInstanced(VertexCountPerInstance, InstanceCount, StartVertexLocation, StartInstanceLocation); } + void GSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->GSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void GSSetShader(ID3D11GeometryShader* pShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->GSSetShader(pShader, ppClassInstances, NumClassInstances); } + void IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) override { ctx->IASetPrimitiveTopology(Topology); } + void VSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->VSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void VSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->VSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void Begin(ID3D11Asynchronous* pAsync) override { ctx->Begin(pAsync); } + void End(ID3D11Asynchronous* pAsync) override { ctx->End(pAsync); } + HRESULT GetData(ID3D11Asynchronous* pAsync, void* pData, UINT DataSize, UINT GetDataFlags) override { return ctx->GetData(pAsync, pData, DataSize, GetDataFlags); } + void SetPredication(ID3D11Predicate* pPredicate, BOOL PredicateValue) override { ctx->SetPredication(pPredicate, PredicateValue); } + void GSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->GSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void GSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->GSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void OMSetBlendState(ID3D11BlendState* pBlendState, const FLOAT BlendFactor[4], UINT SampleMask) override { ctx->OMSetBlendState(pBlendState, BlendFactor, SampleMask); } + void OMSetDepthStencilState(ID3D11DepthStencilState* pDepthStencilState, UINT StencilRef) override { ctx->OMSetDepthStencilState(pDepthStencilState, StencilRef); } + void SOSetTargets(UINT NumBuffers, ID3D11Buffer* const* ppSOTargets, const UINT* pOffsets) override { ctx->SOSetTargets(NumBuffers, ppSOTargets, pOffsets); } + void DrawAuto() override { ctx->DrawAuto(); } + void DrawIndexedInstancedIndirect(ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) override { ctx->DrawIndexedInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); } + void DrawInstancedIndirect(ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) override { ctx->DrawInstancedIndirect(pBufferForArgs, AlignedByteOffsetForArgs); } + void RSSetState(ID3D11RasterizerState* pRasterizerState) override { ctx->RSSetState(pRasterizerState); } + void RSSetViewports(UINT NumViewports, const D3D11_VIEWPORT* pViewports) override { ctx->RSSetViewports(NumViewports, pViewports); } + void RSSetScissorRects(UINT NumRects, const D3D11_RECT* pRects) override { ctx->RSSetScissorRects(NumRects, pRects); } + void CopyStructureCount(ID3D11Buffer* pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView* pSrcView) override { ctx->CopyStructureCount(pDstBuffer, DstAlignedByteOffset, pSrcView); } + void ClearDepthStencilView(ID3D11DepthStencilView* pDepthStencilView, UINT ClearFlags, FLOAT Depth, UINT8 Stencil) override { ctx->ClearDepthStencilView(pDepthStencilView, ClearFlags, Depth, Stencil); } + void GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) override { ctx->GenerateMips(pShaderResourceView); } + void SetResourceMinLOD(ID3D11Resource* pResource, FLOAT MinLOD) override { ctx->SetResourceMinLOD(pResource, MinLOD); } + FLOAT GetResourceMinLOD(ID3D11Resource* pResource) override { return ctx->GetResourceMinLOD(pResource); } + void ResolveSubresource(ID3D11Resource* pDstResource, UINT DstSubresource, ID3D11Resource* pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format) override { ctx->ResolveSubresource(pDstResource, DstSubresource, pSrcResource, SrcSubresource, Format); } + void ExecuteCommandList(ID3D11CommandList* pCommandList, BOOL RestoreContextState) override { ctx->ExecuteCommandList(pCommandList, RestoreContextState); } + void HSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->HSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void HSSetShader(ID3D11HullShader* pHullShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->HSSetShader(pHullShader, ppClassInstances, NumClassInstances); } + void HSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->HSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void HSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->HSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void DSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->DSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void DSSetShader(ID3D11DomainShader* pDomainShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->DSSetShader(pDomainShader, ppClassInstances, NumClassInstances); } + void DSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->DSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void DSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->DSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void CSSetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) override { ctx->CSSetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void CSSetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) override { ctx->CSSetUnorderedAccessViews(StartSlot, NumUAVs, ppUnorderedAccessViews, pUAVInitialCounts); } + void CSSetShader(ID3D11ComputeShader* pComputeShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) override { ctx->CSSetShader(pComputeShader, ppClassInstances, NumClassInstances); } + void CSSetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) override { ctx->CSSetSamplers(StartSlot, NumSamplers, ppSamplers); } + void CSSetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) override { ctx->CSSetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void VSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->VSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void PSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->PSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void PSGetShader(ID3D11PixelShader** ppPixelShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->PSGetShader(ppPixelShader, ppClassInstances, pNumClassInstances); } + void PSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->PSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void VSGetShader(ID3D11VertexShader** ppVertexShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->VSGetShader(ppVertexShader, ppClassInstances, pNumClassInstances); } + void PSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->PSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void IAGetInputLayout(ID3D11InputLayout** ppInputLayout) override { ctx->IAGetInputLayout(ppInputLayout); } + void IAGetVertexBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppVertexBuffers, UINT* pStrides, UINT* pOffsets) override { ctx->IAGetVertexBuffers(StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); } + void IAGetIndexBuffer(ID3D11Buffer** pIndexBuffer, DXGI_FORMAT* Format, UINT* Offset) override { ctx->IAGetIndexBuffer(pIndexBuffer, Format, Offset); } + void GSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->GSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void GSGetShader(ID3D11GeometryShader** ppGeometryShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->GSGetShader(ppGeometryShader, ppClassInstances, pNumClassInstances); } + void IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) override { ctx->IAGetPrimitiveTopology(pTopology); } + void VSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->VSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void VSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->VSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void GetPredication(ID3D11Predicate** ppPredicate, BOOL* pPredicateValue) override { ctx->GetPredication(ppPredicate, pPredicateValue); } + void GSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->GSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void GSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->GSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void OMGetRenderTargets(UINT NumViews, ID3D11RenderTargetView** ppRenderTargetViews, ID3D11DepthStencilView** ppDepthStencilView) override { ctx->OMGetRenderTargets(NumViews, ppRenderTargetViews, ppDepthStencilView); } + void OMGetRenderTargetsAndUnorderedAccessViews(UINT NumRTVs, ID3D11RenderTargetView** ppRenderTargetViews, ID3D11DepthStencilView** ppDepthStencilView, UINT UAVStartSlot, UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews) override { ctx->OMGetRenderTargetsAndUnorderedAccessViews(NumRTVs, ppRenderTargetViews, ppDepthStencilView, UAVStartSlot, NumUAVs, ppUnorderedAccessViews); } + void OMGetBlendState(ID3D11BlendState** ppBlendState, FLOAT BlendFactor[4], UINT* pSampleMask) override { ctx->OMGetBlendState(ppBlendState, BlendFactor, pSampleMask); } + void OMGetDepthStencilState(ID3D11DepthStencilState** ppDepthStencilState, UINT* pStencilRef) override { ctx->OMGetDepthStencilState(ppDepthStencilState, pStencilRef); } + void SOGetTargets(UINT NumBuffers, ID3D11Buffer** ppSOTargets) override { ctx->SOGetTargets(NumBuffers, ppSOTargets); } + void RSGetState(ID3D11RasterizerState** ppRasterizerState) override { ctx->RSGetState(ppRasterizerState); } + void RSGetViewports(UINT* pNumViewports, D3D11_VIEWPORT* pViewports) override { ctx->RSGetViewports(pNumViewports, pViewports); } + void RSGetScissorRects(UINT* pNumRects, D3D11_RECT* pRects) override { ctx->RSGetScissorRects(pNumRects, pRects); } + void HSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->HSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void HSGetShader(ID3D11HullShader** ppHullShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->HSGetShader(ppHullShader, ppClassInstances, pNumClassInstances); } + void HSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->HSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void HSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->HSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void DSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->DSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void DSGetShader(ID3D11DomainShader** ppDomainShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->DSGetShader(ppDomainShader, ppClassInstances, pNumClassInstances); } + void DSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->DSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void DSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->DSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void CSGetShaderResources(UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) override { ctx->CSGetShaderResources(StartSlot, NumViews, ppShaderResourceViews); } + void CSGetUnorderedAccessViews(UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews) override { ctx->CSGetUnorderedAccessViews(StartSlot, NumUAVs, ppUnorderedAccessViews); } + void CSGetShader(ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) override { ctx->CSGetShader(ppComputeShader, ppClassInstances, pNumClassInstances); } + void CSGetSamplers(UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) override { ctx->CSGetSamplers(StartSlot, NumSamplers, ppSamplers); } + void CSGetConstantBuffers(UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) override { ctx->CSGetConstantBuffers(StartSlot, NumBuffers, ppConstantBuffers); } + void ClearState() override { ctx->ClearState(); } + void Flush() override { ctx->Flush(); } + D3D11_DEVICE_CONTEXT_TYPE GetType() override { return ctx->GetType(); } + UINT GetContextFlags() override { return ctx->GetContextFlags(); } + HRESULT FinishCommandList(BOOL RestoreDeferredContextState, ID3D11CommandList** ppCommandList) override { return ctx->FinishCommandList(RestoreDeferredContextState, ppCommandList); } + + void ClearRenderTargetView( + ID3D11RenderTargetView* pRTV, + const FLOAT pColor[4]) override { + ctx->ClearRenderTargetView(pRTV, pColor); + if (pRTV) + updateViewShadowResource(ctx, pRTV); + } - if (!isImmediatecontext(pContext)) { - flag = HOOK_DEF_CTX; - procs = &g_defContextProcs; + void ClearUnorderedAccessViewFloat( + ID3D11UnorderedAccessView* pUAV, + const FLOAT pColor[4]) override { + ctx->ClearUnorderedAccessViewFloat(pUAV, pColor); + if (pUAV) + updateViewShadowResource(ctx, pUAV); } - if (g_installedHooks & flag) - return; + void ClearUnorderedAccessViewUint( + ID3D11UnorderedAccessView* pUAV, + const UINT pColor[4]) override { + ctx->ClearUnorderedAccessViewUint(pUAV, pColor); + if (pUAV) + updateViewShadowResource(ctx, pUAV); + } - log("Hooking context ", pContext); + void CopyResource( + ID3D11Resource* pDstResource, + ID3D11Resource* pSrcResource) override { + ID3D11Resource* dstShadow = getShadowResource(pDstResource); + + bool needsBaseCopy = true; + bool needsShadowCopy = true; - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 50, ClearRenderTargetView); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 52, ClearUnorderedAccessViewFloat); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 51, ClearUnorderedAccessViewUint); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 47, CopyResource); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 46, CopySubresourceRegion); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 49, CopyStructureCount); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 41, Dispatch); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 42, DispatchIndirect); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 33, OMSetRenderTargets); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 34, OMSetRenderTargetsAndUnorderedAccessViews); - HOOK_PROC(ID3D11DeviceContext, pContext, procs, 48, UpdateSubresource); - - g_installedHooks |= flag; - - /* Immediate context and deferred context methods may share code */ - if (flag & HOOK_IMM_CTX) - g_defContextProcs = g_immContextProcs; + if (isImmediatecontext(ctx)) { + HRESULT hr = tryCpuCopy(ctx, pDstResource, + 0, 0, 0, 0, pSrcResource, 0, nullptr); + needsBaseCopy = FAILED(hr); + + if (!needsBaseCopy && dstShadow) { + hr = tryCpuCopy(ctx, dstShadow, + 0, 0, 0, 0, pSrcResource, 0, nullptr); + needsShadowCopy = FAILED(hr); + } + } + + if (needsBaseCopy) + ctx->CopyResource(pDstResource, pSrcResource); + + if (dstShadow) { + if (needsShadowCopy) + ctx->CopyResource(dstShadow, pSrcResource); + + dstShadow->Release(); + } + } + + void CopySubresourceRegion( + ID3D11Resource* pDstResource, + UINT DstSubresource, + UINT DstX, + UINT DstY, + UINT DstZ, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + const D3D11_BOX* pSrcBox) override { + + ID3D11Resource* dstShadow = getShadowResource(pDstResource); + + bool needsBaseCopy = true; + bool needsShadowCopy = true; + + if (isImmediatecontext(ctx)) { + HRESULT hr = tryCpuCopy(ctx, + pDstResource, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox); + needsBaseCopy = FAILED(hr); + + if (!needsBaseCopy && dstShadow) { + hr = tryCpuCopy(ctx, + dstShadow, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox); + needsShadowCopy = FAILED(hr); + } + } + + if (needsBaseCopy) { + ctx->CopySubresourceRegion( + pDstResource, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox); + } + + if (dstShadow) { + if (needsShadowCopy) { + ATFIX_RESOURCE_INFO srcInfo = { }; + getResourceInfo(pSrcResource, &srcInfo); + + ctx->CopySubresourceRegion( + dstShadow, DstSubresource, DstX, DstY, DstZ, + pSrcResource, SrcSubresource, pSrcBox); + } + + dstShadow->Release(); + } + } + + void Dispatch( + UINT X, + UINT Y, + UINT Z) override { + ctx->Dispatch(X, Y, Z); + updateUavShadowResources(ctx); + } + + void DispatchIndirect( + ID3D11Buffer* pParameterBuffer, + UINT pParameterOffset) override { + ctx->DispatchIndirect(pParameterBuffer, pParameterOffset); + updateUavShadowResources(ctx); + } + + void OMSetRenderTargets( + UINT RTVCount, + ID3D11RenderTargetView* const* ppRTVs, + ID3D11DepthStencilView* pDSV) override { + updateRtvShadowResources(ctx); + ctx->OMSetRenderTargets(RTVCount, ppRTVs, pDSV); + } + + void OMSetRenderTargetsAndUnorderedAccessViews( + UINT RTVCount, + ID3D11RenderTargetView* const* ppRTVs, + ID3D11DepthStencilView* pDSV, + UINT UAVIndex, + UINT UAVCount, + ID3D11UnorderedAccessView* const* ppUAVs, + const UINT* pUAVClearValues) override { + updateRtvShadowResources(ctx); + ctx->OMSetRenderTargetsAndUnorderedAccessViews( + RTVCount, ppRTVs, pDSV, UAVIndex, UAVCount, ppUAVs, pUAVClearValues); + } + + void UpdateSubresource( + ID3D11Resource* pResource, + UINT Subresource, + const D3D11_BOX* pBox, + const void* pData, + UINT RowPitch, + UINT SlicePitch) override { + ctx->UpdateSubresource( + pResource, Subresource, pBox, pData, RowPitch, SlicePitch); + + ID3D11Resource* shadowResource = getShadowResource(pResource); + if (shadowResource) { + ctx->UpdateSubresource( + shadowResource, Subresource, pBox, pData, RowPitch, SlicePitch); + shadowResource->Release(); + } + } +}; + +ID3D11DeviceContext* hookContext(ID3D11DeviceContext* pContext) { + log("Hooking context ", pContext); + return new ContextWrapper(pContext); } } \ No newline at end of file diff --git a/impl.h b/impl.h index d36b971..de71504 100644 --- a/impl.h +++ b/impl.h @@ -7,7 +7,7 @@ namespace atfix { void hookDevice(ID3D11Device* pDevice); -void hookContext(ID3D11DeviceContext* pContext); +ID3D11DeviceContext* hookContext(ID3D11DeviceContext* pContext); /* lives in main.cpp */ extern Log log; diff --git a/main.cpp b/main.cpp index 3b2f19a..e77a4ea 100644 --- a/main.cpp +++ b/main.cpp @@ -112,7 +112,7 @@ DLLEXPORT HRESULT __stdcall D3D11CreateDevice( return hr; atfix::hookDevice(device); - atfix::hookContext(context); + context = atfix::hookContext(context); if (ppDevice) { device->AddRef(); @@ -167,7 +167,7 @@ DLLEXPORT HRESULT __stdcall D3D11CreateDeviceAndSwapChain( return hr; atfix::hookDevice(device); - atfix::hookContext(context); + context = atfix::hookContext(context); if (ppDevice) { device->AddRef(); From 400c63ff83183ba25235d09c0178e32d25715d4e Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Wed, 5 Apr 2023 00:15:05 -0500 Subject: [PATCH 3/4] Remove spammy debug log --- impl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/impl.cpp b/impl.cpp index 13956f6..957abf5 100644 --- a/impl.cpp +++ b/impl.cpp @@ -1034,7 +1034,6 @@ class ContextWrapper final : public ID3D11DeviceContext { }; ID3D11DeviceContext* hookContext(ID3D11DeviceContext* pContext) { - log("Hooking context ", pContext); return new ContextWrapper(pContext); } From 349fdbc14e120b6bde05a6f35e58a43610aef775 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Wed, 5 Apr 2023 20:03:15 -0500 Subject: [PATCH 4/4] Use normal LoadLibrary for loading d3d11_proxy For some reason, LOAD_LIBRARY_SEARCH_APPLICATION_DIR won't find a dxvk dll next to the main exe on Windows --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index e77a4ea..f657d87 100644 --- a/main.cpp +++ b/main.cpp @@ -45,7 +45,7 @@ D3D11Proc loadSystemD3D11() { if (d3d11Proc.D3D11CreateDevice) return d3d11Proc; - HMODULE libD3D11 = LoadLibraryExA("d3d11_proxy.dll", nullptr, LOAD_LIBRARY_SEARCH_APPLICATION_DIR); + HMODULE libD3D11 = LoadLibraryA("d3d11_proxy.dll"); if (libD3D11) { log("Using d3d11_proxy.dll");