diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index eaf26a827d..ce1f31d0cd 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -264,6 +264,17 @@ ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVerte return vertexBuffer; } +static bool +isContained(const std::vector > &ranges, const std::pair &range) +{ + for (auto &r : ranges) + { + if (r == range) + return true; + } + return false; +} + std::pair, D3D12_INDEX_BUFFER_VIEW> D3D12GSRender::UploadVertexBuffers(bool indexed_draw) { std::pair, D3D12_INDEX_BUFFER_VIEW> result; @@ -280,7 +291,19 @@ std::pair, D3D12_INDEX_BUFFER_VIEW> D3D12G if (vbf.stride) subBufferSize = ((subBufferSize + vbf.stride - 1) / vbf.stride) * vbf.stride; - ID3D12Resource *vertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device, m_vertexIndexData); + u64 key = vbf.range.first; + key = key << 32; + key = key | vbf.range.second; + auto It = m_vertexCache.find(key); + + ID3D12Resource *vertexBuffer; + if (It != m_vertexCache.end()) + vertexBuffer = It->second; + else + { + vertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device, m_vertexIndexData); + m_vertexCache[key] = vertexBuffer; + } D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress(); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 33fbdf8b71..23aa68cbea 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -1057,6 +1057,7 @@ void D3D12GSRender::Flip() // Flush m_texturesRTTs.clear(); + m_vertexCache.clear(); std::vector > cleaningFunction = { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index 7934a566e3..bccb6e6042 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -218,6 +218,10 @@ private: std::unordered_map m_texturesCache; // std::vector m_post_draw_objs; + // TODO: Use a tree structure to parse more efficiently + // Key is begin << 32 | end + std::unordered_map m_vertexCache; + PipelineStateObjectCache m_cachePSO; std::pair *m_PSO; // m_rootSignatures[N] is RS with N texture/sample