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:
parent
7751541662
commit
d1e9e1392d
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user