@@ -9,6 +9,7 @@ static mutex g_globalMutex;
99
1010/* * Metadata */
1111static const GUID IID_StagingShadowResource = {0xe2728d91 ,0x9fdd ,0x40d0 ,{0x87 ,0xa8 ,0x09 ,0xb6 ,0x2d ,0xf3 ,0x14 ,0x9a }};
12+ static const GUID IID_CopiedVertexBuffer = {0xe2728d92 ,0x9fdd ,0x40d0 ,{0x87 ,0xa8 ,0x09 ,0xb6 ,0x2d ,0xf3 ,0x14 ,0x9a }};
1213
1314struct ATFIX_RESOURCE_INFO {
1415 D3D11_RESOURCE_DIMENSION Dim;
@@ -786,8 +787,6 @@ class ContextWrapper final : public ID3D11DeviceContext {
786787 void VSSetShader (ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const * ppClassInstances, UINT NumClassInstances) override { ctx->VSSetShader (pVertexShader, ppClassInstances, NumClassInstances); }
787788 void DrawIndexed (UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) override { ctx->DrawIndexed (IndexCount, StartIndexLocation, BaseVertexLocation); }
788789 void Draw (UINT VertexCount, UINT StartVertexLocation) override { ctx->Draw (VertexCount, StartVertexLocation); }
789- HRESULT Map (ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) override { return ctx->Map (pResource, Subresource, MapType, MapFlags, pMappedResource); }
790- void Unmap (ID3D11Resource* pResource, UINT Subresource) override { ctx->Unmap (pResource, Subresource); }
791790 void PSSetConstantBuffers (UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const * ppConstantBuffers) override { ctx->PSSetConstantBuffers (StartSlot, NumBuffers, ppConstantBuffers); }
792791 void IASetInputLayout (ID3D11InputLayout* pInputLayout) override { ctx->IASetInputLayout (pInputLayout); }
793792 void IASetVertexBuffers (UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const * ppVertexBuffers, const UINT* pStrides, const UINT* pOffsets) override { ctx->IASetVertexBuffers (StartSlot, NumBuffers, ppVertexBuffers, pStrides, pOffsets); }
@@ -878,6 +877,29 @@ class ContextWrapper final : public ID3D11DeviceContext {
878877 UINT GetContextFlags () override { return ctx->GetContextFlags (); }
879878 HRESULT FinishCommandList (BOOL RestoreDeferredContextState, ID3D11CommandList** ppCommandList) override { return ctx->FinishCommandList (RestoreDeferredContextState, ppCommandList); }
880879
880+ HRESULT Map (ID3D11Resource* pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) override {
881+ ID3D11Buffer* vertexBuffer = nullptr ;
882+ UINT size = sizeof (vertexBuffer);
883+ if (SUCCEEDED (pResource->GetPrivateData (IID_CopiedVertexBuffer, &size, &vertexBuffer))) {
884+ HRESULT res = ctx->Map (vertexBuffer, 0 , D3D11_MAP_WRITE_DISCARD, 0 , pMappedResource);
885+ vertexBuffer->Release ();
886+ return res;
887+ }
888+ return ctx->Map (pResource, Subresource, MapType, MapFlags, pMappedResource);
889+ }
890+
891+ void Unmap (ID3D11Resource* pResource, UINT Subresource) override {
892+ ID3D11Buffer* vertexBuffer = nullptr ;
893+ UINT size = sizeof (vertexBuffer);
894+ if (SUCCEEDED (pResource->GetPrivateData (IID_CopiedVertexBuffer, &size, &vertexBuffer))) {
895+ ctx->Unmap (vertexBuffer, 0 );
896+ vertexBuffer->Release ();
897+ return ;
898+ }
899+ ctx->Unmap (pResource, Subresource);
900+ }
901+
902+
881903 void ClearRenderTargetView (
882904 ID3D11RenderTargetView* pRTV,
883905 const FLOAT pColor[4 ]) override {
@@ -905,6 +927,40 @@ class ContextWrapper final : public ID3D11DeviceContext {
905927 void CopyResource (
906928 ID3D11Resource* pDstResource,
907929 ID3D11Resource* pSrcResource) override {
930+ if (isImmediatecontext (ctx)) {
931+ ID3D11Buffer* srcBuffer = nullptr ;
932+ ID3D11Buffer* dstBuffer = nullptr ;
933+ UINT size = sizeof (srcBuffer);
934+ bool skip_rest = false ;
935+ if (SUCCEEDED (pSrcResource->GetPrivateData (IID_CopiedVertexBuffer, &size, &srcBuffer))) {
936+ // Don't copy back to vertex buffer
937+ srcBuffer->Release ();
938+ return ;
939+ }
940+ if (SUCCEEDED (pDstResource->QueryInterface (IID_PPV_ARGS (&dstBuffer)))) {
941+ if (SUCCEEDED (pSrcResource->QueryInterface (IID_PPV_ARGS (&srcBuffer)))) {
942+ D3D11_BUFFER_DESC srcDesc, dstDesc;
943+ srcBuffer->GetDesc (&srcDesc);
944+ dstBuffer->GetDesc (&dstDesc);
945+ if (srcDesc.Usage == D3D11_USAGE_DYNAMIC && srcDesc.BindFlags == D3D11_BIND_VERTEX_BUFFER && dstDesc.Usage == D3D11_USAGE_STAGING)
946+ {
947+ // Game really likes copying to and from vertex buffers
948+ // AMD Windows driver syncs with the driver thread for every D3D11_MAP_READWRITE map
949+ // Skip it entirely by redirecting the map to the vertex buffer with D3D11_MAP_WRITE_DISCARD
950+ // Then drop any copies from the staging buffer, since it wasn't updated
951+ // Helps the Ryza synthesis UI (which really spams this) keep a smooth 144fps
952+ // Also removes frame drops when jumping in Ryza 2 on steam deck
953+ skip_rest = true ;
954+ dstBuffer->SetPrivateDataInterface (IID_CopiedVertexBuffer, srcBuffer);
955+ }
956+ srcBuffer->Release ();
957+ }
958+ dstBuffer->Release ();
959+ }
960+ if (skip_rest)
961+ return ;
962+ }
963+
908964 ID3D11Resource* dstShadow = getShadowResource (pDstResource);
909965
910966 bool needsBaseCopy = true ;
@@ -943,6 +999,16 @@ class ContextWrapper final : public ID3D11DeviceContext {
943999 UINT SrcSubresource,
9441000 const D3D11_BOX* pSrcBox) override {
9451001
1002+ if (isImmediatecontext (ctx)) {
1003+ ID3D11Buffer* srcBuffer = nullptr ;
1004+ UINT size = sizeof (srcBuffer);
1005+ if (SUCCEEDED (pSrcResource->GetPrivateData (IID_CopiedVertexBuffer, &size, &srcBuffer))) {
1006+ // Don't copy back to vertex buffer
1007+ srcBuffer->Release ();
1008+ return ;
1009+ }
1010+ }
1011+
9461012 ID3D11Resource* dstShadow = getShadowResource (pDstResource);
9471013
9481014 bool needsBaseCopy = true ;
0 commit comments