1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-01 16:24:12 +01:00

[dxvk] Support multi-plane formats in copyImage

This commit is contained in:
Philip Rebohle 2021-05-19 18:21:30 +02:00
parent 41e28cb280
commit ed57019e13
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 38 additions and 15 deletions

View File

@ -3051,7 +3051,9 @@ namespace dxvk {
VkExtent3D extent) {
auto dstSubresourceRange = vk::makeSubresourceRange(dstSubresource);
auto srcSubresourceRange = vk::makeSubresourceRange(srcSubresource);
auto dstFormatInfo = dstImage->formatInfo();
if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|| m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
m_execBarriers.recordCommands(m_cmd);
@ -3086,17 +3088,33 @@ namespace dxvk {
m_execAcquires.recordCommands(m_cmd);
VkImageCopy imageRegion;
imageRegion.srcSubresource = srcSubresource;
imageRegion.srcOffset = srcOffset;
imageRegion.dstSubresource = dstSubresource;
imageRegion.dstOffset = dstOffset;
imageRegion.extent = extent;
m_cmd->cmdCopyImage(DxvkCmdBuffer::ExecBuffer,
srcImage->handle(), srcImageLayout,
dstImage->handle(), dstImageLayout,
1, &imageRegion);
for (auto aspects = dstSubresource.aspectMask; aspects; ) {
auto aspect = vk::getNextAspect(aspects);
VkImageCopy imageRegion;
imageRegion.srcSubresource = srcSubresource;
imageRegion.srcSubresource.aspectMask = aspect;
imageRegion.srcOffset = srcOffset;
imageRegion.dstSubresource = dstSubresource;
imageRegion.dstSubresource.aspectMask = aspect;
imageRegion.dstOffset = dstOffset;
imageRegion.extent = extent;
if (dstFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) {
auto plane = &dstFormatInfo->planes[vk::getPlaneIndex(aspect)];
imageRegion.srcOffset.x /= plane->blockSize.width;
imageRegion.srcOffset.y /= plane->blockSize.height;
imageRegion.dstOffset.x /= plane->blockSize.width;
imageRegion.dstOffset.y /= plane->blockSize.height;
imageRegion.extent.width /= plane->blockSize.width;
imageRegion.extent.height /= plane->blockSize.height;
}
m_cmd->cmdCopyImage(DxvkCmdBuffer::ExecBuffer,
srcImage->handle(), srcImageLayout,
dstImage->handle(), dstImageLayout,
1, &imageRegion);
}
m_execBarriers.accessImage(
dstImage, dstSubresourceRange,

View File

@ -115,9 +115,14 @@ namespace dxvk::vk {
}
inline VkImageAspectFlags getNextAspect(VkImageAspectFlags& mask) {
VkImageAspectFlags result = mask & -mask;
mask &= ~result;
return result;
if (likely(mask & (VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
// Depth-stencil isn't considered multi-planar
return std::exchange(mask, VkImageAspectFlags(0));
} else {
VkImageAspectFlags result = mask & -mask;
mask &= ~result;
return result;
}
}
}