mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-04-01 09:25:24 +02: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)
|
D3D11Device* pParent)
|
||||||
: m_parent(pParent),
|
: m_parent(pParent),
|
||||||
m_device(pParent->GetDXVKDevice()),
|
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_context->beginRecording(
|
||||||
m_device->createCommandList());
|
m_device->createCommandList());
|
||||||
}
|
}
|
||||||
@ -81,20 +82,22 @@ namespace dxvk {
|
|||||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||||
|
|
||||||
DxvkBufferSlice bufferSlice = pBuffer->GetBufferSlice();
|
Rc<DxvkBuffer> buffer = pBuffer->GetBuffer();
|
||||||
|
|
||||||
if (pInitialData != nullptr && pInitialData->pSysMem != nullptr) {
|
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_transferCommands += 1;
|
||||||
|
|
||||||
m_context->uploadBuffer(
|
m_context->uploadBuffer(buffer,
|
||||||
bufferSlice.buffer(),
|
stagingSlice.buffer(),
|
||||||
pInitialData->pSysMem);
|
stagingSlice.offset());
|
||||||
} else {
|
} else {
|
||||||
m_transferCommands += 1;
|
m_transferCommands += 1;
|
||||||
|
|
||||||
m_context->initBuffer(
|
m_context->initBuffer(buffer);
|
||||||
bufferSlice.buffer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushImplicit();
|
FlushImplicit();
|
||||||
@ -284,6 +287,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
m_transferCommands = 0;
|
m_transferCommands = 0;
|
||||||
m_transferMemory = 0;
|
m_transferMemory = 0;
|
||||||
|
|
||||||
|
m_stagingBuffer.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../dxvk/dxvk_staging.h"
|
||||||
|
|
||||||
#include "d3d11_buffer.h"
|
#include "d3d11_buffer.h"
|
||||||
#include "d3d11_texture.h"
|
#include "d3d11_texture.h"
|
||||||
|
|
||||||
@ -18,6 +20,9 @@ namespace dxvk {
|
|||||||
class D3D11Initializer {
|
class D3D11Initializer {
|
||||||
constexpr static size_t MaxTransferMemory = 32 * 1024 * 1024;
|
constexpr static size_t MaxTransferMemory = 32 * 1024 * 1024;
|
||||||
constexpr static size_t MaxTransferCommands = 512;
|
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:
|
public:
|
||||||
|
|
||||||
D3D11Initializer(
|
D3D11Initializer(
|
||||||
@ -45,6 +50,8 @@ namespace dxvk {
|
|||||||
D3D11Device* m_parent;
|
D3D11Device* m_parent;
|
||||||
Rc<DxvkDevice> m_device;
|
Rc<DxvkDevice> m_device;
|
||||||
Rc<DxvkContext> m_context;
|
Rc<DxvkContext> m_context;
|
||||||
|
|
||||||
|
DxvkStagingBuffer m_stagingBuffer;
|
||||||
|
|
||||||
size_t m_transferCommands = 0;
|
size_t m_transferCommands = 0;
|
||||||
size_t m_transferMemory = 0;
|
size_t m_transferMemory = 0;
|
||||||
|
@ -2537,20 +2537,18 @@ namespace dxvk {
|
|||||||
|
|
||||||
void DxvkContext::uploadBuffer(
|
void DxvkContext::uploadBuffer(
|
||||||
const Rc<DxvkBuffer>& buffer,
|
const Rc<DxvkBuffer>& buffer,
|
||||||
const void* data) {
|
const Rc<DxvkBuffer>& source,
|
||||||
|
VkDeviceSize sourceOffset) {
|
||||||
auto bufferSlice = buffer->getSliceHandle();
|
auto bufferSlice = buffer->getSliceHandle();
|
||||||
|
auto sourceSlice = source->getSliceHandle(sourceOffset, buffer->info().size);
|
||||||
auto stagingSlice = m_staging.alloc(bufferSlice.length);
|
|
||||||
auto stagingHandle = stagingSlice.getSliceHandle();
|
|
||||||
std::memcpy(stagingHandle.mapPtr, data, bufferSlice.length);
|
|
||||||
|
|
||||||
VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
|
VkBufferCopy2 copyRegion = { VK_STRUCTURE_TYPE_BUFFER_COPY_2 };
|
||||||
copyRegion.srcOffset = stagingHandle.offset;
|
copyRegion.srcOffset = sourceSlice.offset;
|
||||||
copyRegion.dstOffset = bufferSlice.offset;
|
copyRegion.dstOffset = bufferSlice.offset;
|
||||||
copyRegion.size = bufferSlice.length;
|
copyRegion.size = bufferSlice.length;
|
||||||
|
|
||||||
VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
|
VkCopyBufferInfo2 copyInfo = { VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2 };
|
||||||
copyInfo.srcBuffer = stagingHandle.handle;
|
copyInfo.srcBuffer = sourceSlice.handle;
|
||||||
copyInfo.dstBuffer = bufferSlice.handle;
|
copyInfo.dstBuffer = bufferSlice.handle;
|
||||||
copyInfo.regionCount = 1;
|
copyInfo.regionCount = 1;
|
||||||
copyInfo.pRegions = ©Region;
|
copyInfo.pRegions = ©Region;
|
||||||
@ -2574,7 +2572,7 @@ namespace dxvk {
|
|||||||
buffer->info().stages, buffer->info().access);
|
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);
|
m_cmd->trackResource<DxvkAccess::Write>(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1151,14 +1151,17 @@ namespace dxvk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Uses transfer queue to initialize buffer
|
* \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] 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(
|
void uploadBuffer(
|
||||||
const Rc<DxvkBuffer>& buffer,
|
const Rc<DxvkBuffer>& buffer,
|
||||||
const void* data);
|
const Rc<DxvkBuffer>& source,
|
||||||
|
VkDeviceSize sourceOffset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Uses transfer queue to initialize image
|
* \brief Uses transfer queue to initialize image
|
||||||
|
Loading…
x
Reference in New Issue
Block a user