diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 45af2f7b..6dacfdb2 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -4398,7 +4398,7 @@ namespace dxvk { DxvkDataSlice D3D11DeviceContext::AllocUpdateBufferSlice(size_t Size) { - constexpr size_t UpdateBufferSize = 16 * 1024 * 1024; + constexpr size_t UpdateBufferSize = 1 * 1024 * 1024; if (Size >= UpdateBufferSize) { Rc buffer = new DxvkDataBuffer(Size); @@ -4421,6 +4421,8 @@ namespace dxvk { DxvkBufferSlice D3D11DeviceContext::AllocStagingBuffer( VkDeviceSize Size) { + constexpr VkDeviceSize StagingBufferSize = 4 * 1024 * 1024; + DxvkBufferCreateInfo info; info.size = Size; info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT @@ -4432,8 +4434,32 @@ namespace dxvk { info.access = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_SHADER_READ_BIT; - return DxvkBufferSlice(m_device->createBuffer(info, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)); + // Create a dedicated buffer for large allocations + VkDeviceSize alignedSize = align(Size, 256); + + if (alignedSize >= StagingBufferSize) { + return DxvkBufferSlice(m_device->createBuffer(info, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)); + } + + // Otherwise, try to suballocate from an existing buffer + if (m_stagingOffset + alignedSize > StagingBufferSize || m_stagingBuffer == nullptr) { + info.size = StagingBufferSize; + + m_stagingBuffer = m_device->createBuffer(info, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + m_stagingOffset = 0; + } + + DxvkBufferSlice slice(m_stagingBuffer, m_stagingOffset, Size); + m_stagingOffset += alignedSize; + return slice; + } + + + void D3D11DeviceContext::ResetStagingBuffer() { + m_stagingBuffer = nullptr; + m_stagingOffset = 0; } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 483b0415..3c1d3b0d 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -712,7 +712,10 @@ namespace dxvk { Rc m_device; Rc m_updateBuffer; - + + Rc m_stagingBuffer; + VkDeviceSize m_stagingOffset = 0ull; + DxvkCsChunkFlags m_csFlags; DxvkCsChunkRef m_csChunk; @@ -927,7 +930,9 @@ namespace dxvk { DxvkBufferSlice AllocStagingBuffer( VkDeviceSize Size); - + + void ResetStagingBuffer(); + DxvkCsChunkRef AllocCsChunk(); static void InitDefaultPrimitiveTopology( diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index e8042cf3..3a11f0a2 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -175,6 +175,7 @@ namespace dxvk { ClearState(); m_mappedResources.clear(); + ResetStagingBuffer(); return S_OK; }