1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 22:29:15 +01:00

[dxvk] Refactor depth-stencil resolve to also work on color images

This commit is contained in:
Philip Rebohle 2025-03-04 02:11:15 +01:00
parent 2edc9c880e
commit 2dd815049c
2 changed files with 68 additions and 51 deletions

View File

@ -1999,13 +1999,11 @@ namespace dxvk {
this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource)); this->prepareImage(srcImage, vk::makeSubresourceRange(region.srcSubresource));
if (useFb) { if (useFb) {
this->resolveImageFb( this->resolveImageFb(dstImage, srcImage, region,
dstImage, srcImage, region, VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED, depthMode, stencilMode);
depthMode, stencilMode);
} else { } else {
this->resolveImageDs( this->resolveImageRp(dstImage, srcImage, region,
dstImage, srcImage, region, VK_FORMAT_UNDEFINED, depthMode, stencilMode);
depthMode, stencilMode);
} }
} }
@ -4693,21 +4691,31 @@ namespace dxvk {
} }
void DxvkContext::resolveImageDs( void DxvkContext::resolveImageRp(
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage, const Rc<DxvkImage>& srcImage,
const VkImageResolve& region, const VkImageResolve& region,
VkResolveModeFlagBits depthMode, VkFormat format,
VkResolveModeFlagBits mode,
VkResolveModeFlagBits stencilMode) { VkResolveModeFlagBits stencilMode) {
auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource); auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource);
auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource); auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource);
bool isDepthStencil = (dstImage->formatInfo()->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
DxvkImageUsageInfo usageInfo = { }; DxvkImageUsageInfo usageInfo = { };
usageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; usageInfo.usage = isDepthStencil
? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (format) {
usageInfo.viewFormatCount = 1u;
usageInfo.viewFormats = &format;
}
if (!ensureImageCompatibility(dstImage, usageInfo) if (!ensureImageCompatibility(dstImage, usageInfo)
|| !ensureImageCompatibility(srcImage, usageInfo)) { || !ensureImageCompatibility(srcImage, usageInfo)) {
Logger::err(str::format("DxvkContext: resolveImageDs: Unsupported images:" Logger::err(str::format("DxvkContext: resolveImageRp: Unsupported images:"
"\n dst format: ", dstImage->info().format, "\n dst format: ", dstImage->info().format,
"\n src format: ", srcImage->info().format)); "\n src format: ", srcImage->info().format));
} }
@ -4720,42 +4728,54 @@ namespace dxvk {
const char* srcName = srcImage->info().debugName; const char* srcName = srcImage->info().debugName;
m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer, m_cmd->cmdBeginDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer,
vk::makeLabel(0xf0dcdc, str::format("Resolve DS (", vk::makeLabel(0xf0dcdc, str::format("Resolve pass (",
dstName ? dstName : "unknown", ", ", dstName ? dstName : "unknown", ", ",
srcName ? srcName : "unknown", ")").c_str())); srcName ? srcName : "unknown", ")").c_str()));
} }
// Transition both images to usable layouts if necessary. For the source image we // Transition both images to usable layouts if necessary. For the source image
// can be fairly leniet since writable layouts are allowed for resolve attachments. // we can be fairly lenient when dealing with writable depth-stencil layouts.
VkImageLayout dstLayout = dstImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); VkImageLayout writableLayout = isDepthStencil
? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
: VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkImageLayout dstLayout = dstImage->pickLayout(writableLayout);
VkImageLayout srcLayout = srcImage->info().layout; VkImageLayout srcLayout = srcImage->info().layout;
if (srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL if (srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
&& srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL) && srcLayout != VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL)
srcLayout = srcImage->pickLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); srcLayout = srcImage->pickLayout(writableLayout);
addImageLayoutTransition(*srcImage, srcSubresourceRange, srcLayout, VkPipelineStageFlags2 stages = isDepthStencil
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, ? VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT, false); : VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
addImageLayoutTransition(*dstImage, dstSubresourceRange, dstLayout,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, VkAccessFlags2 srcAccess = isDepthStencil
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, true); ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
: VK_ACCESS_COLOR_ATTACHMENT_READ_BIT;
VkAccessFlags2 dstAccess = isDepthStencil
? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
: VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
addImageLayoutTransition(*srcImage, srcSubresourceRange, srcLayout, stages, srcAccess, false);
addImageLayoutTransition(*dstImage, dstSubresourceRange, dstLayout, stages, dstAccess, true);
flushImageLayoutTransitions(DxvkCmdBuffer::ExecBuffer); flushImageLayoutTransitions(DxvkCmdBuffer::ExecBuffer);
// Create a pair of views for the attachment resolve // Create a pair of views for the attachment resolve
DxvkMetaResolveViews views(dstImage, region.dstSubresource, DxvkMetaResolveViews views(dstImage, region.dstSubresource,
srcImage, region.srcSubresource, dstImage->info().format); srcImage, region.srcSubresource, dstImage->info().format);
VkRenderingAttachmentInfo depthAttachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO }; VkRenderingAttachmentInfo attachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
depthAttachment.imageView = views.srcView->handle(); attachment.imageView = views.srcView->handle();
depthAttachment.imageLayout = srcLayout; attachment.imageLayout = srcLayout;
depthAttachment.resolveMode = depthMode; attachment.resolveMode = mode;
depthAttachment.resolveImageView = views.dstView->handle(); attachment.resolveImageView = views.dstView->handle();
depthAttachment.resolveImageLayout = dstLayout; attachment.resolveImageLayout = dstLayout;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
VkRenderingAttachmentInfo stencilAttachment = depthAttachment; VkRenderingAttachmentInfo stencilAttachment = attachment;
stencilAttachment.resolveMode = stencilMode; stencilAttachment.resolveMode = stencilMode;
VkExtent3D extent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel); VkExtent3D extent = dstImage->mipLevelExtent(region.dstSubresource.mipLevel);
@ -4765,29 +4785,25 @@ namespace dxvk {
renderingInfo.renderArea.extent = VkExtent2D { extent.width, extent.height }; renderingInfo.renderArea.extent = VkExtent2D { extent.width, extent.height };
renderingInfo.layerCount = region.dstSubresource.layerCount; renderingInfo.layerCount = region.dstSubresource.layerCount;
if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) if (isDepthStencil) {
renderingInfo.pDepthAttachment = &depthAttachment; if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)
renderingInfo.pDepthAttachment = &attachment;
if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) if (dstImage->formatInfo()->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
renderingInfo.pStencilAttachment = &stencilAttachment; renderingInfo.pStencilAttachment = &stencilAttachment;
} else {
renderingInfo.colorAttachmentCount = 1u;
renderingInfo.pColorAttachments = &attachment;
}
m_cmd->cmdBeginRendering(&renderingInfo); m_cmd->cmdBeginRendering(&renderingInfo);
m_cmd->cmdEndRendering(); m_cmd->cmdEndRendering();
// Add barriers for the resolve operation // Add barriers for the render pass resolve
accessImage(DxvkCmdBuffer::ExecBuffer, accessImage(DxvkCmdBuffer::ExecBuffer, *srcImage, srcSubresourceRange,
*srcImage, srcSubresourceRange, srcLayout, srcLayout, stages, srcAccess, DxvkAccessOp::None);
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | accessImage(DxvkCmdBuffer::ExecBuffer, *dstImage, dstSubresourceRange,
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT, dstLayout, stages, dstAccess, DxvkAccessOp::None);
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
DxvkAccessOp::None);
accessImage(DxvkCmdBuffer::ExecBuffer,
*dstImage, dstSubresourceRange, dstLayout,
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,
VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
DxvkAccessOp::None);
if (unlikely(m_features.test(DxvkContextFeature::DebugUtils))) if (unlikely(m_features.test(DxvkContextFeature::DebugUtils)))
m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer); m_cmd->cmdEndDebugUtilsLabel(DxvkCmdBuffer::ExecBuffer);

View File

@ -1616,13 +1616,14 @@ namespace dxvk {
const Rc<DxvkImage>& srcImage, const Rc<DxvkImage>& srcImage,
const VkImageResolve& region); const VkImageResolve& region);
void resolveImageDs( void resolveImageRp(
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage, const Rc<DxvkImage>& srcImage,
const VkImageResolve& region, const VkImageResolve& region,
VkResolveModeFlagBits depthMode, VkFormat format,
VkResolveModeFlagBits mode,
VkResolveModeFlagBits stencilMode); VkResolveModeFlagBits stencilMode);
void resolveImageFb( void resolveImageFb(
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage, const Rc<DxvkImage>& srcImage,