mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-11-30 04:24:11 +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);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "dxvk_buffer.h"
|
||||
|
||||
namespace dxvk {
|
||||
@ -118,5 +120,43 @@ namespace dxvk {
|
||||
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