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:
parent
e749a4a4ac
commit
ff9d6e3226
@ -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);
|
||||
}
|
||||
|
@ -906,6 +906,9 @@ namespace dxvk {
|
||||
|
||||
DxvkDataSlice AllocUpdateBufferSlice(size_t Size);
|
||||
|
||||
DxvkBufferSlice AllocStagingBuffer(
|
||||
VkDeviceSize Size);
|
||||
|
||||
DxvkCsChunkRef AllocCsChunk();
|
||||
|
||||
static void InitDefaultPrimitiveTopology(
|
||||
|
Loading…
x
Reference in New Issue
Block a user