mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +01:00
[d3d11] Use staging buffer and copyBufferToImage for UpdateSubresource
Reduces number of copies and also fixes problems with multi-plane formats.
This commit is contained in:
parent
e749a4a4ac
commit
ff9d6e3226
@ -1218,38 +1218,33 @@ namespace dxvk {
|
|||||||
|| !util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent))
|
|| !util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const VkExtent3D regionExtent = util::computeBlockCount(extent, formatInfo->blockSize);
|
auto image = textureInfo->GetImage();
|
||||||
|
auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent));
|
||||||
const VkDeviceSize bytesPerRow = regionExtent.width * formatInfo->elementSize;
|
|
||||||
const VkDeviceSize bytesPerLayer = regionExtent.height * bytesPerRow;
|
util::packImageData(stagingSlice.mapPtr(0),
|
||||||
const VkDeviceSize bytesTotal = regionExtent.depth * bytesPerLayer;
|
pSrcData, SrcRowPitch, SrcDepthPitch,
|
||||||
|
image->info().type, extent, 1,
|
||||||
DxvkDataSlice imageDataBuffer = AllocUpdateBufferSlice(bytesTotal);
|
formatInfo, formatInfo->aspectMask);
|
||||||
|
|
||||||
util::packImageData(imageDataBuffer.ptr(), pSrcData,
|
|
||||||
regionExtent, formatInfo->elementSize,
|
|
||||||
SrcRowPitch, SrcDepthPitch);
|
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cDstImage = textureInfo->GetImage(),
|
cDstImage = std::move(image),
|
||||||
cDstLayers = layers,
|
cDstLayers = layers,
|
||||||
cDstOffset = offset,
|
cDstOffset = offset,
|
||||||
cDstExtent = extent,
|
cDstExtent = extent,
|
||||||
cSrcData = std::move(imageDataBuffer),
|
cStagingSlice = std::move(stagingSlice),
|
||||||
cSrcBytesPerRow = bytesPerRow,
|
|
||||||
cSrcBytesPerLayer = bytesPerLayer,
|
|
||||||
cPackedFormat = packedFormat
|
cPackedFormat = packedFormat
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||||
ctx->updateImage(cDstImage, cDstLayers,
|
ctx->copyBufferToImage(cDstImage,
|
||||||
cDstOffset, cDstExtent, cSrcData.ptr(),
|
cDstLayers, cDstOffset, cDstExtent,
|
||||||
cSrcBytesPerRow, cSrcBytesPerLayer);
|
cStagingSlice.buffer(),
|
||||||
|
cStagingSlice.offset(), 0);
|
||||||
} else {
|
} else {
|
||||||
ctx->updateDepthStencilImage(cDstImage, cDstLayers,
|
ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers,
|
||||||
VkOffset2D { cDstOffset.x, cDstOffset.y },
|
VkOffset2D { cDstOffset.x, cDstOffset.y },
|
||||||
VkExtent2D { cDstExtent.width, cDstExtent.height },
|
VkExtent2D { cDstExtent.width, cDstExtent.height },
|
||||||
cSrcData.ptr(), cSrcBytesPerRow, cSrcBytesPerLayer,
|
cStagingSlice.buffer(),
|
||||||
cPackedFormat);
|
cStagingSlice.offset(), cPackedFormat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4310,6 +4305,23 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkBufferSlice D3D11DeviceContext::AllocStagingBuffer(
|
||||||
|
VkDeviceSize Size) {
|
||||||
|
DxvkBufferCreateInfo info;
|
||||||
|
info.size = Size;
|
||||||
|
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_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;
|
||||||
|
|
||||||
|
return DxvkBufferSlice(m_device->createBuffer(info,
|
||||||
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() {
|
DxvkCsChunkRef D3D11DeviceContext::AllocCsChunk() {
|
||||||
return m_parent->AllocCsChunk(m_csFlags);
|
return m_parent->AllocCsChunk(m_csFlags);
|
||||||
}
|
}
|
||||||
|
@ -906,6 +906,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
|
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
|
||||||
|
|
||||||
|
DxvkBufferSlice AllocStagingBuffer(
|
||||||
|
VkDeviceSize Size);
|
||||||
|
|
||||||
DxvkCsChunkRef AllocCsChunk();
|
DxvkCsChunkRef AllocCsChunk();
|
||||||
|
|
||||||
static void InitDefaultPrimitiveTopology(
|
static void InitDefaultPrimitiveTopology(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user