[dxvk] Introduce DxvkStagingBuffer

This commit is contained in:
Philip Rebohle 2022-02-12 16:45:13 +01:00
parent 82518de4b4
commit 0bc19472e8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 104 additions and 1 deletions

View File

@ -66,5 +66,58 @@ namespace dxvk {
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
}
DxvkStagingBuffer::DxvkStagingBuffer(
const Rc<DxvkDevice>& device,
VkDeviceSize size)
: m_device(device), m_offset(0), m_size(size) {
}
DxvkStagingBuffer::~DxvkStagingBuffer() {
}
DxvkBufferSlice DxvkStagingBuffer::alloc(VkDeviceSize align, VkDeviceSize size) {
DxvkBufferCreateInfo info;
info.size = size;
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
| VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT
| VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
| VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
info.access = VK_ACCESS_TRANSFER_READ_BIT
| VK_ACCESS_SHADER_READ_BIT;
VkDeviceSize alignedSize = dxvk::align(size, align);
VkDeviceSize alignedOffset = dxvk::align(m_offset, align);
if (alignedSize >= m_size) {
return DxvkBufferSlice(m_device->createBuffer(info,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT));
}
if (alignedOffset + alignedSize > m_size || m_buffer == nullptr) {
info.size = m_size;
m_buffer = m_device->createBuffer(info,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
alignedOffset = 0;
}
DxvkBufferSlice slice(m_buffer, alignedOffset, size);
m_offset = alignedOffset + alignedSize;
return slice;
}
void DxvkStagingBuffer::reset() {
m_buffer = nullptr;
m_offset = 0;
}
}

View File

@ -52,5 +52,55 @@ namespace dxvk {
Rc<DxvkBuffer> createBuffer(VkDeviceSize size);
};
/**
* \brief Staging buffer
*
* Provides a simple linear staging buffer
* allocator for data uploads.
*/
class DxvkStagingBuffer {
public:
/**
* \brief Creates staging buffer
*
* \param [in] device DXVK device
* \param [in] size Buffer size
*/
DxvkStagingBuffer(
const Rc<DxvkDevice>& device,
VkDeviceSize size);
/**
* \brief Frees staging buffer
*/
~DxvkStagingBuffer();
/**
* \brief Allocates staging buffer memory
*
* Tries to suballocate from existing buffer,
* or creates a new buffer if necessary.
* \param [in] align Minimum alignment
* \param [in] size Number of bytes to allocate
* \returns Allocated slice
*/
DxvkBufferSlice alloc(VkDeviceSize align, VkDeviceSize size);
/**
* \brief Resets staging buffer and allocator
*/
void reset();
private:
Rc<DxvkDevice> m_device;
Rc<DxvkBuffer> m_buffer;
VkDeviceSize m_offset;
VkDeviceSize m_size;
};
}