Skip to content

Commit 28b19cc

Browse files
committed
Specially optimize Ryza's vertex buffer copy spam
1 parent 6af15e6 commit 28b19cc

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

impl.cpp

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ static mutex g_globalMutex;
99

1010
/** Metadata */
1111
static 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

1314
struct 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

Comments
 (0)