mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[dxvk] Refactor meta resolves
This commit is contained in:
parent
2c176f4950
commit
8c67af680c
@ -2107,6 +2107,11 @@ namespace dxvk {
|
||||
}
|
||||
}
|
||||
|
||||
// If the source image is shader-readable anyway, we can use the
|
||||
// FB path if it's beneficial on the device we're running on
|
||||
if (m_device->perfHints().preferFbDepthStencilCopy)
|
||||
useFb |= srcImage->info().usage & VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
if (useFb) {
|
||||
this->resolveImageFb(
|
||||
dstImage, srcImage, region, VK_FORMAT_UNDEFINED,
|
||||
@ -4287,6 +4292,16 @@ namespace dxvk {
|
||||
auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource);
|
||||
auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource);
|
||||
|
||||
DxvkImageUsageInfo usageInfo = { };
|
||||
usageInfo.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
if (!ensureImageCompatibility(dstImage, usageInfo)
|
||||
|| !ensureImageCompatibility(srcImage, usageInfo)) {
|
||||
Logger::err(str::format("DxvkContext: resolveImageDs: Unsupported images:"
|
||||
"\n dst format: ", dstImage->info().format,
|
||||
"\n src format: ", srcImage->info().format));
|
||||
}
|
||||
|
||||
if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
||||
|| m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
@ -4322,15 +4337,14 @@ namespace dxvk {
|
||||
m_execAcquires.recordCommands(m_cmd);
|
||||
|
||||
// Create a pair of views for the attachment resolve
|
||||
Rc<DxvkMetaResolveViews> views = new DxvkMetaResolveViews(m_device->vkd(),
|
||||
dstImage, region.dstSubresource, srcImage, region.srcSubresource,
|
||||
dstImage->info().format);
|
||||
DxvkMetaResolveViews views(dstImage, region.dstSubresource,
|
||||
srcImage, region.srcSubresource, dstImage->info().format);
|
||||
|
||||
VkRenderingAttachmentInfo depthAttachment = { VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO };
|
||||
depthAttachment.imageView = views->getSrcView();
|
||||
depthAttachment.imageView = views.srcView->handle();
|
||||
depthAttachment.imageLayout = srcLayout;
|
||||
depthAttachment.resolveMode = depthMode;
|
||||
depthAttachment.resolveImageView = views->getDstView();
|
||||
depthAttachment.resolveImageView = views.dstView->handle();
|
||||
depthAttachment.resolveImageLayout = dstLayout;
|
||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
@ -4375,11 +4389,10 @@ namespace dxvk {
|
||||
|
||||
m_cmd->trackResource<DxvkAccess::Write>(dstImage);
|
||||
m_cmd->trackResource<DxvkAccess::Read>(srcImage);
|
||||
m_cmd->trackResource<DxvkAccess::None>(views);
|
||||
}
|
||||
|
||||
|
||||
void DxvkContext::resolveImageFbDirect(
|
||||
void DxvkContext::resolveImageFb(
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const Rc<DxvkImage>& srcImage,
|
||||
const VkImageResolve& region,
|
||||
@ -4391,6 +4404,33 @@ namespace dxvk {
|
||||
auto dstSubresourceRange = vk::makeSubresourceRange(region.dstSubresource);
|
||||
auto srcSubresourceRange = vk::makeSubresourceRange(region.srcSubresource);
|
||||
|
||||
// Ensure we can access the destination image for rendering,
|
||||
// and the source image for reading within the shader.
|
||||
DxvkImageUsageInfo dstUsage = { };
|
||||
dstUsage.usage = (dstImage->formatInfo()->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
|
||||
? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
|
||||
: VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
|
||||
DxvkImageUsageInfo srcUsage = { };
|
||||
srcUsage.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
||||
|
||||
if (format) {
|
||||
dstUsage.viewFormatCount = 1u;
|
||||
dstUsage.viewFormats = &format;
|
||||
|
||||
srcUsage.viewFormatCount = 1u;
|
||||
srcUsage.viewFormats = &format;
|
||||
}
|
||||
|
||||
if (!ensureImageCompatibility(dstImage, dstUsage)
|
||||
|| !ensureImageCompatibility(srcImage, srcUsage)) {
|
||||
Logger::err(str::format("DxvkContext: resolveImageFb: Unsupported images:",
|
||||
"\n dst format: ", dstImage->info().format,
|
||||
"\n src format: ", srcImage->info().format,
|
||||
"\n view format: ", format));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_execBarriers.isImageDirty(dstImage, dstSubresourceRange, DxvkAccess::Write)
|
||||
|| m_execBarriers.isImageDirty(srcImage, srcSubresourceRange, DxvkAccess::Write))
|
||||
m_execBarriers.recordCommands(m_cmd);
|
||||
@ -4572,58 +4612,6 @@ 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))
|
||||
&& (!format || 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();
|
||||
|
@ -1579,14 +1579,6 @@ 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,
|
||||
|
@ -15,38 +15,36 @@
|
||||
namespace dxvk {
|
||||
|
||||
DxvkMetaResolveViews::DxvkMetaResolveViews(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const VkImageSubresourceLayers& dstSubresources,
|
||||
const Rc<DxvkImage>& srcImage,
|
||||
const VkImageSubresourceLayers& srcSubresources,
|
||||
VkFormat format)
|
||||
: m_vkd(vkd) {
|
||||
VkImageViewUsageCreateInfo usageInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO };
|
||||
usageInfo.usage = (lookupFormatInfo(format)->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
VkFormat format) {
|
||||
DxvkImageViewKey viewInfo;
|
||||
viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
viewInfo.format = format;
|
||||
viewInfo.aspects = dstSubresources.aspectMask;
|
||||
viewInfo.mipIndex = dstSubresources.mipLevel;
|
||||
viewInfo.mipCount = 1u;
|
||||
viewInfo.layerIndex = dstSubresources.baseArrayLayer;
|
||||
viewInfo.layerCount = dstSubresources.layerCount;
|
||||
viewInfo.usage = (lookupFormatInfo(format)->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT)
|
||||
? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
|
||||
: VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
VkImageViewCreateInfo info = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, &usageInfo };
|
||||
info.image = dstImage->handle();
|
||||
info.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY;
|
||||
info.format = format;
|
||||
info.subresourceRange = vk::makeSubresourceRange(dstSubresources);
|
||||
dstView = dstImage->createView(viewInfo);
|
||||
|
||||
if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_dstImageView))
|
||||
throw DxvkError("DxvkMetaResolveViews: Failed to create destination view");
|
||||
viewInfo.aspects = srcSubresources.aspectMask;
|
||||
viewInfo.mipIndex = srcSubresources.mipLevel;
|
||||
viewInfo.layerIndex = srcSubresources.baseArrayLayer;
|
||||
viewInfo.layerCount = srcSubresources.layerCount;
|
||||
|
||||
info.image = srcImage->handle();
|
||||
info.subresourceRange = vk::makeSubresourceRange(srcSubresources);
|
||||
|
||||
if (m_vkd->vkCreateImageView(m_vkd->device(), &info, nullptr, &m_srcImageView))
|
||||
throw DxvkError("DxvkMetaResolveViews: Failed to create source view");
|
||||
srcView = srcImage->createView(viewInfo);
|
||||
}
|
||||
|
||||
|
||||
DxvkMetaResolveViews::~DxvkMetaResolveViews() {
|
||||
m_vkd->vkDestroyImageView(m_vkd->device(), m_srcImageView, nullptr);
|
||||
m_vkd->vkDestroyImageView(m_vkd->device(), m_dstImageView, nullptr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,12 +53,11 @@ namespace dxvk {
|
||||
/**
|
||||
* \brief Meta resolve views for attachment-based resolves
|
||||
*/
|
||||
class DxvkMetaResolveViews : public DxvkResource {
|
||||
class DxvkMetaResolveViews {
|
||||
|
||||
public:
|
||||
|
||||
DxvkMetaResolveViews(
|
||||
const Rc<vk::DeviceFn>& vkd,
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
const VkImageSubresourceLayers& dstSubresources,
|
||||
const Rc<DxvkImage>& srcImage,
|
||||
@ -67,15 +66,8 @@ namespace dxvk {
|
||||
|
||||
~DxvkMetaResolveViews();
|
||||
|
||||
VkImageView getDstView() const { return m_dstImageView; }
|
||||
VkImageView getSrcView() const { return m_srcImageView; }
|
||||
|
||||
private:
|
||||
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
VkImageView m_dstImageView = VK_NULL_HANDLE;
|
||||
VkImageView m_srcImageView = VK_NULL_HANDLE;
|
||||
Rc<DxvkImageView> dstView;
|
||||
Rc<DxvkImageView> srcView;
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user