From 77216867cc7e994cd31a44c64fde026653e3d79e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 3 Mar 2025 23:16:04 +0100 Subject: [PATCH] [dxvk] Store various image properties inside the view --- src/dxvk/dxvk_image.cpp | 32 +++++++++++++++++++++++----- src/dxvk/dxvk_image.h | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index c8cb51ff6..e085ff570 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -234,23 +234,30 @@ namespace dxvk { // Self-assignment is possible here if we // just update the image properties + bool invalidateViews = false; m_storage = std::move(resource); if (m_storage != old) { m_imageInfo = m_storage->getImageInfo(); - m_version += 1u; if (unlikely(m_info.debugName)) updateDebugName(); + + invalidateViews = true; } + if ((m_info.access | usageInfo.access) != m_info.access) + invalidateViews = true; + m_info.flags |= usageInfo.flags; m_info.usage |= usageInfo.usage; m_info.stages |= usageInfo.stages; m_info.access |= usageInfo.access; - if (usageInfo.layout != VK_IMAGE_LAYOUT_UNDEFINED) + if (usageInfo.layout != VK_IMAGE_LAYOUT_UNDEFINED) { m_info.layout = usageInfo.layout; + invalidateViews = true; + } if (usageInfo.colorSpace != VK_COLOR_SPACE_MAX_ENUM_KHR) m_info.colorSpace = usageInfo.colorSpace; @@ -266,6 +273,10 @@ namespace dxvk { } m_stableAddress |= usageInfo.stableGpuAddress; + + if (invalidateViews) + m_version += 1u; + return old; } @@ -423,8 +434,9 @@ namespace dxvk { DxvkImageView::DxvkImageView( DxvkImage* image, const DxvkImageViewKey& key) - : m_image(image), m_key(key) { - + : m_image (image), + m_key (key) { + updateProperties(); } @@ -509,6 +521,9 @@ namespace dxvk { void DxvkImageView::updateViews() { + // Latch updated image properties + updateProperties(); + // Update all views that are not currently null for (uint32_t i = 0; i < m_views.size(); i++) { if (m_views[i]) @@ -517,5 +532,12 @@ namespace dxvk { m_version = m_image->m_version; } - + + + void DxvkImageView::updateProperties() { + m_properties.layout = m_image->info().layout; + m_properties.samples = m_image->info().sampleCount; + m_properties.layout = m_image->info().layout; + } + } diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index b303218d6..78b863868 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -104,6 +104,18 @@ namespace dxvk { }; + /** + * \brief Image properties stored in the view + * + * Used to reduce some pointer chasing. + */ + struct DxvkImageViewImageProperties { + VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED; + VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_FLAG_BITS_MAX_ENUM; + VkAccessFlags access = 0u; + }; + + /** * \brief Virtual image view * @@ -272,6 +284,30 @@ namespace dxvk { view->imageSubresources()); } + /** + * \brief Queries the default image layout + * + * Used when binding the view as a descriptor. + * \returns Default image layout + */ + VkImageLayout defaultLayout() const { + return m_properties.layout; + } + + /** + * \brief Checks whether the image is multisampled + * \returns \c true if the image is multisampled + */ + bool isMultisampled() const { + return m_properties.samples > VK_SAMPLE_COUNT_1_BIT; + } + + /** + * \brief Checks whether the image has graphics stores + * \returns \c true if the image has graphics pipeline stores + */ + bool hasGfxStores() const; + private: DxvkImage* m_image = nullptr; @@ -279,12 +315,16 @@ namespace dxvk { uint32_t m_version = 0u; + DxvkImageViewImageProperties m_properties = { }; + std::array m_views = { }; VkImageView createView(VkImageViewType type) const; void updateViews(); + void updateProperties(); + }; @@ -760,4 +800,10 @@ namespace dxvk { return m_views[viewType]; } + + inline bool DxvkImageView::hasGfxStores() const { + return (m_properties.access & VK_ACCESS_SHADER_WRITE_BIT) + && (m_image->hasGfxStores()); + } + }