diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2021-02-28 18:49:55 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2021-03-19 00:38:12 +0000 |
| commit | d859f681fcb3cb4fdf0c9aa8f8642dc9b8862c55 (patch) | |
| tree | 6ee08c3b426536f9db0c68cd30e320d7311ae4cf /Graphics/GraphicsEngineVulkan | |
| parent | Few minor updates to DeviceContextD3D12Impl (diff) | |
| download | DiligentCore-d859f681fcb3cb4fdf0c9aa8f8642dc9b8862c55.tar.gz DiligentCore-d859f681fcb3cb4fdf0c9aa8f8642dc9b8862c55.zip | |
Fixed handling of dynamic structured buffers in Vulkan
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
5 files changed, 30 insertions, 56 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp index 99e55bc6..bbba917f 100644 --- a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp @@ -61,9 +61,6 @@ public: /// Implementation of IBufferViewVk::GetVkBufferView(). virtual VkBufferView DILIGENT_CALL_TYPE GetVkBufferView() const override final { return m_BuffView; } - const BufferVkImpl* GetBufferVk() const; - BufferVkImpl* GetBufferVk(); - protected: VulkanUtilities::BufferViewWrapper m_BuffView; }; diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp index 7b546bdd..3faeb7e8 100644 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp @@ -268,7 +268,7 @@ __forceinline Uint32 ShaderResourceCacheVk::GetDynamicBufferOffsets(Uint32 Res.Type == DescriptorType::StorageBufferDynamic_ReadOnly) { const auto* pBufferVkView = Res.pObject.RawPtr<const BufferViewVkImpl>(); - const auto* pBufferVk = pBufferVkView != nullptr ? pBufferVkView->GetBufferVk() : 0; + const auto* pBufferVk = pBufferVkView != nullptr ? pBufferVkView->GetBuffer<const BufferVkImpl>() : 0; auto Offset = pBufferVk != nullptr ? pBufferVk->GetDynamicOffset(CtxId, pCtxVkImpl) : 0; Offsets[OffsetInd++] = Offset; ++res; diff --git a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp index 0579bccf..3265b6a8 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp @@ -58,14 +58,4 @@ BufferViewVkImpl::~BufferViewVkImpl() m_pDevice->SafeReleaseDeviceObject(std::move(m_BuffView), m_pBuffer->GetDesc().CommandQueueMask); } -const BufferVkImpl* BufferViewVkImpl::GetBufferVk() const -{ - return ValidatedCast<const BufferVkImpl>(m_pBuffer); -} - -BufferVkImpl* BufferViewVkImpl::GetBufferVk() -{ - return ValidatedCast<BufferVkImpl>(m_pBuffer); -} - } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp index d19454ca..077b4500 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp @@ -98,21 +98,9 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, { case BIND_UNORDERED_ACCESS: { - // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - // HLSL formatted buffers are mapped to GLSL storage buffers: - // - // RWBuffer<uint4> RWBuff - // - // | - // V - // - // layout(std140, binding = 3) buffer RWBuff - // { - // uvec4 data[]; - // }g_RWBuff; - // - // So we have to set both VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT bits - VkBuffCI.usage |= VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + // RWStructured and RWByteAddress buffers are mapped to storage buffers in Vulkan. + // RW formatted buffers are mapped to storage texel buffers in Vulkan. + VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; // Each element of pDynamicOffsets of vkCmdBindDescriptorSets function which corresponds to a descriptor // binding with type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC must be a multiple of @@ -123,10 +111,9 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, } case BIND_SHADER_RESOURCE: { - // VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - // HLSL buffer SRVs are mapped to storge buffers in GLSL, so we need to set both - // VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT and VK_BUFFER_USAGE_STORAGE_BUFFER_BIT flags - VkBuffCI.usage |= VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + // Structured and ByteAddress buffers are mapped to read-only storage buffers in Vulkan. + // Formatted buffers are mapped to uniform texel buffers in Vulkan. + VkBuffCI.usage |= m_Desc.Mode == BUFFER_MODE_FORMATTED ? VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT : VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minTexelBufferOffsetAlignment)); m_DynamicOffsetAlignment = std::max(m_DynamicOffsetAlignment, static_cast<Uint32>(DeviceLimits.minStorageBufferOffsetAlignment)); @@ -179,10 +166,12 @@ BufferVkImpl::BufferVkImpl(IReferenceCounters* pRefCounters, m_DynamicData.emplace_back(); } - if (m_Desc.Usage == USAGE_DYNAMIC && (VkBuffCI.usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) == 0) + if (m_Desc.Usage == USAGE_DYNAMIC && + (VkBuffCI.usage & (VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) == 0 && + (m_Desc.BindFlags & BIND_UNORDERED_ACCESS) == 0) { - // Dynamic constant/vertex/index buffers are suballocated in the upload heap when Map() is called. - // Dynamic buffers with SRV or UAV flags need to be allocated in GPU-only memory + // Dynamic constant/vertex/index/structured buffers are suballocated in the upload heap when Map() is called. + // Dynamic formatted buffers or writable buffers need to be allocated in GPU-local memory. constexpr RESOURCE_STATE State = static_cast<RESOURCE_STATE>( RESOURCE_STATE_VERTEX_BUFFER | RESOURCE_STATE_INDEX_BUFFER | @@ -445,8 +434,7 @@ VulkanUtilities::BufferViewWrapper BufferVkImpl::CreateView(struct BufferViewDes { VulkanUtilities::BufferViewWrapper BuffView; ValidateAndCorrectBufferViewDesc(m_Desc, ViewDesc); - if ((ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE || ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) && - (m_Desc.Mode == BUFFER_MODE_FORMATTED || m_Desc.Mode == BUFFER_MODE_RAW)) + if (m_Desc.Mode == BUFFER_MODE_FORMATTED) { VkBufferViewCreateInfo ViewCI = {}; @@ -454,21 +442,20 @@ VulkanUtilities::BufferViewWrapper BufferVkImpl::CreateView(struct BufferViewDes ViewCI.pNext = nullptr; ViewCI.flags = 0; // reserved for future use ViewCI.buffer = m_VulkanBuffer; - if (m_Desc.Mode == BUFFER_MODE_RAW && ViewDesc.Format.ValueType == VT_UNDEFINED) - { - ViewCI.format = VK_FORMAT_R32_UINT; - } - else - { - DEV_CHECK_ERR(ViewDesc.Format.ValueType != VT_UNDEFINED, "Undefined format"); - ViewCI.format = TypeToVkFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized); - } + DEV_CHECK_ERR(ViewDesc.Format.ValueType != VT_UNDEFINED, "Undefined format"); + ViewCI.format = TypeToVkFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized); ViewCI.offset = ViewDesc.ByteOffset; // offset in bytes from the base address of the buffer ViewCI.range = ViewDesc.ByteWidth; // size in bytes of the buffer view const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); BuffView = LogicalDevice.CreateBufferView(ViewCI, ViewDesc.Name); } + else if (m_Desc.Mode == BUFFER_MODE_STRUCTURED || + m_Desc.Mode == BUFFER_MODE_RAW) + { + // Strucutred and raw buffers are mapped to storage buffers in GLSL + } + return BuffView; } diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 11816486..0086b34b 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -388,7 +388,7 @@ VkDescriptorBufferInfo ShaderResourceCacheVk::Resource::GetUniformBufferDescript // clang-format on DEV_CHECK_ERR(pObject != nullptr, "Unable to get uniform buffer write info: cached object is null"); - auto* pBuffVk = pObject.RawPtr<const BufferVkImpl>(); + const auto* pBuffVk = pObject.RawPtr<const BufferVkImpl>(); // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC descriptor type require // buffer to be created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT VERIFY_EXPR((pBuffVk->GetDesc().BindFlags & BIND_UNIFORM_BUFFER) != 0); @@ -415,9 +415,9 @@ VkDescriptorBufferInfo ShaderResourceCacheVk::Resource::GetStorageBufferDescript // clang-format on DEV_CHECK_ERR(pObject != nullptr, "Unable to get storage buffer write info: cached object is null"); - auto* const pBuffViewVk = pObject.RawPtr<const BufferViewVkImpl>(); + const auto* pBuffViewVk = pObject.RawPtr<const BufferViewVkImpl>(); const auto& ViewDesc = pBuffViewVk->GetDesc(); - auto* const pBuffVk = pBuffViewVk->GetBufferVk(); + const auto* pBuffVk = pBuffViewVk->GetBuffer<const BufferVkImpl>(); VERIFY(Type == DescriptorType::StorageBufferDynamic || Type == DescriptorType::StorageBufferDynamic_ReadOnly || pBuffVk->GetDesc().Usage != USAGE_DYNAMIC, "Dynamic buffer must be used with StorageBufferDynamic or StorageBufferDynamic_ReadOnly descriptor"); @@ -466,7 +466,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetImageDescriptorWriteIn bool IsStorageImage = (Type == DescriptorType::StorageImage); - auto* pTexViewVk = pObject.RawPtr<const TextureViewVkImpl>(); + const auto* pTexViewVk = pObject.RawPtr<const TextureViewVkImpl>(); VERIFY_EXPR(pTexViewVk->GetDesc().ViewType == (IsStorageImage ? TEXTURE_VIEW_UNORDERED_ACCESS : TEXTURE_VIEW_SHADER_RESOURCE)); VkDescriptorImageInfo DescrImgInfo; @@ -477,7 +477,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetImageDescriptorWriteIn { // Immutable samplers are permanently bound into the set layout; later binding a sampler // into an immutable sampler slot in a descriptor set is not allowed (13.2.1) - auto* pSamplerVk = ValidatedCast<const SamplerVkImpl>(pTexViewVk->GetSampler()); + const auto* pSamplerVk = ValidatedCast<const SamplerVkImpl>(pTexViewVk->GetSampler()); if (pSamplerVk != nullptr) { // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, @@ -524,7 +524,7 @@ VkBufferView ShaderResourceCacheVk::Resource::GetBufferViewWriteInfo() const // The following bits must have been set at buffer creation time: // * VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER -> VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT // * VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER -> VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT - auto* pBuffViewVk = pObject.RawPtr<const BufferViewVkImpl>(); + const auto* pBuffViewVk = pObject.RawPtr<const BufferViewVkImpl>(); return pBuffViewVk->GetVkBufferView(); } @@ -533,7 +533,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetSamplerDescriptorWrite VERIFY(Type == DescriptorType::Sampler, "Separate sampler resource is expected"); DEV_CHECK_ERR(pObject != nullptr, "Unable to get separate sampler descriptor write info: cached object is null"); - auto* pSamplerVk = pObject.RawPtr<const SamplerVkImpl>(); + const auto* pSamplerVk = pObject.RawPtr<const SamplerVkImpl>(); VkDescriptorImageInfo DescrImgInfo; // For VK_DESCRIPTOR_TYPE_SAMPLER, only the sample member of each element of VkWriteDescriptorSet::pImageInfo is accessed (13.2.4) @@ -548,7 +548,7 @@ VkDescriptorImageInfo ShaderResourceCacheVk::Resource::GetInputAttachmentDescrip VERIFY(Type == DescriptorType::InputAttachment, "Input attachment resource is expected"); DEV_CHECK_ERR(pObject != nullptr, "Unable to get input attachment write info: cached object is null"); - auto* pTexViewVk = pObject.RawPtr<const TextureViewVkImpl>(); + const auto* pTexViewVk = pObject.RawPtr<const TextureViewVkImpl>(); VERIFY_EXPR(pTexViewVk->GetDesc().ViewType == TEXTURE_VIEW_SHADER_RESOURCE); VkDescriptorImageInfo DescrImgInfo; @@ -564,7 +564,7 @@ VkWriteDescriptorSetAccelerationStructureKHR ShaderResourceCacheVk::Resource::Ge VERIFY(Type == DescriptorType::AccelerationStructure, "Acceleration structure resource is expected"); DEV_CHECK_ERR(pObject != nullptr, "Unable to get acceleration structure write info: cached object is null"); - auto* pTLASVk = pObject.RawPtr<const TopLevelASVkImpl>(); + const auto* pTLASVk = pObject.RawPtr<const TopLevelASVkImpl>(); VkWriteDescriptorSetAccelerationStructureKHR DescrAS; DescrAS.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR; |
