mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 13:24:10 +01:00
[dxvk] Implement new staging buffer allocator
This commit is contained in:
parent
a41bd8c4a0
commit
970deb452e
@ -89,5 +89,61 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_stagingBuffers.resize(0);
|
m_stagingBuffers.resize(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkStagingDataAlloc::DxvkStagingDataAlloc(const Rc<DxvkDevice>& device)
|
||||||
|
: m_device(device) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkStagingDataAlloc::~DxvkStagingDataAlloc() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkBufferSlice DxvkStagingDataAlloc::alloc(VkDeviceSize align, VkDeviceSize size) {
|
||||||
|
if (size > MaxBufferSize)
|
||||||
|
return DxvkBufferSlice(createBuffer(size));
|
||||||
|
|
||||||
|
if (m_buffer == nullptr)
|
||||||
|
m_buffer = createBuffer(MaxBufferSize);
|
||||||
|
|
||||||
|
if (!m_buffer->isInUse())
|
||||||
|
m_offset = 0;
|
||||||
|
|
||||||
|
m_offset = dxvk::align(m_offset, align);
|
||||||
|
|
||||||
|
if (m_offset + size > MaxBufferSize) {
|
||||||
|
m_offset = 0;
|
||||||
|
|
||||||
|
if (m_buffers.size() < MaxBufferCount)
|
||||||
|
m_buffers.push(std::move(m_buffer));
|
||||||
|
|
||||||
|
if (!m_buffers.front()->isInUse()) {
|
||||||
|
m_buffer = std::move(m_buffers.front());
|
||||||
|
m_buffers.pop();
|
||||||
|
} else {
|
||||||
|
m_buffer = createBuffer(MaxBufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkBufferSlice slice(m_buffer, m_offset, size);
|
||||||
|
m_offset = dxvk::align(m_offset + size, align);
|
||||||
|
return slice;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Rc<DxvkBuffer> DxvkStagingDataAlloc::createBuffer(VkDeviceSize size) {
|
||||||
|
DxvkBufferCreateInfo info;
|
||||||
|
info.size = size;
|
||||||
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||||
|
info.access = VK_ACCESS_TRANSFER_READ_BIT;
|
||||||
|
|
||||||
|
return m_device->createBuffer(info,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
||||||
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include "dxvk_buffer.h"
|
#include "dxvk_buffer.h"
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
@ -118,5 +120,43 @@ namespace dxvk {
|
|||||||
std::vector<Rc<DxvkStagingBuffer>> m_stagingBuffers;
|
std::vector<Rc<DxvkStagingBuffer>> m_stagingBuffers;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Staging data allocator
|
||||||
|
*
|
||||||
|
* Allocates buffer slices for resource uploads,
|
||||||
|
* while trying to keep the number of allocations
|
||||||
|
* but also the amount of allocated memory low.
|
||||||
|
*/
|
||||||
|
class DxvkStagingDataAlloc {
|
||||||
|
constexpr static VkDeviceSize MaxBufferSize = 1 << 24; // 16 MiB
|
||||||
|
constexpr static uint32_t MaxBufferCount = 2;
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkStagingDataAlloc(const Rc<DxvkDevice>& device);
|
||||||
|
|
||||||
|
~DxvkStagingDataAlloc();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Alloctaes a staging buffer slice
|
||||||
|
*
|
||||||
|
* \param [in] align Alignment of the allocation
|
||||||
|
* \param [in] size Size of the allocation
|
||||||
|
* \returns Staging buffer slice
|
||||||
|
*/
|
||||||
|
DxvkBufferSlice alloc(VkDeviceSize align, VkDeviceSize size);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Rc<DxvkDevice> m_device;
|
||||||
|
Rc<DxvkBuffer> m_buffer;
|
||||||
|
VkDeviceSize m_offset = 0;
|
||||||
|
|
||||||
|
std::queue<Rc<DxvkBuffer>> m_buffers;
|
||||||
|
|
||||||
|
Rc<DxvkBuffer> createBuffer(VkDeviceSize size);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user