From 046a6fdcc82251bf6ae5118c5b5a410b1a976936 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 19 Oct 2019 14:23:04 -0700 Subject: Vulkan backend: added a bunch of __forceinline's to improve performance --- .../include/DeviceContextVkImpl.h | 24 ++-- .../GraphicsEngineVulkan/include/PipelineLayout.h | 45 ++++++- .../include/PipelineStateVkImpl.h | 8 +- .../include/ShaderResourceCacheVk.h | 63 +++++++++- .../include/VulkanUtilities/VulkanCommandBuffer.h | 134 ++++++++++----------- .../src/DeviceContextVkImpl.cpp | 4 +- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 37 ------ .../src/ShaderResourceCacheVk.cpp | 61 ---------- 8 files changed, 191 insertions(+), 185 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 9bcbb869..631faa64 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -233,7 +233,7 @@ public: size_t GetNumCommandsInCtx()const { return m_State.NumCommands; } - VulkanUtilities::VulkanCommandBuffer& GetCommandBuffer() + __forceinline VulkanUtilities::VulkanCommandBuffer& GetCommandBuffer() { EnsureVkCmdBuffer(); return m_CommandBuffer; @@ -264,17 +264,17 @@ private: void CommitViewports(); void CommitScissorRects(); - inline void TransitionOrVerifyBufferState(BufferVkImpl& Buffer, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - RESOURCE_STATE RequiredState, - VkAccessFlagBits ExpectedAccessFlags, - const char* OperationName); - - inline void TransitionOrVerifyTextureState(TextureVkImpl& Texture, - RESOURCE_STATE_TRANSITION_MODE TransitionMode, - RESOURCE_STATE RequiredState, - VkImageLayout ExpectedLayout, - const char* OperationName); + __forceinline void TransitionOrVerifyBufferState(BufferVkImpl& Buffer, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkAccessFlagBits ExpectedAccessFlags, + const char* OperationName); + + __forceinline void TransitionOrVerifyTextureState(TextureVkImpl& Texture, + RESOURCE_STATE_TRANSITION_MODE TransitionMode, + RESOURCE_STATE RequiredState, + VkImageLayout ExpectedLayout, + const char* OperationName); __forceinline void EnsureVkCmdBuffer() diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h index cf7c4533..902dcdd4 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h @@ -131,8 +131,10 @@ public: VkDescriptorSet VkDynamicDescrSet)const; // Computes dynamic offsets and binds descriptor sets - void BindDescriptorSetsWithDynamicOffsets(DeviceContextVkImpl* pCtxVkImpl, - DescriptorSetBindInfo& BindInfo)const; + __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, + Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + DescriptorSetBindInfo& BindInfo)const; private: @@ -207,4 +209,43 @@ private: DescriptorSetLayoutManager m_LayoutMgr; }; + +__forceinline void PipelineLayout::BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, + Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + DescriptorSetBindInfo& BindInfo)const +{ + VERIFY(BindInfo.pDbgPipelineLayout != nullptr, "Pipeline layout is not initialized, which most likely means that CommitShaderResources() has never been called"); + VERIFY(BindInfo.pDbgPipelineLayout->IsSameAs(*this), "Inconsistent pipeline layout"); + VERIFY(BindInfo.DynamicOffsetCount > 0, "This function should only be called for pipelines that contain dynamic descriptors"); + + VERIFY_EXPR(BindInfo.pResourceCache != nullptr); +#ifdef _DEBUG + Uint32 TotalDynamicDescriptors = 0; + for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType + 1)) + { + const auto &Set = m_LayoutMgr.GetDescriptorSet(VarType); + TotalDynamicDescriptors += Set.NumDynamicDescriptors; + } + VERIFY(BindInfo.DynamicOffsetCount == TotalDynamicDescriptors, "Incosistent dynamic buffer size"); + VERIFY_EXPR(BindInfo.DynamicOffsets.size() >= BindInfo.DynamicOffsetCount); +#endif + + auto NumOffsetsWritten = BindInfo.pResourceCache->GetDynamicBufferOffsets(CtxId, pCtxVkImpl, BindInfo.DynamicOffsets); + VERIFY_EXPR(NumOffsetsWritten == BindInfo.DynamicOffsetCount); (void)NumOffsetsWritten; + + // vkCmdBindDescriptorSets causes the sets numbered [firstSet .. firstSet+descriptorSetCount-1] to use the + // bindings stored in pDescriptorSets[0 .. descriptorSetCount-1] for subsequent rendering commands + // (either compute or graphics, according to the pipelineBindPoint). Any bindings that were previously + // applied via these sets are no longer valid (13.2.5) + CmdBuffer.BindDescriptorSets(BindInfo.BindPoint, + m_LayoutMgr.GetVkPipelineLayout(), + 0, // First set + BindInfo.SetCout, + BindInfo.vkSets.data(), // BindInfo.vkSets is never empty + // dynamicOffsetCount must equal the total number of dynamic descriptors in the sets being bound (13.2.5) + BindInfo.DynamicOffsetCount, + BindInfo.DynamicOffsets.data()); +} + } diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h index 9dee4114..ec11ee0d 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h @@ -80,10 +80,12 @@ public: RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, PipelineLayout::DescriptorSetBindInfo* pDescrSetBindInfo)const; - void BindDescriptorSetsWithDynamicOffsets(DeviceContextVkImpl* pCtxVkImpl, - PipelineLayout::DescriptorSetBindInfo& BindInfo) + __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, + Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + PipelineLayout::DescriptorSetBindInfo& BindInfo) { - m_PipelineLayout.BindDescriptorSetsWithDynamicOffsets(pCtxVkImpl, BindInfo); + m_PipelineLayout.BindDescriptorSetsWithDynamicOffsets(CmdBuffer, CtxId, pCtxVkImpl, BindInfo); } const PipelineLayout& GetPipelineLayout()const{return m_PipelineLayout;} diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h index c9b97d57..201b8148 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h @@ -52,6 +52,7 @@ #include #include "DescriptorPoolManager.h" #include "SPIRVShaderResources.h" +#include "BufferVkImpl.h" namespace Diligent { @@ -178,7 +179,7 @@ public: template void TransitionResources(DeviceContextVkImpl *pCtxVkImpl); - Uint32 GetDynamicBufferOffsets(DeviceContextVkImpl *pCtxVkImpl, std::vector& Offsets)const; + __forceinline Uint32 GetDynamicBufferOffsets(Uint32 CtxId, DeviceContextVkImpl* pCtxVkImpl, std::vector& Offsets)const; private: @@ -200,4 +201,64 @@ private: #endif }; +__forceinline Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + std::vector& Offsets)const +{ + // If any of the sets being bound include dynamic uniform or storage buffers, then + // pDynamicOffsets includes one element for each array element in each dynamic descriptor + // type binding in each set. Values are taken from pDynamicOffsets in an order such that + // all entries for set N come before set N+1; within a set, entries are ordered by the binding + // numbers (unclear if this is SPIRV binding or VkDescriptorSetLayoutBinding number) in the + // descriptor set layouts; and within a binding array, elements are in order. (13.2.5) + + // In each descriptor set, all uniform buffers for every shader stage come first, + // followed by all storage buffers for every shader stage, followed by all other resources + Uint32 OffsetInd = 0; + for (Uint32 set=0; set < m_NumSets; ++set) + { + const auto& DescrSet = GetDescriptorSet(set); + Uint32 res = 0; + while (res < DescrSet.GetSize()) + { + const auto& Res = DescrSet.GetResource(res); + if (Res.Type != SPIRVShaderResourceAttribs::ResourceType::UniformBuffer) + break; + + const auto* pBufferVk = Res.pObject.RawPtr(); + auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; + Offsets[OffsetInd++] = Offset; + + ++res; + } + + while (res < DescrSet.GetSize()) + { + const auto& Res = DescrSet.GetResource(res); + if (Res.Type != SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer && + Res.Type != SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer) + break; + + const auto* pBufferVkView = Res.pObject.RawPtr(); + const auto* pBufferVk = pBufferVkView != nullptr ? pBufferVkView->GetBufferVk() : 0; + auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; + Offsets[OffsetInd++] = Offset; + + ++res; + } + +#ifdef _DEBUG + for (; res < DescrSet.GetSize(); ++res) + { + const auto& Res = DescrSet.GetResource(res); + VERIFY(Res.Type != SPIRVShaderResourceAttribs::ResourceType::UniformBuffer && + Res.Type != SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer && + Res.Type != SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer, + "All uniform and storage buffers are expected to go first in the beginning of each descriptor set"); + } +#endif + } + return OffsetInd; +} + } diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h index c038bbf5..a95dce56 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h @@ -40,7 +40,7 @@ namespace VulkanUtilities VulkanCommandBuffer& operator = (const VulkanCommandBuffer&) = delete; VulkanCommandBuffer& operator = ( VulkanCommandBuffer&&) = delete; - void ClearColorImage(VkImage Image, const VkClearColorValue& Color, const VkImageSubresourceRange& Subresource) + __forceinline void ClearColorImage(VkImage Image, const VkClearColorValue& Color, const VkImageSubresourceRange& Subresource) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdClearColorImage() must be called outside of render pass (17.1)"); @@ -56,7 +56,7 @@ namespace VulkanUtilities ); } - void ClearDepthStencilImage(VkImage Image, const VkClearDepthStencilValue& DepthStencil, const VkImageSubresourceRange& Subresource) + __forceinline void ClearDepthStencilImage(VkImage Image, const VkClearDepthStencilValue& DepthStencil, const VkImageSubresourceRange& Subresource) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdClearDepthStencilImage() must be called outside of render pass (17.1)"); @@ -74,7 +74,7 @@ namespace VulkanUtilities ); } - void ClearAttachment(const VkClearAttachment& Attachment, const VkClearRect& ClearRect) + __forceinline void ClearAttachment(const VkClearAttachment& Attachment, const VkClearRect& ClearRect) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdClearAttachments() must be called inside render pass (17.2)"); @@ -89,7 +89,7 @@ namespace VulkanUtilities ); } - void Draw(uint32_t VertexCount, uint32_t InstanceCount, uint32_t FirstVertex, uint32_t FirstInstance) + __forceinline void Draw(uint32_t VertexCount, uint32_t InstanceCount, uint32_t FirstVertex, uint32_t FirstInstance) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDraw() must be called inside render pass (19.3)"); @@ -98,7 +98,7 @@ namespace VulkanUtilities vkCmdDraw(m_VkCmdBuffer, VertexCount, InstanceCount, FirstVertex, FirstInstance); } - void DrawIndexed(uint32_t IndexCount,uint32_t InstanceCount, uint32_t FirstIndex, int32_t VertexOffset, uint32_t FirstInstance) + __forceinline void DrawIndexed(uint32_t IndexCount,uint32_t InstanceCount, uint32_t FirstIndex, int32_t VertexOffset, uint32_t FirstInstance) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndexed() must be called inside render pass (19.3)"); @@ -108,7 +108,7 @@ namespace VulkanUtilities vkCmdDrawIndexed(m_VkCmdBuffer, IndexCount, InstanceCount, FirstIndex, VertexOffset, FirstInstance); } - void DrawIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride) + __forceinline void DrawIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndirect() must be called inside render pass (19.3)"); @@ -117,7 +117,7 @@ namespace VulkanUtilities vkCmdDrawIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride); } - void DrawIndexedIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride) + __forceinline void DrawIndexedIndirect(VkBuffer Buffer, VkDeviceSize Offset, uint32_t DrawCount, uint32_t Stride) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawIndirect() must be called inside render pass (19.3)"); @@ -127,7 +127,7 @@ namespace VulkanUtilities vkCmdDrawIndexedIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride); } - void Dispatch(uint32_t GroupCountX, uint32_t GroupCountY, uint32_t GroupCountZ) + __forceinline void Dispatch(uint32_t GroupCountX, uint32_t GroupCountY, uint32_t GroupCountZ) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdDispatch() must be called outside of render pass (27)"); @@ -136,7 +136,7 @@ namespace VulkanUtilities vkCmdDispatch(m_VkCmdBuffer, GroupCountX, GroupCountY, GroupCountZ); } - void DispatchIndirect(VkBuffer Buffer, VkDeviceSize Offset) + __forceinline void DispatchIndirect(VkBuffer Buffer, VkDeviceSize Offset) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "vkCmdDispatchIndirect() must be called outside of render pass (27)"); @@ -145,7 +145,7 @@ namespace VulkanUtilities vkCmdDispatchIndirect(m_VkCmdBuffer, Buffer, Offset); } - void BeginRenderPass(VkRenderPass RenderPass, VkFramebuffer Framebuffer, uint32_t FramebufferWidth, uint32_t FramebufferHeight) + __forceinline void BeginRenderPass(VkRenderPass RenderPass, VkFramebuffer Framebuffer, uint32_t FramebufferWidth, uint32_t FramebufferHeight) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); VERIFY(m_State.RenderPass == VK_NULL_HANDLE, "Current pass has not been ended"); @@ -179,7 +179,7 @@ namespace VulkanUtilities } } - void EndRenderPass() + __forceinline void EndRenderPass() { VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "Render pass has not been started"); VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); @@ -190,19 +190,19 @@ namespace VulkanUtilities m_State.FramebufferHeight = 0; } - void EndCommandBuffer() + __forceinline void EndCommandBuffer() { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkEndCommandBuffer(m_VkCmdBuffer); } - void Reset() + __forceinline void Reset() { m_VkCmdBuffer = VK_NULL_HANDLE; m_State = StateCache{}; } - void BindComputePipeline(VkPipeline ComputePipeline) + __forceinline void BindComputePipeline(VkPipeline ComputePipeline) { // 9.8 VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); @@ -213,7 +213,7 @@ namespace VulkanUtilities } } - void BindGraphicsPipeline(VkPipeline GraphicsPipeline) + __forceinline void BindGraphicsPipeline(VkPipeline GraphicsPipeline) { // 9.8 VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); @@ -224,31 +224,31 @@ namespace VulkanUtilities } } - void SetViewports(uint32_t FirstViewport, uint32_t ViewportCount, const VkViewport* pViewports) + __forceinline void SetViewports(uint32_t FirstViewport, uint32_t ViewportCount, const VkViewport* pViewports) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdSetViewport(m_VkCmdBuffer, FirstViewport, ViewportCount, pViewports); } - void SetScissorRects(uint32_t FirstScissor, uint32_t ScissorCount, const VkRect2D* pScissors) + __forceinline void SetScissorRects(uint32_t FirstScissor, uint32_t ScissorCount, const VkRect2D* pScissors) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdSetScissor(m_VkCmdBuffer, FirstScissor, ScissorCount, pScissors); } - void SetStencilReference(uint32_t Reference) + __forceinline void SetStencilReference(uint32_t Reference) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdSetStencilReference(m_VkCmdBuffer, VK_STENCIL_FRONT_AND_BACK, Reference); } - void SetBlendConstants(const float BlendConstants[4]) + __forceinline void SetBlendConstants(const float BlendConstants[4]) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdSetBlendConstants(m_VkCmdBuffer, BlendConstants); } - void BindIndexBuffer(VkBuffer Buffer, VkDeviceSize Offset, VkIndexType IndexType) + __forceinline void BindIndexBuffer(VkBuffer Buffer, VkDeviceSize Offset, VkIndexType IndexType) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.IndexBuffer != Buffer || @@ -262,7 +262,7 @@ namespace VulkanUtilities } } - void BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets) + __forceinline void BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdBindVertexBuffers(m_VkCmdBuffer, firstBinding, bindingCount, pBuffers, pOffsets); @@ -277,12 +277,12 @@ namespace VulkanUtilities VkPipelineStageFlags SrcStages = 0, VkPipelineStageFlags DestStages = 0); - void TransitionImageLayout(VkImage Image, - VkImageLayout OldLayout, - VkImageLayout NewLayout, - const VkImageSubresourceRange& SubresRange, - VkPipelineStageFlags SrcStages = 0, - VkPipelineStageFlags DestStages = 0) + __forceinline void TransitionImageLayout(VkImage Image, + VkImageLayout OldLayout, + VkImageLayout NewLayout, + const VkImageSubresourceRange& SubresRange, + VkPipelineStageFlags SrcStages = 0, + VkPipelineStageFlags DestStages = 0) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -303,11 +303,11 @@ namespace VulkanUtilities VkPipelineStageFlags SrcStages = 0, VkPipelineStageFlags DestStages = 0); - void BufferMemoryBarrier(VkBuffer Buffer, - VkAccessFlags srcAccessMask, - VkAccessFlags dstAccessMask, - VkPipelineStageFlags SrcStages = 0, - VkPipelineStageFlags DestStages = 0) + __forceinline void BufferMemoryBarrier(VkBuffer Buffer, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkPipelineStageFlags SrcStages = 0, + VkPipelineStageFlags DestStages = 0) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -319,22 +319,22 @@ namespace VulkanUtilities BufferMemoryBarrier(m_VkCmdBuffer, Buffer, srcAccessMask, dstAccessMask, m_EnabledGraphicsShaderStages, SrcStages, DestStages); } - void BindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, - VkPipelineLayout layout, - uint32_t firstSet, - uint32_t descriptorSetCount, - const VkDescriptorSet* pDescriptorSets, - uint32_t dynamicOffsetCount = 0, - const uint32_t* pDynamicOffsets = nullptr) + __forceinline void BindDescriptorSets(VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet* pDescriptorSets, + uint32_t dynamicOffsetCount = 0, + const uint32_t* pDynamicOffsets = nullptr) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); vkCmdBindDescriptorSets(m_VkCmdBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); } - void CopyBuffer(VkBuffer srcBuffer, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferCopy* pRegions) + __forceinline void CopyBuffer(VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy* pRegions) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -345,12 +345,12 @@ namespace VulkanUtilities vkCmdCopyBuffer(m_VkCmdBuffer, srcBuffer, dstBuffer, regionCount, pRegions); } - void CopyImage(VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageCopy* pRegions) + __forceinline void CopyImage(VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy* pRegions) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -362,11 +362,11 @@ namespace VulkanUtilities vkCmdCopyImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); } - void CopyBufferToImage(VkBuffer srcBuffer, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) + __forceinline void CopyBufferToImage(VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy* pRegions) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -378,11 +378,11 @@ namespace VulkanUtilities vkCmdCopyBufferToImage(m_VkCmdBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions); } - void CopyImageToBuffer(VkImage srcImage, - VkImageLayout srcImageLayout, - VkBuffer dstBuffer, - uint32_t regionCount, - const VkBufferImageCopy* pRegions) + __forceinline void CopyImageToBuffer(VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy* pRegions) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -394,13 +394,13 @@ namespace VulkanUtilities vkCmdCopyImageToBuffer(m_VkCmdBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); } - void BlitImage(VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageBlit* pRegions, - VkFilter filter) + __forceinline void BlitImage(VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit* pRegions, + VkFilter filter) { VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); if (m_State.RenderPass != VK_NULL_HANDLE) @@ -414,7 +414,7 @@ namespace VulkanUtilities void FlushBarriers(); - void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) + __forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) { m_VkCmdBuffer = VkCmdBuffer; } diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 385bf07a..2bc18ce1 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -421,7 +421,7 @@ namespace Diligent #endif if (m_DescrSetBindInfo.DynamicOffsetCount != 0) - m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(this, m_DescrSetBindInfo); + m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(GetCommandBuffer(), m_ContextId, this, m_DescrSetBindInfo); #if 0 #ifdef _DEBUG else @@ -535,7 +535,7 @@ namespace Diligent m_CommandBuffer.EndRenderPass(); if (m_DescrSetBindInfo.DynamicOffsetCount != 0) - m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(this, m_DescrSetBindInfo); + m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(GetCommandBuffer(), m_ContextId, this, m_DescrSetBindInfo); #if 0 #ifdef _DEBUG else diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 6f2bb597..b978f3c6 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -501,41 +501,4 @@ void PipelineLayout::PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkI } } -void PipelineLayout::BindDescriptorSetsWithDynamicOffsets(DeviceContextVkImpl* pCtxVkImpl, - DescriptorSetBindInfo& BindInfo)const -{ - VERIFY(BindInfo.pDbgPipelineLayout != nullptr, "Pipeline layout is not initialized, which most likely means that CommitShaderResources() has never been called"); - VERIFY(BindInfo.pDbgPipelineLayout->IsSameAs(*this), "Inconsistent pipeline layout"); - VERIFY(BindInfo.DynamicOffsetCount > 0, "This function should only be called for pipelines that contain dynamic descriptors"); - - VERIFY_EXPR(BindInfo.pResourceCache != nullptr); -#ifdef _DEBUG - Uint32 TotalDynamicDescriptors = 0; - for (SHADER_RESOURCE_VARIABLE_TYPE VarType = SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE; VarType <= SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC; VarType = static_cast(VarType + 1)) - { - const auto &Set = m_LayoutMgr.GetDescriptorSet(VarType); - TotalDynamicDescriptors += Set.NumDynamicDescriptors; - } - VERIFY(BindInfo.DynamicOffsetCount == TotalDynamicDescriptors, "Incosistent dynamic buffer size"); - VERIFY_EXPR(BindInfo.DynamicOffsets.size() >= BindInfo.DynamicOffsetCount); -#endif - - auto NumOffsetsWritten = BindInfo.pResourceCache->GetDynamicBufferOffsets(pCtxVkImpl, BindInfo.DynamicOffsets); - VERIFY_EXPR(NumOffsetsWritten == BindInfo.DynamicOffsetCount); (void)NumOffsetsWritten; - - auto& CmdBuffer = pCtxVkImpl->GetCommandBuffer(); - // vkCmdBindDescriptorSets causes the sets numbered [firstSet .. firstSet+descriptorSetCount-1] to use the - // bindings stored in pDescriptorSets[0 .. descriptorSetCount-1] for subsequent rendering commands - // (either compute or graphics, according to the pipelineBindPoint). Any bindings that were previously - // applied via these sets are no longer valid (13.2.5) - CmdBuffer.BindDescriptorSets(BindInfo.BindPoint, - m_LayoutMgr.GetVkPipelineLayout(), - 0, // First set - BindInfo.SetCout, - BindInfo.vkSets.data(), // BindInfo.vkSets is never empty - // dynamicOffsetCount must equal the total number of dynamic descriptors in the sets being bound (13.2.5) - BindInfo.DynamicOffsetCount, - BindInfo.DynamicOffsets.data()); -} - } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 0063fe8a..e51603c8 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -25,7 +25,6 @@ #include "ShaderResourceCacheVk.h" #include "DeviceContextVkImpl.h" -#include "BufferVkImpl.h" #include "BufferViewVkImpl.h" #include "TextureViewVkImpl.h" #include "TextureVkImpl.h" @@ -434,64 +433,4 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetSamplerDescriptorWrite return DescrImgInfo; } -Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(DeviceContextVkImpl *pCtxVkImpl, std::vector& Offsets)const -{ - auto CtxId = pCtxVkImpl->GetContextId(); - - // If any of the sets being bound include dynamic uniform or storage buffers, then - // pDynamicOffsets includes one element for each array element in each dynamic descriptor - // type binding in each set. Values are taken from pDynamicOffsets in an order such that - // all entries for set N come before set N+1; within a set, entries are ordered by the binding - // numbers (unclear if this is SPIRV binding or VkDescriptorSetLayoutBinding number) in the - // descriptor set layouts; and within a binding array, elements are in order. (13.2.5) - - // In each descriptor set, all uniform buffers for every shader stage come first, - // followed by all storage buffers for every shader stage, followed by all other resources - Uint32 OffsetInd = 0; - for (Uint32 set=0; set < m_NumSets; ++set) - { - const auto& DescrSet = GetDescriptorSet(set); - Uint32 res = 0; - while (res < DescrSet.GetSize()) - { - const auto& Res = DescrSet.GetResource(res); - if (Res.Type != SPIRVShaderResourceAttribs::ResourceType::UniformBuffer) - break; - - const auto* pBufferVk = Res.pObject.RawPtr(); - auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; - Offsets[OffsetInd++] = Offset; - - ++res; - } - - while (res < DescrSet.GetSize()) - { - const auto& Res = DescrSet.GetResource(res); - if (Res.Type != SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer && - Res.Type != SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer) - break; - - const auto* pBufferVkView = Res.pObject.RawPtr(); - const auto* pBufferVk = pBufferVkView != nullptr ? pBufferVkView->GetBufferVk() : 0; - auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; - Offsets[OffsetInd++] = Offset; - - ++res; - } - -#ifdef _DEBUG - for (; res < DescrSet.GetSize(); ++res) - { - const auto& Res = DescrSet.GetResource(res); - VERIFY(Res.Type != SPIRVShaderResourceAttribs::ResourceType::UniformBuffer && - Res.Type != SPIRVShaderResourceAttribs::ResourceType::ROStorageBuffer && - Res.Type != SPIRVShaderResourceAttribs::ResourceType::RWStorageBuffer, - "All uniform and storage buffers are expected to go first in the beginning of each descriptor set"); - } -#endif - } - return OffsetInd; -} - } -- cgit v1.2.3