1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 04: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:
Philip Rebohle 2021-05-27 17:56:55 +02:00
parent e749a4a4ac
commit ff9d6e3226
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 36 additions and 21 deletions

View File

@ -1218,38 +1218,33 @@ namespace dxvk {
|| !util::isBlockAligned(offset, extent, formatInfo->blockSize, mipExtent))
return;
const VkExtent3D regionExtent = util::computeBlockCount(extent, formatInfo->blockSize);
const VkDeviceSize bytesPerRow = regionExtent.width * formatInfo->elementSize;
const VkDeviceSize bytesPerLayer = regionExtent.height * bytesPerRow;
const VkDeviceSize bytesTotal = regionExtent.depth * bytesPerLayer;
DxvkDataSlice imageDataBuffer = AllocUpdateBufferSlice(bytesTotal);
util::packImageData(imageDataBuffer.ptr(), pSrcData,
regionExtent, formatInfo->elementSize,
SrcRowPitch, SrcDepthPitch);
auto image = textureInfo->GetImage();
auto stagingSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, extent));
util::packImageData(stagingSlice.mapPtr(0),
pSrcData, SrcRowPitch, SrcDepthPitch,
image->info().type, extent, 1,
formatInfo, formatInfo->aspectMask);
EmitCs([
cDstImage = textureInfo->GetImage(),
cDstImage = std::move(image),
cDstLayers = layers,
cDstOffset = offset,
cDstExtent = extent,
cSrcData = std::move(imageDataBuffer),
cSrcBytesPerRow = bytesPerRow,
cSrcBytesPerLayer = bytesPerLayer,
cStagingSlice = std::move(stagingSlice),
cPackedFormat = packedFormat
] (DxvkContext* ctx) {
if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
ctx->updateImage(cDstImage, cDstLayers,
cDstOffset, cDstExtent, cSrcData.ptr(),
cSrcBytesPerRow, cSrcBytesPerLayer);
ctx->copyBufferToImage(cDstImage,
cDstLayers, cDstOffset, cDstExtent,
cStagingSlice.buffer(),
cStagingSlice.offset(), 0);
} else {
ctx->updateDepthStencilImage(cDstImage, cDstLayers,
ctx->copyPackedBufferToDepthStencilImage(cDstImage, cDstLayers,
VkOffset2D { cDstOffset.x, cDstOffset.y },
VkExtent2D { cDstExtent.width, cDstExtent.height },
cSrcData.ptr(), cSrcBytesPerRow, cSrcBytesPerLayer,
cPackedFormat);
cStagingSlice.buffer(),
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() {
return m_parent->AllocCsChunk(m_csFlags);
}

View File

@ -906,6 +906,9 @@ namespace dxvk {
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
DxvkBufferSlice AllocStagingBuffer(
VkDeviceSize Size);
DxvkCsChunkRef AllocCsChunk();
static void InitDefaultPrimitiveTopology(