diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index ac518b92..d9ca2e38 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -113,12 +113,12 @@ namespace dxvk { : DxvkBufferSlice(); } - Rc AllocSlice() { - return m_buffer->allocateSlice(); + Rc AllocSlice(DxvkLocalAllocationCache* cache) { + return m_buffer->allocateSlice(cache); } - Rc DiscardSlice() { - m_allocation = m_buffer->allocateSlice(); + Rc DiscardSlice(DxvkLocalAllocationCache* cache) { + m_allocation = m_buffer->allocateSlice(cache); return m_allocation; } diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 7f64d874..a717536d 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -21,7 +21,34 @@ namespace dxvk { m_csFlags (CsFlags), m_csChunk (AllocCsChunk()), m_cmdData (nullptr) { + // Create local allocation cache with the same properties + // that we will use for common dynamic buffer types + uint32_t cachedDynamic = pParent->GetOptions()->cachedDynamicResources; + VkMemoryPropertyFlags memoryFlags = + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + + if (cachedDynamic & D3D11_BIND_CONSTANT_BUFFER) { + memoryFlags &= ~VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; + cachedDynamic = 0; + } + + VkBufferUsageFlags bufferUsage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + + if (!(cachedDynamic & D3D11_BIND_SHADER_RESOURCE)) { + bufferUsage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT + | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; + } + + if (!(cachedDynamic & D3D11_BIND_VERTEX_BUFFER)) + bufferUsage |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + + if (!(cachedDynamic & D3D11_BIND_INDEX_BUFFER)) + bufferUsage |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + + m_allocationCache = m_device->createAllocationCache(bufferUsage, memoryFlags); } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 7383507f..e0ee32dc 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -775,6 +775,8 @@ namespace dxvk { DxvkCsChunkRef m_csChunk; D3D11CmdData* m_cmdData; + DxvkLocalAllocationCache m_allocationCache; + DxvkCsChunkRef AllocCsChunk(); DxvkDataSlice AllocUpdateBufferSlice(size_t Size); diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 441c3b82..2e1a0bfe 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -278,7 +278,7 @@ namespace dxvk { // For resources that cannot be written by the GPU, // we may write to the buffer resource directly and // just swap in the buffer slice as needed. - auto bufferSlice = pBuffer->AllocSlice(); + auto bufferSlice = pBuffer->AllocSlice(&m_allocationCache); pMappedResource->pData = bufferSlice->mapPtr(); EmitCs([ diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 02e6bada..b4a627a1 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -332,7 +332,7 @@ namespace dxvk { // Allocate a new backing slice for the buffer and set // it as the 'new' mapped slice. This assumes that the // only way to invalidate a buffer is by mapping it. - auto bufferSlice = pResource->DiscardSlice(); + auto bufferSlice = pResource->DiscardSlice(&m_allocationCache); pMappedResource->pData = bufferSlice->mapPtr(); pMappedResource->RowPitch = bufferSize; pMappedResource->DepthPitch = bufferSize; @@ -377,7 +377,7 @@ namespace dxvk { if (doInvalidatePreserve) { auto srcSlice = pResource->GetMappedSlice(); - auto dstSlice = pResource->DiscardSlice(); + auto dstSlice = pResource->DiscardSlice(nullptr); auto srcPtr = srcSlice->mapPtr(); auto dstPtr = dstSlice->mapPtr(); @@ -703,7 +703,7 @@ namespace dxvk { void* mapPtr = nullptr; if (likely(CopyFlags != D3D11_COPY_NO_OVERWRITE)) { - auto bufferSlice = pDstBuffer->DiscardSlice(); + auto bufferSlice = pDstBuffer->DiscardSlice(&m_allocationCache); mapPtr = bufferSlice->mapPtr(); EmitCs([