From edfe8e2fe6ca1989fa122d5fe890a5cb4bf57d9f Mon Sep 17 00:00:00 2001 From: assiduous Date: Sat, 1 Feb 2025 22:02:52 -0800 Subject: [PATCH] DeviceContextVk: enabled VRS with dynamic rendering --- .../include/FramebufferCache.hpp | 21 ++++++---- .../VulkanUtilities/RenderingInfoWrapper.hpp | 5 ++- .../src/DeviceContextVkImpl.cpp | 25 ++++++++---- .../src/FramebufferCache.cpp | 38 ++++++++++--------- .../src/PipelineStateVkImpl.cpp | 18 +++++---- .../VulkanUtilities/RenderingInfoWrapper.cpp | 13 +++++++ 6 files changed, 80 insertions(+), 40 deletions(-) diff --git a/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp b/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp index a3349f5cf..7b6cb7b86 100644 --- a/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp +++ b/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp @@ -79,15 +79,22 @@ class FramebufferCache void OnDestroyImageView(VkImageView ImgView); void OnDestroyRenderPass(VkRenderPass Pass); + struct CreateDyanmicRenderInfoAttribs + { + VkExtent2D Extent = {}; + uint32_t Layers = 0; + uint32_t ViewMask = 0; + + VkExtent2D ShadingRateTexelSize = {}; + + bool UseDepthAttachment = false; + bool UseStencilAttachment = false; + }; static std::unique_ptr CreateDyanmicRenderInfo( - const FramebufferCacheKey& Key, - bool UseDepthAttachment, - bool UseStencilAttachment, - uint32_t width, - uint32_t height, - uint32_t layers, - uint32_t viewMask); + const FramebufferCacheKey& Key, + const CreateDyanmicRenderInfoAttribs& Attribs); +private: RenderDeviceVkImpl& m_DeviceVk; struct FramebufferCacheKeyHash diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/RenderingInfoWrapper.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/RenderingInfoWrapper.hpp index 69f62f2ac..196333828 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/RenderingInfoWrapper.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/RenderingInfoWrapper.hpp @@ -95,12 +95,15 @@ class RenderingInfoWrapper return m_Attachments[m_StencilAttachmentIndex]; } + VkRenderingFragmentShadingRateAttachmentInfoKHR& GetShadingRateAttachment(); + private: VkRenderingInfoKHR m_RI; const size_t m_Hash = 0; - std::unique_ptr m_Attachments; + std::unique_ptr m_Attachments; + std::unique_ptr m_ShadingRateAttachment; uint32_t m_DepthAttachmentIndex = ~0u; uint32_t m_StencilAttachmentIndex = ~0u; diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 4d109c0cd..7fea4cb1e 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -1911,21 +1911,30 @@ void DeviceContextVkImpl::ChooseRenderPassAndFramebuffer() } else { - bool UseDepthAttachment = false; - bool UseStencilAttachment = false; + FramebufferCache::CreateDyanmicRenderInfoAttribs CreateRIAttribs; + CreateRIAttribs.Extent = {m_FramebufferWidth, m_FramebufferHeight}; + CreateRIAttribs.Layers = m_FramebufferSlices; + CreateRIAttribs.ViewMask = (1u << m_NumViewports) - 1u; if (m_pBoundDepthStencil) { const TEXTURE_FORMAT DepthStencilFmt = m_pBoundDepthStencil->GetTexture()->GetDesc().Format; const TextureFormatAttribs& FmtAttribs = GetTextureFormatAttribs(DepthStencilFmt); - UseDepthAttachment = true; - UseStencilAttachment = FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL; + CreateRIAttribs.UseDepthAttachment = true; + CreateRIAttribs.UseStencilAttachment = FmtAttribs.ComponentType == COMPONENT_TYPE_DEPTH_STENCIL; + } + if (m_pBoundShadingRateMap) + { + const TextureDesc& ShadingRateDesc = m_pBoundShadingRateMap->GetTexture()->GetDesc(); + // Framebuffer size may not be an integer multiple of the shading rate texel size + // Shading rate texel size be a power of two + // https://registry.khronos.org/vulkan/specs/latest/man/html/VkRenderingFragmentShadingRateAttachmentInfoKHR.html#VUID-VkRenderingFragmentShadingRateAttachmentInfoKHR-imageView-06149 + // https://registry.khronos.org/vulkan/specs/latest/man/html/VkRenderingFragmentShadingRateAttachmentInfoKHR.html#VUID-VkRenderingFragmentShadingRateAttachmentInfoKHR-imageView-06152 + CreateRIAttribs.ShadingRateTexelSize.width = AlignUpToPowerOfTwo(m_FramebufferWidth / ShadingRateDesc.Width); + CreateRIAttribs.ShadingRateTexelSize.height = AlignUpToPowerOfTwo(m_FramebufferHeight / ShadingRateDesc.Height); } - uint32_t ViewMask = (1u << m_NumViewports) - 1u; - m_DynamicRenderingInfo = FramebufferCache::CreateDyanmicRenderInfo(FBKey, UseDepthAttachment, UseStencilAttachment, - m_FramebufferWidth, m_FramebufferHeight, m_FramebufferSlices, - ViewMask); + m_DynamicRenderingInfo = FramebufferCache::CreateDyanmicRenderInfo(FBKey, CreateRIAttribs); } } diff --git a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp index 4ac11d154..99a27193c 100644 --- a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp @@ -137,22 +137,17 @@ VkFramebuffer FramebufferCache::GetFramebuffer(const FramebufferCacheKey& Key, u } } -std::unique_ptr FramebufferCache::CreateDyanmicRenderInfo(const FramebufferCacheKey& Key, - bool UseDepthAttachment, - bool UseStencilAttachment, - uint32_t width, - uint32_t height, - uint32_t layers, - uint32_t viewMask) +std::unique_ptr FramebufferCache::CreateDyanmicRenderInfo(const FramebufferCacheKey& Key, + const CreateDyanmicRenderInfoAttribs& Attribs) { std::unique_ptr RI = std::make_unique( - Key.GetHash(), Key.NumRenderTargets, UseDepthAttachment, UseStencilAttachment); + Key.GetHash(), Key.NumRenderTargets, Attribs.UseDepthAttachment, Attribs.UseStencilAttachment); - RI->SetRenderArea({{0, 0}, {width, height}}) - .SetLayerCount(layers) - .SetViewMask(viewMask); + RI->SetRenderArea({{0, 0}, Attribs.Extent}) + .SetLayerCount(Attribs.Layers) + .SetViewMask(Attribs.ViewMask); - auto InitAttachment = [](VkRenderingAttachmentInfo& Attachment, VkImageView View, VkImageLayout Layout) { + auto InitAttachment = [](VkRenderingAttachmentInfoKHR& Attachment, VkImageView View, VkImageLayout Layout) { Attachment.imageView = View; Attachment.imageLayout = Layout; Attachment.resolveMode = VK_RESOLVE_MODE_NONE_KHR; @@ -165,22 +160,31 @@ std::unique_ptr FramebufferCache::CreateD for (Uint32 rt = 0; rt < Key.NumRenderTargets; ++rt) { - VkRenderingAttachmentInfo& RTAttachment = RI->GetColorAttachment(rt); + VkRenderingAttachmentInfoKHR& RTAttachment = RI->GetColorAttachment(rt); InitAttachment(RTAttachment, Key.RTVs[rt], VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); } - if (UseDepthAttachment) + if (Attribs.UseDepthAttachment) { - VkRenderingAttachmentInfo& DepthAttachment = RI->GetDepthAttachment(); + VkRenderingAttachmentInfoKHR& DepthAttachment = RI->GetDepthAttachment(); InitAttachment(DepthAttachment, Key.DSV, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); } - if (UseStencilAttachment) + if (Attribs.UseStencilAttachment) { - VkRenderingAttachmentInfo& StencilAttachment = RI->GetStencilAttachment(); + VkRenderingAttachmentInfoKHR& StencilAttachment = RI->GetStencilAttachment(); InitAttachment(StencilAttachment, Key.DSV, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); } + if (Key.ShadingRate) + { + VkRenderingFragmentShadingRateAttachmentInfoKHR& ShadingRateAttachment = RI->GetShadingRateAttachment(); + + ShadingRateAttachment.imageView = Key.ShadingRate; + ShadingRateAttachment.imageLayout = VK_IMAGE_LAYOUT_FRAGMENT_SHADING_RATE_ATTACHMENT_OPTIMAL_KHR; + ShadingRateAttachment.shadingRateAttachmentTexelSize = Attribs.ShadingRateTexelSize; + } + return RI; } diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 4ac2b8e79..409e55431 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -138,6 +138,13 @@ void CreateGraphicsPipeline(RenderDeviceVkImpl* pDevic const VulkanUtilities::VulkanLogicalDevice& LogicalDevice = pDeviceVk->GetLogicalDevice(); const VulkanUtilities::VulkanPhysicalDevice& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); + VkGraphicsPipelineCreateInfo PipelineCI{}; + PipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; + PipelineCI.pNext = nullptr; +#ifdef DILIGENT_DEBUG + PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; +#endif + VkPipelineRenderingCreateInfoKHR PipelineRenderingCI{}; std::vector ColorAttachmentFormats; if (pRenderPass == nullptr) @@ -159,16 +166,13 @@ void CreateGraphicsPipeline(RenderDeviceVkImpl* pDevic { // VK_KHR_dynamic_rendering PipelineRenderingCI = GraphicsPipelineDesc_To_VkPipelineRenderingCreateInfo(GraphicsPipeline, ColorAttachmentFormats); + if ((GraphicsPipeline.ShadingRateFlags & PIPELINE_SHADING_RATE_FLAG_TEXTURE_BASED) != 0) + { + PipelineCI.flags |= VK_PIPELINE_CREATE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; + } } } - VkGraphicsPipelineCreateInfo PipelineCI{}; - PipelineCI.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; - PipelineCI.pNext = nullptr; -#ifdef DILIGENT_DEBUG - PipelineCI.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT; -#endif - PipelineCI.stageCount = static_cast(Stages.size()); PipelineCI.pStages = Stages.data(); PipelineCI.layout = Layout.GetVkPipelineLayout(); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/RenderingInfoWrapper.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/RenderingInfoWrapper.cpp index 9e2471545..183efde2e 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/RenderingInfoWrapper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/RenderingInfoWrapper.cpp @@ -69,4 +69,17 @@ RenderingInfoWrapper::RenderingInfoWrapper(size_t Hash, VERIFY_EXPR(AttachmentInd == TotalAttachmentCount); } +VkRenderingFragmentShadingRateAttachmentInfoKHR& RenderingInfoWrapper::GetShadingRateAttachment() +{ + if (!m_ShadingRateAttachment) + { + m_ShadingRateAttachment = std::make_unique(); + m_ShadingRateAttachment->sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR; + + m_RI.pNext = m_ShadingRateAttachment.get(); + } + + return *m_ShadingRateAttachment; +} + } // namespace VulkanUtilities