mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Discard buffer slice in copyBuffer if possible
This commit is contained in:
parent
5e763853e5
commit
82518de4b4
@ -651,33 +651,46 @@ namespace dxvk {
|
|||||||
const Rc<DxvkBuffer>& srcBuffer,
|
const Rc<DxvkBuffer>& srcBuffer,
|
||||||
VkDeviceSize srcOffset,
|
VkDeviceSize srcOffset,
|
||||||
VkDeviceSize numBytes) {
|
VkDeviceSize numBytes) {
|
||||||
if (numBytes == 0)
|
// When overwriting small buffers, we can allocate a new slice in order to
|
||||||
return;
|
// avoid suspending the current render pass or inserting barriers. The source
|
||||||
|
// buffer must be read-only since otherwise we cannot schedule the copy early.
|
||||||
this->spillRenderPass(true);
|
bool srcIsReadOnly = DxvkBarrierSet::getAccessTypes(srcBuffer->info().access) == DxvkAccess::Read;
|
||||||
|
bool replaceBuffer = srcIsReadOnly && this->tryInvalidateDeviceLocalBuffer(dstBuffer, numBytes);
|
||||||
auto dstSlice = dstBuffer->getSliceHandle(dstOffset, numBytes);
|
|
||||||
auto srcSlice = srcBuffer->getSliceHandle(srcOffset, numBytes);
|
|
||||||
|
|
||||||
if (m_execBarriers.isBufferDirty(srcSlice, DxvkAccess::Read)
|
auto srcSlice = srcBuffer->getSliceHandle(srcOffset, numBytes);
|
||||||
|| m_execBarriers.isBufferDirty(dstSlice, DxvkAccess::Write))
|
auto dstSlice = dstBuffer->getSliceHandle(dstOffset, numBytes);
|
||||||
m_execBarriers.recordCommands(m_cmd);
|
|
||||||
|
if (!replaceBuffer) {
|
||||||
|
this->spillRenderPass(true);
|
||||||
|
|
||||||
|
if (m_execBarriers.isBufferDirty(srcSlice, DxvkAccess::Read)
|
||||||
|
|| m_execBarriers.isBufferDirty(dstSlice, DxvkAccess::Write))
|
||||||
|
m_execBarriers.recordCommands(m_cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
DxvkCmdBuffer cmdBuffer = replaceBuffer
|
||||||
|
? DxvkCmdBuffer::InitBuffer
|
||||||
|
: DxvkCmdBuffer::ExecBuffer;
|
||||||
|
|
||||||
VkBufferCopy bufferRegion;
|
VkBufferCopy bufferRegion;
|
||||||
bufferRegion.srcOffset = srcSlice.offset;
|
bufferRegion.srcOffset = srcSlice.offset;
|
||||||
bufferRegion.dstOffset = dstSlice.offset;
|
bufferRegion.dstOffset = dstSlice.offset;
|
||||||
bufferRegion.size = dstSlice.length;
|
bufferRegion.size = dstSlice.length;
|
||||||
|
|
||||||
m_cmd->cmdCopyBuffer(DxvkCmdBuffer::ExecBuffer,
|
m_cmd->cmdCopyBuffer(cmdBuffer,
|
||||||
srcSlice.handle, dstSlice.handle, 1, &bufferRegion);
|
srcSlice.handle, dstSlice.handle, 1, &bufferRegion);
|
||||||
|
|
||||||
m_execBarriers.accessBuffer(srcSlice,
|
auto& barriers = replaceBuffer
|
||||||
|
? m_initBarriers
|
||||||
|
: m_execBarriers;
|
||||||
|
|
||||||
|
barriers.accessBuffer(srcSlice,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_READ_BIT,
|
VK_ACCESS_TRANSFER_READ_BIT,
|
||||||
srcBuffer->info().stages,
|
srcBuffer->info().stages,
|
||||||
srcBuffer->info().access);
|
srcBuffer->info().access);
|
||||||
|
|
||||||
m_execBarriers.accessBuffer(dstSlice,
|
barriers.accessBuffer(dstSlice,
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT,
|
VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||||
dstBuffer->info().stages,
|
dstBuffer->info().stages,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user