From a987b729a7efb99cb45733d07e87c56f8ae944f8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 9 Nov 2021 17:18:09 +0100 Subject: [PATCH] [dxvk] Introduce DxvkFramebufferKey Can be used to cache framebuffer objects. --- src/dxvk/dxvk_framebuffer.cpp | 20 ++++++++++++++- src/dxvk/dxvk_framebuffer.h | 47 ++++++++++++++++++++++++++++++++--- src/dxvk/dxvk_image.cpp | 5 +++- src/dxvk/dxvk_image.h | 16 ++++++++++++ 4 files changed, 83 insertions(+), 5 deletions(-) diff --git a/src/dxvk/dxvk_framebuffer.cpp b/src/dxvk/dxvk_framebuffer.cpp index 6a545caec..58d07e3b0 100644 --- a/src/dxvk/dxvk_framebuffer.cpp +++ b/src/dxvk/dxvk_framebuffer.cpp @@ -70,6 +70,24 @@ namespace dxvk { } + DxvkFramebufferKey DxvkFramebufferInfo::key() const { + DxvkFramebufferKey result = { }; + + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) { + if (m_renderTargets.color[i].view != nullptr) + result.colorViews[i] = m_renderTargets.color[i].view->cookie(); + } + + if (m_renderTargets.depth.view != nullptr) + result.depthView = m_renderTargets.depth.view->cookie(); + + if (result.renderPass) + result.renderPass = m_renderPass->getDefaultHandle(); + + return result; + } + + DxvkRenderPassFormat DxvkFramebufferInfo::getRenderPassFormat(const DxvkRenderTargets& renderTargets) { DxvkRenderPassFormat format; @@ -128,7 +146,7 @@ namespace dxvk { DxvkFramebuffer::DxvkFramebuffer( const Rc& vkd, const DxvkFramebufferInfo& info) - : m_vkd (vkd) { + : m_vkd(vkd), m_key(info.key()) { std::array views; uint32_t attachmentCount = 0; diff --git a/src/dxvk/dxvk_framebuffer.h b/src/dxvk/dxvk_framebuffer.h index 2c14f95c1..eaeb62c10 100644 --- a/src/dxvk/dxvk_framebuffer.h +++ b/src/dxvk/dxvk_framebuffer.h @@ -17,7 +17,7 @@ namespace dxvk { uint32_t height; uint32_t layers; }; - + /** * \brief Framebuffer attachment @@ -52,6 +52,33 @@ namespace dxvk { }; + /** + * \brief Framebuffer key + */ + struct DxvkFramebufferKey { + uint64_t colorViews[MaxNumRenderTargets]; + uint64_t depthView; + VkRenderPass renderPass; + + size_t hash() const { + DxvkHashState state; + state.add(depthView); + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) + state.add(colorViews[i]); + state.add(reinterpret_cast(renderPass)); + return state; + } + + bool eq(const DxvkFramebufferKey& other) const { + bool eq = depthView == other.depthView + && renderPass == other.renderPass; + for (uint32_t i = 0; i < MaxNumRenderTargets; i++) + eq &= colorViews[i] == other.colorViews[i]; + return eq; + } + }; + + /** * \brief Framebuffer info * @@ -192,6 +219,12 @@ namespace dxvk { */ bool isWritable(uint32_t attachmentIndex, VkImageAspectFlags aspects) const; + /** + * \brief Generates framebuffer key + * \returns Framebuffer key + */ + DxvkFramebufferKey key() const; + /** * \brief Generatess render pass format * @@ -247,11 +280,19 @@ namespace dxvk { VkFramebuffer handle() const { return m_handle; } + + /** + * \brief Framebuffer key + */ + const DxvkFramebufferKey& key() const { + return m_key; + } private: - Rc m_vkd; - VkFramebuffer m_handle; + Rc m_vkd; + VkFramebuffer m_handle; + DxvkFramebufferKey m_key; }; diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index f849a72d8..89509456c 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -2,6 +2,9 @@ namespace dxvk { + std::atomic DxvkImageView::s_cookie = { 0ull }; + + DxvkImage::DxvkImage( const Rc& vkd, const DxvkImageCreateInfo& createInfo, @@ -135,7 +138,7 @@ namespace dxvk { const Rc& vkd, const Rc& image, const DxvkImageViewCreateInfo& info) - : m_vkd(vkd), m_image(image), m_info(info) { + : m_vkd(vkd), m_image(image), m_info(info), m_cookie(++s_cookie) { for (uint32_t i = 0; i < ViewCount; i++) m_views[i] = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index b3b721e0f..5b1a8b154 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -418,6 +418,18 @@ namespace dxvk { return imageFormatInfo(m_info.format); } + /** + * \brief Unique object identifier + * + * Can be used to identify an object even when + * the lifetime of the object is unknown, and + * without referencing the actual object. + * \returns Unique identifier + */ + uint64_t cookie() const { + return m_cookie; + } + /** * \brief Mip level size * @@ -535,6 +547,10 @@ namespace dxvk { DxvkImageViewCreateInfo m_info; VkImageView m_views[ViewCount]; + uint64_t m_cookie; + + static std::atomic s_cookie; + void createView(VkImageViewType type, uint32_t numLayers); };