1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 10:24:10 +01:00

[dxvk] Lazily allocate slices of small buffers

Reduces memory overhead in case games create small static
buffers. This is somewhat common for index buffers used
to render fullscreen quads or triangles.
This commit is contained in:
Philip Rebohle 2019-10-26 15:15:21 +02:00
parent 7751541662
commit d1e9e1392d
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 23 additions and 19 deletions

View File

@ -36,13 +36,7 @@ namespace dxvk {
slice.mapPtr = m_buffer.memory.mapPtr(0); slice.mapPtr = m_buffer.memory.mapPtr(0);
m_physSlice = slice; m_physSlice = slice;
m_lazyAlloc = m_physSliceCount > 1;
// Push extra slices to the free list
for (uint32_t i = 1; i < m_physSliceCount; i++) {
slice.offset = m_physSliceStride * i;
slice.mapPtr = m_buffer.memory.mapPtr(slice.offset);
m_freeSlices.push_back(slice);
}
} }

View File

@ -244,20 +244,20 @@ namespace dxvk {
// If there are still no slices available, create a new // If there are still no slices available, create a new
// backing buffer and add all slices to the free list. // backing buffer and add all slices to the free list.
if (unlikely(m_freeSlices.empty())) { if (unlikely(m_freeSlices.empty())) {
if (likely(!m_lazyAlloc)) {
DxvkBufferHandle handle = allocBuffer(m_physSliceCount); DxvkBufferHandle handle = allocBuffer(m_physSliceCount);
DxvkBufferSliceHandle slice; for (uint32_t i = 0; i < m_physSliceCount; i++)
slice.handle = handle.buffer; pushSlice(handle, i);
slice.length = m_physSliceLength;
for (uint32_t i = 0; i < m_physSliceCount; i++) {
slice.offset = m_physSliceStride * i;
slice.mapPtr = handle.memory.mapPtr(slice.offset);
m_freeSlices.push_back(slice);
}
m_buffers.push_back(std::move(handle)); m_buffers.push_back(std::move(handle));
m_physSliceCount = std::min(m_physSliceCount * 2, m_physSliceMaxCount); m_physSliceCount = std::min(m_physSliceCount * 2, m_physSliceMaxCount);
} else {
for (uint32_t i = 1; i < m_physSliceCount; i++)
pushSlice(m_buffer, i);
m_lazyAlloc = false;
}
} }
// Take the first slice from the queue // Take the first slice from the queue
@ -291,6 +291,7 @@ namespace dxvk {
DxvkBufferSliceHandle m_physSlice; DxvkBufferSliceHandle m_physSlice;
uint32_t m_vertexStride = 0; uint32_t m_vertexStride = 0;
uint32_t m_lazyAlloc = false;
sync::Spinlock m_freeMutex; sync::Spinlock m_freeMutex;
sync::Spinlock m_swapMutex; sync::Spinlock m_swapMutex;
@ -304,6 +305,15 @@ namespace dxvk {
VkDeviceSize m_physSliceCount = 1; VkDeviceSize m_physSliceCount = 1;
VkDeviceSize m_physSliceMaxCount = 1; VkDeviceSize m_physSliceMaxCount = 1;
void pushSlice(const DxvkBufferHandle& handle, uint32_t index) {
DxvkBufferSliceHandle slice;
slice.handle = handle.buffer;
slice.length = m_physSliceLength;
slice.offset = m_physSliceStride * index;
slice.mapPtr = handle.memory.mapPtr(slice.offset);
m_freeSlices.push_back(slice);
}
DxvkBufferHandle allocBuffer( DxvkBufferHandle allocBuffer(
VkDeviceSize sliceCount) const; VkDeviceSize sliceCount) const;