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

[dxvk] Create and copy temporary image for resolves as necessary

Fixes #3337.
This commit is contained in:
Philip Rebohle 2023-04-06 21:04:04 +02:00
parent 6d14fffdbd
commit d9a6b40ae3
2 changed files with 63 additions and 3 deletions

View File

@ -3663,7 +3663,7 @@ namespace dxvk {
VK_ACCESS_SHADER_READ_BIT);
}
if (dstImage->info().layout != dstLayout) {
if (dstImage->info().layout != dstLayout || doDiscard) {
m_execAcquires.accessImage(
dstImage, dstSubresourceRange,
doDiscard ? VK_IMAGE_LAYOUT_UNDEFINED
@ -4221,7 +4221,7 @@ namespace dxvk {
}
void DxvkContext::resolveImageFb(
void DxvkContext::resolveImageFbDirect(
const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage,
const VkImageResolve& region,
@ -4267,7 +4267,7 @@ namespace dxvk {
dstAccess |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
}
if (dstImage->info().layout != dstLayout) {
if (dstImage->info().layout != dstLayout || doDiscard) {
m_execAcquires.accessImage(
dstImage, dstSubresourceRange,
doDiscard ? VK_IMAGE_LAYOUT_UNDEFINED
@ -4410,6 +4410,58 @@ namespace dxvk {
}
void DxvkContext::resolveImageFb(
const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage,
const VkImageResolve& region,
VkFormat format,
VkResolveModeFlagBits depthMode,
VkResolveModeFlagBits stencilMode) {
// Usually we should be able to draw directly to the destination image,
// but in some cases this might not be possible, e.g. if when copying
// from something like D32_SFLOAT to RGBA8_UNORM. In those situations,
// create a temporary image to draw to, and then copy to the actual
// destination image using a regular Vulkan transfer function.
bool useDirectCopy = (dstImage->info().usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
&& (dstImage->isViewCompatible(format));
if (useDirectCopy) {
this->resolveImageFbDirect(dstImage, srcImage,
region, format, depthMode, stencilMode);
} else {
DxvkImageCreateInfo imageInfo;
imageInfo.type = dstImage->info().type;
imageInfo.format = format;
imageInfo.flags = 0;
imageInfo.sampleCount = VK_SAMPLE_COUNT_1_BIT;
imageInfo.extent = region.extent;
imageInfo.numLayers = region.dstSubresource.layerCount;
imageInfo.mipLevels = 1;
imageInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
imageInfo.stages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
imageInfo.access = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT;
imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageInfo.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
Rc<DxvkImage> tmpImage = m_device->createImage(imageInfo,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
VkImageResolve tmpRegion = region;
tmpRegion.dstSubresource.baseArrayLayer = 0;
tmpRegion.dstSubresource.mipLevel = 0;
tmpRegion.dstOffset = VkOffset3D { 0, 0, 0 };
this->resolveImageFbDirect(tmpImage, srcImage,
tmpRegion, format, depthMode, stencilMode);
this->copyImageHw(
dstImage, region.dstSubresource, region.dstOffset,
tmpImage, tmpRegion.dstSubresource, tmpRegion.dstOffset,
region.extent);
}
}
void DxvkContext::startRenderPass() {
if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
this->applyRenderTargetLoadLayouts();

View File

@ -1552,6 +1552,14 @@ namespace dxvk {
VkResolveModeFlagBits depthMode,
VkResolveModeFlagBits stencilMode);
void resolveImageFbDirect(
const Rc<DxvkImage>& dstImage,
const Rc<DxvkImage>& srcImage,
const VkImageResolve& region,
VkFormat format,
VkResolveModeFlagBits depthMode,
VkResolveModeFlagBits stencilMode);
void performClear(
const Rc<DxvkImageView>& imageView,
int32_t attachmentIndex,