dxvk/src/dxvk/dxvk_staging.cpp

94 lines
2.3 KiB
C++

#include "dxvk_device.h"
#include "dxvk_staging.h"
namespace dxvk {
DxvkStagingBuffer::DxvkStagingBuffer(
const Rc<DxvkBuffer>& buffer)
: m_buffer(buffer), m_bufferSize(buffer->info().size){
}
DxvkStagingBuffer::~DxvkStagingBuffer() {
}
VkDeviceSize DxvkStagingBuffer::size() const {
return m_bufferSize;
}
VkDeviceSize DxvkStagingBuffer::freeBytes() const {
return m_bufferSize >= m_bufferOffset
? m_bufferSize - m_bufferOffset
: VkDeviceSize(0);
}
bool DxvkStagingBuffer::alloc(
VkDeviceSize size,
DxvkStagingBufferSlice& slice) {
if (m_bufferOffset + size > m_bufferSize)
return false;
auto physicalSlice = m_buffer->subSlice(m_bufferOffset, size);
slice.buffer = physicalSlice.handle();
slice.offset = physicalSlice.offset();
slice.mapPtr = physicalSlice.mapPtr(0);
m_bufferOffset = align(m_bufferOffset + size, 64);
return true;
}
void DxvkStagingBuffer::reset() {
m_bufferOffset = 0;
}
DxvkStagingAlloc::DxvkStagingAlloc(DxvkDevice* device)
: m_device(device) { }
DxvkStagingAlloc::~DxvkStagingAlloc() {
this->reset();
}
DxvkStagingBufferSlice DxvkStagingAlloc::alloc(VkDeviceSize size) {
Rc<DxvkStagingBuffer> selectedBuffer;
// Try a worst-fit allocation strategy on the existing staging
// buffers first. This should keep the amount of wasted space
// small, especially if there are large allocations.
for (const auto& buf : m_stagingBuffers) {
if (selectedBuffer == nullptr || (buf->freeBytes() > selectedBuffer->freeBytes()))
selectedBuffer = buf;
}
// If we have no suitable buffer, allocate one from the device
// that is *at least* as large as the amount of data we need
// to upload. Usually it will be bigger.
DxvkStagingBufferSlice slice;
if ((selectedBuffer == nullptr) || (!selectedBuffer->alloc(size, slice))) {
selectedBuffer = m_device->allocStagingBuffer(size);
selectedBuffer->alloc(size, slice);
m_stagingBuffers.push_back(selectedBuffer);
}
return slice;
}
void DxvkStagingAlloc::reset() {
for (const auto& buf : m_stagingBuffers)
m_device->recycleStagingBuffer(buf);
m_stagingBuffers.resize(0);
}
}