mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-01 16:24:12 +01:00
[dxvk,d3d11] Refactor uploadBuffer to consume a staging buffer
This commit is contained in:
parent
c27cae2f10
commit
c92ee8ee07
@ -9,7 +9,8 @@ namespace dxvk {
|
||||
D3D11Device* pParent)
|
||||
: m_parent(pParent),
|
||||
m_device(pParent->GetDXVKDevice()),
|
||||
m_context(m_device->createContext(DxvkContextType::Supplementary)) {
|
||||
m_context(m_device->createContext(DxvkContextType::Supplementary)),
|
||||
m_stagingBuffer(m_device, StagingBufferSize) {
|
||||
m_context->beginRecording(
|
||||
m_device->createCommandList());
|
||||
}
|
||||
@ -81,20 +82,22 @@ namespace dxvk {
|
||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
DxvkBufferSlice bufferSlice = pBuffer->GetBufferSlice();
|
||||
Rc<DxvkBuffer> buffer = pBuffer->GetBuffer();
|
||||
|
||||
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
||||
m_transferMemory += bufferSlice.length();
|
||||
auto stagingSlice = m_stagingBuffer.alloc(buffer->info().size);
|
||||
std::memcpy(stagingSlice.mapPtr(0), pInitialData->pSysMem, stagingSlice.length());
|
||||
|
||||
m_transferMemory += buffer->info().size;
|
||||
m_transferCommands += 1;
|
||||
|
||||
m_context->uploadBuffer(
|
||||
bufferSlice.buffer(),
|
||||
pInitialData->pSysMem);
|
||||
m_context->uploadBuffer(buffer,
|
||||
stagingSlice.buffer(),
|
||||
stagingSlice.offset());
|
||||
} else {
|
||||
m_transferCommands += 1;
|
||||
|
||||
m_context->initBuffer(
|
||||
bufferSlice.buffer());
|
||||
m_context->initBuffer(buffer);
|
||||
}
|
||||
|
||||
FlushImplicit();
|
||||
@ -284,6 +287,8 @@ namespace dxvk {
|
||||
|
||||
m_transferCommands = 0;
|
||||
m_transferMemory = 0;
|
||||
|
||||
m_stagingBuffer.reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../dxvk/dxvk_staging.h"
|
||||
|
||||
#include "d3d11_buffer.h"
|
||||
#include "d3d11_texture.h"
|
||||
|
||||
@ -18,6 +20,9 @@ namespace dxvk {
|
||||
class D3D11Initializer {
|
||||
constexpr static size_t MaxTransferMemory = 32 * 1024 * 1024;
|
||||
constexpr static size_t MaxTransferCommands = 512;
|
||||
|
||||
// Use a staging buffer with a linear allocator to service small uploads
|
||||
constexpr static VkDeviceSize StagingBufferSize = 1ull << 20;
|
||||
public:
|
||||
|
||||
D3D11Initializer(
|
||||
@ -45,6 +50,8 @@ namespace dxvk {
|
||||
D3D11Device* m_parent;
|
||||
Rc<DxvkDevice> m_device;
|
||||
Rc<DxvkContext> m_context;
|
||||
|
||||
DxvkStagingBuffer m_stagingBuffer;
|
||||
|
||||
size_t m_transferCommands = 0;
|
||||
size_t m_transferMemory = 0;
|
||||
|
@ -2537,20 +2537,18 @@ namespace dxvk {
|
||||
|
||||
void DxvkContext::uploadBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
const void* data) {
|
||||
const Rc<DxvkBuffer>& source,
|
||||
VkDeviceSize sourceOffset) {
|
||||
auto bufferSlice = buffer->getSliceHandle();
|
||||
|
||||
auto stagingSlice = m_staging.alloc(bufferSlice.length);
|
||||
auto stagingHandle = stagingSlice.getSliceHandle();
|
||||
std::memcpy(stagingHandle.mapPtr, data, bufferSlice.length);
|
||||
auto sourceSlice = source->getSliceHandle(sourceOffset, buffer->info().size);
|
||||
|
||||
VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
|
||||
copyRegion.srcOffset = stagingHandle.offset;
|
||||
copyRegion.srcOffset = sourceSlice.offset;
|
||||
copyRegion.dstOffset = bufferSlice.offset;
|
||||
copyRegion.size = bufferSlice.length;
|
||||
|
||||
VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
|
||||
copyInfo.srcBuffer = stagingHandle.handle;
|
||||
copyInfo.srcBuffer = sourceSlice.handle;
|
||||
copyInfo.dstBuffer = bufferSlice.handle;
|
||||
copyInfo.regionCount = 1;
|
||||
copyInfo.pRegions = ©Region;
|
||||
@ -2574,7 +2572,7 @@ namespace dxvk {
|
||||
buffer->info().stages, buffer->info().access);
|
||||
}
|
||||
|
||||
m_cmd->trackResource<DxvkAccess::Read>(stagingSlice.buffer());
|
||||
m_cmd->trackResource<DxvkAccess::Read>(source);
|
||||
m_cmd->trackResource<DxvkAccess::Write>(buffer);
|
||||
}
|
||||
|
||||
|
@ -1151,14 +1151,17 @@ namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Uses transfer queue to initialize buffer
|
||||
*
|
||||
* Only safe to use if the buffer is not in use by the GPU.
|
||||
*
|
||||
* Always replaces the entire buffer. Only safe to use
|
||||
* if the buffer is currently not in use by the GPU.
|
||||
* \param [in] buffer The buffer to initialize
|
||||
* \param [in] data The data to copy to the buffer
|
||||
* \param [in] source Staging buffer containing data
|
||||
* \param [in] sourceOffset Offset into staging buffer
|
||||
*/
|
||||
void uploadBuffer(
|
||||
const Rc<DxvkBuffer>& buffer,
|
||||
const void* data);
|
||||
const Rc<DxvkBuffer>& source,
|
||||
VkDeviceSize sourceOffset);
|
||||
|
||||
/**
|
||||
* \brief Uses transfer queue to initialize image
|
||||
|
Loading…
Reference in New Issue
Block a user