mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Pad buffers more tightly
This will allow for smaller buffers to be laid out more efficiently.
This commit is contained in:
parent
83fc15c594
commit
e868f829b5
@ -12,10 +12,12 @@ namespace dxvk {
|
|||||||
m_info (createInfo),
|
m_info (createInfo),
|
||||||
m_memAlloc (&memAlloc),
|
m_memAlloc (&memAlloc),
|
||||||
m_memFlags (memFlags) {
|
m_memFlags (memFlags) {
|
||||||
// Align slices to 256 bytes, which guarantees that
|
// Align slices so that we don't violate any alignment
|
||||||
// we don't violate any Vulkan alignment requirements
|
// requirements imposed by the Vulkan device/driver
|
||||||
|
VkDeviceSize sliceAlignment = computeSliceAlignment();
|
||||||
m_physSliceLength = createInfo.size;
|
m_physSliceLength = createInfo.size;
|
||||||
m_physSliceStride = align(createInfo.size, 256);
|
m_physSliceStride = align(createInfo.size, sliceAlignment);
|
||||||
|
m_physSliceCount = std::max<VkDeviceSize>(1, 256 / m_physSliceStride);
|
||||||
|
|
||||||
// Limit size of multi-slice buffers to reduce fragmentation
|
// Limit size of multi-slice buffers to reduce fragmentation
|
||||||
constexpr VkDeviceSize MaxBufferSize = 4 << 20;
|
constexpr VkDeviceSize MaxBufferSize = 4 << 20;
|
||||||
@ -24,13 +26,23 @@ namespace dxvk {
|
|||||||
? MaxBufferSize / m_physSliceStride
|
? MaxBufferSize / m_physSliceStride
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
// Allocate a single buffer slice
|
// Allocate the initial set of buffer slices
|
||||||
m_buffer = allocBuffer(1);
|
m_buffer = allocBuffer(m_physSliceCount);
|
||||||
|
|
||||||
m_physSlice.handle = m_buffer.buffer;
|
DxvkBufferSliceHandle slice;
|
||||||
m_physSlice.offset = 0;
|
slice.handle = m_buffer.buffer;
|
||||||
m_physSlice.length = m_physSliceLength;
|
slice.offset = 0;
|
||||||
m_physSlice.mapPtr = m_buffer.memory.mapPtr(0);
|
slice.length = m_physSliceLength;
|
||||||
|
slice.mapPtr = m_buffer.memory.mapPtr(0);
|
||||||
|
|
||||||
|
m_physSlice = slice;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,6 +121,34 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkDeviceSize DxvkBuffer::computeSliceAlignment() const {
|
||||||
|
const auto& devInfo = m_device->properties().core.properties;
|
||||||
|
|
||||||
|
VkDeviceSize result = sizeof(uint32_t);
|
||||||
|
|
||||||
|
if (m_info.usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
|
||||||
|
result = std::max(result, devInfo.limits.minUniformBufferOffsetAlignment);
|
||||||
|
|
||||||
|
if (m_info.usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
|
||||||
|
result = std::max(result, devInfo.limits.minStorageBufferOffsetAlignment);
|
||||||
|
|
||||||
|
if (m_info.usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
|
||||||
|
result = std::max(result, devInfo.limits.minTexelBufferOffsetAlignment);
|
||||||
|
|
||||||
|
if (m_info.usage & (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||||
|
&& m_info.size > (devInfo.limits.optimalBufferCopyOffsetAlignment / 2))
|
||||||
|
result = std::max(result, devInfo.limits.optimalBufferCopyOffsetAlignment);
|
||||||
|
|
||||||
|
if (m_memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
|
||||||
|
result = std::max(result, devInfo.limits.nonCoherentAtomSize);
|
||||||
|
result = std::max(result, VkDeviceSize(64));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DxvkBufferView::DxvkBufferView(
|
DxvkBufferView::DxvkBufferView(
|
||||||
const Rc<vk::DeviceFn>& vkd,
|
const Rc<vk::DeviceFn>& vkd,
|
||||||
|
@ -247,11 +247,12 @@ namespace dxvk {
|
|||||||
std::unique_lock<sync::Spinlock> swapLock(m_swapMutex);
|
std::unique_lock<sync::Spinlock> swapLock(m_swapMutex);
|
||||||
DxvkBufferHandle handle = allocBuffer(m_physSliceCount);
|
DxvkBufferHandle handle = allocBuffer(m_physSliceCount);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < m_physSliceCount; i++) {
|
|
||||||
DxvkBufferSliceHandle slice;
|
DxvkBufferSliceHandle slice;
|
||||||
slice.handle = handle.buffer;
|
slice.handle = handle.buffer;
|
||||||
slice.offset = m_physSliceStride * i;
|
|
||||||
slice.length = m_physSliceLength;
|
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);
|
slice.mapPtr = handle.memory.mapPtr(slice.offset);
|
||||||
m_freeSlices.push_back(slice);
|
m_freeSlices.push_back(slice);
|
||||||
}
|
}
|
||||||
@ -307,6 +308,8 @@ namespace dxvk {
|
|||||||
DxvkBufferHandle allocBuffer(
|
DxvkBufferHandle allocBuffer(
|
||||||
VkDeviceSize sliceCount) const;
|
VkDeviceSize sliceCount) const;
|
||||||
|
|
||||||
|
VkDeviceSize computeSliceAlignment() const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user