1
0
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:
Philip Rebohle 2019-06-21 15:56:41 +02:00
parent a41bd8c4a0
commit 970deb452e
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 96 additions and 0 deletions

View File

@ -90,4 +90,60 @@ 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);
}
}

View File

@ -1,5 +1,7 @@
#pragma once
#include <queue>
#include "dxvk_buffer.h"
namespace dxvk {
@ -119,4 +121,42 @@ namespace dxvk {
};
/**
* \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);
};
}