mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-23 10:54:14 +01:00
[dxvk] Add store op optimization for image discards in tiler mode
This commit is contained in:
parent
821386aeff
commit
fcabffc1e5
@ -858,13 +858,39 @@ namespace dxvk {
|
|||||||
VkImageAspectFlags discardAspects) {
|
VkImageAspectFlags discardAspects) {
|
||||||
VkImageUsageFlags viewUsage = imageView->info().usage;
|
VkImageUsageFlags viewUsage = imageView->info().usage;
|
||||||
|
|
||||||
// Ignore non-render target views since there's likely no good use case for
|
if (!(viewUsage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)))
|
||||||
// discarding those. Also, force reinitialization even if the image is bound
|
return;
|
||||||
// as a render target, which may have niche use cases for depth buffers.
|
|
||||||
if (viewUsage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
|
// Perform store op optimization on bound render targets
|
||||||
this->spillRenderPass(true);
|
if (m_flags.test(DxvkContextFlag::GpRenderPassBound)) {
|
||||||
this->deferDiscard(imageView, discardAspects);
|
VkImageSubresourceRange subresource = imageView->imageSubresources();
|
||||||
|
subresource.aspectMask &= discardAspects;
|
||||||
|
|
||||||
|
discardRenderTarget(*imageView->image(), subresource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform load op optimization on subsequent render passes
|
||||||
|
deferDiscard(imageView, discardAspects);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::discardImage(
|
||||||
|
const Rc<DxvkImage>& image) {
|
||||||
|
VkImageUsageFlags imageUsage = image->info().usage;
|
||||||
|
|
||||||
|
if (!(imageUsage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Perform store op optimization on bound render targets
|
||||||
|
VkImageSubresourceRange subresource = { };
|
||||||
|
subresource.aspectMask = image->formatInfo()->aspectMask;
|
||||||
|
subresource.layerCount = image->info().numLayers;
|
||||||
|
subresource.levelCount = image->info().mipLevels;
|
||||||
|
|
||||||
|
discardRenderTarget(*image, subresource);
|
||||||
|
|
||||||
|
// We don't really have a good way to queue up discards for
|
||||||
|
// subsequent render passes here without a view, so don't.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -7266,6 +7292,43 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkContext::discardRenderTarget(
|
||||||
|
const DxvkImage& image,
|
||||||
|
const VkImageSubresourceRange& subresources) {
|
||||||
|
if (!m_flags.test(DxvkContextFlag::GpRenderPassBound)
|
||||||
|
|| !m_device->perfHints().preferRenderPassOps)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < m_state.om.framebufferInfo.numAttachments(); i++) {
|
||||||
|
auto& view = m_state.om.framebufferInfo.getAttachment(i).view;
|
||||||
|
|
||||||
|
if (view->image() != &image)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// If the given subresource range fully contains any bound render target,
|
||||||
|
// retroactively change the corresponding store op to DONT_CARE.
|
||||||
|
auto viewSubresources = view->imageSubresources();
|
||||||
|
|
||||||
|
if (vk::checkSubresourceRangeSuperset(subresources, viewSubresources)) {
|
||||||
|
if (subresources.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||||
|
if ((subresources.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && m_state.om.renderingInfo.depth.imageView)
|
||||||
|
m_state.om.renderingInfo.depth.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
|
||||||
|
if ((subresources.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && m_state.om.renderingInfo.stencil.imageView)
|
||||||
|
m_state.om.renderingInfo.stencil.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
} else {
|
||||||
|
uint32_t index = m_state.om.framebufferInfo.getColorAttachmentIndex(i);
|
||||||
|
|
||||||
|
if (index < m_state.om.renderingInfo.rendering.colorAttachmentCount)
|
||||||
|
m_state.om.renderingInfo.color[i].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_flags.set(DxvkContextFlag::GpDirtyFramebuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkContext::flushImageLayoutTransitions(
|
void DxvkContext::flushImageLayoutTransitions(
|
||||||
DxvkCmdBuffer cmdBuffer) {
|
DxvkCmdBuffer cmdBuffer) {
|
||||||
if (m_imageLayoutTransitions.empty())
|
if (m_imageLayoutTransitions.empty())
|
||||||
|
@ -700,7 +700,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Discards contents of an image view
|
* \brief Discards contents of an image view
|
||||||
*
|
*
|
||||||
* Discards the current contents of the image
|
* Discards the current contents of the image
|
||||||
* and performs a fast layout transition. This
|
* and performs a fast layout transition. This
|
||||||
* may improve performance in some cases.
|
* may improve performance in some cases.
|
||||||
@ -711,6 +711,14 @@ namespace dxvk {
|
|||||||
const Rc<DxvkImageView>& imageView,
|
const Rc<DxvkImageView>& imageView,
|
||||||
VkImageAspectFlags discardAspects);
|
VkImageAspectFlags discardAspects);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Discards contents of an image
|
||||||
|
*
|
||||||
|
* \param [in] image Image to discard
|
||||||
|
*/
|
||||||
|
void discardImage(
|
||||||
|
const Rc<DxvkImage>& image);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Starts compute jobs
|
* \brief Starts compute jobs
|
||||||
*
|
*
|
||||||
@ -1808,6 +1816,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
void splitCommands();
|
void splitCommands();
|
||||||
|
|
||||||
|
void discardRenderTarget(
|
||||||
|
const DxvkImage& image,
|
||||||
|
const VkImageSubresourceRange& subresources);
|
||||||
|
|
||||||
void flushImageLayoutTransitions(
|
void flushImageLayoutTransitions(
|
||||||
DxvkCmdBuffer cmdBuffer);
|
DxvkCmdBuffer cmdBuffer);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user