From 95f27d72605b4f56df0fb4fc4ce87ba5a192726f Mon Sep 17 00:00:00 2001 From: assiduous Date: Sun, 26 Jan 2020 14:37:28 -0800 Subject: Renamed .h -> .hpp in GraphicsEngineVulkan project --- Graphics/GraphicsEngineVulkan/CMakeLists.txt | 78 +-- .../include/BufferViewVkImpl.h | 71 --- .../include/BufferViewVkImpl.hpp | 71 +++ .../GraphicsEngineVulkan/include/BufferVkImpl.h | 136 ----- .../GraphicsEngineVulkan/include/BufferVkImpl.hpp | 136 +++++ .../include/CommandListVkImpl.h | 76 --- .../include/CommandListVkImpl.hpp | 76 +++ .../include/CommandPoolManager.h | 89 ---- .../include/CommandPoolManager.hpp | 89 ++++ .../include/CommandQueueVkImpl.h | 103 ---- .../include/CommandQueueVkImpl.hpp | 103 ++++ .../include/DescriptorPoolManager.h | 289 ----------- .../include/DescriptorPoolManager.hpp | 289 +++++++++++ .../include/DeviceContextVkImpl.h | 479 ----------------- .../include/DeviceContextVkImpl.hpp | 479 +++++++++++++++++ .../GraphicsEngineVulkan/include/FenceVkImpl.h | 84 --- .../GraphicsEngineVulkan/include/FenceVkImpl.hpp | 84 +++ .../include/FramebufferCache.h | 96 ---- .../include/FramebufferCache.hpp | 96 ++++ .../include/GenerateMipsVkHelper.h | 78 --- .../include/GenerateMipsVkHelper.hpp | 78 +++ .../include/ManagedVulkanObject.h | 80 --- .../include/ManagedVulkanObject.hpp | 80 +++ .../GraphicsEngineVulkan/include/PipelineLayout.h | 272 ---------- .../include/PipelineLayout.hpp | 272 ++++++++++ .../include/PipelineStateVkImpl.h | 164 ------ .../include/PipelineStateVkImpl.hpp | 164 ++++++ .../GraphicsEngineVulkan/include/QueryManagerVk.h | 95 ---- .../include/QueryManagerVk.hpp | 95 ++++ .../GraphicsEngineVulkan/include/QueryVkImpl.h | 79 --- .../GraphicsEngineVulkan/include/QueryVkImpl.hpp | 79 +++ .../include/RenderDeviceVkImpl.h | 180 ------- .../include/RenderDeviceVkImpl.hpp | 180 +++++++ .../GraphicsEngineVulkan/include/RenderPassCache.h | 143 ------ .../include/RenderPassCache.hpp | 143 ++++++ .../GraphicsEngineVulkan/include/SamplerVkImpl.h | 65 --- .../GraphicsEngineVulkan/include/SamplerVkImpl.hpp | 65 +++ .../include/ShaderResourceBindingVkImpl.h | 86 ---- .../include/ShaderResourceBindingVkImpl.hpp | 86 ++++ .../include/ShaderResourceCacheVk.h | 288 ----------- .../include/ShaderResourceCacheVk.hpp | 288 +++++++++++ .../include/ShaderResourceLayoutVk.h | 373 -------------- .../include/ShaderResourceLayoutVk.hpp | 373 ++++++++++++++ .../include/ShaderVariableVk.h | 212 -------- .../include/ShaderVariableVk.hpp | 212 ++++++++ .../GraphicsEngineVulkan/include/ShaderVkImpl.h | 86 ---- .../GraphicsEngineVulkan/include/ShaderVkImpl.hpp | 86 ++++ .../GraphicsEngineVulkan/include/SwapChainVkImpl.h | 114 ----- .../include/SwapChainVkImpl.hpp | 114 +++++ .../include/TextureViewVkImpl.h | 95 ---- .../include/TextureViewVkImpl.hpp | 95 ++++ .../GraphicsEngineVulkan/include/TextureVkImpl.h | 119 ----- .../GraphicsEngineVulkan/include/TextureVkImpl.hpp | 119 +++++ .../include/VulkanDynamicHeap.h | 234 --------- .../include/VulkanDynamicHeap.hpp | 234 +++++++++ .../GraphicsEngineVulkan/include/VulkanErrors.h | 47 -- .../GraphicsEngineVulkan/include/VulkanErrors.hpp | 47 ++ .../include/VulkanTypeConversions.h | 72 --- .../include/VulkanTypeConversions.hpp | 72 +++ .../include/VulkanUploadHeap.h | 170 ------- .../include/VulkanUploadHeap.hpp | 170 +++++++ .../include/VulkanUtilities/VulkanCommandBuffer.h | 566 --------------------- .../VulkanUtilities/VulkanCommandBuffer.hpp | 566 +++++++++++++++++++++ .../VulkanUtilities/VulkanCommandBufferPool.h | 82 --- .../VulkanUtilities/VulkanCommandBufferPool.hpp | 82 +++ .../include/VulkanUtilities/VulkanDebug.h | 108 ---- .../include/VulkanUtilities/VulkanDebug.hpp | 108 ++++ .../include/VulkanUtilities/VulkanFencePool.h | 62 --- .../include/VulkanUtilities/VulkanFencePool.hpp | 62 +++ .../include/VulkanUtilities/VulkanInstance.h | 88 ---- .../include/VulkanUtilities/VulkanInstance.hpp | 88 ++++ .../include/VulkanUtilities/VulkanLogicalDevice.h | 231 --------- .../VulkanUtilities/VulkanLogicalDevice.hpp | 231 +++++++++ .../include/VulkanUtilities/VulkanMemoryManager.h | 264 ---------- .../VulkanUtilities/VulkanMemoryManager.hpp | 264 ++++++++++ .../include/VulkanUtilities/VulkanObjectWrappers.h | 113 ---- .../VulkanUtilities/VulkanObjectWrappers.hpp | 113 ++++ .../include/VulkanUtilities/VulkanPhysicalDevice.h | 75 --- .../VulkanUtilities/VulkanPhysicalDevice.hpp | 75 +++ Graphics/GraphicsEngineVulkan/include/pch.h | 2 +- .../GraphicsEngineVulkan/src/BufferViewVkImpl.cpp | 6 +- Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp | 14 +- .../src/CommandPoolManager.cpp | 4 +- .../src/CommandQueueVkImpl.cpp | 2 +- .../src/DescriptorPoolManager.cpp | 4 +- .../src/DeviceContextVkImpl.cpp | 16 +- .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 12 +- Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp | 4 +- .../GraphicsEngineVulkan/src/FramebufferCache.cpp | 4 +- .../src/GenerateMipsVkHelper.cpp | 12 +- .../GraphicsEngineVulkan/src/PipelineLayout.cpp | 16 +- .../src/PipelineStateVkImpl.cpp | 12 +- .../GraphicsEngineVulkan/src/QueryManagerVk.cpp | 6 +- Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp | 6 +- .../src/RenderDeviceVkImpl.cpp | 22 +- .../GraphicsEngineVulkan/src/RenderPassCache.cpp | 6 +- .../GraphicsEngineVulkan/src/SamplerVkImpl.cpp | 6 +- .../src/ShaderResourceBindingVkImpl.cpp | 8 +- .../src/ShaderResourceCacheVk.cpp | 14 +- .../src/ShaderResourceLayoutVk.cpp | 18 +- .../GraphicsEngineVulkan/src/ShaderVariableVk.cpp | 2 +- Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp | 4 +- .../GraphicsEngineVulkan/src/SwapChainVkImpl.cpp | 10 +- .../GraphicsEngineVulkan/src/TextureViewVkImpl.cpp | 6 +- .../GraphicsEngineVulkan/src/TextureVkImpl.cpp | 12 +- .../GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp | 4 +- .../src/VulkanTypeConversions.cpp | 2 +- .../GraphicsEngineVulkan/src/VulkanUploadHeap.cpp | 4 +- .../src/VulkanUtilities/VulkanCommandBuffer.cpp | 2 +- .../VulkanUtilities/VulkanCommandBufferPool.cpp | 6 +- .../src/VulkanUtilities/VulkanDebug.cpp | 4 +- .../src/VulkanUtilities/VulkanFencePool.cpp | 2 +- .../src/VulkanUtilities/VulkanInstance.cpp | 6 +- .../src/VulkanUtilities/VulkanLogicalDevice.cpp | 8 +- .../src/VulkanUtilities/VulkanMemoryManager.cpp | 2 +- .../src/VulkanUtilities/VulkanPhysicalDevice.cpp | 4 +- 116 files changed, 6239 insertions(+), 6239 deletions(-) delete mode 100644 Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h create mode 100644 Graphics/GraphicsEngineVulkan/include/CommandPoolManager.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h create mode 100644 Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/FramebufferCache.h create mode 100644 Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.h create mode 100644 Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/PipelineLayout.h create mode 100644 Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/QueryManagerVk.h create mode 100644 Graphics/GraphicsEngineVulkan/include/QueryManagerVk.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/QueryVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/QueryVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/RenderPassCache.h create mode 100644 Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h create mode 100644 Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanErrors.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanErrors.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.hpp delete mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h create mode 100644 Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/CMakeLists.txt b/Graphics/GraphicsEngineVulkan/CMakeLists.txt index bd670456..5e0a3558 100644 --- a/Graphics/GraphicsEngineVulkan/CMakeLists.txt +++ b/Graphics/GraphicsEngineVulkan/CMakeLists.txt @@ -3,49 +3,49 @@ cmake_minimum_required (VERSION 3.10) project(Diligent-GraphicsEngineVk CXX) set(INCLUDE - include/BufferVkImpl.h - include/BufferViewVkImpl.h - include/CommandListVkImpl.h - include/CommandPoolManager.h - include/CommandQueueVkImpl.h - include/DescriptorPoolManager.h - include/DeviceContextVkImpl.h - include/FenceVkImpl.h - include/VulkanDynamicHeap.h - include/FramebufferCache.h - include/GenerateMipsVkHelper.h + include/BufferVkImpl.hpp + include/BufferViewVkImpl.hpp + include/CommandListVkImpl.hpp + include/CommandPoolManager.hpp + include/CommandQueueVkImpl.hpp + include/DescriptorPoolManager.hpp + include/DeviceContextVkImpl.hpp + include/FenceVkImpl.hpp + include/VulkanDynamicHeap.hpp + include/FramebufferCache.hpp + include/GenerateMipsVkHelper.hpp include/pch.h - include/PipelineLayout.h - include/PipelineStateVkImpl.h - include/QueryManagerVk.h - include/QueryVkImpl.h - include/RenderDeviceVkImpl.h - include/RenderPassCache.h - include/SamplerVkImpl.h - include/ShaderVkImpl.h - include/ManagedVulkanObject.h - include/ShaderResourceBindingVkImpl.h - include/ShaderResourceCacheVk.h - include/ShaderResourceLayoutVk.h - include/ShaderVariableVk.h - include/SwapChainVkImpl.h - include/TextureVkImpl.h - include/TextureViewVkImpl.h - include/VulkanErrors.h - include/VulkanTypeConversions.h - include/VulkanUploadHeap.h + include/PipelineLayout.hpp + include/PipelineStateVkImpl.hpp + include/QueryManagerVk.hpp + include/QueryVkImpl.hpp + include/RenderDeviceVkImpl.hpp + include/RenderPassCache.hpp + include/SamplerVkImpl.hpp + include/ShaderVkImpl.hpp + include/ManagedVulkanObject.hpp + include/ShaderResourceBindingVkImpl.hpp + include/ShaderResourceCacheVk.hpp + include/ShaderResourceLayoutVk.hpp + include/ShaderVariableVk.hpp + include/SwapChainVkImpl.hpp + include/TextureVkImpl.hpp + include/TextureViewVkImpl.hpp + include/VulkanErrors.hpp + include/VulkanTypeConversions.hpp + include/VulkanUploadHeap.hpp ) set(VULKAN_UTILS_INCLUDE - include/VulkanUtilities/VulkanCommandBuffer.h - include/VulkanUtilities/VulkanCommandBufferPool.h - include/VulkanUtilities/VulkanDebug.h - include/VulkanUtilities/VulkanFencePool.h - include/VulkanUtilities/VulkanInstance.h - include/VulkanUtilities/VulkanLogicalDevice.h - include/VulkanUtilities/VulkanMemoryManager.h - include/VulkanUtilities/VulkanObjectWrappers.h - include/VulkanUtilities/VulkanPhysicalDevice.h + include/VulkanUtilities/VulkanCommandBuffer.hpp + include/VulkanUtilities/VulkanCommandBufferPool.hpp + include/VulkanUtilities/VulkanDebug.hpp + include/VulkanUtilities/VulkanFencePool.hpp + include/VulkanUtilities/VulkanInstance.hpp + include/VulkanUtilities/VulkanLogicalDevice.hpp + include/VulkanUtilities/VulkanMemoryManager.hpp + include/VulkanUtilities/VulkanObjectWrappers.hpp + include/VulkanUtilities/VulkanPhysicalDevice.hpp ) diff --git a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h deleted file mode 100644 index d2dc9285..00000000 --- a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::BufferViewVkImpl class - -#include "BufferViewVk.h" -#include "RenderDeviceVk.h" -#include "BufferViewBase.hpp" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; -class BufferVkImpl; - -/// Buffer view implementation in Vulkan backend. -class BufferViewVkImpl final : public BufferViewBase -{ -public: - using TBufferViewBase = BufferViewBase; - - BufferViewVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - const BufferViewDesc& ViewDesc, - class IBuffer* pBuffer, - VulkanUtilities::BufferViewWrapper&& BuffView, - bool bIsDefaultView); - ~BufferViewVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IBufferViewVk::GetVkBufferView(). - virtual VkBufferView GetVkBufferView() const override final { return m_BuffView; } - - const BufferVkImpl* GetBufferVk() const; - BufferVkImpl* GetBufferVk(); - -protected: - VulkanUtilities::BufferViewWrapper m_BuffView; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp new file mode 100644 index 00000000..e6a18966 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/BufferViewVkImpl.hpp @@ -0,0 +1,71 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BufferViewVkImpl class + +#include "BufferViewVk.h" +#include "RenderDeviceVk.h" +#include "BufferViewBase.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +class BufferVkImpl; + +/// Buffer view implementation in Vulkan backend. +class BufferViewVkImpl final : public BufferViewBase +{ +public: + using TBufferViewBase = BufferViewBase; + + BufferViewVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + const BufferViewDesc& ViewDesc, + class IBuffer* pBuffer, + VulkanUtilities::BufferViewWrapper&& BuffView, + bool bIsDefaultView); + ~BufferViewVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IBufferViewVk::GetVkBufferView(). + virtual VkBufferView GetVkBufferView() const override final { return m_BuffView; } + + const BufferVkImpl* GetBufferVk() const; + BufferVkImpl* GetBufferVk(); + +protected: + VulkanUtilities::BufferViewWrapper m_BuffView; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h deleted file mode 100644 index e20551e9..00000000 --- a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::BufferVkImpl class - -#include "BufferVk.h" -#include "RenderDeviceVk.h" -#include "BufferBase.hpp" -#include "BufferViewVkImpl.h" -#include "VulkanDynamicHeap.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "VulkanUtilities/VulkanMemoryManager.h" -#include "STDAllocator.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; -class DeviceContextVkImpl; - -/// Buffer object implementation in Vulkan backend. -class BufferVkImpl final : public BufferBase -{ -public: - using TBufferBase = BufferBase; - - BufferVkImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - RenderDeviceVkImpl* pDeviceVk, - const BufferDesc& BuffDesc, - const BufferData* pBuffData = nullptr); - - BufferVkImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& BuffViewObjMemAllocator, - class RenderDeviceVkImpl* pDeviceVk, - const BufferDesc& BuffDesc, - RESOURCE_STATE InitialState, - VkBuffer vkBuffer); - ~BufferVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; - -#ifdef DEVELOPMENT - void DvpVerifyDynamicAllocation(DeviceContextVkImpl* pCtx) const; -#endif - - Uint32 GetDynamicOffset(Uint32 CtxId, DeviceContextVkImpl* pCtx) const - { - if (m_VulkanBuffer != VK_NULL_HANDLE) - { - return 0; - } - else - { - VERIFY(m_Desc.Usage == USAGE_DYNAMIC, "Dynamic buffer is expected"); - VERIFY_EXPR(!m_DynamicAllocations.empty()); -#ifdef DEVELOPMENT - DvpVerifyDynamicAllocation(pCtx); -#endif - auto& DynAlloc = m_DynamicAllocations[CtxId]; - return static_cast(DynAlloc.AlignedOffset); - } - } - - /// Implementation of IBufferVk::GetVkBuffer(). - VkBuffer GetVkBuffer() const override final; - - /// Implementation of IBuffer::GetNativeHandle() in Vulkan backend. - virtual void* GetNativeHandle() override final - { - auto vkBuffer = GetVkBuffer(); - return reinterpret_cast(vkBuffer); - } - - /// Implementation of IBufferVk::SetAccessFlags(). - virtual void SetAccessFlags(VkAccessFlags AccessFlags) override final; - - /// Implementation of IBufferVk::GetAccessFlags(). - virtual VkAccessFlags GetAccessFlags() const override final; - - bool CheckAccessFlags(VkAccessFlags AccessFlags) const - { - return (GetAccessFlags() & AccessFlags) == AccessFlags; - } - - void* GetStagingCPUAddress() - { - VERIFY_EXPR(m_Desc.Usage == USAGE_STAGING); - return reinterpret_cast(m_MemoryAllocation.Page->GetCPUMemory()) + m_BufferMemoryAlignedOffset; - } - -private: - friend class DeviceContextVkImpl; - - virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) override; - - VulkanUtilities::BufferViewWrapper CreateView(struct BufferViewDesc& ViewDesc); - - Uint32 m_DynamicOffsetAlignment = 0; - VkDeviceSize m_BufferMemoryAlignedOffset = 0; - - std::vector> m_DynamicAllocations; - - VulkanUtilities::BufferWrapper m_VulkanBuffer; - VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp new file mode 100644 index 00000000..f7ddd538 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/BufferVkImpl.hpp @@ -0,0 +1,136 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::BufferVkImpl class + +#include "BufferVk.h" +#include "RenderDeviceVk.h" +#include "BufferBase.hpp" +#include "BufferViewVkImpl.hpp" +#include "VulkanDynamicHeap.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "VulkanUtilities/VulkanMemoryManager.hpp" +#include "STDAllocator.h" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +class DeviceContextVkImpl; + +/// Buffer object implementation in Vulkan backend. +class BufferVkImpl final : public BufferBase +{ +public: + using TBufferBase = BufferBase; + + BufferVkImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + RenderDeviceVkImpl* pDeviceVk, + const BufferDesc& BuffDesc, + const BufferData* pBuffData = nullptr); + + BufferVkImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& BuffViewObjMemAllocator, + class RenderDeviceVkImpl* pDeviceVk, + const BufferDesc& BuffDesc, + RESOURCE_STATE InitialState, + VkBuffer vkBuffer); + ~BufferVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; + +#ifdef DEVELOPMENT + void DvpVerifyDynamicAllocation(DeviceContextVkImpl* pCtx) const; +#endif + + Uint32 GetDynamicOffset(Uint32 CtxId, DeviceContextVkImpl* pCtx) const + { + if (m_VulkanBuffer != VK_NULL_HANDLE) + { + return 0; + } + else + { + VERIFY(m_Desc.Usage == USAGE_DYNAMIC, "Dynamic buffer is expected"); + VERIFY_EXPR(!m_DynamicAllocations.empty()); +#ifdef DEVELOPMENT + DvpVerifyDynamicAllocation(pCtx); +#endif + auto& DynAlloc = m_DynamicAllocations[CtxId]; + return static_cast(DynAlloc.AlignedOffset); + } + } + + /// Implementation of IBufferVk::GetVkBuffer(). + VkBuffer GetVkBuffer() const override final; + + /// Implementation of IBuffer::GetNativeHandle() in Vulkan backend. + virtual void* GetNativeHandle() override final + { + auto vkBuffer = GetVkBuffer(); + return reinterpret_cast(vkBuffer); + } + + /// Implementation of IBufferVk::SetAccessFlags(). + virtual void SetAccessFlags(VkAccessFlags AccessFlags) override final; + + /// Implementation of IBufferVk::GetAccessFlags(). + virtual VkAccessFlags GetAccessFlags() const override final; + + bool CheckAccessFlags(VkAccessFlags AccessFlags) const + { + return (GetAccessFlags() & AccessFlags) == AccessFlags; + } + + void* GetStagingCPUAddress() + { + VERIFY_EXPR(m_Desc.Usage == USAGE_STAGING); + return reinterpret_cast(m_MemoryAllocation.Page->GetCPUMemory()) + m_BufferMemoryAlignedOffset; + } + +private: + friend class DeviceContextVkImpl; + + virtual void CreateViewInternal(const struct BufferViewDesc& ViewDesc, IBufferView** ppView, bool bIsDefaultView) override; + + VulkanUtilities::BufferViewWrapper CreateView(struct BufferViewDesc& ViewDesc); + + Uint32 m_DynamicOffsetAlignment = 0; + VkDeviceSize m_BufferMemoryAlignedOffset = 0; + + std::vector> m_DynamicAllocations; + + VulkanUtilities::BufferWrapper m_VulkanBuffer; + VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h deleted file mode 100644 index 4084e51c..00000000 --- a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::CommandListVkImpl class - -#include "vulkan.h" -#include "CommandListBase.hpp" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -/// Command list implementation in Vulkan backend. -class CommandListVkImpl final : public CommandListBase -{ -public: - using TCommandListBase = CommandListBase; - - CommandListVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - IDeviceContext* pDeferredCtx, - VkCommandBuffer vkCmdBuff) : - // clang-format off - TCommandListBase {pRefCounters, pDevice}, - m_pDeferredCtx {pDeferredCtx}, - m_vkCmdBuff {vkCmdBuff } - // clang-format on - { - } - - ~CommandListVkImpl() - { - VERIFY(m_vkCmdBuff == VK_NULL_HANDLE && !m_pDeferredCtx, "Destroying command list that was never executed"); - } - - void Close(VkCommandBuffer& CmdBuff, - RefCntAutoPtr& pDeferredCtx) - { - CmdBuff = m_vkCmdBuff; - m_vkCmdBuff = VK_NULL_HANDLE; - pDeferredCtx = std::move(m_pDeferredCtx); - } - -private: - RefCntAutoPtr m_pDeferredCtx; - VkCommandBuffer m_vkCmdBuff; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp new file mode 100644 index 00000000..d541ca7d --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/CommandListVkImpl.hpp @@ -0,0 +1,76 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::CommandListVkImpl class + +#include "vulkan.h" +#include "CommandListBase.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +/// Command list implementation in Vulkan backend. +class CommandListVkImpl final : public CommandListBase +{ +public: + using TCommandListBase = CommandListBase; + + CommandListVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + IDeviceContext* pDeferredCtx, + VkCommandBuffer vkCmdBuff) : + // clang-format off + TCommandListBase {pRefCounters, pDevice}, + m_pDeferredCtx {pDeferredCtx}, + m_vkCmdBuff {vkCmdBuff } + // clang-format on + { + } + + ~CommandListVkImpl() + { + VERIFY(m_vkCmdBuff == VK_NULL_HANDLE && !m_pDeferredCtx, "Destroying command list that was never executed"); + } + + void Close(VkCommandBuffer& CmdBuff, + RefCntAutoPtr& pDeferredCtx) + { + CmdBuff = m_vkCmdBuff; + m_vkCmdBuff = VK_NULL_HANDLE; + pDeferredCtx = std::move(m_pDeferredCtx); + } + +private: + RefCntAutoPtr m_pDeferredCtx; + VkCommandBuffer m_vkCmdBuff; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h deleted file mode 100644 index f4109d64..00000000 --- a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include -#include "STDAllocator.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; - -class CommandPoolManager -{ -public: - CommandPoolManager(RenderDeviceVkImpl& DeviceVkImpl, - std::string Name, - uint32_t queueFamilyIndex, - VkCommandPoolCreateFlags flags) noexcept; - - // clang-format off - CommandPoolManager (const CommandPoolManager&) = delete; - CommandPoolManager ( CommandPoolManager&&) = delete; - CommandPoolManager& operator = (const CommandPoolManager&) = delete; - CommandPoolManager& operator = ( CommandPoolManager&&) = delete; - // clang-format on - - ~CommandPoolManager(); - - // Allocates Vulkan command pool. - VulkanUtilities::CommandPoolWrapper AllocateCommandPool(const char* DebugName = nullptr); - - void SafeReleaseCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool, Uint32 CmdQueueIndex, Uint64 FenceValue); - - void DestroyPools(); - -#ifdef DEVELOPMENT - int32_t GetAllocatedPoolCount() const - { - return m_AllocatedPoolCounter; - } -#endif - -private: - // Returns command pool to the list of available pools. The GPU must have finished using the pool - void FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool); - - RenderDeviceVkImpl& m_DeviceVkImpl; - const std::string m_Name; - const uint32_t m_QueueFamilyIndex; - const VkCommandPoolCreateFlags m_CmdPoolFlags; - - std::mutex m_Mutex; - std::deque> m_CmdPools; - -#ifdef DEVELOPMENT - std::atomic_int32_t m_AllocatedPoolCounter; -#endif -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.hpp b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.hpp new file mode 100644 index 00000000..aeda8ca4 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/CommandPoolManager.hpp @@ -0,0 +1,89 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include +#include "STDAllocator.h" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; + +class CommandPoolManager +{ +public: + CommandPoolManager(RenderDeviceVkImpl& DeviceVkImpl, + std::string Name, + uint32_t queueFamilyIndex, + VkCommandPoolCreateFlags flags) noexcept; + + // clang-format off + CommandPoolManager (const CommandPoolManager&) = delete; + CommandPoolManager ( CommandPoolManager&&) = delete; + CommandPoolManager& operator = (const CommandPoolManager&) = delete; + CommandPoolManager& operator = ( CommandPoolManager&&) = delete; + // clang-format on + + ~CommandPoolManager(); + + // Allocates Vulkan command pool. + VulkanUtilities::CommandPoolWrapper AllocateCommandPool(const char* DebugName = nullptr); + + void SafeReleaseCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool, Uint32 CmdQueueIndex, Uint64 FenceValue); + + void DestroyPools(); + +#ifdef DEVELOPMENT + int32_t GetAllocatedPoolCount() const + { + return m_AllocatedPoolCounter; + } +#endif + +private: + // Returns command pool to the list of available pools. The GPU must have finished using the pool + void FreeCommandPool(VulkanUtilities::CommandPoolWrapper&& CmdPool); + + RenderDeviceVkImpl& m_DeviceVkImpl; + const std::string m_Name; + const uint32_t m_QueueFamilyIndex; + const VkCommandPoolCreateFlags m_CmdPoolFlags; + + std::mutex m_Mutex; + std::deque> m_CmdPools; + +#ifdef DEVELOPMENT + std::atomic_int32_t m_AllocatedPoolCounter; +#endif +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h deleted file mode 100644 index 1934b351..00000000 --- a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::CommandQueueVkImpl class - -#include -#include -#include "vulkan.h" -#include "CommandQueueVk.h" -#include "ObjectBase.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "FenceVkImpl.h" - -namespace Diligent -{ - -/// Implementation of the Diligent::ICommandQueueVk interface -class CommandQueueVkImpl final : public ObjectBase -{ -public: - using TBase = ObjectBase; - - CommandQueueVkImpl(IReferenceCounters* pRefCounters, - std::shared_ptr LogicalDevice, - uint32_t QueueFamilyIndex); - ~CommandQueueVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ICommandQueueVk::GetNextFenceValue(). - virtual Uint64 GetNextFenceValue() const override final { return m_NextFenceValue; } - - /// Implementation of ICommandQueueVk::Submit(). - virtual Uint64 Submit(VkCommandBuffer cmdBuffer) override final; - - /// Implementation of ICommandQueueVk::Submit(). - virtual Uint64 Submit(const VkSubmitInfo& SubmitInfo) override final; - - /// Implementation of ICommandQueueVk::Present(). - virtual VkResult Present(const VkPresentInfoKHR& PresentInfo) override final; - - /// Implementation of ICommandQueueVk::GetVkQueue(). - virtual VkQueue GetVkQueue() override final { return m_VkQueue; } - - /// Implementation of ICommandQueueVk::GetQueueFamilyIndex(). - virtual uint32_t GetQueueFamilyIndex() const override final { return m_QueueFamilyIndex; } - - /// Implementation of ICommandQueueVk::GetQueueFamilyIndex(). - virtual Uint64 WaitForIdle() override final; - - /// Implementation of ICommandQueueVk::GetCompletedFenceValue(). - virtual Uint64 GetCompletedFenceValue() override final; - - /// Implementation of ICommandQueueVk::SignalFence(). - virtual void SignalFence(VkFence vkFence) override final; - - void SetFence(RefCntAutoPtr pFence) { m_pFence = std::move(pFence); } - -private: - std::shared_ptr m_LogicalDevice; - - const VkQueue m_VkQueue; - const uint32_t m_QueueFamilyIndex; - // Fence is signaled right after a command buffer has been - // submitted to the command queue for execution. - // All command buffers with fence value less than or equal to the signaled value - // are guaranteed to be finished by the GPU - RefCntAutoPtr m_pFence; - - // A value that will be signaled by the command queue next - Atomics::AtomicInt64 m_NextFenceValue; - - std::mutex m_QueueMutex; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp new file mode 100644 index 00000000..85bda3c4 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp @@ -0,0 +1,103 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::CommandQueueVkImpl class + +#include +#include +#include "vulkan.h" +#include "CommandQueueVk.h" +#include "ObjectBase.h" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "FenceVkImpl.hpp" + +namespace Diligent +{ + +/// Implementation of the Diligent::ICommandQueueVk interface +class CommandQueueVkImpl final : public ObjectBase +{ +public: + using TBase = ObjectBase; + + CommandQueueVkImpl(IReferenceCounters* pRefCounters, + std::shared_ptr LogicalDevice, + uint32_t QueueFamilyIndex); + ~CommandQueueVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ICommandQueueVk::GetNextFenceValue(). + virtual Uint64 GetNextFenceValue() const override final { return m_NextFenceValue; } + + /// Implementation of ICommandQueueVk::Submit(). + virtual Uint64 Submit(VkCommandBuffer cmdBuffer) override final; + + /// Implementation of ICommandQueueVk::Submit(). + virtual Uint64 Submit(const VkSubmitInfo& SubmitInfo) override final; + + /// Implementation of ICommandQueueVk::Present(). + virtual VkResult Present(const VkPresentInfoKHR& PresentInfo) override final; + + /// Implementation of ICommandQueueVk::GetVkQueue(). + virtual VkQueue GetVkQueue() override final { return m_VkQueue; } + + /// Implementation of ICommandQueueVk::GetQueueFamilyIndex(). + virtual uint32_t GetQueueFamilyIndex() const override final { return m_QueueFamilyIndex; } + + /// Implementation of ICommandQueueVk::GetQueueFamilyIndex(). + virtual Uint64 WaitForIdle() override final; + + /// Implementation of ICommandQueueVk::GetCompletedFenceValue(). + virtual Uint64 GetCompletedFenceValue() override final; + + /// Implementation of ICommandQueueVk::SignalFence(). + virtual void SignalFence(VkFence vkFence) override final; + + void SetFence(RefCntAutoPtr pFence) { m_pFence = std::move(pFence); } + +private: + std::shared_ptr m_LogicalDevice; + + const VkQueue m_VkQueue; + const uint32_t m_QueueFamilyIndex; + // Fence is signaled right after a command buffer has been + // submitted to the command queue for execution. + // All command buffers with fence value less than or equal to the signaled value + // are guaranteed to be finished by the GPU + RefCntAutoPtr m_pFence; + + // A value that will be signaled by the command queue next + Atomics::AtomicInt64 m_NextFenceValue; + + std::mutex m_QueueMutex; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h deleted file mode 100644 index f408ba33..00000000 --- a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -// Descriptor heap management utilities. -// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-descriptor-heaps/ for details - -#pragma once - -#include -#include -#include -#include -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace Diligent -{ - -class DescriptorSetAllocator; -class RenderDeviceVkImpl; - -// This class manages descriptor set allocation. -// The class destructor calls DescriptorSetAllocator::FreeDescriptorSet() that moves -// the set into the release queue. -// sizeof(DescriptorSetAllocation) == 32 (x64) -class DescriptorSetAllocation -{ -public: - // clang-format off - DescriptorSetAllocation(VkDescriptorSet _Set, - VkDescriptorPool _Pool, - Uint64 _CmdQueueMask, - DescriptorSetAllocator& _DescrSetAllocator)noexcept : - Set {_Set }, - Pool {_Pool }, - CmdQueueMask {_CmdQueueMask }, - DescrSetAllocator{&_DescrSetAllocator} - {} - DescriptorSetAllocation()noexcept{} - - DescriptorSetAllocation (const DescriptorSetAllocation&) = delete; - DescriptorSetAllocation& operator = (const DescriptorSetAllocation&) = delete; - - DescriptorSetAllocation(DescriptorSetAllocation&& rhs)noexcept : - Set {rhs.Set }, - Pool {rhs.Pool }, - CmdQueueMask {rhs.CmdQueueMask }, - DescrSetAllocator{rhs.DescrSetAllocator} - { - rhs.Reset(); - } - // clang-format on - - DescriptorSetAllocation& operator=(DescriptorSetAllocation&& rhs) noexcept - { - Release(); - - Set = rhs.Set; - CmdQueueMask = rhs.CmdQueueMask; - Pool = rhs.Pool; - DescrSetAllocator = rhs.DescrSetAllocator; - - rhs.Reset(); - - return *this; - } - - operator bool() const - { - return Set != VK_NULL_HANDLE; - } - - void Reset() - { - Set = VK_NULL_HANDLE; - Pool = VK_NULL_HANDLE; - CmdQueueMask = 0; - DescrSetAllocator = nullptr; - } - - void Release(); - - ~DescriptorSetAllocation() - { - Release(); - } - - VkDescriptorSet GetVkDescriptorSet() const { return Set; } - -private: - VkDescriptorSet Set = VK_NULL_HANDLE; - VkDescriptorPool Pool = VK_NULL_HANDLE; - Uint64 CmdQueueMask = 0; - DescriptorSetAllocator* DescrSetAllocator = nullptr; -}; - - -// The class manages pool of descriptor set pools -// ______________________________ -// | | -// | DescriptorPoolManager | -// | | -// | | Pool[0] | Pool[1] | ... | -// |______________________________| -// | A -// GetPool() | | FreePool() -// V | -// -class DescriptorPoolManager -{ -public: - // clang-format off - DescriptorPoolManager(RenderDeviceVkImpl& DeviceVkImpl, - std::string PoolName, - std::vector PoolSizes, - uint32_t MaxSets, - bool AllowFreeing) noexcept: - m_DeviceVkImpl{DeviceVkImpl }, - m_PoolName {std::move(PoolName) }, - m_PoolSizes (std::move(PoolSizes)), - m_MaxSets {MaxSets }, - m_AllowFreeing{AllowFreeing } - { -#ifdef DEVELOPMENT - m_AllocatedPoolCounter = 0; -#endif - } - ~DescriptorPoolManager(); - - DescriptorPoolManager (const DescriptorPoolManager&) = delete; - DescriptorPoolManager& operator = (const DescriptorPoolManager&) = delete; - DescriptorPoolManager (DescriptorPoolManager&&) = delete; - DescriptorPoolManager& operator = (DescriptorPoolManager&&) = delete; - // clang-format on - - VulkanUtilities::DescriptorPoolWrapper GetPool(const char* DebugName); - - void DisposePool(VulkanUtilities::DescriptorPoolWrapper&& Pool, Uint64 QueueMask); - - RenderDeviceVkImpl& GetDeviceVkImpl() { return m_DeviceVkImpl; } - -#ifdef DEVELOPMENT - int32_t GetAllocatedPoolCounter() const - { - return m_AllocatedPoolCounter; - } -#endif - -protected: - VulkanUtilities::DescriptorPoolWrapper CreateDescriptorPool(const char* DebugName) const; - - RenderDeviceVkImpl& m_DeviceVkImpl; - const std::string m_PoolName; - - const std::vector m_PoolSizes; - const uint32_t m_MaxSets; - const bool m_AllowFreeing; - - std::mutex m_Mutex; - std::deque m_Pools; - -private: - void FreePool(VulkanUtilities::DescriptorPoolWrapper&& Pool); - -#ifdef DEVELOPMENT - std::atomic_int32_t m_AllocatedPoolCounter; -#endif -}; - - -// The class allocates descriptor sets from the main descriptor pool. -// Descriptors sets can be released and returned to the pool -class DescriptorSetAllocator : public DescriptorPoolManager -{ -public: - friend class DescriptorSetAllocation; - DescriptorSetAllocator(RenderDeviceVkImpl& DeviceVkImpl, - std::string PoolName, - std::vector PoolSizes, - uint32_t MaxSets, - bool AllowFreeing) noexcept : - // clang-format off - DescriptorPoolManager - { - DeviceVkImpl, - std::move(PoolName), - std::move(PoolSizes), - MaxSets, - AllowFreeing - } - // clang-format on - { -#ifdef DEVELOPMENT - m_AllocatedSetCounter = 0; -#endif - } - - ~DescriptorSetAllocator(); - - DescriptorSetAllocation Allocate(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout, const char* DebugName = ""); - -#ifdef DEVELOPMENT - int32_t GetAllocatedDescriptorSetCounter() const - { - return m_AllocatedSetCounter; - } -#endif - -private: - void FreeDescriptorSet(VkDescriptorSet Set, VkDescriptorPool Pool, Uint64 QueueMask); - -#ifdef DEVELOPMENT - std::atomic_int32_t m_AllocatedSetCounter; -#endif -}; - - -// DynamicDescriptorSetAllocator manages dynamic descriptor sets. It first requests descriptor pool from -// the global manager and allocates descriptor sets from this pool. When space in the pool is exhausted, -// the class requests a new pool. -// The class is not thread-safe as device contexts must not be used in multiple threads simultaneously. -// All allocated pools are recycled at the end of every frame. -// ____________________________________________________________________________ -// | | -// | DynamicDescriptorSetAllocator | -// | | -// | || DescriptorPool[0] | DescriptorPool[1] | ... | DescriptorPool[N] || | -// |__________|_________________________________________________________________| -// | A | -// | | | -// |Allocate() GetPool()| |FreePool() -// | _____|___________________V____ -// V | | -// VkDescriptorSet | DescriptorPoolManager | -// | | -// | |Global dynamic buffer| | -// |______________________________| -// -class DynamicDescriptorSetAllocator -{ -public: - DynamicDescriptorSetAllocator(DescriptorPoolManager& PoolMgr, std::string Name) : - // clang-format off - m_GlobalPoolMgr{PoolMgr }, - m_Name {std::move(Name)} - // clang-format on - {} - ~DynamicDescriptorSetAllocator(); - - VkDescriptorSet Allocate(VkDescriptorSetLayout SetLayout, const char* DebugName); - - // Releases all allocated pools that are later returned to the global pool manager. - // As global pool manager is hosted by the render device, the allocator can - // be destroyed before the pools are actually returned to the global pool manager. - void ReleasePools(Uint64 QueueMask); - - size_t GetAllocatedPoolCount() const { return m_AllocatedPools.size(); } - -private: - DescriptorPoolManager& m_GlobalPoolMgr; - const std::string m_Name; - std::vector m_AllocatedPools; - size_t m_PeakPoolCount = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp new file mode 100644 index 00000000..bba4c285 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/DescriptorPoolManager.hpp @@ -0,0 +1,289 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +// Descriptor heap management utilities. +// See http://diligentgraphics.com/diligent-engine/architecture/d3d12/managing-descriptor-heaps/ for details + +#pragma once + +#include +#include +#include +#include +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace Diligent +{ + +class DescriptorSetAllocator; +class RenderDeviceVkImpl; + +// This class manages descriptor set allocation. +// The class destructor calls DescriptorSetAllocator::FreeDescriptorSet() that moves +// the set into the release queue. +// sizeof(DescriptorSetAllocation) == 32 (x64) +class DescriptorSetAllocation +{ +public: + // clang-format off + DescriptorSetAllocation(VkDescriptorSet _Set, + VkDescriptorPool _Pool, + Uint64 _CmdQueueMask, + DescriptorSetAllocator& _DescrSetAllocator)noexcept : + Set {_Set }, + Pool {_Pool }, + CmdQueueMask {_CmdQueueMask }, + DescrSetAllocator{&_DescrSetAllocator} + {} + DescriptorSetAllocation()noexcept{} + + DescriptorSetAllocation (const DescriptorSetAllocation&) = delete; + DescriptorSetAllocation& operator = (const DescriptorSetAllocation&) = delete; + + DescriptorSetAllocation(DescriptorSetAllocation&& rhs)noexcept : + Set {rhs.Set }, + Pool {rhs.Pool }, + CmdQueueMask {rhs.CmdQueueMask }, + DescrSetAllocator{rhs.DescrSetAllocator} + { + rhs.Reset(); + } + // clang-format on + + DescriptorSetAllocation& operator=(DescriptorSetAllocation&& rhs) noexcept + { + Release(); + + Set = rhs.Set; + CmdQueueMask = rhs.CmdQueueMask; + Pool = rhs.Pool; + DescrSetAllocator = rhs.DescrSetAllocator; + + rhs.Reset(); + + return *this; + } + + operator bool() const + { + return Set != VK_NULL_HANDLE; + } + + void Reset() + { + Set = VK_NULL_HANDLE; + Pool = VK_NULL_HANDLE; + CmdQueueMask = 0; + DescrSetAllocator = nullptr; + } + + void Release(); + + ~DescriptorSetAllocation() + { + Release(); + } + + VkDescriptorSet GetVkDescriptorSet() const { return Set; } + +private: + VkDescriptorSet Set = VK_NULL_HANDLE; + VkDescriptorPool Pool = VK_NULL_HANDLE; + Uint64 CmdQueueMask = 0; + DescriptorSetAllocator* DescrSetAllocator = nullptr; +}; + + +// The class manages pool of descriptor set pools +// ______________________________ +// | | +// | DescriptorPoolManager | +// | | +// | | Pool[0] | Pool[1] | ... | +// |______________________________| +// | A +// GetPool() | | FreePool() +// V | +// +class DescriptorPoolManager +{ +public: + // clang-format off + DescriptorPoolManager(RenderDeviceVkImpl& DeviceVkImpl, + std::string PoolName, + std::vector PoolSizes, + uint32_t MaxSets, + bool AllowFreeing) noexcept: + m_DeviceVkImpl{DeviceVkImpl }, + m_PoolName {std::move(PoolName) }, + m_PoolSizes (std::move(PoolSizes)), + m_MaxSets {MaxSets }, + m_AllowFreeing{AllowFreeing } + { +#ifdef DEVELOPMENT + m_AllocatedPoolCounter = 0; +#endif + } + ~DescriptorPoolManager(); + + DescriptorPoolManager (const DescriptorPoolManager&) = delete; + DescriptorPoolManager& operator = (const DescriptorPoolManager&) = delete; + DescriptorPoolManager (DescriptorPoolManager&&) = delete; + DescriptorPoolManager& operator = (DescriptorPoolManager&&) = delete; + // clang-format on + + VulkanUtilities::DescriptorPoolWrapper GetPool(const char* DebugName); + + void DisposePool(VulkanUtilities::DescriptorPoolWrapper&& Pool, Uint64 QueueMask); + + RenderDeviceVkImpl& GetDeviceVkImpl() { return m_DeviceVkImpl; } + +#ifdef DEVELOPMENT + int32_t GetAllocatedPoolCounter() const + { + return m_AllocatedPoolCounter; + } +#endif + +protected: + VulkanUtilities::DescriptorPoolWrapper CreateDescriptorPool(const char* DebugName) const; + + RenderDeviceVkImpl& m_DeviceVkImpl; + const std::string m_PoolName; + + const std::vector m_PoolSizes; + const uint32_t m_MaxSets; + const bool m_AllowFreeing; + + std::mutex m_Mutex; + std::deque m_Pools; + +private: + void FreePool(VulkanUtilities::DescriptorPoolWrapper&& Pool); + +#ifdef DEVELOPMENT + std::atomic_int32_t m_AllocatedPoolCounter; +#endif +}; + + +// The class allocates descriptor sets from the main descriptor pool. +// Descriptors sets can be released and returned to the pool +class DescriptorSetAllocator : public DescriptorPoolManager +{ +public: + friend class DescriptorSetAllocation; + DescriptorSetAllocator(RenderDeviceVkImpl& DeviceVkImpl, + std::string PoolName, + std::vector PoolSizes, + uint32_t MaxSets, + bool AllowFreeing) noexcept : + // clang-format off + DescriptorPoolManager + { + DeviceVkImpl, + std::move(PoolName), + std::move(PoolSizes), + MaxSets, + AllowFreeing + } + // clang-format on + { +#ifdef DEVELOPMENT + m_AllocatedSetCounter = 0; +#endif + } + + ~DescriptorSetAllocator(); + + DescriptorSetAllocation Allocate(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout, const char* DebugName = ""); + +#ifdef DEVELOPMENT + int32_t GetAllocatedDescriptorSetCounter() const + { + return m_AllocatedSetCounter; + } +#endif + +private: + void FreeDescriptorSet(VkDescriptorSet Set, VkDescriptorPool Pool, Uint64 QueueMask); + +#ifdef DEVELOPMENT + std::atomic_int32_t m_AllocatedSetCounter; +#endif +}; + + +// DynamicDescriptorSetAllocator manages dynamic descriptor sets. It first requests descriptor pool from +// the global manager and allocates descriptor sets from this pool. When space in the pool is exhausted, +// the class requests a new pool. +// The class is not thread-safe as device contexts must not be used in multiple threads simultaneously. +// All allocated pools are recycled at the end of every frame. +// ____________________________________________________________________________ +// | | +// | DynamicDescriptorSetAllocator | +// | | +// | || DescriptorPool[0] | DescriptorPool[1] | ... | DescriptorPool[N] || | +// |__________|_________________________________________________________________| +// | A | +// | | | +// |Allocate() GetPool()| |FreePool() +// | _____|___________________V____ +// V | | +// VkDescriptorSet | DescriptorPoolManager | +// | | +// | |Global dynamic buffer| | +// |______________________________| +// +class DynamicDescriptorSetAllocator +{ +public: + DynamicDescriptorSetAllocator(DescriptorPoolManager& PoolMgr, std::string Name) : + // clang-format off + m_GlobalPoolMgr{PoolMgr }, + m_Name {std::move(Name)} + // clang-format on + {} + ~DynamicDescriptorSetAllocator(); + + VkDescriptorSet Allocate(VkDescriptorSetLayout SetLayout, const char* DebugName); + + // Releases all allocated pools that are later returned to the global pool manager. + // As global pool manager is hosted by the render device, the allocator can + // be destroyed before the pools are actually returned to the global pool manager. + void ReleasePools(Uint64 QueueMask); + + size_t GetAllocatedPoolCount() const { return m_AllocatedPools.size(); } + +private: + DescriptorPoolManager& m_GlobalPoolMgr; + const std::string m_Name; + std::vector m_AllocatedPools; + size_t m_PeakPoolCount = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h deleted file mode 100644 index 120a4f29..00000000 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::DeviceContextVkImpl class -#include - -#include "DeviceContextVk.h" -#include "DeviceContextNextGenBase.hpp" -#include "VulkanUtilities/VulkanCommandBufferPool.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" -#include "VulkanUploadHeap.h" -#include "VulkanDynamicHeap.h" -#include "ResourceReleaseQueue.hpp" -#include "DescriptorPoolManager.h" -#include "PipelineLayout.h" -#include "GenerateMipsVkHelper.h" -#include "BufferVkImpl.h" -#include "TextureVkImpl.h" -#include "PipelineStateVkImpl.h" -#include "QueryVkImpl.h" -#include "HashUtils.h" -#include "ManagedVulkanObject.h" -#include "QueryManagerVk.h" - - -namespace Diligent -{ - -class RenderDeviceVkImpl; - -struct DeviceContextVkImplTraits -{ - using BufferType = BufferVkImpl; - using TextureType = TextureVkImpl; - using PipelineStateType = PipelineStateVkImpl; - using DeviceType = RenderDeviceVkImpl; - using ICommandQueueType = ICommandQueueVk; - using QueryType = QueryVkImpl; -}; - -/// Device context implementation in Vulkan backend. -class DeviceContextVkImpl final : public DeviceContextNextGenBase -{ -public: - using TDeviceContextBase = DeviceContextNextGenBase; - - DeviceContextVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - bool bIsDeferred, - const EngineVkCreateInfo& EngineCI, - Uint32 ContextId, - Uint32 CommandQueueId, - std::shared_ptr GenerateMipsHelper); - ~DeviceContextVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IDeviceContext::SetPipelineState() in Vulkan backend. - virtual void SetPipelineState(IPipelineState* pPipelineState) override final; - - /// Implementation of IDeviceContext::TransitionShaderResources() in Vulkan backend. - virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) override final; - - /// Implementation of IDeviceContext::CommitShaderResources() in Vulkan backend. - virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::SetStencilRef() in Vulkan backend. - virtual void SetStencilRef(Uint32 StencilRef) override final; - - /// Implementation of IDeviceContext::SetBlendFactors() in Vulkan backend. - virtual void SetBlendFactors(const float* pBlendFactors = nullptr) override final; - - /// Implementation of IDeviceContext::SetVertexBuffers() in Vulkan backend. - virtual void SetVertexBuffers(Uint32 StartSlot, - Uint32 NumBuffersSet, - IBuffer** ppBuffers, - Uint32* pOffsets, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, - SET_VERTEX_BUFFERS_FLAGS Flags) override final; - - /// Implementation of IDeviceContext::InvalidateState() in Vulkan backend. - virtual void InvalidateState() override final; - - /// Implementation of IDeviceContext::SetIndexBuffer() in Vulkan backend. - virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::SetViewports() in Vulkan backend. - virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) override final; - - /// Implementation of IDeviceContext::SetScissorRects() in Vulkan backend. - virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) override final; - - /// Implementation of IDeviceContext::SetRenderTargets() in Vulkan backend. - virtual void SetRenderTargets(Uint32 NumRenderTargets, - ITextureView* ppRenderTargets[], - ITextureView* pDepthStencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - // clang-format off - /// Implementation of IDeviceContext::Draw() in Vulkan backend. - virtual void Draw (const DrawAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DrawIndexed() in Vulkan backend. - virtual void DrawIndexed (const DrawIndexedAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DrawIndirect() in Vulkan backend. - virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - /// Implementation of IDeviceContext::DrawIndexedIndirect() in Vulkan backend. - virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - - /// Implementation of IDeviceContext::DispatchCompute() in Vulkan backend. - virtual void DispatchCompute (const DispatchComputeAttribs& Attribs) override final; - /// Implementation of IDeviceContext::DispatchComputeIndirect() in Vulkan backend. - virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; - // clang-format on - - /// Implementation of IDeviceContext::ClearDepthStencil() in Vulkan backend. - virtual void ClearDepthStencil(ITextureView* pView, - CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, - float fDepth, - Uint8 Stencil, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::ClearRenderTarget() in Vulkan backend. - virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::UpdateBuffer() in Vulkan backend. - virtual void UpdateBuffer(IBuffer* pBuffer, - Uint32 Offset, - Uint32 Size, - const void* pData, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; - - /// Implementation of IDeviceContext::CopyBuffer() in Vulkan backend. - virtual void CopyBuffer(IBuffer* pSrcBuffer, - Uint32 SrcOffset, - RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, - IBuffer* pDstBuffer, - Uint32 DstOffset, - Uint32 Size, - RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) override final; - - /// Implementation of IDeviceContext::MapBuffer() in Vulkan backend. - virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) override final; - - /// Implementation of IDeviceContext::UnmapBuffer() in Vulkan backend. - virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) override final; - - /// Implementation of IDeviceContext::UpdateTexture() in Vulkan backend. - virtual void UpdateTexture(ITexture* pTexture, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - const TextureSubResData& SubresData, - RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, - RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionModee) override final; - - /// Implementation of IDeviceContext::CopyTexture() in Vulkan backend. - virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) override final; - - /// Implementation of IDeviceContext::MapTextureSubresource() in Vulkan backend. - virtual void MapTextureSubresource(ITexture* pTexture, - Uint32 MipLevel, - Uint32 ArraySlice, - MAP_TYPE MapType, - MAP_FLAGS MapFlags, - const Box* pMapRegion, - MappedTextureSubresource& MappedData) override final; - - /// Implementation of IDeviceContext::UnmapTextureSubresource() in Vulkan backend. - virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) override final; - - /// Implementation of IDeviceContext::FinishCommandList() in Vulkan backend. - virtual void FinishCommandList(class ICommandList** ppCommandList) override final; - - /// Implementation of IDeviceContext::ExecuteCommandList() in Vulkan backend. - virtual void ExecuteCommandList(class ICommandList* pCommandList) override final; - - /// Implementation of IDeviceContext::SignalFence() in Vulkan backend. - virtual void SignalFence(IFence* pFence, Uint64 Value) override final; - - /// Implementation of IDeviceContext::WaitForFence() in Vulkan backend. - virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) override final; - - /// Implementation of IDeviceContext::WaitForIdle() in Vulkan backend. - virtual void WaitForIdle() override final; - - /// Implementation of IDeviceContext::BeginQuery() in Vulkan backend. - virtual void BeginQuery(IQuery* pQuery) override final; - - /// Implementation of IDeviceContext::EndQuery() in Vulkan backend. - virtual void EndQuery(IQuery* pQuery) override final; - - /// Implementation of IDeviceContext::Flush() in Vulkan backend. - virtual void Flush() override final; - - // Transitions texture subresources from OldState to NewState, and optionally updates - // internal texture state. - // If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state. - void TransitionTextureState(TextureVkImpl& TextureVk, - RESOURCE_STATE OldState, - RESOURCE_STATE NewState, - bool UpdateTextureState, - VkImageSubresourceRange* pSubresRange = nullptr); - - void TransitionImageLayout(TextureVkImpl& TextureVk, - VkImageLayout OldLayout, - VkImageLayout NewLayout, - const VkImageSubresourceRange& SubresRange); - - /// Implementation of IDeviceContextVk::TransitionImageLayout(). - virtual void TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout) override final; - - - // Transitions buffer state from OldState to NewState, and optionally updates - // internal buffer state. - // If OldState == RESOURCE_STATE_UNKNOWN, internal buffer state is used as old state. - void TransitionBufferState(BufferVkImpl& BufferVk, - RESOURCE_STATE OldState, - RESOURCE_STATE NewState, - bool UpdateBufferState); - - /// Implementation of IDeviceContextVk::BufferMemoryBarrier(). - virtual void BufferMemoryBarrier(IBuffer* pBuffer, VkAccessFlags NewAccessFlags) override final; - - - void AddWaitSemaphore(ManagedSemaphore* pWaitSemaphore, VkPipelineStageFlags WaitDstStageMask) - { - VERIFY_EXPR(pWaitSemaphore != nullptr); - m_WaitSemaphores.emplace_back(pWaitSemaphore); - m_VkWaitSemaphores.push_back(pWaitSemaphore->Get()); - m_WaitDstStageMasks.push_back(WaitDstStageMask); - } - void AddSignalSemaphore(ManagedSemaphore* pSignalSemaphore) - { - VERIFY_EXPR(pSignalSemaphore != nullptr); - m_SignalSemaphores.emplace_back(pSignalSemaphore); - m_VkSignalSemaphores.push_back(pSignalSemaphore->Get()); - } - - void UpdateBufferRegion(BufferVkImpl* pBuffVk, - Uint64 DstOffset, - Uint64 NumBytes, - VkBuffer vkSrcBuffer, - Uint64 SrcOffset, - RESOURCE_STATE_TRANSITION_MODE TransitionMode); - - void CopyTextureRegion(TextureVkImpl* pSrcTexture, - RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, - TextureVkImpl* pDstTexture, - RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode, - const VkImageCopy& CopyRegion); - - void UpdateTextureRegion(const void* pSrcData, - Uint32 SrcStride, - Uint32 SrcDepthStride, - TextureVkImpl& TextureVk, - Uint32 MipLevel, - Uint32 Slice, - const Box& DstBox, - RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); - - virtual void GenerateMips(ITextureView* pTexView) override final; - - Uint32 GetContextId() const { return m_ContextId; } - - size_t GetNumCommandsInCtx() const { return m_State.NumCommands; } - - __forceinline VulkanUtilities::VulkanCommandBuffer& GetCommandBuffer() - { - EnsureVkCmdBuffer(); - return m_CommandBuffer; - } - - virtual void FinishFrame() override final; - - virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) override final; - - virtual void ResolveTextureSubresource(ITexture* pSrcTexture, - ITexture* pDstTexture, - const ResolveTextureSubresourceAttribs& ResolveAttribs) override final; - - VkDescriptorSet AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = "") - { - // Descriptor pools are externally synchronized, meaning that the application must not allocate - // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3) - return m_DynamicDescrSetAllocator.Allocate(SetLayout, DebugName); - } - - VulkanDynamicAllocation AllocateDynamicSpace(Uint32 SizeInBytes, Uint32 Alignment); - - virtual void ResetRenderTargets() override final; - - Int64 GetContextFrameNumber() const { return m_ContextFrameNumber; } - - GenerateMipsVkHelper& GetGenerateMipsHelper() { return *m_GenerateMipsHelper; } - QueryManagerVk* GetQueryManager() { return m_QueryMgr.get(); } - -private: - void TransitionRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); - __forceinline void CommitRenderPassAndFramebuffer(bool VerifyStates); - void CommitVkVertexBuffers(); - void CommitViewports(); - void CommitScissorRects(); - - __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() - { - // Make sure that the number of commands in the context is at least one, - // so that the context cannot be disposed by Flush() - m_State.NumCommands = m_State.NumCommands != 0 ? m_State.NumCommands : 1; - if (m_CommandBuffer.GetVkCmdBuffer() == VK_NULL_HANDLE) - { - auto vkCmdBuff = m_CmdPool.GetCommandBuffer(); - m_CommandBuffer.SetVkCmdBuffer(vkCmdBuff); - } - } - - inline void DisposeVkCmdBuffer(Uint32 CmdQueue, VkCommandBuffer vkCmdBuff, Uint64 FenceValue); - inline void DisposeCurrentCmdBuffer(Uint32 CmdQueue, Uint64 FenceValue); - - struct BufferToTextureCopyInfo - { - Uint32 RowSize = 0; - Uint32 Stride = 0; - Uint32 StrideInTexels = 0; - Uint32 DepthStride = 0; - Uint32 MemorySize = 0; - Uint32 RowCount = 0; - Box Region; - }; - BufferToTextureCopyInfo GetBufferToTextureCopyInfo(const TextureDesc& TexDesc, - Uint32 MipLevel, - const Box& Region) const; - - void CopyBufferToTexture(VkBuffer vkSrcBuffer, - Uint32 SrcBufferOffset, - Uint32 SrcBufferRowStrideInTexels, - TextureVkImpl& DstTextureVk, - const Box& DstRegion, - Uint32 DstMipLevel, - Uint32 DstArraySlice, - RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode); - - void CopyTextureToBuffer(TextureVkImpl& SrcTextureVk, - const Box& SrcRegion, - Uint32 SrcMipLevel, - Uint32 SrcArraySlice, - RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, - VkBuffer vkDstBuffer, - Uint32 DstBufferOffset, - Uint32 DstBufferRowStrideInTexels); - - __forceinline void PrepareForDraw(DRAW_FLAGS Flags); - __forceinline void PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE IndexType); - __forceinline BufferVkImpl* PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode); - __forceinline void PrepareForDispatchCompute(); - - void DvpLogRenderPass_PSOMismatch(); - - VulkanUtilities::VulkanCommandBuffer m_CommandBuffer; - - const Uint32 m_NumCommandsToFlush = 192; - struct ContextState - { - /// Flag indicating if currently committed vertex buffers are up to date - bool CommittedVBsUpToDate = false; - - /// Flag indicating if currently committed index buffer is up to date - bool CommittedIBUpToDate = false; - - Uint32 NumCommands = 0; - } m_State; - - - /// Render pass that matches currently bound render targets. - /// This render pass may or may not be currently set in the command buffer - VkRenderPass m_RenderPass = VK_NULL_HANDLE; - - /// Framebuffer that matches currently bound render targets. - /// This framebuffer may or may not be currently set in the command buffer - VkFramebuffer m_Framebuffer = VK_NULL_HANDLE; - - FixedBlockMemoryAllocator m_CmdListAllocator; - - // Semaphores are not owned by the command context - std::vector> m_WaitSemaphores; - std::vector m_WaitDstStageMasks; - std::vector> m_SignalSemaphores; - - std::vector m_VkWaitSemaphores; - std::vector m_VkSignalSemaphores; - - // List of fences to signal next time the command context is flushed - std::vector>> m_PendingFences; - - std::unordered_map m_UploadAllocations; - - struct MappedTextureKey - { - TextureVkImpl* const Texture; - Uint32 const MipLevel; - Uint32 const ArraySlice; - - bool operator==(const MappedTextureKey& rhs) const - { - return Texture == rhs.Texture && - MipLevel == rhs.MipLevel && - ArraySlice == rhs.ArraySlice; - } - struct Hasher - { - size_t operator()(const MappedTextureKey& Key) const - { - return ComputeHash(Key.Texture, Key.MipLevel, Key.ArraySlice); - } - }; - }; - struct MappedTexture - { - BufferToTextureCopyInfo CopyInfo; - VulkanDynamicAllocation Allocation; - }; - std::unordered_map m_MappedTextures; - - VulkanUtilities::VulkanCommandBufferPool m_CmdPool; - VulkanUploadHeap m_UploadHeap; - VulkanDynamicHeap m_DynamicHeap; - DynamicDescriptorSetAllocator m_DynamicDescrSetAllocator; - - PipelineLayout::DescriptorSetBindInfo m_DescrSetBindInfo; - std::shared_ptr m_GenerateMipsHelper; - RefCntAutoPtr m_GenerateMipsSRB; - - // In Vulkan we can't bind null vertex buffer, so we have to create a dummy VB - RefCntAutoPtr m_DummyVB; - - std::unique_ptr m_QueryMgr; - Int32 m_ActiveQueriesCounter = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp new file mode 100644 index 00000000..b72fcc36 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.hpp @@ -0,0 +1,479 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::DeviceContextVkImpl class +#include + +#include "DeviceContextVk.h" +#include "DeviceContextNextGenBase.hpp" +#include "VulkanUtilities/VulkanCommandBufferPool.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" +#include "VulkanUploadHeap.hpp" +#include "VulkanDynamicHeap.hpp" +#include "ResourceReleaseQueue.hpp" +#include "DescriptorPoolManager.hpp" +#include "PipelineLayout.hpp" +#include "GenerateMipsVkHelper.hpp" +#include "BufferVkImpl.hpp" +#include "TextureVkImpl.hpp" +#include "PipelineStateVkImpl.hpp" +#include "QueryVkImpl.hpp" +#include "HashUtils.h" +#include "ManagedVulkanObject.hpp" +#include "QueryManagerVk.hpp" + + +namespace Diligent +{ + +class RenderDeviceVkImpl; + +struct DeviceContextVkImplTraits +{ + using BufferType = BufferVkImpl; + using TextureType = TextureVkImpl; + using PipelineStateType = PipelineStateVkImpl; + using DeviceType = RenderDeviceVkImpl; + using ICommandQueueType = ICommandQueueVk; + using QueryType = QueryVkImpl; +}; + +/// Device context implementation in Vulkan backend. +class DeviceContextVkImpl final : public DeviceContextNextGenBase +{ +public: + using TDeviceContextBase = DeviceContextNextGenBase; + + DeviceContextVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + bool bIsDeferred, + const EngineVkCreateInfo& EngineCI, + Uint32 ContextId, + Uint32 CommandQueueId, + std::shared_ptr GenerateMipsHelper); + ~DeviceContextVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IDeviceContext::SetPipelineState() in Vulkan backend. + virtual void SetPipelineState(IPipelineState* pPipelineState) override final; + + /// Implementation of IDeviceContext::TransitionShaderResources() in Vulkan backend. + virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) override final; + + /// Implementation of IDeviceContext::CommitShaderResources() in Vulkan backend. + virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::SetStencilRef() in Vulkan backend. + virtual void SetStencilRef(Uint32 StencilRef) override final; + + /// Implementation of IDeviceContext::SetBlendFactors() in Vulkan backend. + virtual void SetBlendFactors(const float* pBlendFactors = nullptr) override final; + + /// Implementation of IDeviceContext::SetVertexBuffers() in Vulkan backend. + virtual void SetVertexBuffers(Uint32 StartSlot, + Uint32 NumBuffersSet, + IBuffer** ppBuffers, + Uint32* pOffsets, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, + SET_VERTEX_BUFFERS_FLAGS Flags) override final; + + /// Implementation of IDeviceContext::InvalidateState() in Vulkan backend. + virtual void InvalidateState() override final; + + /// Implementation of IDeviceContext::SetIndexBuffer() in Vulkan backend. + virtual void SetIndexBuffer(IBuffer* pIndexBuffer, Uint32 ByteOffset, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::SetViewports() in Vulkan backend. + virtual void SetViewports(Uint32 NumViewports, const Viewport* pViewports, Uint32 RTWidth, Uint32 RTHeight) override final; + + /// Implementation of IDeviceContext::SetScissorRects() in Vulkan backend. + virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) override final; + + /// Implementation of IDeviceContext::SetRenderTargets() in Vulkan backend. + virtual void SetRenderTargets(Uint32 NumRenderTargets, + ITextureView* ppRenderTargets[], + ITextureView* pDepthStencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + // clang-format off + /// Implementation of IDeviceContext::Draw() in Vulkan backend. + virtual void Draw (const DrawAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DrawIndexed() in Vulkan backend. + virtual void DrawIndexed (const DrawIndexedAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DrawIndirect() in Vulkan backend. + virtual void DrawIndirect (const DrawIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + /// Implementation of IDeviceContext::DrawIndexedIndirect() in Vulkan backend. + virtual void DrawIndexedIndirect(const DrawIndexedIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + + /// Implementation of IDeviceContext::DispatchCompute() in Vulkan backend. + virtual void DispatchCompute (const DispatchComputeAttribs& Attribs) override final; + /// Implementation of IDeviceContext::DispatchComputeIndirect() in Vulkan backend. + virtual void DispatchComputeIndirect(const DispatchComputeIndirectAttribs& Attribs, IBuffer* pAttribsBuffer) override final; + // clang-format on + + /// Implementation of IDeviceContext::ClearDepthStencil() in Vulkan backend. + virtual void ClearDepthStencil(ITextureView* pView, + CLEAR_DEPTH_STENCIL_FLAGS ClearFlags, + float fDepth, + Uint8 Stencil, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::ClearRenderTarget() in Vulkan backend. + virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::UpdateBuffer() in Vulkan backend. + virtual void UpdateBuffer(IBuffer* pBuffer, + Uint32 Offset, + Uint32 Size, + const void* pData, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode) override final; + + /// Implementation of IDeviceContext::CopyBuffer() in Vulkan backend. + virtual void CopyBuffer(IBuffer* pSrcBuffer, + Uint32 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE SrcBufferTransitionMode, + IBuffer* pDstBuffer, + Uint32 DstOffset, + Uint32 Size, + RESOURCE_STATE_TRANSITION_MODE DstBufferTransitionMode) override final; + + /// Implementation of IDeviceContext::MapBuffer() in Vulkan backend. + virtual void MapBuffer(IBuffer* pBuffer, MAP_TYPE MapType, MAP_FLAGS MapFlags, PVoid& pMappedData) override final; + + /// Implementation of IDeviceContext::UnmapBuffer() in Vulkan backend. + virtual void UnmapBuffer(IBuffer* pBuffer, MAP_TYPE MapType) override final; + + /// Implementation of IDeviceContext::UpdateTexture() in Vulkan backend. + virtual void UpdateTexture(ITexture* pTexture, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + const TextureSubResData& SubresData, + RESOURCE_STATE_TRANSITION_MODE SrcBufferStateTransitionMode, + RESOURCE_STATE_TRANSITION_MODE TextureStateTransitionModee) override final; + + /// Implementation of IDeviceContext::CopyTexture() in Vulkan backend. + virtual void CopyTexture(const CopyTextureAttribs& CopyAttribs) override final; + + /// Implementation of IDeviceContext::MapTextureSubresource() in Vulkan backend. + virtual void MapTextureSubresource(ITexture* pTexture, + Uint32 MipLevel, + Uint32 ArraySlice, + MAP_TYPE MapType, + MAP_FLAGS MapFlags, + const Box* pMapRegion, + MappedTextureSubresource& MappedData) override final; + + /// Implementation of IDeviceContext::UnmapTextureSubresource() in Vulkan backend. + virtual void UnmapTextureSubresource(ITexture* pTexture, Uint32 MipLevel, Uint32 ArraySlice) override final; + + /// Implementation of IDeviceContext::FinishCommandList() in Vulkan backend. + virtual void FinishCommandList(class ICommandList** ppCommandList) override final; + + /// Implementation of IDeviceContext::ExecuteCommandList() in Vulkan backend. + virtual void ExecuteCommandList(class ICommandList* pCommandList) override final; + + /// Implementation of IDeviceContext::SignalFence() in Vulkan backend. + virtual void SignalFence(IFence* pFence, Uint64 Value) override final; + + /// Implementation of IDeviceContext::WaitForFence() in Vulkan backend. + virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) override final; + + /// Implementation of IDeviceContext::WaitForIdle() in Vulkan backend. + virtual void WaitForIdle() override final; + + /// Implementation of IDeviceContext::BeginQuery() in Vulkan backend. + virtual void BeginQuery(IQuery* pQuery) override final; + + /// Implementation of IDeviceContext::EndQuery() in Vulkan backend. + virtual void EndQuery(IQuery* pQuery) override final; + + /// Implementation of IDeviceContext::Flush() in Vulkan backend. + virtual void Flush() override final; + + // Transitions texture subresources from OldState to NewState, and optionally updates + // internal texture state. + // If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state. + void TransitionTextureState(TextureVkImpl& TextureVk, + RESOURCE_STATE OldState, + RESOURCE_STATE NewState, + bool UpdateTextureState, + VkImageSubresourceRange* pSubresRange = nullptr); + + void TransitionImageLayout(TextureVkImpl& TextureVk, + VkImageLayout OldLayout, + VkImageLayout NewLayout, + const VkImageSubresourceRange& SubresRange); + + /// Implementation of IDeviceContextVk::TransitionImageLayout(). + virtual void TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout) override final; + + + // Transitions buffer state from OldState to NewState, and optionally updates + // internal buffer state. + // If OldState == RESOURCE_STATE_UNKNOWN, internal buffer state is used as old state. + void TransitionBufferState(BufferVkImpl& BufferVk, + RESOURCE_STATE OldState, + RESOURCE_STATE NewState, + bool UpdateBufferState); + + /// Implementation of IDeviceContextVk::BufferMemoryBarrier(). + virtual void BufferMemoryBarrier(IBuffer* pBuffer, VkAccessFlags NewAccessFlags) override final; + + + void AddWaitSemaphore(ManagedSemaphore* pWaitSemaphore, VkPipelineStageFlags WaitDstStageMask) + { + VERIFY_EXPR(pWaitSemaphore != nullptr); + m_WaitSemaphores.emplace_back(pWaitSemaphore); + m_VkWaitSemaphores.push_back(pWaitSemaphore->Get()); + m_WaitDstStageMasks.push_back(WaitDstStageMask); + } + void AddSignalSemaphore(ManagedSemaphore* pSignalSemaphore) + { + VERIFY_EXPR(pSignalSemaphore != nullptr); + m_SignalSemaphores.emplace_back(pSignalSemaphore); + m_VkSignalSemaphores.push_back(pSignalSemaphore->Get()); + } + + void UpdateBufferRegion(BufferVkImpl* pBuffVk, + Uint64 DstOffset, + Uint64 NumBytes, + VkBuffer vkSrcBuffer, + Uint64 SrcOffset, + RESOURCE_STATE_TRANSITION_MODE TransitionMode); + + void CopyTextureRegion(TextureVkImpl* pSrcTexture, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + TextureVkImpl* pDstTexture, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode, + const VkImageCopy& CopyRegion); + + void UpdateTextureRegion(const void* pSrcData, + Uint32 SrcStride, + Uint32 SrcDepthStride, + TextureVkImpl& TextureVk, + Uint32 MipLevel, + Uint32 Slice, + const Box& DstBox, + RESOURCE_STATE_TRANSITION_MODE TextureTransitionMode); + + virtual void GenerateMips(ITextureView* pTexView) override final; + + Uint32 GetContextId() const { return m_ContextId; } + + size_t GetNumCommandsInCtx() const { return m_State.NumCommands; } + + __forceinline VulkanUtilities::VulkanCommandBuffer& GetCommandBuffer() + { + EnsureVkCmdBuffer(); + return m_CommandBuffer; + } + + virtual void FinishFrame() override final; + + virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) override final; + + virtual void ResolveTextureSubresource(ITexture* pSrcTexture, + ITexture* pDstTexture, + const ResolveTextureSubresourceAttribs& ResolveAttribs) override final; + + VkDescriptorSet AllocateDynamicDescriptorSet(VkDescriptorSetLayout SetLayout, const char* DebugName = "") + { + // Descriptor pools are externally synchronized, meaning that the application must not allocate + // and/or free descriptor sets from the same pool in multiple threads simultaneously (13.2.3) + return m_DynamicDescrSetAllocator.Allocate(SetLayout, DebugName); + } + + VulkanDynamicAllocation AllocateDynamicSpace(Uint32 SizeInBytes, Uint32 Alignment); + + virtual void ResetRenderTargets() override final; + + Int64 GetContextFrameNumber() const { return m_ContextFrameNumber; } + + GenerateMipsVkHelper& GetGenerateMipsHelper() { return *m_GenerateMipsHelper; } + QueryManagerVk* GetQueryManager() { return m_QueryMgr.get(); } + +private: + void TransitionRenderTargets(RESOURCE_STATE_TRANSITION_MODE StateTransitionMode); + __forceinline void CommitRenderPassAndFramebuffer(bool VerifyStates); + void CommitVkVertexBuffers(); + void CommitViewports(); + void CommitScissorRects(); + + __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() + { + // Make sure that the number of commands in the context is at least one, + // so that the context cannot be disposed by Flush() + m_State.NumCommands = m_State.NumCommands != 0 ? m_State.NumCommands : 1; + if (m_CommandBuffer.GetVkCmdBuffer() == VK_NULL_HANDLE) + { + auto vkCmdBuff = m_CmdPool.GetCommandBuffer(); + m_CommandBuffer.SetVkCmdBuffer(vkCmdBuff); + } + } + + inline void DisposeVkCmdBuffer(Uint32 CmdQueue, VkCommandBuffer vkCmdBuff, Uint64 FenceValue); + inline void DisposeCurrentCmdBuffer(Uint32 CmdQueue, Uint64 FenceValue); + + struct BufferToTextureCopyInfo + { + Uint32 RowSize = 0; + Uint32 Stride = 0; + Uint32 StrideInTexels = 0; + Uint32 DepthStride = 0; + Uint32 MemorySize = 0; + Uint32 RowCount = 0; + Box Region; + }; + BufferToTextureCopyInfo GetBufferToTextureCopyInfo(const TextureDesc& TexDesc, + Uint32 MipLevel, + const Box& Region) const; + + void CopyBufferToTexture(VkBuffer vkSrcBuffer, + Uint32 SrcBufferOffset, + Uint32 SrcBufferRowStrideInTexels, + TextureVkImpl& DstTextureVk, + const Box& DstRegion, + Uint32 DstMipLevel, + Uint32 DstArraySlice, + RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode); + + void CopyTextureToBuffer(TextureVkImpl& SrcTextureVk, + const Box& SrcRegion, + Uint32 SrcMipLevel, + Uint32 SrcArraySlice, + RESOURCE_STATE_TRANSITION_MODE SrcTextureTransitionMode, + VkBuffer vkDstBuffer, + Uint32 DstBufferOffset, + Uint32 DstBufferRowStrideInTexels); + + __forceinline void PrepareForDraw(DRAW_FLAGS Flags); + __forceinline void PrepareForIndexedDraw(DRAW_FLAGS Flags, VALUE_TYPE IndexType); + __forceinline BufferVkImpl* PrepareIndirectDrawAttribsBuffer(IBuffer* pAttribsBuffer, RESOURCE_STATE_TRANSITION_MODE TransitonMode); + __forceinline void PrepareForDispatchCompute(); + + void DvpLogRenderPass_PSOMismatch(); + + VulkanUtilities::VulkanCommandBuffer m_CommandBuffer; + + const Uint32 m_NumCommandsToFlush = 192; + struct ContextState + { + /// Flag indicating if currently committed vertex buffers are up to date + bool CommittedVBsUpToDate = false; + + /// Flag indicating if currently committed index buffer is up to date + bool CommittedIBUpToDate = false; + + Uint32 NumCommands = 0; + } m_State; + + + /// Render pass that matches currently bound render targets. + /// This render pass may or may not be currently set in the command buffer + VkRenderPass m_RenderPass = VK_NULL_HANDLE; + + /// Framebuffer that matches currently bound render targets. + /// This framebuffer may or may not be currently set in the command buffer + VkFramebuffer m_Framebuffer = VK_NULL_HANDLE; + + FixedBlockMemoryAllocator m_CmdListAllocator; + + // Semaphores are not owned by the command context + std::vector> m_WaitSemaphores; + std::vector m_WaitDstStageMasks; + std::vector> m_SignalSemaphores; + + std::vector m_VkWaitSemaphores; + std::vector m_VkSignalSemaphores; + + // List of fences to signal next time the command context is flushed + std::vector>> m_PendingFences; + + std::unordered_map m_UploadAllocations; + + struct MappedTextureKey + { + TextureVkImpl* const Texture; + Uint32 const MipLevel; + Uint32 const ArraySlice; + + bool operator==(const MappedTextureKey& rhs) const + { + return Texture == rhs.Texture && + MipLevel == rhs.MipLevel && + ArraySlice == rhs.ArraySlice; + } + struct Hasher + { + size_t operator()(const MappedTextureKey& Key) const + { + return ComputeHash(Key.Texture, Key.MipLevel, Key.ArraySlice); + } + }; + }; + struct MappedTexture + { + BufferToTextureCopyInfo CopyInfo; + VulkanDynamicAllocation Allocation; + }; + std::unordered_map m_MappedTextures; + + VulkanUtilities::VulkanCommandBufferPool m_CmdPool; + VulkanUploadHeap m_UploadHeap; + VulkanDynamicHeap m_DynamicHeap; + DynamicDescriptorSetAllocator m_DynamicDescrSetAllocator; + + PipelineLayout::DescriptorSetBindInfo m_DescrSetBindInfo; + std::shared_ptr m_GenerateMipsHelper; + RefCntAutoPtr m_GenerateMipsSRB; + + // In Vulkan we can't bind null vertex buffer, so we have to create a dummy VB + RefCntAutoPtr m_DummyVB; + + std::unique_ptr m_QueryMgr; + Int32 m_ActiveQueriesCounter = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h deleted file mode 100644 index 27aa8510..00000000 --- a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::FenceVkImpl class - -#include -#include "FenceVk.h" -#include "FenceBase.hpp" -#include "VulkanUtilities/VulkanFencePool.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Fence implementation in Vulkan backend. -class FenceVkImpl final : public FenceBase -{ -public: - using TFenceBase = FenceBase; - - FenceVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pRendeDeviceVkImpl, - const FenceDesc& Desc, - bool IsDeviceInternal = false); - ~FenceVkImpl(); - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_FenceVk, TFenceBase); - - /// Implementation of IFence::GetCompletedValue() in Vulkan backend. - /// Note that this method is not thread-safe. The reason is that VulkanFencePool is not thread - /// safe, and DeviceContextVkImpl::SignalFence() adds the fence to the pending fences list that - /// are signaled later by the command context when it submits the command list. So there is no - /// guarantee that the fence pool is not accessed simultaneously by multiple threads even if the - /// fence object itself is protected by mutex. - virtual Uint64 GetCompletedValue() override final; - - /// Implementation of IFence::Reset() in Vulkan backend. - virtual void Reset(Uint64 Value) override final; - - VulkanUtilities::FenceWrapper GetVkFence() { return m_FencePool.GetFence(); } - - void AddPendingFence(VulkanUtilities::FenceWrapper&& vkFence, Uint64 FenceValue) - { - m_PendingFences.emplace_back(FenceValue, std::move(vkFence)); - } - - void Wait(Uint64 Value); - -private: - VulkanUtilities::VulkanFencePool m_FencePool; - std::deque> m_PendingFences; - volatile Uint64 m_LastCompletedFenceValue = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp new file mode 100644 index 00000000..7005f658 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp @@ -0,0 +1,84 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::FenceVkImpl class + +#include +#include "FenceVk.h" +#include "FenceBase.hpp" +#include "VulkanUtilities/VulkanFencePool.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Fence implementation in Vulkan backend. +class FenceVkImpl final : public FenceBase +{ +public: + using TFenceBase = FenceBase; + + FenceVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRendeDeviceVkImpl, + const FenceDesc& Desc, + bool IsDeviceInternal = false); + ~FenceVkImpl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_FenceVk, TFenceBase); + + /// Implementation of IFence::GetCompletedValue() in Vulkan backend. + /// Note that this method is not thread-safe. The reason is that VulkanFencePool is not thread + /// safe, and DeviceContextVkImpl::SignalFence() adds the fence to the pending fences list that + /// are signaled later by the command context when it submits the command list. So there is no + /// guarantee that the fence pool is not accessed simultaneously by multiple threads even if the + /// fence object itself is protected by mutex. + virtual Uint64 GetCompletedValue() override final; + + /// Implementation of IFence::Reset() in Vulkan backend. + virtual void Reset(Uint64 Value) override final; + + VulkanUtilities::FenceWrapper GetVkFence() { return m_FencePool.GetFence(); } + + void AddPendingFence(VulkanUtilities::FenceWrapper&& vkFence, Uint64 FenceValue) + { + m_PendingFences.emplace_back(FenceValue, std::move(vkFence)); + } + + void Wait(Uint64 Value); + +private: + VulkanUtilities::VulkanFencePool m_FencePool; + std::deque> m_PendingFences; + volatile Uint64 m_LastCompletedFenceValue = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/FramebufferCache.h b/Graphics/GraphicsEngineVulkan/include/FramebufferCache.h deleted file mode 100644 index f2efe0f7..00000000 --- a/Graphics/GraphicsEngineVulkan/include/FramebufferCache.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::FramebufferCache class - -#include -#include -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; -class FramebufferCache -{ -public: - FramebufferCache(RenderDeviceVkImpl& DeviceVKImpl) : - m_DeviceVk{DeviceVKImpl} - {} - - // clang-format off - FramebufferCache (const FramebufferCache&) = delete; - FramebufferCache (FramebufferCache&&) = delete; - FramebufferCache& operator = (const FramebufferCache&) = delete; - FramebufferCache& operator = (FramebufferCache&&) = delete; - // clang-format on - - ~FramebufferCache(); - - // This structure is used as the key to find framebuffer - struct FramebufferCacheKey - { - // Default memeber initialization is intentionally omitted - VkRenderPass Pass; - Uint32 NumRenderTargets; - VkImageView DSV; - VkImageView RTVs[MAX_RENDER_TARGETS]; - Uint64 CommandQueueMask; - - bool operator==(const FramebufferCacheKey& rhs) const; - size_t GetHash() const; - - private: - mutable size_t Hash = 0; - }; - - VkFramebuffer GetFramebuffer(const FramebufferCacheKey& Key, uint32_t width, uint32_t height, uint32_t layers); - void OnDestroyImageView(VkImageView ImgView); - void OnDestroyRenderPass(VkRenderPass Pass); - -private: - RenderDeviceVkImpl& m_DeviceVk; - - struct FramebufferCacheKeyHash - { - std::size_t operator()(const FramebufferCacheKey& Key) const - { - return Key.GetHash(); - } - }; - - std::mutex m_Mutex; - std::unordered_map m_Cache; - - std::unordered_multimap m_ViewToKeyMap; - std::unordered_multimap m_RenderPassToKeyMap; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp b/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp new file mode 100644 index 00000000..406f7f6b --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/FramebufferCache.hpp @@ -0,0 +1,96 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::FramebufferCache class + +#include +#include +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; +class FramebufferCache +{ +public: + FramebufferCache(RenderDeviceVkImpl& DeviceVKImpl) : + m_DeviceVk{DeviceVKImpl} + {} + + // clang-format off + FramebufferCache (const FramebufferCache&) = delete; + FramebufferCache (FramebufferCache&&) = delete; + FramebufferCache& operator = (const FramebufferCache&) = delete; + FramebufferCache& operator = (FramebufferCache&&) = delete; + // clang-format on + + ~FramebufferCache(); + + // This structure is used as the key to find framebuffer + struct FramebufferCacheKey + { + // Default memeber initialization is intentionally omitted + VkRenderPass Pass; + Uint32 NumRenderTargets; + VkImageView DSV; + VkImageView RTVs[MAX_RENDER_TARGETS]; + Uint64 CommandQueueMask; + + bool operator==(const FramebufferCacheKey& rhs) const; + size_t GetHash() const; + + private: + mutable size_t Hash = 0; + }; + + VkFramebuffer GetFramebuffer(const FramebufferCacheKey& Key, uint32_t width, uint32_t height, uint32_t layers); + void OnDestroyImageView(VkImageView ImgView); + void OnDestroyRenderPass(VkRenderPass Pass); + +private: + RenderDeviceVkImpl& m_DeviceVk; + + struct FramebufferCacheKeyHash + { + std::size_t operator()(const FramebufferCacheKey& Key) const + { + return Key.GetHash(); + } + }; + + std::mutex m_Mutex; + std::unordered_map m_Cache; + + std::unordered_multimap m_ViewToKeyMap; + std::unordered_multimap m_RenderPassToKeyMap; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.h b/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.h deleted file mode 100644 index 55c7f4c2..00000000 --- a/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Implementation of mipmap generation routines - -#include -#include -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; -class TextureViewVkImpl; -class DeviceContextVkImpl; - -class GenerateMipsVkHelper -{ -public: - GenerateMipsVkHelper(RenderDeviceVkImpl& DeviceVkImpl); - - // clang-format off - GenerateMipsVkHelper (const GenerateMipsVkHelper&) = delete; - GenerateMipsVkHelper ( GenerateMipsVkHelper&&) = delete; - GenerateMipsVkHelper& operator = (const GenerateMipsVkHelper&) = delete; - GenerateMipsVkHelper& operator = ( GenerateMipsVkHelper&&) = delete; - // clang-format on - - void GenerateMips(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB); - void CreateSRB(IShaderResourceBinding** ppSRB); - void WarmUpCache(TEXTURE_FORMAT Fmt); - -private: - std::array, 4> CreatePSOs(TEXTURE_FORMAT Fmt); - std::array, 4>& FindPSOs(TEXTURE_FORMAT Fmt); - - VkImageLayout GenerateMipsCS(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB, VkImageSubresourceRange& SubresRange); - VkImageLayout GenerateMipsBlit(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB, VkImageSubresourceRange& SubresRange) const; - - RenderDeviceVkImpl& m_DeviceVkImpl; - - std::mutex m_PSOMutex; - std::unordered_map, 4>> m_PSOHash; - - static void GetGlImageFormat(const TextureFormatAttribs& FmtAttribs, std::array& GlFmt); - - RefCntAutoPtr m_ConstantsCB; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.hpp b/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.hpp new file mode 100644 index 00000000..845a70f3 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/GenerateMipsVkHelper.hpp @@ -0,0 +1,78 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Implementation of mipmap generation routines + +#include +#include +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; +class TextureViewVkImpl; +class DeviceContextVkImpl; + +class GenerateMipsVkHelper +{ +public: + GenerateMipsVkHelper(RenderDeviceVkImpl& DeviceVkImpl); + + // clang-format off + GenerateMipsVkHelper (const GenerateMipsVkHelper&) = delete; + GenerateMipsVkHelper ( GenerateMipsVkHelper&&) = delete; + GenerateMipsVkHelper& operator = (const GenerateMipsVkHelper&) = delete; + GenerateMipsVkHelper& operator = ( GenerateMipsVkHelper&&) = delete; + // clang-format on + + void GenerateMips(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB); + void CreateSRB(IShaderResourceBinding** ppSRB); + void WarmUpCache(TEXTURE_FORMAT Fmt); + +private: + std::array, 4> CreatePSOs(TEXTURE_FORMAT Fmt); + std::array, 4>& FindPSOs(TEXTURE_FORMAT Fmt); + + VkImageLayout GenerateMipsCS(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB, VkImageSubresourceRange& SubresRange); + VkImageLayout GenerateMipsBlit(TextureViewVkImpl& TexView, DeviceContextVkImpl& Ctx, IShaderResourceBinding& SRB, VkImageSubresourceRange& SubresRange) const; + + RenderDeviceVkImpl& m_DeviceVkImpl; + + std::mutex m_PSOMutex; + std::unordered_map, 4>> m_PSOHash; + + static void GetGlImageFormat(const TextureFormatAttribs& FmtAttribs, std::array& GlFmt); + + RefCntAutoPtr m_ConstantsCB; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.h b/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.h deleted file mode 100644 index d2c11471..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "DeviceObjectBase.hpp" -#include "RenderDeviceVkImpl.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" - -namespace Diligent -{ - -template -class ManagedVulkanObject : public DeviceObjectBase -{ -public: - using TDeviceObjectBase = DeviceObjectBase; - - ManagedVulkanObject(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - const DeviceObjectAttribs& ObjDesc, - VulkanObjectWrapperType&& ObjectWrapper, - bool bIsDeviceInternal = false) : - TDeviceObjectBase{pRefCounters, pDevice, ObjDesc, bIsDeviceInternal}, - m_VkObject{std::move(ObjectWrapper)} - { - } - - ~ManagedVulkanObject() - { - m_pDevice->SafeReleaseDeviceObject(std::move(m_VkObject), ~Uint64{0}); - } - - static void Create(RenderDeviceVkImpl* pDevice, - VulkanObjectWrapperType&& ObjectWrapper, - const char* Name, - ManagedVulkanObject** ppManagedObject) - { - DeviceObjectAttribs Desc; - Desc.Name = Name; - auto* pObj(NEW_RC_OBJ(GetRawAllocator(), "ManagedVulkanObject instance", ManagedVulkanObject)(pDevice, Desc, std::move(ObjectWrapper))); - pObj->QueryInterface(IID_DeviceObject, reinterpret_cast(ppManagedObject)); - } - - typename VulkanObjectWrapperType::VkObjectType Get() const - { - return m_VkObject; - } - -private: - VulkanObjectWrapperType m_VkObject; -}; - -using ManagedSemaphore = ManagedVulkanObject; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.hpp b/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.hpp new file mode 100644 index 00000000..658e41b1 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ManagedVulkanObject.hpp @@ -0,0 +1,80 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "DeviceObjectBase.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" + +namespace Diligent +{ + +template +class ManagedVulkanObject : public DeviceObjectBase +{ +public: + using TDeviceObjectBase = DeviceObjectBase; + + ManagedVulkanObject(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + const DeviceObjectAttribs& ObjDesc, + VulkanObjectWrapperType&& ObjectWrapper, + bool bIsDeviceInternal = false) : + TDeviceObjectBase{pRefCounters, pDevice, ObjDesc, bIsDeviceInternal}, + m_VkObject{std::move(ObjectWrapper)} + { + } + + ~ManagedVulkanObject() + { + m_pDevice->SafeReleaseDeviceObject(std::move(m_VkObject), ~Uint64{0}); + } + + static void Create(RenderDeviceVkImpl* pDevice, + VulkanObjectWrapperType&& ObjectWrapper, + const char* Name, + ManagedVulkanObject** ppManagedObject) + { + DeviceObjectAttribs Desc; + Desc.Name = Name; + auto* pObj(NEW_RC_OBJ(GetRawAllocator(), "ManagedVulkanObject instance", ManagedVulkanObject)(pDevice, Desc, std::move(ObjectWrapper))); + pObj->QueryInterface(IID_DeviceObject, reinterpret_cast(ppManagedObject)); + } + + typename VulkanObjectWrapperType::VkObjectType Get() const + { + return m_VkObject; + } + +private: + VulkanObjectWrapperType m_VkObject; +}; + +using ManagedSemaphore = ManagedVulkanObject; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h deleted file mode 100644 index acd60630..00000000 --- a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.h +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::PipelineLayout class -#include - -#include "ShaderBase.hpp" -#include "ShaderResourceLayoutVk.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; -class DeviceContextVkImpl; -class ShaderResourceCacheVk; - -/// Implementation of the Diligent::PipelineLayout class -class PipelineLayout -{ -public: - static VkDescriptorType GetVkDescriptorType(const SPIRVShaderResourceAttribs& Res); - - PipelineLayout(); - void Release(RenderDeviceVkImpl* pDeviceVkImpl, Uint64 CommandQueueMask); - void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice); - - VkPipelineLayout GetVkPipelineLayout() const { return m_LayoutMgr.GetVkPipelineLayout(); } - - std::array GetDescriptorSetSizes(Uint32& NumSets) const; - - void InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, - ShaderResourceCacheVk& ResourceCache, - IMemoryAllocator& CacheMemAllocator, - const char* DbgPipelineName) const; - - void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkImmutableSampler, - SHADER_TYPE ShaderType, - Uint32& DescriptorSet, - Uint32& Binding, - Uint32& OffsetInCache, - std::vector& SPIRV); - - Uint32 GetTotalDescriptors(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - VERIFY_EXPR(VarType >= 0 && VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES); - return m_LayoutMgr.GetDescriptorSet(VarType).TotalDescriptors; - } - - bool IsSameAs(const PipelineLayout& RS) const - { - return m_LayoutMgr == RS.m_LayoutMgr; - } - size_t GetHash() const - { - return m_LayoutMgr.GetHash(); - } - - VkDescriptorSetLayout GetDynamicDescriptorSetVkLayout() const - { - return m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC).VkLayout; - } - - struct DescriptorSetBindInfo - { - std::vector vkSets; - std::vector DynamicOffsets; - const ShaderResourceCacheVk* pResourceCache = nullptr; - VkPipelineBindPoint BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; - Uint32 SetCout = 0; - Uint32 DynamicOffsetCount = 0; - bool DynamicBuffersPresent = false; - bool DynamicDescriptorsBound = false; -#ifdef _DEBUG - const PipelineLayout* pDbgPipelineLayout = nullptr; -#endif - DescriptorSetBindInfo() : - // clang-format off - vkSets (2), - DynamicOffsets(64) - // clang-format on - { - } - - void Reset() - { - pResourceCache = nullptr; - BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; - SetCout = 0; - DynamicOffsetCount = 0; - DynamicBuffersPresent = false; - DynamicDescriptorsBound = false; - -#ifdef _DEBUG - // In release mode, do not clear vectors as this causes unnecessary work - vkSets.clear(); - DynamicOffsets.clear(); - - pDbgPipelineLayout = nullptr; -#endif - } - }; - - // Prepares Vulkan descriptor sets for binding. Actual binding - // may not be possible until draw command time because dynamic offsets are - // set by the same Vulkan command. If there are no dynamic descriptors, this - // function also binds descriptor sets rightaway. - void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, - bool IsCompute, - const ShaderResourceCacheVk& ResourceCache, - DescriptorSetBindInfo& BindInfo, - VkDescriptorSet VkDynamicDescrSet) const; - - // Computes dynamic offsets and binds descriptor sets - __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, - Uint32 CtxId, - DeviceContextVkImpl* pCtxVkImpl, - DescriptorSetBindInfo& BindInfo) const; - -private: - class DescriptorSetLayoutManager - { - public: - struct DescriptorSetLayout - { - DescriptorSetLayout() noexcept {} - // clang-format off - DescriptorSetLayout (DescriptorSetLayout&&) = default; - DescriptorSetLayout (const DescriptorSetLayout&) = delete; - DescriptorSetLayout& operator = (const DescriptorSetLayout&) = delete; - DescriptorSetLayout& operator = (DescriptorSetLayout&&) = delete; - // clang-format on - - uint32_t TotalDescriptors = 0; - int8_t SetIndex = -1; - uint8_t NumDynamicDescriptors = 0; // Total number of uniform and storage buffers, counting all array elements - uint16_t NumLayoutBindings = 0; - VkDescriptorSetLayoutBinding* pBindings = nullptr; - VulkanUtilities::DescriptorSetLayoutWrapper VkLayout; - - ~DescriptorSetLayout(); - void AddBinding(const VkDescriptorSetLayoutBinding& Binding, IMemoryAllocator& MemAllocator); - void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, IMemoryAllocator& MemAllocator, VkDescriptorSetLayoutBinding* pNewBindings); - void Release(RenderDeviceVkImpl* pRenderDeviceVk, IMemoryAllocator& MemAllocator, Uint64 CommandQueueMask); - - bool operator==(const DescriptorSetLayout& rhs) const; - bool operator!=(const DescriptorSetLayout& rhs) const { return !(*this == rhs); } - size_t GetHash() const; - - private: - void ReserveMemory(Uint32 NumBindings, IMemoryAllocator& MemAllocator); - static size_t GetMemorySize(Uint32 NumBindings); - }; - - DescriptorSetLayoutManager(IMemoryAllocator& MemAllocator); - ~DescriptorSetLayoutManager(); - - // clang-format off - DescriptorSetLayoutManager (const DescriptorSetLayoutManager&) = delete; - DescriptorSetLayoutManager& operator= (const DescriptorSetLayoutManager&) = delete; - DescriptorSetLayoutManager (DescriptorSetLayoutManager&&) = delete; - DescriptorSetLayoutManager& operator= (DescriptorSetLayoutManager&&) = delete; - // clang-format on - - void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice); - void Release(RenderDeviceVkImpl* pRenderDeviceVk, Uint64 CommandQueueMask); - - DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType) { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } - const DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType) const { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } - - bool operator==(const DescriptorSetLayoutManager& rhs) const; - bool operator!=(const DescriptorSetLayoutManager& rhs) const { return !(*this == rhs); } - size_t GetHash() const; - VkPipelineLayout GetVkPipelineLayout() const { return m_VkPipelineLayout; } - - void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, - SHADER_RESOURCE_VARIABLE_TYPE VariableType, - VkSampler vkImmutableSampler, - SHADER_TYPE ShaderType, - Uint32& DescriptorSet, - Uint32& Binding, - Uint32& OffsetInCache); - - private: - IMemoryAllocator& m_MemAllocator; - VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout; - std::array m_DescriptorSetLayouts; - std::vector> m_LayoutBindings; - uint8_t m_ActiveSets = 0; - }; - - IMemoryAllocator& m_MemAllocator; - 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; - - // Note that there is one global dynamic buffer from which all dynamic resources are suballocated in Vulkan back-end, - // and this buffer is not resizable, so the buffer handle can never change. - - // 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()); - - BindInfo.DynamicDescriptorsBound = true; -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp new file mode 100644 index 00000000..a0ac52c8 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/PipelineLayout.hpp @@ -0,0 +1,272 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::PipelineLayout class +#include + +#include "ShaderBase.hpp" +#include "ShaderResourceLayoutVk.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; +class DeviceContextVkImpl; +class ShaderResourceCacheVk; + +/// Implementation of the Diligent::PipelineLayout class +class PipelineLayout +{ +public: + static VkDescriptorType GetVkDescriptorType(const SPIRVShaderResourceAttribs& Res); + + PipelineLayout(); + void Release(RenderDeviceVkImpl* pDeviceVkImpl, Uint64 CommandQueueMask); + void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice); + + VkPipelineLayout GetVkPipelineLayout() const { return m_LayoutMgr.GetVkPipelineLayout(); } + + std::array GetDescriptorSetSizes(Uint32& NumSets) const; + + void InitResourceCache(RenderDeviceVkImpl* pDeviceVkImpl, + ShaderResourceCacheVk& ResourceCache, + IMemoryAllocator& CacheMemAllocator, + const char* DbgPipelineName) const; + + void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + VkSampler vkImmutableSampler, + SHADER_TYPE ShaderType, + Uint32& DescriptorSet, + Uint32& Binding, + Uint32& OffsetInCache, + std::vector& SPIRV); + + Uint32 GetTotalDescriptors(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + VERIFY_EXPR(VarType >= 0 && VarType < SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES); + return m_LayoutMgr.GetDescriptorSet(VarType).TotalDescriptors; + } + + bool IsSameAs(const PipelineLayout& RS) const + { + return m_LayoutMgr == RS.m_LayoutMgr; + } + size_t GetHash() const + { + return m_LayoutMgr.GetHash(); + } + + VkDescriptorSetLayout GetDynamicDescriptorSetVkLayout() const + { + return m_LayoutMgr.GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC).VkLayout; + } + + struct DescriptorSetBindInfo + { + std::vector vkSets; + std::vector DynamicOffsets; + const ShaderResourceCacheVk* pResourceCache = nullptr; + VkPipelineBindPoint BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; + Uint32 SetCout = 0; + Uint32 DynamicOffsetCount = 0; + bool DynamicBuffersPresent = false; + bool DynamicDescriptorsBound = false; +#ifdef _DEBUG + const PipelineLayout* pDbgPipelineLayout = nullptr; +#endif + DescriptorSetBindInfo() : + // clang-format off + vkSets (2), + DynamicOffsets(64) + // clang-format on + { + } + + void Reset() + { + pResourceCache = nullptr; + BindPoint = VK_PIPELINE_BIND_POINT_MAX_ENUM; + SetCout = 0; + DynamicOffsetCount = 0; + DynamicBuffersPresent = false; + DynamicDescriptorsBound = false; + +#ifdef _DEBUG + // In release mode, do not clear vectors as this causes unnecessary work + vkSets.clear(); + DynamicOffsets.clear(); + + pDbgPipelineLayout = nullptr; +#endif + } + }; + + // Prepares Vulkan descriptor sets for binding. Actual binding + // may not be possible until draw command time because dynamic offsets are + // set by the same Vulkan command. If there are no dynamic descriptors, this + // function also binds descriptor sets rightaway. + void PrepareDescriptorSets(DeviceContextVkImpl* pCtxVkImpl, + bool IsCompute, + const ShaderResourceCacheVk& ResourceCache, + DescriptorSetBindInfo& BindInfo, + VkDescriptorSet VkDynamicDescrSet) const; + + // Computes dynamic offsets and binds descriptor sets + __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, + Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + DescriptorSetBindInfo& BindInfo) const; + +private: + class DescriptorSetLayoutManager + { + public: + struct DescriptorSetLayout + { + DescriptorSetLayout() noexcept {} + // clang-format off + DescriptorSetLayout (DescriptorSetLayout&&) = default; + DescriptorSetLayout (const DescriptorSetLayout&) = delete; + DescriptorSetLayout& operator = (const DescriptorSetLayout&) = delete; + DescriptorSetLayout& operator = (DescriptorSetLayout&&) = delete; + // clang-format on + + uint32_t TotalDescriptors = 0; + int8_t SetIndex = -1; + uint8_t NumDynamicDescriptors = 0; // Total number of uniform and storage buffers, counting all array elements + uint16_t NumLayoutBindings = 0; + VkDescriptorSetLayoutBinding* pBindings = nullptr; + VulkanUtilities::DescriptorSetLayoutWrapper VkLayout; + + ~DescriptorSetLayout(); + void AddBinding(const VkDescriptorSetLayoutBinding& Binding, IMemoryAllocator& MemAllocator); + void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice, IMemoryAllocator& MemAllocator, VkDescriptorSetLayoutBinding* pNewBindings); + void Release(RenderDeviceVkImpl* pRenderDeviceVk, IMemoryAllocator& MemAllocator, Uint64 CommandQueueMask); + + bool operator==(const DescriptorSetLayout& rhs) const; + bool operator!=(const DescriptorSetLayout& rhs) const { return !(*this == rhs); } + size_t GetHash() const; + + private: + void ReserveMemory(Uint32 NumBindings, IMemoryAllocator& MemAllocator); + static size_t GetMemorySize(Uint32 NumBindings); + }; + + DescriptorSetLayoutManager(IMemoryAllocator& MemAllocator); + ~DescriptorSetLayoutManager(); + + // clang-format off + DescriptorSetLayoutManager (const DescriptorSetLayoutManager&) = delete; + DescriptorSetLayoutManager& operator= (const DescriptorSetLayoutManager&) = delete; + DescriptorSetLayoutManager (DescriptorSetLayoutManager&&) = delete; + DescriptorSetLayoutManager& operator= (DescriptorSetLayoutManager&&) = delete; + // clang-format on + + void Finalize(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice); + void Release(RenderDeviceVkImpl* pRenderDeviceVk, Uint64 CommandQueueMask); + + DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType) { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } + const DescriptorSetLayout& GetDescriptorSet(SHADER_RESOURCE_VARIABLE_TYPE VarType) const { return m_DescriptorSetLayouts[VarType == SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC ? 1 : 0]; } + + bool operator==(const DescriptorSetLayoutManager& rhs) const; + bool operator!=(const DescriptorSetLayoutManager& rhs) const { return !(*this == rhs); } + size_t GetHash() const; + VkPipelineLayout GetVkPipelineLayout() const { return m_VkPipelineLayout; } + + void AllocateResourceSlot(const SPIRVShaderResourceAttribs& ResAttribs, + SHADER_RESOURCE_VARIABLE_TYPE VariableType, + VkSampler vkImmutableSampler, + SHADER_TYPE ShaderType, + Uint32& DescriptorSet, + Uint32& Binding, + Uint32& OffsetInCache); + + private: + IMemoryAllocator& m_MemAllocator; + VulkanUtilities::PipelineLayoutWrapper m_VkPipelineLayout; + std::array m_DescriptorSetLayouts; + std::vector> m_LayoutBindings; + uint8_t m_ActiveSets = 0; + }; + + IMemoryAllocator& m_MemAllocator; + 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; + + // Note that there is one global dynamic buffer from which all dynamic resources are suballocated in Vulkan back-end, + // and this buffer is not resizable, so the buffer handle can never change. + + // 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()); + + BindInfo.DynamicDescriptorsBound = true; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h deleted file mode 100644 index d41e7ce5..00000000 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::PipelineStateVkImpl class - -#include - -#include "RenderDeviceVk.h" -#include "PipelineStateVk.h" -#include "PipelineStateBase.hpp" -#include "PipelineLayout.h" -#include "ShaderResourceLayoutVk.h" -#include "ShaderVariableVk.h" -#include "FixedBlockMemoryAllocator.h" -#include "SRBMemoryAllocator.hpp" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" -#include "PipelineLayout.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; -class ShaderVariableManagerVk; - -/// Pipeline state object implementation in Vulkan backend. -class PipelineStateVkImpl final : public PipelineStateBase -{ -public: - using TPipelineStateBase = PipelineStateBase; - - PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc); - ~PipelineStateVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IPipelineState::CreateShaderResourceBinding() in Vulkan backend. - virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final; - - /// Implementation of IPipelineState::IsCompatibleWith() in Vulkan backend. - virtual bool IsCompatibleWith(const IPipelineState* pPSO) const override final; - - /// Implementation of IPipelineStateVk::GetVkRenderPass(). - virtual VkRenderPass GetVkRenderPass() const override final { return m_RenderPass; } - - /// Implementation of IPipelineStateVk::GetVkPipeline(). - virtual VkPipeline GetVkPipeline() const override final { return m_Pipeline; } - - /// Implementation of IPipelineState::BindStaticResources() in Vulkan backend. - virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final; - - /// Implementation of IPipelineState::GetStaticVariableCount() in Vulkan backend. - virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; - - /// Implementation of IPipelineState::GetStaticVariableByName() in Vulkan backend. - virtual IShaderResourceVariable* GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final; - - /// Implementation of IPipelineState::GetStaticVariableByIndex() in Vulkan backend. - virtual IShaderResourceVariable* GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; - - void CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, - DeviceContextVkImpl* pCtxVkImpl, - bool CommitResources, - RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, - PipelineLayout::DescriptorSetBindInfo* pDescrSetBindInfo) const; - - __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, - Uint32 CtxId, - DeviceContextVkImpl* pCtxVkImpl, - PipelineLayout::DescriptorSetBindInfo& BindInfo) - { - m_PipelineLayout.BindDescriptorSetsWithDynamicOffsets(CmdBuffer, CtxId, pCtxVkImpl, BindInfo); - } - - const PipelineLayout& GetPipelineLayout() const { return m_PipelineLayout; } - - const ShaderResourceLayoutVk& GetShaderResLayout(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_ShaderResourceLayouts[ShaderInd]; - } - - SRBMemoryAllocator& GetSRBMemoryAllocator() - { - return m_SRBMemAllocator; - } - - static VkRenderPassCreateInfo GetRenderPassCreateInfo(Uint32 NumRenderTargets, - const TEXTURE_FORMAT RTVFormats[], - TEXTURE_FORMAT DSVFormat, - Uint32 SampleCount, - std::array& Attachments, - std::array& AttachmentReferences, - VkSubpassDescription& SubpassDesc); - - - void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const; - -private: - const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_ShaderResourceLayouts[m_NumShaders + ShaderInd]; - } - - const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_StaticResCaches[ShaderInd]; - } - - ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const - { - VERIFY_EXPR(ShaderInd < m_NumShaders); - return m_StaticVarsMgrs[ShaderInd]; - } - - ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; - ShaderResourceCacheVk* m_StaticResCaches = nullptr; - ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; - - // SRB memory allocator must be declared before m_pDefaultShaderResBinding - SRBMemoryAllocator m_SRBMemAllocator; - - std::array m_ShaderModules; - - VkRenderPass m_RenderPass = VK_NULL_HANDLE; // Render passes are managed by the render device - VulkanUtilities::PipelineWrapper m_Pipeline; - PipelineLayout m_PipelineLayout; - - Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; - bool m_HasStaticResources = false; - bool m_HasNonStaticResources = false; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp new file mode 100644 index 00000000..b3cd3d0a --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -0,0 +1,164 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::PipelineStateVkImpl class + +#include + +#include "RenderDeviceVk.h" +#include "PipelineStateVk.h" +#include "PipelineStateBase.hpp" +#include "PipelineLayout.hpp" +#include "ShaderResourceLayoutVk.hpp" +#include "ShaderVariableVk.hpp" +#include "FixedBlockMemoryAllocator.h" +#include "SRBMemoryAllocator.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" +#include "PipelineLayout.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; +class ShaderVariableManagerVk; + +/// Pipeline state object implementation in Vulkan backend. +class PipelineStateVkImpl final : public PipelineStateBase +{ +public: + using TPipelineStateBase = PipelineStateBase; + + PipelineStateVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pDeviceVk, const PipelineStateDesc& PipelineDesc); + ~PipelineStateVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IPipelineState::CreateShaderResourceBinding() in Vulkan backend. + virtual void CreateShaderResourceBinding(IShaderResourceBinding** ppShaderResourceBinding, bool InitStaticResources) override final; + + /// Implementation of IPipelineState::IsCompatibleWith() in Vulkan backend. + virtual bool IsCompatibleWith(const IPipelineState* pPSO) const override final; + + /// Implementation of IPipelineStateVk::GetVkRenderPass(). + virtual VkRenderPass GetVkRenderPass() const override final { return m_RenderPass; } + + /// Implementation of IPipelineStateVk::GetVkPipeline(). + virtual VkPipeline GetVkPipeline() const override final { return m_Pipeline; } + + /// Implementation of IPipelineState::BindStaticResources() in Vulkan backend. + virtual void BindStaticResources(Uint32 ShaderFlags, IResourceMapping* pResourceMapping, Uint32 Flags) override final; + + /// Implementation of IPipelineState::GetStaticVariableCount() in Vulkan backend. + virtual Uint32 GetStaticVariableCount(SHADER_TYPE ShaderType) const override final; + + /// Implementation of IPipelineState::GetStaticVariableByName() in Vulkan backend. + virtual IShaderResourceVariable* GetStaticVariableByName(SHADER_TYPE ShaderType, const Char* Name) override final; + + /// Implementation of IPipelineState::GetStaticVariableByIndex() in Vulkan backend. + virtual IShaderResourceVariable* GetStaticVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; + + void CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, + DeviceContextVkImpl* pCtxVkImpl, + bool CommitResources, + RESOURCE_STATE_TRANSITION_MODE StateTransitionMode, + PipelineLayout::DescriptorSetBindInfo* pDescrSetBindInfo) const; + + __forceinline void BindDescriptorSetsWithDynamicOffsets(VulkanUtilities::VulkanCommandBuffer& CmdBuffer, + Uint32 CtxId, + DeviceContextVkImpl* pCtxVkImpl, + PipelineLayout::DescriptorSetBindInfo& BindInfo) + { + m_PipelineLayout.BindDescriptorSetsWithDynamicOffsets(CmdBuffer, CtxId, pCtxVkImpl, BindInfo); + } + + const PipelineLayout& GetPipelineLayout() const { return m_PipelineLayout; } + + const ShaderResourceLayoutVk& GetShaderResLayout(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_ShaderResourceLayouts[ShaderInd]; + } + + SRBMemoryAllocator& GetSRBMemoryAllocator() + { + return m_SRBMemAllocator; + } + + static VkRenderPassCreateInfo GetRenderPassCreateInfo(Uint32 NumRenderTargets, + const TEXTURE_FORMAT RTVFormats[], + TEXTURE_FORMAT DSVFormat, + Uint32 SampleCount, + std::array& Attachments, + std::array& AttachmentReferences, + VkSubpassDescription& SubpassDesc); + + + void InitializeStaticSRBResources(ShaderResourceCacheVk& ResourceCache) const; + +private: + const ShaderResourceLayoutVk& GetStaticShaderResLayout(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_ShaderResourceLayouts[m_NumShaders + ShaderInd]; + } + + const ShaderResourceCacheVk& GetStaticResCache(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticResCaches[ShaderInd]; + } + + ShaderVariableManagerVk& GetStaticVarMgr(Uint32 ShaderInd) const + { + VERIFY_EXPR(ShaderInd < m_NumShaders); + return m_StaticVarsMgrs[ShaderInd]; + } + + ShaderResourceLayoutVk* m_ShaderResourceLayouts = nullptr; + ShaderResourceCacheVk* m_StaticResCaches = nullptr; + ShaderVariableManagerVk* m_StaticVarsMgrs = nullptr; + + // SRB memory allocator must be declared before m_pDefaultShaderResBinding + SRBMemoryAllocator m_SRBMemAllocator; + + std::array m_ShaderModules; + + VkRenderPass m_RenderPass = VK_NULL_HANDLE; // Render passes are managed by the render device + VulkanUtilities::PipelineWrapper m_Pipeline; + PipelineLayout m_PipelineLayout; + + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; + bool m_HasStaticResources = false; + bool m_HasNonStaticResources = false; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.h b/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.h deleted file mode 100644 index a435527d..00000000 --- a/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include -#include - -#include "Query.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanPhysicalDevice.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; - -class QueryManagerVk -{ -public: - QueryManagerVk(RenderDeviceVkImpl* RenderDeviceVk, - const Uint32 QueryHeapSizes[]); - ~QueryManagerVk(); - - // clang-format off - QueryManagerVk (const QueryManagerVk&) = delete; - QueryManagerVk ( QueryManagerVk&&) = delete; - QueryManagerVk& operator = (const QueryManagerVk&) = delete; - QueryManagerVk& operator = ( QueryManagerVk&&) = delete; - // clang-format on - - static constexpr Uint32 InvalidIndex = static_cast(-1); - - Uint32 AllocateQuery(QUERY_TYPE Type); - void DiscardQuery(QUERY_TYPE Type, Uint32 Index); - - VkQueryPool GetQueryPool(QUERY_TYPE Type) - { - return m_Heaps[Type].vkQueryPool; - } - - Uint64 GetCounterFrequency() const - { - return m_CounterFrequency; - } - - Uint32 ResetStaleQueries(VulkanUtilities::VulkanCommandBuffer& CmdBuff); - -private: - struct QueryHeapInfo - { - VulkanUtilities::QueryPoolWrapper vkQueryPool; - - std::deque AvailableQueries; - std::vector StaleQueries; - - Uint32 PoolSize = 0; - Uint32 MaxAllocatedQueries = 0; - }; - - std::mutex m_HeapMutex; - std::array m_Heaps; - - Uint64 m_CounterFrequency = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.hpp b/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.hpp new file mode 100644 index 00000000..6c60beaa --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/QueryManagerVk.hpp @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include +#include + +#include "Query.h" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanPhysicalDevice.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; + +class QueryManagerVk +{ +public: + QueryManagerVk(RenderDeviceVkImpl* RenderDeviceVk, + const Uint32 QueryHeapSizes[]); + ~QueryManagerVk(); + + // clang-format off + QueryManagerVk (const QueryManagerVk&) = delete; + QueryManagerVk ( QueryManagerVk&&) = delete; + QueryManagerVk& operator = (const QueryManagerVk&) = delete; + QueryManagerVk& operator = ( QueryManagerVk&&) = delete; + // clang-format on + + static constexpr Uint32 InvalidIndex = static_cast(-1); + + Uint32 AllocateQuery(QUERY_TYPE Type); + void DiscardQuery(QUERY_TYPE Type, Uint32 Index); + + VkQueryPool GetQueryPool(QUERY_TYPE Type) + { + return m_Heaps[Type].vkQueryPool; + } + + Uint64 GetCounterFrequency() const + { + return m_CounterFrequency; + } + + Uint32 ResetStaleQueries(VulkanUtilities::VulkanCommandBuffer& CmdBuff); + +private: + struct QueryHeapInfo + { + VulkanUtilities::QueryPoolWrapper vkQueryPool; + + std::deque AvailableQueries; + std::vector StaleQueries; + + Uint32 PoolSize = 0; + Uint32 MaxAllocatedQueries = 0; + }; + + std::mutex m_HeapMutex; + std::array m_Heaps; + + Uint64 m_CounterFrequency = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.h b/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.h deleted file mode 100644 index c326ce4f..00000000 --- a/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::QueryVkImpl class - -#include "QueryVk.h" -#include "QueryBase.hpp" -#include "RenderDeviceVkImpl.h" -#include "QueryManagerVk.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Query implementation in Vulkan backend. -class QueryVkImpl final : public QueryBase -{ -public: - using TQueryBase = QueryBase; - - QueryVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pRendeDeviceVkImpl, - const QueryDesc& Desc, - bool IsDeviceInternal = false); - ~QueryVkImpl(); - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryVk, TQueryBase); - - /// Implementation of IQuery::GetData(). - virtual bool GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) override final; - - /// Implementation of IQuery::Invalidate(). - virtual void Invalidate() override final; - - Uint32 GetQueryPoolIndex() const - { - return m_QueryPoolIndex; - } - - bool OnEndQuery(IDeviceContext* pContext); - bool OnBeginQuery(IDeviceContext* pContext); - -private: - bool AllocateQuery(); - void DiscardQuery(); - - Uint32 m_QueryPoolIndex = QueryManagerVk::InvalidIndex; - Uint64 m_QueryEndFenceValue = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.hpp new file mode 100644 index 00000000..a17e3fde --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/QueryVkImpl.hpp @@ -0,0 +1,79 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::QueryVkImpl class + +#include "QueryVk.h" +#include "QueryBase.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "QueryManagerVk.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Query implementation in Vulkan backend. +class QueryVkImpl final : public QueryBase +{ +public: + using TQueryBase = QueryBase; + + QueryVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pRendeDeviceVkImpl, + const QueryDesc& Desc, + bool IsDeviceInternal = false); + ~QueryVkImpl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_QueryVk, TQueryBase); + + /// Implementation of IQuery::GetData(). + virtual bool GetData(void* pData, Uint32 DataSize, bool AutoInvalidate) override final; + + /// Implementation of IQuery::Invalidate(). + virtual void Invalidate() override final; + + Uint32 GetQueryPoolIndex() const + { + return m_QueryPoolIndex; + } + + bool OnEndQuery(IDeviceContext* pContext); + bool OnBeginQuery(IDeviceContext* pContext); + +private: + bool AllocateQuery(); + void DiscardQuery(); + + Uint32 m_QueryPoolIndex = QueryManagerVk::InvalidIndex; + Uint64 m_QueryEndFenceValue = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h deleted file mode 100644 index bd1451f6..00000000 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::RenderDeviceVkImpl class -#include - -#include "RenderDeviceVk.h" -#include "RenderDeviceBase.hpp" -#include "RenderDeviceNextGenBase.hpp" -#include "DescriptorPoolManager.h" -#include "VulkanDynamicHeap.h" -#include "Atomics.h" -#include "CommandQueueVk.h" -#include "VulkanUtilities/VulkanInstance.h" -#include "VulkanUtilities/VulkanPhysicalDevice.h" -#include "VulkanUtilities/VulkanCommandBufferPool.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "VulkanUtilities/VulkanMemoryManager.h" -#include "VulkanUploadHeap.h" -#include "FramebufferCache.h" -#include "RenderPassCache.h" -#include "CommandPoolManager.h" - -namespace Diligent -{ - -/// Render device implementation in Vulkan backend. -class RenderDeviceVkImpl final : public RenderDeviceNextGenBase, ICommandQueueVk> -{ -public: - using TRenderDeviceBase = RenderDeviceNextGenBase, ICommandQueueVk>; - - RenderDeviceVkImpl(IReferenceCounters* pRefCounters, - IMemoryAllocator& RawMemAllocator, - IEngineFactory* pEngineFactory, - const EngineVkCreateInfo& EngineCI, - size_t CommandQueueCount, - ICommandQueueVk** pCmdQueues, - std::shared_ptr Instance, - std::unique_ptr PhysicalDevice, - std::shared_ptr LogicalDevice); - ~RenderDeviceVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IRenderDevice::CreatePipelineState() in Vulkan backend. - virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) override final; - - /// Implementation of IRenderDevice::CreateBuffer() in Vulkan backend. - virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer) override final; - - /// Implementation of IRenderDevice::CreateShader() in Vulkan backend. - virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) override final; - - /// Implementation of IRenderDevice::CreateTexture() in Vulkan backend. - virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture) override final; - - void CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, RESOURCE_STATE InitialState, class TextureVkImpl** ppTexture); - - /// Implementation of IRenderDevice::CreateSampler() in Vulkan backend. - virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) override final; - - /// Implementation of IRenderDevice::CreateFence() in Vulkan backend. - virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; - - /// Implementation of IRenderDevice::CreateQuery() in Vulkan backend. - virtual void CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; - - /// Implementation of IRenderDeviceVk::GetVkDevice(). - virtual VkDevice GetVkDevice() override final { return m_LogicalVkDevice->GetVkDevice(); } - - /// Implementation of IRenderDeviceVk::GetVkPhysicalDevice(). - virtual VkPhysicalDevice GetVkPhysicalDevice() override final { return m_PhysicalDevice->GetVkDeviceHandle(); } - - /// Implementation of IRenderDeviceVk::GetVkInstance(). - virtual VkInstance GetVkInstance() override final { return m_VulkanInstance->GetVkInstance(); } - - /// Implementation of IRenderDeviceVk::CreateTextureFromVulkanImage(). - virtual void CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture) override final; - - /// Implementation of IRenderDeviceVk::CreateBufferFromVulkanResource(). - virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; - - /// Implementation of IRenderDevice::IdleGPU() in Vulkan backend. - virtual void IdleGPU() override final; - - // pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context - // The method returns fence value associated with the submitted command buffer - Uint64 ExecuteCommandBuffer(Uint32 QueueIndex, const VkSubmitInfo& SubmitInfo, class DeviceContextVkImpl* pImmediateCtx, std::vector>>* pSignalFences); - - void AllocateTransientCmdPool(VulkanUtilities::CommandPoolWrapper& CmdPool, VkCommandBuffer& vkCmdBuff, const Char* DebugPoolName = nullptr); - void ExecuteAndDisposeTransientCmdBuff(Uint32 QueueIndex, VkCommandBuffer vkCmdBuff, VulkanUtilities::CommandPoolWrapper&& CmdPool); - - /// Implementation of IRenderDevice::ReleaseStaleResources() in Vulkan backend. - virtual void ReleaseStaleResources(bool ForceRelease = false) override final; - - DescriptorSetAllocation AllocateDescriptorSet(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout, const char* DebugName = "") - { - return m_DescriptorSetAllocator.Allocate(CommandQueueMask, SetLayout, DebugName); - } - DescriptorPoolManager& GetDynamicDescriptorPool() { return m_DynamicDescriptorPool; } - - std::shared_ptr GetVulkanInstance() const { return m_VulkanInstance; } - - const VulkanUtilities::VulkanPhysicalDevice& GetPhysicalDevice() const { return *m_PhysicalDevice; } - const VulkanUtilities::VulkanLogicalDevice& GetLogicalDevice() { return *m_LogicalVkDevice; } - - FramebufferCache& GetFramebufferCache() { return m_FramebufferCache; } - RenderPassCache& GetRenderPassCache() { return m_RenderPassCache; } - - VulkanUtilities::VulkanMemoryAllocation AllocateMemory(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProperties) - { - return m_MemoryMgr.Allocate(MemReqs, MemoryProperties); - } - VulkanUtilities::VulkanMemoryManager& GetGlobalMemoryManager() { return m_MemoryMgr; } - - VulkanDynamicMemoryManager& GetDynamicMemoryManager() { return m_DynamicMemoryManager; } - - void FlushStaleResources(Uint32 CmdQueueIndex); - -private: - virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; - - // Submits command buffer for execution to the command queue - // Returns the submitted command buffer number and the fence value - // Parameters: - // * SubmittedCmdBuffNumber - submitted command buffer number - // * SubmittedFenceValue - fence value associated with the submitted command buffer - void SubmitCommandBuffer(Uint32 QueueIndex, const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue, std::vector>>* pFences); - - std::shared_ptr m_VulkanInstance; - std::unique_ptr m_PhysicalDevice; - std::shared_ptr m_LogicalVkDevice; - - EngineVkCreateInfo m_EngineAttribs; - - FramebufferCache m_FramebufferCache; - RenderPassCache m_RenderPassCache; - DescriptorSetAllocator m_DescriptorSetAllocator; - DescriptorPoolManager m_DynamicDescriptorPool; - - // These one-time command pools are used by buffer and texture constructors to - // issue copy commands. Vulkan requires that every command pool is used by one thread - // at a time, so every constructor must allocate command buffer from its own pool. - CommandPoolManager m_TransientCmdPoolMgr; - - VulkanUtilities::VulkanMemoryManager m_MemoryMgr; - - VulkanDynamicMemoryManager m_DynamicMemoryManager; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp new file mode 100644 index 00000000..3a1c6330 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -0,0 +1,180 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderDeviceVkImpl class +#include + +#include "RenderDeviceVk.h" +#include "RenderDeviceBase.hpp" +#include "RenderDeviceNextGenBase.hpp" +#include "DescriptorPoolManager.hpp" +#include "VulkanDynamicHeap.hpp" +#include "Atomics.h" +#include "CommandQueueVk.h" +#include "VulkanUtilities/VulkanInstance.hpp" +#include "VulkanUtilities/VulkanPhysicalDevice.hpp" +#include "VulkanUtilities/VulkanCommandBufferPool.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "VulkanUtilities/VulkanMemoryManager.hpp" +#include "VulkanUploadHeap.hpp" +#include "FramebufferCache.hpp" +#include "RenderPassCache.hpp" +#include "CommandPoolManager.hpp" + +namespace Diligent +{ + +/// Render device implementation in Vulkan backend. +class RenderDeviceVkImpl final : public RenderDeviceNextGenBase, ICommandQueueVk> +{ +public: + using TRenderDeviceBase = RenderDeviceNextGenBase, ICommandQueueVk>; + + RenderDeviceVkImpl(IReferenceCounters* pRefCounters, + IMemoryAllocator& RawMemAllocator, + IEngineFactory* pEngineFactory, + const EngineVkCreateInfo& EngineCI, + size_t CommandQueueCount, + ICommandQueueVk** pCmdQueues, + std::shared_ptr Instance, + std::unique_ptr PhysicalDevice, + std::shared_ptr LogicalDevice); + ~RenderDeviceVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IRenderDevice::CreatePipelineState() in Vulkan backend. + virtual void CreatePipelineState(const PipelineStateDesc& PipelineDesc, IPipelineState** ppPipelineState) override final; + + /// Implementation of IRenderDevice::CreateBuffer() in Vulkan backend. + virtual void CreateBuffer(const BufferDesc& BuffDesc, const BufferData* pBuffData, IBuffer** ppBuffer) override final; + + /// Implementation of IRenderDevice::CreateShader() in Vulkan backend. + virtual void CreateShader(const ShaderCreateInfo& ShaderCreateInfo, IShader** ppShader) override final; + + /// Implementation of IRenderDevice::CreateTexture() in Vulkan backend. + virtual void CreateTexture(const TextureDesc& TexDesc, const TextureData* pData, ITexture** ppTexture) override final; + + void CreateTexture(const TextureDesc& TexDesc, VkImage vkImgHandle, RESOURCE_STATE InitialState, class TextureVkImpl** ppTexture); + + /// Implementation of IRenderDevice::CreateSampler() in Vulkan backend. + virtual void CreateSampler(const SamplerDesc& SamplerDesc, ISampler** ppSampler) override final; + + /// Implementation of IRenderDevice::CreateFence() in Vulkan backend. + virtual void CreateFence(const FenceDesc& Desc, IFence** ppFence) override final; + + /// Implementation of IRenderDevice::CreateQuery() in Vulkan backend. + virtual void CreateQuery(const QueryDesc& Desc, IQuery** ppQuery) override final; + + /// Implementation of IRenderDeviceVk::GetVkDevice(). + virtual VkDevice GetVkDevice() override final { return m_LogicalVkDevice->GetVkDevice(); } + + /// Implementation of IRenderDeviceVk::GetVkPhysicalDevice(). + virtual VkPhysicalDevice GetVkPhysicalDevice() override final { return m_PhysicalDevice->GetVkDeviceHandle(); } + + /// Implementation of IRenderDeviceVk::GetVkInstance(). + virtual VkInstance GetVkInstance() override final { return m_VulkanInstance->GetVkInstance(); } + + /// Implementation of IRenderDeviceVk::CreateTextureFromVulkanImage(). + virtual void CreateTextureFromVulkanImage(VkImage vkImage, const TextureDesc& TexDesc, RESOURCE_STATE InitialState, ITexture** ppTexture) override final; + + /// Implementation of IRenderDeviceVk::CreateBufferFromVulkanResource(). + virtual void CreateBufferFromVulkanResource(VkBuffer vkBuffer, const BufferDesc& BuffDesc, RESOURCE_STATE InitialState, IBuffer** ppBuffer) override final; + + /// Implementation of IRenderDevice::IdleGPU() in Vulkan backend. + virtual void IdleGPU() override final; + + // pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context + // The method returns fence value associated with the submitted command buffer + Uint64 ExecuteCommandBuffer(Uint32 QueueIndex, const VkSubmitInfo& SubmitInfo, class DeviceContextVkImpl* pImmediateCtx, std::vector>>* pSignalFences); + + void AllocateTransientCmdPool(VulkanUtilities::CommandPoolWrapper& CmdPool, VkCommandBuffer& vkCmdBuff, const Char* DebugPoolName = nullptr); + void ExecuteAndDisposeTransientCmdBuff(Uint32 QueueIndex, VkCommandBuffer vkCmdBuff, VulkanUtilities::CommandPoolWrapper&& CmdPool); + + /// Implementation of IRenderDevice::ReleaseStaleResources() in Vulkan backend. + virtual void ReleaseStaleResources(bool ForceRelease = false) override final; + + DescriptorSetAllocation AllocateDescriptorSet(Uint64 CommandQueueMask, VkDescriptorSetLayout SetLayout, const char* DebugName = "") + { + return m_DescriptorSetAllocator.Allocate(CommandQueueMask, SetLayout, DebugName); + } + DescriptorPoolManager& GetDynamicDescriptorPool() { return m_DynamicDescriptorPool; } + + std::shared_ptr GetVulkanInstance() const { return m_VulkanInstance; } + + const VulkanUtilities::VulkanPhysicalDevice& GetPhysicalDevice() const { return *m_PhysicalDevice; } + const VulkanUtilities::VulkanLogicalDevice& GetLogicalDevice() { return *m_LogicalVkDevice; } + + FramebufferCache& GetFramebufferCache() { return m_FramebufferCache; } + RenderPassCache& GetRenderPassCache() { return m_RenderPassCache; } + + VulkanUtilities::VulkanMemoryAllocation AllocateMemory(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProperties) + { + return m_MemoryMgr.Allocate(MemReqs, MemoryProperties); + } + VulkanUtilities::VulkanMemoryManager& GetGlobalMemoryManager() { return m_MemoryMgr; } + + VulkanDynamicMemoryManager& GetDynamicMemoryManager() { return m_DynamicMemoryManager; } + + void FlushStaleResources(Uint32 CmdQueueIndex); + +private: + virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final; + + // Submits command buffer for execution to the command queue + // Returns the submitted command buffer number and the fence value + // Parameters: + // * SubmittedCmdBuffNumber - submitted command buffer number + // * SubmittedFenceValue - fence value associated with the submitted command buffer + void SubmitCommandBuffer(Uint32 QueueIndex, const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue, std::vector>>* pFences); + + std::shared_ptr m_VulkanInstance; + std::unique_ptr m_PhysicalDevice; + std::shared_ptr m_LogicalVkDevice; + + EngineVkCreateInfo m_EngineAttribs; + + FramebufferCache m_FramebufferCache; + RenderPassCache m_RenderPassCache; + DescriptorSetAllocator m_DescriptorSetAllocator; + DescriptorPoolManager m_DynamicDescriptorPool; + + // These one-time command pools are used by buffer and texture constructors to + // issue copy commands. Vulkan requires that every command pool is used by one thread + // at a time, so every constructor must allocate command buffer from its own pool. + CommandPoolManager m_TransientCmdPoolMgr; + + VulkanUtilities::VulkanMemoryManager m_MemoryMgr; + + VulkanDynamicMemoryManager m_DynamicMemoryManager; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassCache.h b/Graphics/GraphicsEngineVulkan/include/RenderPassCache.h deleted file mode 100644 index 2cc0ba95..00000000 --- a/Graphics/GraphicsEngineVulkan/include/RenderPassCache.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::RenderPassCache class - -#include -#include -#include "GraphicsTypes.h" -#include "Constants.h" -#include "HashUtils.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace Diligent -{ - -class RenderDeviceVkImpl; -class RenderPassCache -{ -public: - RenderPassCache(RenderDeviceVkImpl& DeviceVk) noexcept : - m_DeviceVkImpl{DeviceVk} - {} - - // clang-format off - RenderPassCache (const RenderPassCache&) = delete; - RenderPassCache (RenderPassCache&&) = delete; - RenderPassCache& operator = (const RenderPassCache&) = delete; - RenderPassCache& operator = (RenderPassCache&&) = delete; - // clang-format on - - ~RenderPassCache(); - - // This structure is used as the key to find framebuffer - struct RenderPassCacheKey - { - // clang-format off - RenderPassCacheKey() : - NumRenderTargets{0}, - SampleCount {0}, - DSVFormat {TEX_FORMAT_UNKNOWN} - {} - // clang-format on - - RenderPassCacheKey(Uint32 _NumRenderTargets, - Uint32 _SampleCount, - const TEXTURE_FORMAT _RTVFormats[], - TEXTURE_FORMAT _DSVFormat) : - // clang-format off - NumRenderTargets{static_cast(_NumRenderTargets)}, - SampleCount {static_cast (_SampleCount) }, - DSVFormat {_DSVFormat } - // clang-format on - { - VERIFY_EXPR(_NumRenderTargets <= std::numeric_limits::max()); - VERIFY_EXPR(_SampleCount <= std::numeric_limits::max()); - for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) - RTVFormats[rt] = _RTVFormats[rt]; - } - // Default memeber initialization is intentionally omitted - Uint8 NumRenderTargets; - Uint8 SampleCount; - TEXTURE_FORMAT DSVFormat; - TEXTURE_FORMAT RTVFormats[MAX_RENDER_TARGETS]; - - bool operator==(const RenderPassCacheKey& rhs) const - { - // clang-format off - if (GetHash() != rhs.GetHash() || - NumRenderTargets != rhs.NumRenderTargets || - SampleCount != rhs.SampleCount || - DSVFormat != rhs.DSVFormat) - { - return false; - } - // clang-format on - - for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) - if (RTVFormats[rt] != rhs.RTVFormats[rt]) - return false; - - return true; - } - - size_t GetHash() const - { - if (Hash == 0) - { - Hash = ComputeHash(NumRenderTargets, SampleCount, DSVFormat); - for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) - HashCombine(Hash, RTVFormats[rt]); - } - return Hash; - } - - private: - mutable size_t Hash = 0; - }; - - VkRenderPass GetRenderPass(const RenderPassCacheKey& Key); - -private: - struct RenderPassCacheKeyHash - { - std::size_t operator()(const RenderPassCacheKey& Key) const - { - return Key.GetHash(); - } - }; - - RenderDeviceVkImpl& m_DeviceVkImpl; - - std::mutex m_Mutex; - std::unordered_map m_Cache; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp b/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp new file mode 100644 index 00000000..68587de6 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/RenderPassCache.hpp @@ -0,0 +1,143 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::RenderPassCache class + +#include +#include +#include "GraphicsTypes.h" +#include "Constants.h" +#include "HashUtils.h" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace Diligent +{ + +class RenderDeviceVkImpl; +class RenderPassCache +{ +public: + RenderPassCache(RenderDeviceVkImpl& DeviceVk) noexcept : + m_DeviceVkImpl{DeviceVk} + {} + + // clang-format off + RenderPassCache (const RenderPassCache&) = delete; + RenderPassCache (RenderPassCache&&) = delete; + RenderPassCache& operator = (const RenderPassCache&) = delete; + RenderPassCache& operator = (RenderPassCache&&) = delete; + // clang-format on + + ~RenderPassCache(); + + // This structure is used as the key to find framebuffer + struct RenderPassCacheKey + { + // clang-format off + RenderPassCacheKey() : + NumRenderTargets{0}, + SampleCount {0}, + DSVFormat {TEX_FORMAT_UNKNOWN} + {} + // clang-format on + + RenderPassCacheKey(Uint32 _NumRenderTargets, + Uint32 _SampleCount, + const TEXTURE_FORMAT _RTVFormats[], + TEXTURE_FORMAT _DSVFormat) : + // clang-format off + NumRenderTargets{static_cast(_NumRenderTargets)}, + SampleCount {static_cast (_SampleCount) }, + DSVFormat {_DSVFormat } + // clang-format on + { + VERIFY_EXPR(_NumRenderTargets <= std::numeric_limits::max()); + VERIFY_EXPR(_SampleCount <= std::numeric_limits::max()); + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + RTVFormats[rt] = _RTVFormats[rt]; + } + // Default memeber initialization is intentionally omitted + Uint8 NumRenderTargets; + Uint8 SampleCount; + TEXTURE_FORMAT DSVFormat; + TEXTURE_FORMAT RTVFormats[MAX_RENDER_TARGETS]; + + bool operator==(const RenderPassCacheKey& rhs) const + { + // clang-format off + if (GetHash() != rhs.GetHash() || + NumRenderTargets != rhs.NumRenderTargets || + SampleCount != rhs.SampleCount || + DSVFormat != rhs.DSVFormat) + { + return false; + } + // clang-format on + + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + if (RTVFormats[rt] != rhs.RTVFormats[rt]) + return false; + + return true; + } + + size_t GetHash() const + { + if (Hash == 0) + { + Hash = ComputeHash(NumRenderTargets, SampleCount, DSVFormat); + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) + HashCombine(Hash, RTVFormats[rt]); + } + return Hash; + } + + private: + mutable size_t Hash = 0; + }; + + VkRenderPass GetRenderPass(const RenderPassCacheKey& Key); + +private: + struct RenderPassCacheKeyHash + { + std::size_t operator()(const RenderPassCacheKey& Key) const + { + return Key.GetHash(); + } + }; + + RenderDeviceVkImpl& m_DeviceVkImpl; + + std::mutex m_Mutex; + std::unordered_map m_Cache; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h deleted file mode 100644 index ed412ed7..00000000 --- a/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::SamplerVkImpl class - -#include "SamplerVk.h" -#include "RenderDeviceVk.h" -#include "SamplerBase.hpp" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Sampler object object implementation in Vulkan backend. -class SamplerVkImpl final : public SamplerBase -{ -public: - using TSamplerBase = SamplerBase; - - SamplerVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const SamplerDesc& SamplerDesc); - ~SamplerVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; - - /// Implementation of ISamplerVk::GetVkSampler(). - virtual VkSampler GetVkSampler() const override final { return m_VkSampler; } - -private: - friend class ShaderVkImpl; - /// Vk sampler handle - VulkanUtilities::SamplerWrapper m_VkSampler; - static constexpr Uint64 m_CommandQueueMask = ~Uint64{0}; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.hpp new file mode 100644 index 00000000..37a8d863 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/SamplerVkImpl.hpp @@ -0,0 +1,65 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::SamplerVkImpl class + +#include "SamplerVk.h" +#include "RenderDeviceVk.h" +#include "SamplerBase.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Sampler object object implementation in Vulkan backend. +class SamplerVkImpl final : public SamplerBase +{ +public: + using TSamplerBase = SamplerBase; + + SamplerVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const SamplerDesc& SamplerDesc); + ~SamplerVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override; + + /// Implementation of ISamplerVk::GetVkSampler(). + virtual VkSampler GetVkSampler() const override final { return m_VkSampler; } + +private: + friend class ShaderVkImpl; + /// Vk sampler handle + VulkanUtilities::SamplerWrapper m_VkSampler; + static constexpr Uint64 m_CommandQueueMask = ~Uint64{0}; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h deleted file mode 100644 index b79177e5..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderResourceBindingVkImpl class - -#include "ShaderResourceBindingVk.h" -#include "RenderDeviceVk.h" -#include "ShaderResourceBindingBase.hpp" -#include "ShaderBase.hpp" -#include "ShaderResourceCacheVk.h" -#include "ShaderVariableVk.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Implementation of the Diligent::IShaderResourceBindingVk interface -// sizeof(ShaderResourceBindingVkImpl) == 72 (x64, msvc, Release) -class ShaderResourceBindingVkImpl final : public ShaderResourceBindingBase -{ -public: - using TBase = ShaderResourceBindingBase; - - ShaderResourceBindingVkImpl(IReferenceCounters* pRefCounters, class PipelineStateVkImpl* pPSO, bool IsPSOInternal); - ~ShaderResourceBindingVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of IShaderResourceBinding::BindResources() in Vulkan backend. - virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) override final; - - /// Implementation of IShaderResourceBinding::GetVariableByName() in Vulkan backend. - virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override final; - - /// Implementation of IShaderResourceBinding::GetVariableCount() in Vulkan backend. - virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; - - /// Implementation of IShaderResourceBinding::GetVariableByIndex() in Vulkan backend. - virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; - - /// Implementation of IShaderResourceBinding::InitializeStaticResources() in Vulkan backend. - virtual void InitializeStaticResources(const IPipelineState* pPipelineState) override final; - - ShaderResourceCacheVk& GetResourceCache() { return m_ShaderResourceCache; } - - bool StaticResourcesInitialized() const { return m_bStaticResourcesInitialized; } - -private: - ShaderResourceCacheVk m_ShaderResourceCache; - ShaderVariableManagerVk* m_pShaderVarMgrs = nullptr; - - // Shader variable manager index in m_pShaderVarMgrs[] array for every shader stage - Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; - bool m_bStaticResourcesInitialized = false; - Uint8 m_NumShaders = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp new file mode 100644 index 00000000..a839222b --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceBindingVkImpl.hpp @@ -0,0 +1,86 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceBindingVkImpl class + +#include "ShaderResourceBindingVk.h" +#include "RenderDeviceVk.h" +#include "ShaderResourceBindingBase.hpp" +#include "ShaderBase.hpp" +#include "ShaderResourceCacheVk.hpp" +#include "ShaderVariableVk.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Implementation of the Diligent::IShaderResourceBindingVk interface +// sizeof(ShaderResourceBindingVkImpl) == 72 (x64, msvc, Release) +class ShaderResourceBindingVkImpl final : public ShaderResourceBindingBase +{ +public: + using TBase = ShaderResourceBindingBase; + + ShaderResourceBindingVkImpl(IReferenceCounters* pRefCounters, class PipelineStateVkImpl* pPSO, bool IsPSOInternal); + ~ShaderResourceBindingVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of IShaderResourceBinding::BindResources() in Vulkan backend. + virtual void BindResources(Uint32 ShaderFlags, IResourceMapping* pResMapping, Uint32 Flags) override final; + + /// Implementation of IShaderResourceBinding::GetVariableByName() in Vulkan backend. + virtual IShaderResourceVariable* GetVariableByName(SHADER_TYPE ShaderType, const char* Name) override final; + + /// Implementation of IShaderResourceBinding::GetVariableCount() in Vulkan backend. + virtual Uint32 GetVariableCount(SHADER_TYPE ShaderType) const override final; + + /// Implementation of IShaderResourceBinding::GetVariableByIndex() in Vulkan backend. + virtual IShaderResourceVariable* GetVariableByIndex(SHADER_TYPE ShaderType, Uint32 Index) override final; + + /// Implementation of IShaderResourceBinding::InitializeStaticResources() in Vulkan backend. + virtual void InitializeStaticResources(const IPipelineState* pPipelineState) override final; + + ShaderResourceCacheVk& GetResourceCache() { return m_ShaderResourceCache; } + + bool StaticResourcesInitialized() const { return m_bStaticResourcesInitialized; } + +private: + ShaderResourceCacheVk m_ShaderResourceCache; + ShaderVariableManagerVk* m_pShaderVarMgrs = nullptr; + + // Shader variable manager index in m_pShaderVarMgrs[] array for every shader stage + Int8 m_ResourceLayoutIndex[6] = {-1, -1, -1, -1, -1, -1}; + bool m_bStaticResourcesInitialized = false; + Uint8 m_NumShaders = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h deleted file mode 100644 index a8548dd4..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderResourceCacheVk class - -// Shader resource cache stores Vk resources in a continuous chunk of memory: -// -// |Vulkan Descriptor Set| -// A ___________________________________________________________ -// m_pMemory | | m_pResources, m_NumResources == m | -// | m_DescriptorSetAllocation| | | -// V | | V -// | DescriptorSet[0] | .... | DescriptorSet[Ns-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | -// | | A \ -// | | | \ -// | |________________________________________________| \RefCntAutoPtr -// | m_pResources, m_NumResources == n \_________ -// | | Object | -// | m_DescriptorSetAllocation --------- -// V -// |Vulkan Descriptor Set| -// -// Ns = m_NumSets -// -// -// Descriptor set for static and mutable resources is assigned during cache initialization -// Descriptor set for dynamic resources is assigned at every draw call - -#include -#include "DescriptorPoolManager.h" -#include "SPIRVShaderResources.hpp" -#include "BufferVkImpl.h" - -namespace Diligent -{ - -class DeviceContextVkImpl; - -// sizeof(ShaderResourceCacheVk) == 24 (x64, msvc, Release) -class ShaderResourceCacheVk -{ -public: - // This enum is used for debug purposes only - enum DbgCacheContentType - { - StaticShaderResources, - SRBResources - }; - - // clang-format off - ShaderResourceCacheVk(DbgCacheContentType dbgContentType) -#ifdef _DEBUG - : m_DbgContentType{dbgContentType} -#endif - { - } - - ShaderResourceCacheVk (const ShaderResourceCacheVk&) = delete; - ShaderResourceCacheVk (ShaderResourceCacheVk&&) = delete; - ShaderResourceCacheVk& operator = (const ShaderResourceCacheVk&) = delete; - ShaderResourceCacheVk& operator = (ShaderResourceCacheVk&&) = delete; - // clang-format on - - ~ShaderResourceCacheVk(); - - static size_t GetRequiredMemorySize(Uint32 NumSets, Uint32 SetSizes[]); - - void InitializeSets(IMemoryAllocator& MemAllocator, Uint32 NumSets, Uint32 SetSizes[]); - void InitializeResources(Uint32 Set, Uint32 Offset, Uint32 ArraySize, SPIRVShaderResourceAttribs::ResourceType Type); - - // sizeof(Resource) == 16 (x64, msvc, Release) - struct Resource - { - // clang-format off - Resource(SPIRVShaderResourceAttribs::ResourceType _Type) : - Type{_Type} - {} - - Resource (const Resource&) = delete; - Resource (Resource&&) = delete; - Resource& operator = (const Resource&) = delete; - Resource& operator = (Resource&&) = delete; - -/* 0 */ const SPIRVShaderResourceAttribs::ResourceType Type; -/*1-7*/ // Unused -/* 8 */ RefCntAutoPtr pObject; - - VkDescriptorBufferInfo GetUniformBufferDescriptorWriteInfo () const; - VkDescriptorBufferInfo GetStorageBufferDescriptorWriteInfo () const; - VkDescriptorImageInfo GetImageDescriptorWriteInfo (bool IsImmutableSampler)const; - VkBufferView GetBufferViewWriteInfo () const; - VkDescriptorImageInfo GetSamplerDescriptorWriteInfo() const; - // clang-format on - }; - - // sizeof(DescriptorSet) == 48 (x64, msvc, Release) - class DescriptorSet - { - public: - // clang-format off - DescriptorSet(Uint32 NumResources, Resource *pResources) : - m_NumResources {NumResources}, - m_pResources {pResources } - {} - - DescriptorSet (const DescriptorSet&) = delete; - DescriptorSet (DescriptorSet&&) = delete; - DescriptorSet& operator = (const DescriptorSet&) = delete; - DescriptorSet& operator = (DescriptorSet&&) = delete; - // clang-format on - - inline Resource& GetResource(Uint32 CacheOffset) - { - VERIFY(CacheOffset < m_NumResources, "Offset ", CacheOffset, " is out of range"); - return m_pResources[CacheOffset]; - } - inline const Resource& GetResource(Uint32 CacheOffset) const - { - VERIFY(CacheOffset < m_NumResources, "Offset ", CacheOffset, " is out of range"); - return m_pResources[CacheOffset]; - } - - inline Uint32 GetSize() const { return m_NumResources; } - - VkDescriptorSet GetVkDescriptorSet() const - { - return m_DescriptorSetAllocation.GetVkDescriptorSet(); - } - - void AssignDescriptorSetAllocation(DescriptorSetAllocation&& Allocation) - { - VERIFY(m_NumResources > 0, "Descriptor set is empty"); - m_DescriptorSetAllocation = std::move(Allocation); - } - - // clang-format off -/* 0 */ const Uint32 m_NumResources = 0; - - private: -/* 8 */ Resource* const m_pResources = nullptr; -/*16 */ DescriptorSetAllocation m_DescriptorSetAllocation; -/*48 */ // End of structure - // clang-format on - }; - - inline DescriptorSet& GetDescriptorSet(Uint32 Index) - { - VERIFY_EXPR(Index < m_NumSets); - return reinterpret_cast(m_pMemory)[Index]; - } - inline const DescriptorSet& GetDescriptorSet(Uint32 Index) const - { - VERIFY_EXPR(Index < m_NumSets); - return reinterpret_cast(m_pMemory)[Index]; - } - - inline Uint32 GetNumDescriptorSets() const { return m_NumSets; } - inline Uint32 GetNumDynamicBuffers() const { return m_NumDynamicBuffers; } - - Uint16& GetDynamicBuffersCounter() { return m_NumDynamicBuffers; } - -#ifdef _DEBUG - // Only for debug purposes: indicates what types of resources are stored in the cache - DbgCacheContentType DbgGetContentType() const { return m_DbgContentType; } - void DbgVerifyResourceInitialization() const; - void DbgVerifyDynamicBuffersCounter() const; -#endif - - template - void TransitionResources(DeviceContextVkImpl* pCtxVkImpl); - - __forceinline Uint32 GetDynamicBufferOffsets(Uint32 CtxId, DeviceContextVkImpl* pCtxVkImpl, std::vector& Offsets) const; - -private: - Resource* GetFirstResourcePtr() - { - return reinterpret_cast(reinterpret_cast(m_pMemory) + m_NumSets); - } - const Resource* GetFirstResourcePtr() const - { - return reinterpret_cast(reinterpret_cast(m_pMemory) + m_NumSets); - } - - IMemoryAllocator* m_pAllocator = nullptr; - void* m_pMemory = nullptr; - Uint16 m_NumSets = 0; - // Total number of dynamic buffers bound in the resource cache regardless of the variable type - Uint16 m_NumDynamicBuffers = 0; - Uint32 m_TotalResources = 0; - -#ifdef _DEBUG - // Only for debug purposes: indicates what types of resources are stored in the cache - const DbgCacheContentType m_DbgContentType; - // Debug array that stores flags indicating if resources in the cache have been initialized - std::vector> m_DbgInitializedResources; -#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); - // clang-format off - 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"); - // clang-format on - } -#endif - } - return OffsetInd; -} - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp new file mode 100644 index 00000000..b1c7f56b --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp @@ -0,0 +1,288 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceCacheVk class + +// Shader resource cache stores Vk resources in a continuous chunk of memory: +// +// |Vulkan Descriptor Set| +// A ___________________________________________________________ +// m_pMemory | | m_pResources, m_NumResources == m | +// | m_DescriptorSetAllocation| | | +// V | | V +// | DescriptorSet[0] | .... | DescriptorSet[Ns-1] | Res[0] | ... | Res[n-1] | .... | Res[0] | ... | Res[m-1] | +// | | A \ +// | | | \ +// | |________________________________________________| \RefCntAutoPtr +// | m_pResources, m_NumResources == n \_________ +// | | Object | +// | m_DescriptorSetAllocation --------- +// V +// |Vulkan Descriptor Set| +// +// Ns = m_NumSets +// +// +// Descriptor set for static and mutable resources is assigned during cache initialization +// Descriptor set for dynamic resources is assigned at every draw call + +#include +#include "DescriptorPoolManager.hpp" +#include "SPIRVShaderResources.hpp" +#include "BufferVkImpl.hpp" + +namespace Diligent +{ + +class DeviceContextVkImpl; + +// sizeof(ShaderResourceCacheVk) == 24 (x64, msvc, Release) +class ShaderResourceCacheVk +{ +public: + // This enum is used for debug purposes only + enum DbgCacheContentType + { + StaticShaderResources, + SRBResources + }; + + // clang-format off + ShaderResourceCacheVk(DbgCacheContentType dbgContentType) +#ifdef _DEBUG + : m_DbgContentType{dbgContentType} +#endif + { + } + + ShaderResourceCacheVk (const ShaderResourceCacheVk&) = delete; + ShaderResourceCacheVk (ShaderResourceCacheVk&&) = delete; + ShaderResourceCacheVk& operator = (const ShaderResourceCacheVk&) = delete; + ShaderResourceCacheVk& operator = (ShaderResourceCacheVk&&) = delete; + // clang-format on + + ~ShaderResourceCacheVk(); + + static size_t GetRequiredMemorySize(Uint32 NumSets, Uint32 SetSizes[]); + + void InitializeSets(IMemoryAllocator& MemAllocator, Uint32 NumSets, Uint32 SetSizes[]); + void InitializeResources(Uint32 Set, Uint32 Offset, Uint32 ArraySize, SPIRVShaderResourceAttribs::ResourceType Type); + + // sizeof(Resource) == 16 (x64, msvc, Release) + struct Resource + { + // clang-format off + Resource(SPIRVShaderResourceAttribs::ResourceType _Type) : + Type{_Type} + {} + + Resource (const Resource&) = delete; + Resource (Resource&&) = delete; + Resource& operator = (const Resource&) = delete; + Resource& operator = (Resource&&) = delete; + +/* 0 */ const SPIRVShaderResourceAttribs::ResourceType Type; +/*1-7*/ // Unused +/* 8 */ RefCntAutoPtr pObject; + + VkDescriptorBufferInfo GetUniformBufferDescriptorWriteInfo () const; + VkDescriptorBufferInfo GetStorageBufferDescriptorWriteInfo () const; + VkDescriptorImageInfo GetImageDescriptorWriteInfo (bool IsImmutableSampler)const; + VkBufferView GetBufferViewWriteInfo () const; + VkDescriptorImageInfo GetSamplerDescriptorWriteInfo() const; + // clang-format on + }; + + // sizeof(DescriptorSet) == 48 (x64, msvc, Release) + class DescriptorSet + { + public: + // clang-format off + DescriptorSet(Uint32 NumResources, Resource *pResources) : + m_NumResources {NumResources}, + m_pResources {pResources } + {} + + DescriptorSet (const DescriptorSet&) = delete; + DescriptorSet (DescriptorSet&&) = delete; + DescriptorSet& operator = (const DescriptorSet&) = delete; + DescriptorSet& operator = (DescriptorSet&&) = delete; + // clang-format on + + inline Resource& GetResource(Uint32 CacheOffset) + { + VERIFY(CacheOffset < m_NumResources, "Offset ", CacheOffset, " is out of range"); + return m_pResources[CacheOffset]; + } + inline const Resource& GetResource(Uint32 CacheOffset) const + { + VERIFY(CacheOffset < m_NumResources, "Offset ", CacheOffset, " is out of range"); + return m_pResources[CacheOffset]; + } + + inline Uint32 GetSize() const { return m_NumResources; } + + VkDescriptorSet GetVkDescriptorSet() const + { + return m_DescriptorSetAllocation.GetVkDescriptorSet(); + } + + void AssignDescriptorSetAllocation(DescriptorSetAllocation&& Allocation) + { + VERIFY(m_NumResources > 0, "Descriptor set is empty"); + m_DescriptorSetAllocation = std::move(Allocation); + } + + // clang-format off +/* 0 */ const Uint32 m_NumResources = 0; + + private: +/* 8 */ Resource* const m_pResources = nullptr; +/*16 */ DescriptorSetAllocation m_DescriptorSetAllocation; +/*48 */ // End of structure + // clang-format on + }; + + inline DescriptorSet& GetDescriptorSet(Uint32 Index) + { + VERIFY_EXPR(Index < m_NumSets); + return reinterpret_cast(m_pMemory)[Index]; + } + inline const DescriptorSet& GetDescriptorSet(Uint32 Index) const + { + VERIFY_EXPR(Index < m_NumSets); + return reinterpret_cast(m_pMemory)[Index]; + } + + inline Uint32 GetNumDescriptorSets() const { return m_NumSets; } + inline Uint32 GetNumDynamicBuffers() const { return m_NumDynamicBuffers; } + + Uint16& GetDynamicBuffersCounter() { return m_NumDynamicBuffers; } + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + DbgCacheContentType DbgGetContentType() const { return m_DbgContentType; } + void DbgVerifyResourceInitialization() const; + void DbgVerifyDynamicBuffersCounter() const; +#endif + + template + void TransitionResources(DeviceContextVkImpl* pCtxVkImpl); + + __forceinline Uint32 GetDynamicBufferOffsets(Uint32 CtxId, DeviceContextVkImpl* pCtxVkImpl, std::vector& Offsets) const; + +private: + Resource* GetFirstResourcePtr() + { + return reinterpret_cast(reinterpret_cast(m_pMemory) + m_NumSets); + } + const Resource* GetFirstResourcePtr() const + { + return reinterpret_cast(reinterpret_cast(m_pMemory) + m_NumSets); + } + + IMemoryAllocator* m_pAllocator = nullptr; + void* m_pMemory = nullptr; + Uint16 m_NumSets = 0; + // Total number of dynamic buffers bound in the resource cache regardless of the variable type + Uint16 m_NumDynamicBuffers = 0; + Uint32 m_TotalResources = 0; + +#ifdef _DEBUG + // Only for debug purposes: indicates what types of resources are stored in the cache + const DbgCacheContentType m_DbgContentType; + // Debug array that stores flags indicating if resources in the cache have been initialized + std::vector> m_DbgInitializedResources; +#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); + // clang-format off + 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"); + // clang-format on + } +#endif + } + return OffsetInd; +} + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h deleted file mode 100644 index 2cd12452..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.h +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderResourceLayoutVk class - -// All resources are stored in a single continuous chunk of memory using the following layout: -// -// m_ResourceBuffer -// | -// || VkResource[0] ... VkResource[s-1] | VkResource[s] ... VkResource[s+m-1] | VkResource[s+m] ... VkResource[s+m+d-1] || || -// || | | || || -// || VARIABLE_TYPE_STATIC | VARIABLE_TYPE_MUTABLE | VARIABLE_TYPE_DYNAMIC || Immutable Samplers || -// || | | || || -// -// s == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] -// m == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] -// d == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] -// -// -// -// * Every VkResource structure holds a reference to SPIRVShaderResourceAttribs structure from SPIRVShaderResources. -// * ShaderResourceLayoutVk keeps a shared pointer to SPIRVShaderResources instance. -// * Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource. -// -// -// ______________________ ________________________________________________________________________ -// | | unique_ptr | | | | | | | | -// | SPIRVShaderResources |--------------->| UBs | SBs | StrgImgs | SmplImgs | ACs | SepSamplers | SepImgs | -// |______________________| |________|_________|__________|__________|_______|_____________|_________| -// A A A -// | | | -// |shared_ptr Ref Ref -// ________|__________________ ________\____________________|_____________________________________________ -// | | unique_ptr | | | | | -// | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | -// |___________________________| |___________________|_________________|_______________|_____________________| -// A A -// / | -// Ref Ref -// / | -// __________________________ __________________/___________________________|___________________________ -// | | | | | | -// | ShaderVariableManagerVk |---------------->| ShaderVariableVkImpl[0] | ShaderVariableVkImpl[1] | ... | -// |__________________________| |___________________________|____________________________|_________________| -// -// -// -// -// Resources in the resource cache are identified by the descriptor set index and the offset from the set start -// -// ___________________________ ___________________________________________________________________________ -// | | unique_ptr | | | | | -// | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | -// |___________________________| |___________________|_________________|_______________|_____________________| -// | | -// | | -// | (DescriptorSet, CacheOffset) / (DescriptorSet, CacheOffset) -// \ / -// __________________________ ________V_______________________________________________________V_______ -// | | | | -// | ShaderResourceCacheVk |---------------->| Resources | -// |__________________________| |________________________________________________________________________| -// -// -// -// Every pipeline state object (PipelineStateVkImpl) keeps the following layouts: -// * One layout object per shader stage to facilitate management of static shader resources -// - Uses artificial layout where resource binding matches the resource type (SPIRVShaderResourceAttribs::ResourceType) -// * One layout object per shader stage used by SRBs to manage all resource types: -// - All variable types are preserved -// - Bindings, descriptor sets and offsets are assigned during the initialization - -#include -#include - -#include "PipelineState.h" -#include "ShaderBase.hpp" -#include "HashUtils.h" -#include "ShaderResourceCacheVk.h" -#include "SPIRVShaderResources.hpp" -#include "VulkanUtilities/VulkanLogicalDevice.h" - -namespace Diligent -{ - -/// Diligent::ShaderResourceLayoutVk class -// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) -class ShaderResourceLayoutVk -{ -public: - ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : - m_LogicalDevice{LogicalDevice} - { - } - - // clang-format off - ShaderResourceLayoutVk (const ShaderResourceLayoutVk&) = delete; - ShaderResourceLayoutVk (ShaderResourceLayoutVk&&) = delete; - ShaderResourceLayoutVk& operator = (const ShaderResourceLayoutVk&) = delete; - ShaderResourceLayoutVk& operator = (ShaderResourceLayoutVk&&) = delete; - // clang-format on - - ~ShaderResourceLayoutVk(); - - // This method is called by PipelineStateVkImpl class instance to initialize static - // shader resource layout and the cache - void InitializeStaticResourceLayout(std::shared_ptr pSrcResources, - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - ShaderResourceCacheVk& StaticResourceCache); - - // This method is called by PipelineStateVkImpl class instance to initialize resource - // layouts for all shader stages in the pipeline. - static void Initialize(IRenderDevice* pRenderDevice, - Uint32 NumShaders, - ShaderResourceLayoutVk Layouts[], - std::shared_ptr pShaderResources[], - IMemoryAllocator& LayoutDataAllocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - std::vector SPIRVs[], - class PipelineLayout& PipelineLayout); - - // sizeof(VkResource) == 24 (x64) - struct VkResource - { - // clang-format off - VkResource (const VkResource&) = delete; - VkResource ( VkResource&&) = delete; - VkResource& operator = (const VkResource&) = delete; - VkResource& operator = ( VkResource&&) = delete; - - static constexpr const Uint32 CacheOffsetBits = 21; - static constexpr const Uint32 SamplerIndBits = 8; - static constexpr const Uint32 VariableTypeBits = 2; - static constexpr const Uint32 ImmutableSamplerFlagBits = 1; - static_assert(CacheOffsetBits + SamplerIndBits + VariableTypeBits + ImmutableSamplerFlagBits == 32, "Elements are expected to be packed into 32 bits"); - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES <= (1<(_Binding) }, - DescriptorSet {static_cast(_DescriptorSet)}, - CacheOffset {_CacheOffset }, - SamplerInd {_SamplerInd }, - VariableType {_VariableType }, - ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, - SpirvAttribs {_SpirvAttribs }, - ParentResLayout {_ParentLayout } - { - VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) ); - VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) ); - VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max() ); - VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); - } - // clang-format on - - // Checks if a resource is bound in ResourceCache at the given ArrayIndex - bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const; - - // Binds a resource pObject in the ResourceCache - void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex, ShaderResourceCacheVk& ResourceCache) const; - - // Updates resource descriptor in the descriptor set - inline void UpdateDescriptorHandle(VkDescriptorSet vkDescrSet, - uint32_t ArrayElement, - const VkDescriptorImageInfo* pImageInfo, - const VkDescriptorBufferInfo* pBufferInfo, - const VkBufferView* pTexelBufferView) const; - - bool IsImmutableSamplerAssigned() const - { - VERIFY(ImmutableSamplerAssigned == 0 || - SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || - SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, - "Immutable sampler can only be assigned to a sampled image or separate sampler"); - return ImmutableSamplerAssigned != 0; - } - - SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const - { - return static_cast(VariableType); - } - - private: - void CacheUniformBuffer(IDeviceObject* pBuffer, - ShaderResourceCacheVk::Resource& DstRes, - VkDescriptorSet vkDescrSet, - Uint32 ArrayInd, - Uint16& DynamicBuffersCounter) const; - - void CacheStorageBuffer(IDeviceObject* pBufferView, - ShaderResourceCacheVk::Resource& DstRes, - VkDescriptorSet vkDescrSet, - Uint32 ArrayInd, - Uint16& DynamicBuffersCounter) const; - - void CacheTexelBuffer(IDeviceObject* pBufferView, - ShaderResourceCacheVk::Resource& DstRes, - VkDescriptorSet vkDescrSet, - Uint32 ArrayInd, - Uint16& DynamicBuffersCounter) const; - - template - void CacheImage(IDeviceObject* pTexView, - ShaderResourceCacheVk::Resource& DstRes, - VkDescriptorSet vkDescrSet, - Uint32 ArrayInd, - TCacheSampler CacheSampler) const; - - void CacheSeparateSampler(IDeviceObject* pSampler, - ShaderResourceCacheVk::Resource& DstRes, - VkDescriptorSet vkDescrSet, - Uint32 ArrayInd) const; - - template - bool UpdateCachedResource(ShaderResourceCacheVk::Resource& DstRes, - RefCntAutoPtr&& pObject, - TPreUpdateObject PreUpdateObject) const; - }; - - // Copies static resources from SrcResourceCache defined by SrcLayout - // to DstResourceCache defined by this layout - void InitializeStaticResources(const ShaderResourceLayoutVk& SrcLayout, - const ShaderResourceCacheVk& SrcResourceCache, - ShaderResourceCacheVk& DstResourceCache) const; - -#ifdef DEVELOPMENT - bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache) const; - static void dvpVerifyResourceLayoutDesc(Uint32 NumShaders, - const std::shared_ptr pShaderResources[], - const PipelineResourceLayoutDesc& ResourceLayoutDesc); -#endif - - Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const - { - return m_NumResources[VarType]; - } - - // Initializes resource slots in the ResourceCache - void InitializeResourceMemoryInCache(ShaderResourceCacheVk& ResourceCache) const; - - // Writes dynamic resource descriptors from ResourceCache to vkDynamicDescriptorSet - void CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache, - VkDescriptorSet vkDynamicDescriptorSet) const; - - const Char* GetShaderName() const - { - return m_pResources->GetShaderName(); - } - - SHADER_TYPE GetShaderType() const - { - return m_pResources->GetShaderType(); - } - - const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const - { - VERIFY_EXPR(r < m_NumResources[VarType]); - auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); - return Resources[GetResourceOffset(VarType, r)]; - } - - bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedSamplers(); } - -private: - Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const - { - VERIFY_EXPR(r < m_NumResources[VarType]); - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0, "SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0 expected"); - r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_STATIC) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] : 0; - static_assert(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1, "SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1 expected"); - r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] : 0; - return r; - } - VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) - { - VERIFY_EXPR(r < m_NumResources[VarType]); - auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); - return Resources[GetResourceOffset(VarType, r)]; - } - - const VkResource& GetResource(Uint32 r) const - { - VERIFY_EXPR(r < GetTotalResourceCount()); - auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); - return Resources[r]; - } - - Uint32 GetTotalResourceCount() const - { - return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; - } - - void AllocateMemory(std::shared_ptr pSrcResources, - IMemoryAllocator& Allocator, - const PipelineResourceLayoutDesc& ResourceLayoutDesc, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - bool AllocateImmutableSamplers); - - Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, - Uint32 CurrResourceCount, - SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) const; - - using ImmutableSamplerPtrType = RefCntAutoPtr; - ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n) noexcept - { - VERIFY(n < m_NumImmutableSamplers, "Immutable sampler index (", n, ") is out of range. Total immutable sampler count: ", m_NumImmutableSamplers); - auto* ResourceMemoryEnd = reinterpret_cast(m_ResourceBuffer.get()) + GetTotalResourceCount(); - return reinterpret_cast(ResourceMemoryEnd)[n]; - } - - // clang-format off -/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; -/* 8 */ std::unique_ptr > m_ResourceBuffer; - - // We must use shared_ptr to reference ShaderResources instance, because - // there may be multiple objects referencing the same set of resources -/*24 */ std::shared_ptr m_pResources; - -/*40 */ std::array m_NumResources = {}; -/*48 */ Uint32 m_NumImmutableSamplers = 0; -/*56*/ // End of class - // clang-format on -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp new file mode 100644 index 00000000..56615308 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ShaderResourceLayoutVk.hpp @@ -0,0 +1,373 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderResourceLayoutVk class + +// All resources are stored in a single continuous chunk of memory using the following layout: +// +// m_ResourceBuffer +// | +// || VkResource[0] ... VkResource[s-1] | VkResource[s] ... VkResource[s+m-1] | VkResource[s+m] ... VkResource[s+m+d-1] || || +// || | | || || +// || VARIABLE_TYPE_STATIC | VARIABLE_TYPE_MUTABLE | VARIABLE_TYPE_DYNAMIC || Immutable Samplers || +// || | | || || +// +// s == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] +// m == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] +// d == m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC] +// +// +// +// * Every VkResource structure holds a reference to SPIRVShaderResourceAttribs structure from SPIRVShaderResources. +// * ShaderResourceLayoutVk keeps a shared pointer to SPIRVShaderResources instance. +// * Every ShaderVariableVkImpl variable managed by ShaderVariableManagerVk keeps a reference to corresponding VkResource. +// +// +// ______________________ ________________________________________________________________________ +// | | unique_ptr | | | | | | | | +// | SPIRVShaderResources |--------------->| UBs | SBs | StrgImgs | SmplImgs | ACs | SepSamplers | SepImgs | +// |______________________| |________|_________|__________|__________|_______|_____________|_________| +// A A A +// | | | +// |shared_ptr Ref Ref +// ________|__________________ ________\____________________|_____________________________________________ +// | | unique_ptr | | | | | +// | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | +// |___________________________| |___________________|_________________|_______________|_____________________| +// A A +// / | +// Ref Ref +// / | +// __________________________ __________________/___________________________|___________________________ +// | | | | | | +// | ShaderVariableManagerVk |---------------->| ShaderVariableVkImpl[0] | ShaderVariableVkImpl[1] | ... | +// |__________________________| |___________________________|____________________________|_________________| +// +// +// +// +// Resources in the resource cache are identified by the descriptor set index and the offset from the set start +// +// ___________________________ ___________________________________________________________________________ +// | | unique_ptr | | | | | +// | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | +// |___________________________| |___________________|_________________|_______________|_____________________| +// | | +// | | +// | (DescriptorSet, CacheOffset) / (DescriptorSet, CacheOffset) +// \ / +// __________________________ ________V_______________________________________________________V_______ +// | | | | +// | ShaderResourceCacheVk |---------------->| Resources | +// |__________________________| |________________________________________________________________________| +// +// +// +// Every pipeline state object (PipelineStateVkImpl) keeps the following layouts: +// * One layout object per shader stage to facilitate management of static shader resources +// - Uses artificial layout where resource binding matches the resource type (SPIRVShaderResourceAttribs::ResourceType) +// * One layout object per shader stage used by SRBs to manage all resource types: +// - All variable types are preserved +// - Bindings, descriptor sets and offsets are assigned during the initialization + +#include +#include + +#include "PipelineState.h" +#include "ShaderBase.hpp" +#include "HashUtils.h" +#include "ShaderResourceCacheVk.hpp" +#include "SPIRVShaderResources.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" + +namespace Diligent +{ + +/// Diligent::ShaderResourceLayoutVk class +// sizeof(ShaderResourceLayoutVk)==56 (MS compiler, x64) +class ShaderResourceLayoutVk +{ +public: + ShaderResourceLayoutVk(const VulkanUtilities::VulkanLogicalDevice& LogicalDevice) : + m_LogicalDevice{LogicalDevice} + { + } + + // clang-format off + ShaderResourceLayoutVk (const ShaderResourceLayoutVk&) = delete; + ShaderResourceLayoutVk (ShaderResourceLayoutVk&&) = delete; + ShaderResourceLayoutVk& operator = (const ShaderResourceLayoutVk&) = delete; + ShaderResourceLayoutVk& operator = (ShaderResourceLayoutVk&&) = delete; + // clang-format on + + ~ShaderResourceLayoutVk(); + + // This method is called by PipelineStateVkImpl class instance to initialize static + // shader resource layout and the cache + void InitializeStaticResourceLayout(std::shared_ptr pSrcResources, + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + ShaderResourceCacheVk& StaticResourceCache); + + // This method is called by PipelineStateVkImpl class instance to initialize resource + // layouts for all shader stages in the pipeline. + static void Initialize(IRenderDevice* pRenderDevice, + Uint32 NumShaders, + ShaderResourceLayoutVk Layouts[], + std::shared_ptr pShaderResources[], + IMemoryAllocator& LayoutDataAllocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + std::vector SPIRVs[], + class PipelineLayout& PipelineLayout); + + // sizeof(VkResource) == 24 (x64) + struct VkResource + { + // clang-format off + VkResource (const VkResource&) = delete; + VkResource ( VkResource&&) = delete; + VkResource& operator = (const VkResource&) = delete; + VkResource& operator = ( VkResource&&) = delete; + + static constexpr const Uint32 CacheOffsetBits = 21; + static constexpr const Uint32 SamplerIndBits = 8; + static constexpr const Uint32 VariableTypeBits = 2; + static constexpr const Uint32 ImmutableSamplerFlagBits = 1; + static_assert(CacheOffsetBits + SamplerIndBits + VariableTypeBits + ImmutableSamplerFlagBits == 32, "Elements are expected to be packed into 32 bits"); + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES <= (1<(_Binding) }, + DescriptorSet {static_cast(_DescriptorSet)}, + CacheOffset {_CacheOffset }, + SamplerInd {_SamplerInd }, + VariableType {_VariableType }, + ImmutableSamplerAssigned {_ImmutableSamplerAssigned ? 1U : 0U}, + SpirvAttribs {_SpirvAttribs }, + ParentResLayout {_ParentLayout } + { + VERIFY(_CacheOffset < (1 << CacheOffsetBits), "Cache offset (", _CacheOffset, ") exceeds max representable value ", (1 << CacheOffsetBits) ); + VERIFY(_SamplerInd < (1 << SamplerIndBits), "Sampler index (", _SamplerInd, ") exceeds max representable value ", (1 << SamplerIndBits) ); + VERIFY(_Binding <= std::numeric_limits::max(), "Binding (", _Binding, ") exceeds max representable value ", std::numeric_limits::max() ); + VERIFY(_DescriptorSet <= std::numeric_limits::max(), "Descriptor set (", _DescriptorSet, ") exceeds max representable value ", std::numeric_limits::max()); + } + // clang-format on + + // Checks if a resource is bound in ResourceCache at the given ArrayIndex + bool IsBound(Uint32 ArrayIndex, const ShaderResourceCacheVk& ResourceCache) const; + + // Binds a resource pObject in the ResourceCache + void BindResource(IDeviceObject* pObject, Uint32 ArrayIndex, ShaderResourceCacheVk& ResourceCache) const; + + // Updates resource descriptor in the descriptor set + inline void UpdateDescriptorHandle(VkDescriptorSet vkDescrSet, + uint32_t ArrayElement, + const VkDescriptorImageInfo* pImageInfo, + const VkDescriptorBufferInfo* pBufferInfo, + const VkBufferView* pTexelBufferView) const; + + bool IsImmutableSamplerAssigned() const + { + VERIFY(ImmutableSamplerAssigned == 0 || + SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SampledImage || + SpirvAttribs.Type == SPIRVShaderResourceAttribs::ResourceType::SeparateSampler, + "Immutable sampler can only be assigned to a sampled image or separate sampler"); + return ImmutableSamplerAssigned != 0; + } + + SHADER_RESOURCE_VARIABLE_TYPE GetVariableType() const + { + return static_cast(VariableType); + } + + private: + void CacheUniformBuffer(IDeviceObject* pBuffer, + ShaderResourceCacheVk::Resource& DstRes, + VkDescriptorSet vkDescrSet, + Uint32 ArrayInd, + Uint16& DynamicBuffersCounter) const; + + void CacheStorageBuffer(IDeviceObject* pBufferView, + ShaderResourceCacheVk::Resource& DstRes, + VkDescriptorSet vkDescrSet, + Uint32 ArrayInd, + Uint16& DynamicBuffersCounter) const; + + void CacheTexelBuffer(IDeviceObject* pBufferView, + ShaderResourceCacheVk::Resource& DstRes, + VkDescriptorSet vkDescrSet, + Uint32 ArrayInd, + Uint16& DynamicBuffersCounter) const; + + template + void CacheImage(IDeviceObject* pTexView, + ShaderResourceCacheVk::Resource& DstRes, + VkDescriptorSet vkDescrSet, + Uint32 ArrayInd, + TCacheSampler CacheSampler) const; + + void CacheSeparateSampler(IDeviceObject* pSampler, + ShaderResourceCacheVk::Resource& DstRes, + VkDescriptorSet vkDescrSet, + Uint32 ArrayInd) const; + + template + bool UpdateCachedResource(ShaderResourceCacheVk::Resource& DstRes, + RefCntAutoPtr&& pObject, + TPreUpdateObject PreUpdateObject) const; + }; + + // Copies static resources from SrcResourceCache defined by SrcLayout + // to DstResourceCache defined by this layout + void InitializeStaticResources(const ShaderResourceLayoutVk& SrcLayout, + const ShaderResourceCacheVk& SrcResourceCache, + ShaderResourceCacheVk& DstResourceCache) const; + +#ifdef DEVELOPMENT + bool dvpVerifyBindings(const ShaderResourceCacheVk& ResourceCache) const; + static void dvpVerifyResourceLayoutDesc(Uint32 NumShaders, + const std::shared_ptr pShaderResources[], + const PipelineResourceLayoutDesc& ResourceLayoutDesc); +#endif + + Uint32 GetResourceCount(SHADER_RESOURCE_VARIABLE_TYPE VarType) const + { + return m_NumResources[VarType]; + } + + // Initializes resource slots in the ResourceCache + void InitializeResourceMemoryInCache(ShaderResourceCacheVk& ResourceCache) const; + + // Writes dynamic resource descriptors from ResourceCache to vkDynamicDescriptorSet + void CommitDynamicResources(const ShaderResourceCacheVk& ResourceCache, + VkDescriptorSet vkDynamicDescriptorSet) const; + + const Char* GetShaderName() const + { + return m_pResources->GetShaderName(); + } + + SHADER_TYPE GetShaderType() const + { + return m_pResources->GetShaderType(); + } + + const VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const + { + VERIFY_EXPR(r < m_NumResources[VarType]); + auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return Resources[GetResourceOffset(VarType, r)]; + } + + bool IsUsingSeparateSamplers() const { return !m_pResources->IsUsingCombinedSamplers(); } + +private: + Uint32 GetResourceOffset(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) const + { + VERIFY_EXPR(r < m_NumResources[VarType]); + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0, "SHADER_RESOURCE_VARIABLE_TYPE_STATIC == 0 expected"); + r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_STATIC) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_STATIC] : 0; + static_assert(SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1, "SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE == 1 expected"); + r += (VarType > SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE) ? m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE] : 0; + return r; + } + VkResource& GetResource(SHADER_RESOURCE_VARIABLE_TYPE VarType, Uint32 r) + { + VERIFY_EXPR(r < m_NumResources[VarType]); + auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return Resources[GetResourceOffset(VarType, r)]; + } + + const VkResource& GetResource(Uint32 r) const + { + VERIFY_EXPR(r < GetTotalResourceCount()); + auto* Resources = reinterpret_cast(m_ResourceBuffer.get()); + return Resources[r]; + } + + Uint32 GetTotalResourceCount() const + { + return m_NumResources[SHADER_RESOURCE_VARIABLE_TYPE_NUM_TYPES]; + } + + void AllocateMemory(std::shared_ptr pSrcResources, + IMemoryAllocator& Allocator, + const PipelineResourceLayoutDesc& ResourceLayoutDesc, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + bool AllocateImmutableSamplers); + + Uint32 FindAssignedSampler(const SPIRVShaderResourceAttribs& SepImg, + Uint32 CurrResourceCount, + SHADER_RESOURCE_VARIABLE_TYPE ImgVarType) const; + + using ImmutableSamplerPtrType = RefCntAutoPtr; + ImmutableSamplerPtrType& GetImmutableSampler(Uint32 n) noexcept + { + VERIFY(n < m_NumImmutableSamplers, "Immutable sampler index (", n, ") is out of range. Total immutable sampler count: ", m_NumImmutableSamplers); + auto* ResourceMemoryEnd = reinterpret_cast(m_ResourceBuffer.get()) + GetTotalResourceCount(); + return reinterpret_cast(ResourceMemoryEnd)[n]; + } + + // clang-format off +/* 0 */ const VulkanUtilities::VulkanLogicalDevice& m_LogicalDevice; +/* 8 */ std::unique_ptr > m_ResourceBuffer; + + // We must use shared_ptr to reference ShaderResources instance, because + // there may be multiple objects referencing the same set of resources +/*24 */ std::shared_ptr m_pResources; + +/*40 */ std::array m_NumResources = {}; +/*48 */ Uint32 m_NumImmutableSamplers = 0; +/*56*/ // End of class + // clang-format on +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h deleted file mode 100644 index b494f4b5..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderVariableManagerVk and Diligent::ShaderVariableVkImpl classes - -// -// * ShaderVariableManagerVk keeps list of variables of specific types -// * Every ShaderVariableVkImpl references VkResource from ShaderResourceLayoutVk -// * ShaderVariableManagerVk keeps reference to ShaderResourceCacheVk -// * ShaderVariableManagerVk is used by PipelineStateVkImpl to manage static resources and by -// ShaderResourceBindingVkImpl to manage mutable and dynamic resources -// -// __________________________ __________________________________________________________________________ -// | | | | | | -// .----| ShaderVariableManagerVk |---------------->| ShaderVariableVkImpl[0] | ShaderVariableVkImpl[1] | ... | -// | |__________________________| |___________________________|____________________________|_________________| -// | \ | -// | Ref Ref -// | \ | -// | ___________________________ ______________________V_______________________V____________________________ -// | | | unique_ptr | | | | | -// | | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | -// | |___________________________| |___________________|_________________|_______________|_____________________| -// | | | -// | | | -// | | (DescriptorSet, CacheOffset) / (DescriptorSet, CacheOffset) -// | \ / -// | __________________________ ________V_______________________________________________________V_______ -// | | | | | -// '--->| ShaderResourceCacheVk |---------------->| Resources | -// |__________________________| |________________________________________________________________________| -// -// - -#include - -#include "ShaderResourceLayoutVk.h" -#include "ShaderResourceVariableBase.hpp" - -namespace Diligent -{ - -class ShaderVariableVkImpl; - -// sizeof(ShaderVariableManagerVk) == 32 (x64, msvc, Release) -class ShaderVariableManagerVk -{ -public: - ShaderVariableManagerVk(IObject& Owner, - const ShaderResourceLayoutVk& SrcLayout, - IMemoryAllocator& Allocator, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - ShaderResourceCacheVk& ResourceCache); - - ~ShaderVariableManagerVk(); - - void DestroyVariables(IMemoryAllocator& Allocator); - - ShaderVariableVkImpl* GetVariable(const Char* Name); - ShaderVariableVkImpl* GetVariable(Uint32 Index); - - void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); - - static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, - const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, - Uint32 NumAllowedTypes, - Uint32& NumVariables); - - Uint32 GetVariableCount() const { return m_NumVariables; } - -private: - friend ShaderVariableVkImpl; - - Uint32 GetVariableIndex(const ShaderVariableVkImpl& Variable); - - IObject& m_Owner; - // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references - // static resource cache owned by the same PSO object), or by SRB object (in which case - // m_ResourceCache references the cache in the SRB). Thus the cache and the resource layout - // (which the variables reference) are guaranteed to be alive while the manager is alive. - ShaderResourceCacheVk& m_ResourceCache; - - // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block - // memory allocator is used. This ensures that all resources from different shader resource bindings reside in - // continuous memory. If allocation granularity == 1, raw allocator is used. - ShaderVariableVkImpl* m_pVariables = nullptr; - Uint32 m_NumVariables = 0; - -#ifdef _DEBUG - IMemoryAllocator& m_DbgAllocator; -#endif -}; - -// sizeof(ShaderVariableVkImpl) == 24 (x64) -class ShaderVariableVkImpl final : public IShaderResourceVariable -{ -public: - ShaderVariableVkImpl(ShaderVariableManagerVk& ParentManager, - const ShaderResourceLayoutVk::VkResource& Resource) : - m_ParentManager{ParentManager}, - m_Resource{Resource} - {} - - // clang-format off - ShaderVariableVkImpl (const ShaderVariableVkImpl&) = delete; - ShaderVariableVkImpl (ShaderVariableVkImpl&&) = delete; - ShaderVariableVkImpl& operator= (const ShaderVariableVkImpl&) = delete; - ShaderVariableVkImpl& operator= (ShaderVariableVkImpl&&) = delete; - // clang-format on - - - virtual IReferenceCounters* GetReferenceCounters() const override final - { - return m_ParentManager.m_Owner.GetReferenceCounters(); - } - - virtual Atomics::Long AddRef() override final - { - return m_ParentManager.m_Owner.AddRef(); - } - - virtual Atomics::Long Release() override final - { - return m_ParentManager.m_Owner.Release(); - } - - void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final - { - if (ppInterface == nullptr) - return; - - *ppInterface = nullptr; - if (IID == IID_ShaderResourceVariable || IID == IID_Unknown) - { - *ppInterface = this; - (*ppInterface)->AddRef(); - } - } - - virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final - { - return m_Resource.GetVariableType(); - } - - virtual void Set(IDeviceObject* pObject) override final - { - m_Resource.BindResource(pObject, 0, m_ParentManager.m_ResourceCache); - } - - virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final - { - VerifyAndCorrectSetArrayArguments(m_Resource.SpirvAttribs.Name, m_Resource.SpirvAttribs.ArraySize, FirstElement, NumElements); - for (Uint32 Elem = 0; Elem < NumElements; ++Elem) - m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); - } - - virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final - { - ResourceDesc = m_Resource.SpirvAttribs.GetResourceDesc(); - } - - virtual Uint32 GetIndex() const override final - { - return m_ParentManager.GetVariableIndex(*this); - } - - virtual bool IsBound(Uint32 ArrayIndex) const override final - { - return m_Resource.IsBound(ArrayIndex, m_ParentManager.m_ResourceCache); - } - - const ShaderResourceLayoutVk::VkResource& GetResource() const - { - return m_Resource; - } - -private: - friend ShaderVariableManagerVk; - - ShaderVariableManagerVk& m_ParentManager; - const ShaderResourceLayoutVk::VkResource& m_Resource; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp new file mode 100644 index 00000000..24931767 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVariableVk.hpp @@ -0,0 +1,212 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderVariableManagerVk and Diligent::ShaderVariableVkImpl classes + +// +// * ShaderVariableManagerVk keeps list of variables of specific types +// * Every ShaderVariableVkImpl references VkResource from ShaderResourceLayoutVk +// * ShaderVariableManagerVk keeps reference to ShaderResourceCacheVk +// * ShaderVariableManagerVk is used by PipelineStateVkImpl to manage static resources and by +// ShaderResourceBindingVkImpl to manage mutable and dynamic resources +// +// __________________________ __________________________________________________________________________ +// | | | | | | +// .----| ShaderVariableManagerVk |---------------->| ShaderVariableVkImpl[0] | ShaderVariableVkImpl[1] | ... | +// | |__________________________| |___________________________|____________________________|_________________| +// | \ | +// | Ref Ref +// | \ | +// | ___________________________ ______________________V_______________________V____________________________ +// | | | unique_ptr | | | | | +// | | ShaderResourceLayoutVk |--------------->| VkResource[0] | VkResource[1] | ... | VkResource[s+m+d-1] | +// | |___________________________| |___________________|_________________|_______________|_____________________| +// | | | +// | | | +// | | (DescriptorSet, CacheOffset) / (DescriptorSet, CacheOffset) +// | \ / +// | __________________________ ________V_______________________________________________________V_______ +// | | | | | +// '--->| ShaderResourceCacheVk |---------------->| Resources | +// |__________________________| |________________________________________________________________________| +// +// + +#include + +#include "ShaderResourceLayoutVk.hpp" +#include "ShaderResourceVariableBase.hpp" + +namespace Diligent +{ + +class ShaderVariableVkImpl; + +// sizeof(ShaderVariableManagerVk) == 32 (x64, msvc, Release) +class ShaderVariableManagerVk +{ +public: + ShaderVariableManagerVk(IObject& Owner, + const ShaderResourceLayoutVk& SrcLayout, + IMemoryAllocator& Allocator, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + ShaderResourceCacheVk& ResourceCache); + + ~ShaderVariableManagerVk(); + + void DestroyVariables(IMemoryAllocator& Allocator); + + ShaderVariableVkImpl* GetVariable(const Char* Name); + ShaderVariableVkImpl* GetVariable(Uint32 Index); + + void BindResources(IResourceMapping* pResourceMapping, Uint32 Flags); + + static size_t GetRequiredMemorySize(const ShaderResourceLayoutVk& Layout, + const SHADER_RESOURCE_VARIABLE_TYPE* AllowedVarTypes, + Uint32 NumAllowedTypes, + Uint32& NumVariables); + + Uint32 GetVariableCount() const { return m_NumVariables; } + +private: + friend ShaderVariableVkImpl; + + Uint32 GetVariableIndex(const ShaderVariableVkImpl& Variable); + + IObject& m_Owner; + // Variable mgr is owned by either Pipeline state object (in which case m_ResourceCache references + // static resource cache owned by the same PSO object), or by SRB object (in which case + // m_ResourceCache references the cache in the SRB). Thus the cache and the resource layout + // (which the variables reference) are guaranteed to be alive while the manager is alive. + ShaderResourceCacheVk& m_ResourceCache; + + // Memory is allocated through the allocator provided by the pipeline state. If allocation granularity > 1, fixed block + // memory allocator is used. This ensures that all resources from different shader resource bindings reside in + // continuous memory. If allocation granularity == 1, raw allocator is used. + ShaderVariableVkImpl* m_pVariables = nullptr; + Uint32 m_NumVariables = 0; + +#ifdef _DEBUG + IMemoryAllocator& m_DbgAllocator; +#endif +}; + +// sizeof(ShaderVariableVkImpl) == 24 (x64) +class ShaderVariableVkImpl final : public IShaderResourceVariable +{ +public: + ShaderVariableVkImpl(ShaderVariableManagerVk& ParentManager, + const ShaderResourceLayoutVk::VkResource& Resource) : + m_ParentManager{ParentManager}, + m_Resource{Resource} + {} + + // clang-format off + ShaderVariableVkImpl (const ShaderVariableVkImpl&) = delete; + ShaderVariableVkImpl (ShaderVariableVkImpl&&) = delete; + ShaderVariableVkImpl& operator= (const ShaderVariableVkImpl&) = delete; + ShaderVariableVkImpl& operator= (ShaderVariableVkImpl&&) = delete; + // clang-format on + + + virtual IReferenceCounters* GetReferenceCounters() const override final + { + return m_ParentManager.m_Owner.GetReferenceCounters(); + } + + virtual Atomics::Long AddRef() override final + { + return m_ParentManager.m_Owner.AddRef(); + } + + virtual Atomics::Long Release() override final + { + return m_ParentManager.m_Owner.Release(); + } + + void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final + { + if (ppInterface == nullptr) + return; + + *ppInterface = nullptr; + if (IID == IID_ShaderResourceVariable || IID == IID_Unknown) + { + *ppInterface = this; + (*ppInterface)->AddRef(); + } + } + + virtual SHADER_RESOURCE_VARIABLE_TYPE GetType() const override final + { + return m_Resource.GetVariableType(); + } + + virtual void Set(IDeviceObject* pObject) override final + { + m_Resource.BindResource(pObject, 0, m_ParentManager.m_ResourceCache); + } + + virtual void SetArray(IDeviceObject* const* ppObjects, Uint32 FirstElement, Uint32 NumElements) override final + { + VerifyAndCorrectSetArrayArguments(m_Resource.SpirvAttribs.Name, m_Resource.SpirvAttribs.ArraySize, FirstElement, NumElements); + for (Uint32 Elem = 0; Elem < NumElements; ++Elem) + m_Resource.BindResource(ppObjects[Elem], FirstElement + Elem, m_ParentManager.m_ResourceCache); + } + + virtual void GetResourceDesc(ShaderResourceDesc& ResourceDesc) const override final + { + ResourceDesc = m_Resource.SpirvAttribs.GetResourceDesc(); + } + + virtual Uint32 GetIndex() const override final + { + return m_ParentManager.GetVariableIndex(*this); + } + + virtual bool IsBound(Uint32 ArrayIndex) const override final + { + return m_Resource.IsBound(ArrayIndex, m_ParentManager.m_ResourceCache); + } + + const ShaderResourceLayoutVk::VkResource& GetResource() const + { + return m_Resource; + } + +private: + friend ShaderVariableManagerVk; + + ShaderVariableManagerVk& m_ParentManager; + const ShaderResourceLayoutVk::VkResource& m_Resource; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h deleted file mode 100644 index d1bee3ba..00000000 --- a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::ShaderVkImpl class - -#include "RenderDeviceVk.h" -#include "ShaderVk.h" -#include "ShaderBase.hpp" -#include "SPIRVShaderResources.hpp" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class ResourceMapping; -class FixedBlockMemoryAllocator; - -/// Shader object object implementation in Vulkan backend. -class ShaderVkImpl final : public ShaderBase -{ -public: - using TShaderBase = ShaderBase; - - ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreateInfo& CreationAttribs); - ~ShaderVkImpl(); - - IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderVk, TShaderBase); - - /// Implementation of IShader::GetResourceCount() in Vulkan backend. - virtual Uint32 GetResourceCount() const override final - { - return m_pShaderResources->GetTotalResources(); - } - - /// Implementation of IShader::GetResource() in Vulkan backend. - virtual void GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final; - - /// Implementation of IShaderVk::GetSPIRV(). - virtual const std::vector& GetSPIRV() const override final - { - return m_SPIRV; - } - - const std::shared_ptr& GetShaderResources() const { return m_pShaderResources; } - - const char* GetEntryPoint() const { return m_EntryPoint.c_str(); } - -private: - void MapHLSLVertexShaderInputs(); - - // SPIRVShaderResources class instance must be referenced through the shared pointer, because - // it is referenced by ShaderResourceLayoutVk class instances - std::shared_ptr m_pShaderResources; - - std::string m_EntryPoint; - std::vector m_SPIRV; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp new file mode 100644 index 00000000..d1801615 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/ShaderVkImpl.hpp @@ -0,0 +1,86 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::ShaderVkImpl class + +#include "RenderDeviceVk.h" +#include "ShaderVk.h" +#include "ShaderBase.hpp" +#include "SPIRVShaderResources.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class ResourceMapping; +class FixedBlockMemoryAllocator; + +/// Shader object object implementation in Vulkan backend. +class ShaderVkImpl final : public ShaderBase +{ +public: + using TShaderBase = ShaderBase; + + ShaderVkImpl(IReferenceCounters* pRefCounters, RenderDeviceVkImpl* pRenderDeviceVk, const ShaderCreateInfo& CreationAttribs); + ~ShaderVkImpl(); + + IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_ShaderVk, TShaderBase); + + /// Implementation of IShader::GetResourceCount() in Vulkan backend. + virtual Uint32 GetResourceCount() const override final + { + return m_pShaderResources->GetTotalResources(); + } + + /// Implementation of IShader::GetResource() in Vulkan backend. + virtual void GetResourceDesc(Uint32 Index, ShaderResourceDesc& ResourceDesc) const override final; + + /// Implementation of IShaderVk::GetSPIRV(). + virtual const std::vector& GetSPIRV() const override final + { + return m_SPIRV; + } + + const std::shared_ptr& GetShaderResources() const { return m_pShaderResources; } + + const char* GetEntryPoint() const { return m_EntryPoint.c_str(); } + +private: + void MapHLSLVertexShaderInputs(); + + // SPIRVShaderResources class instance must be referenced through the shared pointer, because + // it is referenced by ShaderResourceLayoutVk class instances + std::shared_ptr m_pShaderResources; + + std::string m_EntryPoint; + std::vector m_SPIRV; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h deleted file mode 100644 index 807d7489..00000000 --- a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::SwapChainVkImpl class - -#include "SwapChainVk.h" -#include "SwapChainBase.hpp" -#include "VulkanUtilities/VulkanInstance.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "ManagedVulkanObject.h" - -namespace Diligent -{ - -class ITextureViewVk; -class IMemoryAllocator; - -/// Swap chain implementation in Vulkan backend. -class SwapChainVkImpl final : public SwapChainBase -{ -public: - using TSwapChainBase = SwapChainBase; - - SwapChainVkImpl(IReferenceCounters* pRefCounters, - const SwapChainDesc& SwapChainDesc, - class RenderDeviceVkImpl* pRenderDeviceVk, - class DeviceContextVkImpl* pDeviceContextVk, - void* pNativeWndHandle); - ~SwapChainVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ISwapChain::Present() in Vulkan backend. - virtual void Present(Uint32 SyncInterval) override final; - - /// Implementation of ISwapChain::Resize() in Vulkan backend. - virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; - - /// Implementation of ISwapChain::SetFullscreenMode() in Vulkan backend. - virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final; - - /// Implementation of ISwapChain::SetWindowedMode() in Vulkan backend. - virtual void SetWindowedMode() override final; - - /// Implementation of ISwapChainVk::GetVkSwapChain(). - virtual VkSwapchainKHR GetVkSwapChain() override final { return m_VkSwapChain; } - - /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in Vulkan backend. - virtual ITextureViewVk* GetCurrentBackBufferRTV() override final - { - VERIFY_EXPR(m_BackBufferIndex >= 0 && m_BackBufferIndex < m_SwapChainDesc.BufferCount); - return m_pBackBufferRTV[m_BackBufferIndex]; - } - - /// Implementation of ISwapChain::GetDepthBufferDSV() in Vulkan backend. - virtual ITextureViewVk* GetDepthBufferDSV() override final { return m_pDepthBufferDSV; } - -private: - void CreateVulkanSwapChain(); - void InitBuffersAndViews(); - VkResult AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk); - void RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk); - void WaitForImageAcquiredFences(); - - std::shared_ptr m_VulkanInstance; - - VkSurfaceKHR m_VkSurface = VK_NULL_HANDLE; - VkSwapchainKHR m_VkSwapChain = VK_NULL_HANDLE; - VkFormat m_VkColorFormat = VK_FORMAT_UNDEFINED; - - std::vector> m_ImageAcquiredSemaphores; - std::vector> m_DrawCompleteSemaphores; - std::vector m_ImageAcquiredFences; - - std::vector, STDAllocatorRawMem>> m_pBackBufferRTV; - - std::vector> m_SwapChainImagesInitialized; - std::vector> m_ImageAcquiredFenceSubmitted; - - RefCntAutoPtr m_pDepthBufferDSV; - - Uint32 m_SemaphoreIndex = 0; - uint32_t m_BackBufferIndex = 0; - bool m_IsMinimized = false; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp new file mode 100644 index 00000000..961343f2 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/SwapChainVkImpl.hpp @@ -0,0 +1,114 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::SwapChainVkImpl class + +#include "SwapChainVk.h" +#include "SwapChainBase.hpp" +#include "VulkanUtilities/VulkanInstance.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "ManagedVulkanObject.hpp" + +namespace Diligent +{ + +class ITextureViewVk; +class IMemoryAllocator; + +/// Swap chain implementation in Vulkan backend. +class SwapChainVkImpl final : public SwapChainBase +{ +public: + using TSwapChainBase = SwapChainBase; + + SwapChainVkImpl(IReferenceCounters* pRefCounters, + const SwapChainDesc& SwapChainDesc, + class RenderDeviceVkImpl* pRenderDeviceVk, + class DeviceContextVkImpl* pDeviceContextVk, + void* pNativeWndHandle); + ~SwapChainVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ISwapChain::Present() in Vulkan backend. + virtual void Present(Uint32 SyncInterval) override final; + + /// Implementation of ISwapChain::Resize() in Vulkan backend. + virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final; + + /// Implementation of ISwapChain::SetFullscreenMode() in Vulkan backend. + virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final; + + /// Implementation of ISwapChain::SetWindowedMode() in Vulkan backend. + virtual void SetWindowedMode() override final; + + /// Implementation of ISwapChainVk::GetVkSwapChain(). + virtual VkSwapchainKHR GetVkSwapChain() override final { return m_VkSwapChain; } + + /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in Vulkan backend. + virtual ITextureViewVk* GetCurrentBackBufferRTV() override final + { + VERIFY_EXPR(m_BackBufferIndex >= 0 && m_BackBufferIndex < m_SwapChainDesc.BufferCount); + return m_pBackBufferRTV[m_BackBufferIndex]; + } + + /// Implementation of ISwapChain::GetDepthBufferDSV() in Vulkan backend. + virtual ITextureViewVk* GetDepthBufferDSV() override final { return m_pDepthBufferDSV; } + +private: + void CreateVulkanSwapChain(); + void InitBuffersAndViews(); + VkResult AcquireNextImage(DeviceContextVkImpl* pDeviceCtxVk); + void RecreateVulkanSwapchain(DeviceContextVkImpl* pImmediateCtxVk); + void WaitForImageAcquiredFences(); + + std::shared_ptr m_VulkanInstance; + + VkSurfaceKHR m_VkSurface = VK_NULL_HANDLE; + VkSwapchainKHR m_VkSwapChain = VK_NULL_HANDLE; + VkFormat m_VkColorFormat = VK_FORMAT_UNDEFINED; + + std::vector> m_ImageAcquiredSemaphores; + std::vector> m_DrawCompleteSemaphores; + std::vector m_ImageAcquiredFences; + + std::vector, STDAllocatorRawMem>> m_pBackBufferRTV; + + std::vector> m_SwapChainImagesInitialized; + std::vector> m_ImageAcquiredFenceSubmitted; + + RefCntAutoPtr m_pDepthBufferDSV; + + Uint32 m_SemaphoreIndex = 0; + uint32_t m_BackBufferIndex = 0; + bool m_IsMinimized = false; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h deleted file mode 100644 index abde01ef..00000000 --- a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::TextureViewVkImpl class - -#include "TextureViewVk.h" -#include "RenderDeviceVk.h" -#include "TextureViewBase.hpp" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -/// Texture view implementation in Vulkan backend. -class TextureViewVkImpl final : public TextureViewBase -{ -public: - using TTextureViewBase = TextureViewBase; - - TextureViewVkImpl(IReferenceCounters* pRefCounters, - RenderDeviceVkImpl* pDevice, - const TextureViewDesc& ViewDesc, - class ITexture* pTexture, - VulkanUtilities::ImageViewWrapper&& ImgView, - bool bIsDefaultView); - ~TextureViewVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ITextureViewVk::GetVulkanImageView(). - VkImageView GetVulkanImageView() const override final { return m_ImageView; } - - bool HasMipLevelViews() const - { - return m_MipLevelViews != nullptr; - } - - TextureViewVkImpl* GetMipLevelSRV(Uint32 MipLevel) - { - VERIFY_EXPR(m_MipLevelViews != nullptr && MipLevel < m_Desc.NumMipLevels); - return m_MipLevelViews[MipLevel * 2].get(); - } - - TextureViewVkImpl* GetMipLevelUAV(Uint32 MipLevel) - { - VERIFY_EXPR(m_MipLevelViews != nullptr && MipLevel < m_Desc.NumMipLevels); - return m_MipLevelViews[MipLevel * 2 + 1].get(); - } - - using MipLevelViewAutoPtrType = std::unique_ptr>; - - void AssignMipLevelViews(MipLevelViewAutoPtrType* MipLevelViews) - { - m_MipLevelViews = MipLevelViews; - } - -protected: - /// Vulkan image view descriptor handle - VulkanUtilities::ImageViewWrapper m_ImageView; - - /// Individual mip level views used for mipmap generation - MipLevelViewAutoPtrType* m_MipLevelViews = nullptr; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.hpp new file mode 100644 index 00000000..5731512f --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/TextureViewVkImpl.hpp @@ -0,0 +1,95 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureViewVkImpl class + +#include "TextureViewVk.h" +#include "RenderDeviceVk.h" +#include "TextureViewBase.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +/// Texture view implementation in Vulkan backend. +class TextureViewVkImpl final : public TextureViewBase +{ +public: + using TTextureViewBase = TextureViewBase; + + TextureViewVkImpl(IReferenceCounters* pRefCounters, + RenderDeviceVkImpl* pDevice, + const TextureViewDesc& ViewDesc, + class ITexture* pTexture, + VulkanUtilities::ImageViewWrapper&& ImgView, + bool bIsDefaultView); + ~TextureViewVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ITextureViewVk::GetVulkanImageView(). + VkImageView GetVulkanImageView() const override final { return m_ImageView; } + + bool HasMipLevelViews() const + { + return m_MipLevelViews != nullptr; + } + + TextureViewVkImpl* GetMipLevelSRV(Uint32 MipLevel) + { + VERIFY_EXPR(m_MipLevelViews != nullptr && MipLevel < m_Desc.NumMipLevels); + return m_MipLevelViews[MipLevel * 2].get(); + } + + TextureViewVkImpl* GetMipLevelUAV(Uint32 MipLevel) + { + VERIFY_EXPR(m_MipLevelViews != nullptr && MipLevel < m_Desc.NumMipLevels); + return m_MipLevelViews[MipLevel * 2 + 1].get(); + } + + using MipLevelViewAutoPtrType = std::unique_ptr>; + + void AssignMipLevelViews(MipLevelViewAutoPtrType* MipLevelViews) + { + m_MipLevelViews = MipLevelViews; + } + +protected: + /// Vulkan image view descriptor handle + VulkanUtilities::ImageViewWrapper m_ImageView; + + /// Individual mip level views used for mipmap generation + MipLevelViewAutoPtrType* m_MipLevelViews = nullptr; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h deleted file mode 100644 index 2140a43d..00000000 --- a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Declaration of Diligent::TextureVkImpl class - -#include "TextureVk.h" -#include "RenderDeviceVk.h" -#include "TextureBase.hpp" -#include "TextureViewVkImpl.h" -#include "VulkanUtilities/VulkanMemoryManager.h" -#include "RenderDeviceVkImpl.h" - -namespace Diligent -{ - -class FixedBlockMemoryAllocator; - -Uint32 GetStagingDataOffset(const TextureDesc& TexDesc, Uint32 ArraySlice, Uint32 MipLevel); - -/// Texture object implementation in Vulkan backend. -class TextureVkImpl final : public TextureBase -{ -public: - using TTextureBase = TextureBase; - using ViewImplType = TextureViewVkImpl; - - // Creates a new Vk resource - TextureVkImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - RenderDeviceVkImpl* pDeviceVk, - const TextureDesc& TexDesc, - const TextureData* pInitData = nullptr); - - // Attaches to an existing Vk resource - TextureVkImpl(IReferenceCounters* pRefCounters, - FixedBlockMemoryAllocator& TexViewObjAllocator, - class RenderDeviceVkImpl* pDeviceVk, - const TextureDesc& TexDesc, - RESOURCE_STATE InitialState, - VkImage VkImageHandle); - - ~TextureVkImpl(); - - virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; - - /// Implementation of ITextureVk::GetVkImage(). - virtual VkImage GetVkImage() const override final { return m_VulkanImage; } - - /// Implementation of ITexture::GetNativeHandle() in Vulkan backend. - virtual void* GetNativeHandle() override final - { - auto vkImage = GetVkImage(); - return reinterpret_cast(vkImage); - } - - /// Implementation of ITextureVk::SetLayout(). - void SetLayout(VkImageLayout Layout) override final; - - /// Implementation of ITextureVk::GetLayout(). - VkImageLayout GetLayout() const override final; - - VkBuffer GetVkStagingBuffer() const - { - return m_StagingBuffer; - } - - uint8_t* GetStagingDataCPUAddress() const - { - auto* StagingDataCPUAddress = reinterpret_cast(m_MemoryAllocation.Page->GetCPUMemory()); - VERIFY_EXPR(StagingDataCPUAddress != nullptr); - StagingDataCPUAddress += m_StagingDataAlignedOffset; - return StagingDataCPUAddress; - } - - void InvalidateStagingRange(VkDeviceSize Offset, VkDeviceSize Size); - -protected: - void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override; - //void PrepareVkInitData(const TextureData &InitData, Uint32 NumSubresources, std::vector &VkInitData); - - bool CheckCSBasedMipGenerationSupport(VkFormat vkFmt) const; - - VulkanUtilities::ImageViewWrapper CreateImageView(TextureViewDesc& ViewDesc); - - VulkanUtilities::ImageWrapper m_VulkanImage; - VulkanUtilities::BufferWrapper m_StagingBuffer; - VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; - VkDeviceSize m_StagingDataAlignedOffset; - bool m_bCSBasedMipGenerationSupported = false; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp new file mode 100644 index 00000000..8ba8a392 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/TextureVkImpl.hpp @@ -0,0 +1,119 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Declaration of Diligent::TextureVkImpl class + +#include "TextureVk.h" +#include "RenderDeviceVk.h" +#include "TextureBase.hpp" +#include "TextureViewVkImpl.hpp" +#include "VulkanUtilities/VulkanMemoryManager.hpp" +#include "RenderDeviceVkImpl.hpp" + +namespace Diligent +{ + +class FixedBlockMemoryAllocator; + +Uint32 GetStagingDataOffset(const TextureDesc& TexDesc, Uint32 ArraySlice, Uint32 MipLevel); + +/// Texture object implementation in Vulkan backend. +class TextureVkImpl final : public TextureBase +{ +public: + using TTextureBase = TextureBase; + using ViewImplType = TextureViewVkImpl; + + // Creates a new Vk resource + TextureVkImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceVkImpl* pDeviceVk, + const TextureDesc& TexDesc, + const TextureData* pInitData = nullptr); + + // Attaches to an existing Vk resource + TextureVkImpl(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceVkImpl* pDeviceVk, + const TextureDesc& TexDesc, + RESOURCE_STATE InitialState, + VkImage VkImageHandle); + + ~TextureVkImpl(); + + virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) override final; + + /// Implementation of ITextureVk::GetVkImage(). + virtual VkImage GetVkImage() const override final { return m_VulkanImage; } + + /// Implementation of ITexture::GetNativeHandle() in Vulkan backend. + virtual void* GetNativeHandle() override final + { + auto vkImage = GetVkImage(); + return reinterpret_cast(vkImage); + } + + /// Implementation of ITextureVk::SetLayout(). + void SetLayout(VkImageLayout Layout) override final; + + /// Implementation of ITextureVk::GetLayout(). + VkImageLayout GetLayout() const override final; + + VkBuffer GetVkStagingBuffer() const + { + return m_StagingBuffer; + } + + uint8_t* GetStagingDataCPUAddress() const + { + auto* StagingDataCPUAddress = reinterpret_cast(m_MemoryAllocation.Page->GetCPUMemory()); + VERIFY_EXPR(StagingDataCPUAddress != nullptr); + StagingDataCPUAddress += m_StagingDataAlignedOffset; + return StagingDataCPUAddress; + } + + void InvalidateStagingRange(VkDeviceSize Offset, VkDeviceSize Size); + +protected: + void CreateViewInternal(const struct TextureViewDesc& ViewDesc, ITextureView** ppView, bool bIsDefaultView) override; + //void PrepareVkInitData(const TextureData &InitData, Uint32 NumSubresources, std::vector &VkInitData); + + bool CheckCSBasedMipGenerationSupport(VkFormat vkFmt) const; + + VulkanUtilities::ImageViewWrapper CreateImageView(TextureViewDesc& ViewDesc); + + VulkanUtilities::ImageWrapper m_VulkanImage; + VulkanUtilities::BufferWrapper m_StagingBuffer; + VulkanUtilities::VulkanMemoryAllocation m_MemoryAllocation; + VkDeviceSize m_StagingDataAlignedOffset; + bool m_bCSBasedMipGenerationSupported = false; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h b/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h deleted file mode 100644 index 86b9434a..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include "vulkan.h" -#include "VulkanUtilities/VulkanMemoryManager.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "DynamicHeap.hpp" - -namespace Diligent -{ - -// Vulkand dynamic heap implementation consists of a number of dynamic heaps, one per context. -// Every dynamic heap suballocates chunk of memory from the global memory manager. Within -// every chunk, memory is allocated in a simple lock-free linear fashion. All used allocations are discarded -// when FinishFrame() is called - -class RenderDeviceVkImpl; -class VulkanRingBuffer; -class VulkanDynamicMemoryManager; - -// sizeof(VulkanDynamicAllocation) must be at least 16 to avoid false cache line sharing problems -struct VulkanDynamicAllocation -{ - VulkanDynamicAllocation() noexcept {} - - // clang-format off - VulkanDynamicAllocation(VulkanDynamicMemoryManager& _DynamicMemMgr, size_t _AlignedOffset, size_t _Size)noexcept : - pDynamicMemMgr{&_DynamicMemMgr}, - AlignedOffset {_AlignedOffset }, - Size {_Size } - {} - - VulkanDynamicAllocation (const VulkanDynamicAllocation&) = delete; - VulkanDynamicAllocation& operator = (const VulkanDynamicAllocation&) = delete; - - VulkanDynamicAllocation (VulkanDynamicAllocation&& rhs)noexcept : - pDynamicMemMgr{rhs.pDynamicMemMgr}, - AlignedOffset {rhs.AlignedOffset }, - Size {rhs.Size } -#ifdef DEVELOPMENT - , dvpFrameNumber{rhs.dvpFrameNumber} -#endif - { - rhs.pDynamicMemMgr = nullptr; - rhs.AlignedOffset = 0; - rhs.Size = 0; -#ifdef DEVELOPMENT - rhs.dvpFrameNumber = 0; -#endif - } - // clang-format on - - VulkanDynamicAllocation& operator=(VulkanDynamicAllocation&& rhs) noexcept // Must be noexcept on MSVC, so can't use = default - { - pDynamicMemMgr = rhs.pDynamicMemMgr; - AlignedOffset = rhs.AlignedOffset; - Size = rhs.Size; - rhs.pDynamicMemMgr = nullptr; - rhs.AlignedOffset = 0; - rhs.Size = 0; -#ifdef DEVELOPMENT - dvpFrameNumber = rhs.dvpFrameNumber; - rhs.dvpFrameNumber = 0; -#endif - return *this; - } - - VulkanDynamicMemoryManager* pDynamicMemMgr = nullptr; - size_t AlignedOffset = 0; // Offset from the start of the buffer - size_t Size = 0; // Reserved size of this allocation -#ifdef DEVELOPMENT - Int64 dvpFrameNumber = 0; -#endif -}; - - -// VulkanDynamicMemoryManager manages allocation of master blocks from global dynamic buffer -// -// _______________________________________________________________________ -// | | -// | VulkanDynamicMemoryManager | -// | | -// | || - - - - - - - - - - Dynamic Memory Buffer- - - - - - - - - -|| | -// | || MasterBlock[0] | MasterBlock[1] | ... | MasterBlock[N-1] || | -// |_______________________________________________________________________| -// -// We cannot use global memory manager for dynamic resources because they -// need to use the same Vulkan buffer -class VulkanDynamicMemoryManager : public DynamicHeap::MasterBlockListBasedManager -{ -public: - using TBase = DynamicHeap::MasterBlockListBasedManager; - using OffsetType = TBase::OffsetType; - using MasterBlock = TBase::MasterBlock; - - VulkanDynamicMemoryManager(IMemoryAllocator& Allocator, - class RenderDeviceVkImpl& DeviceVk, - Uint32 Size, - Uint64 CommandQueueMask); - ~VulkanDynamicMemoryManager(); - - // clang-format off - VulkanDynamicMemoryManager (const VulkanDynamicMemoryManager&) = delete; - VulkanDynamicMemoryManager ( VulkanDynamicMemoryManager&&) = delete; - VulkanDynamicMemoryManager& operator= (const VulkanDynamicMemoryManager&) = delete; - VulkanDynamicMemoryManager& operator= ( VulkanDynamicMemoryManager&&) = delete; - - VkBuffer GetVkBuffer() const{return m_VkBuffer;} - Uint8* GetCPUAddress()const{return m_CPUAddress;} - // clang-format on - - void Destroy(); - - static constexpr const Uint32 MasterBlockAlignment = 1024; - MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment); - -private: - RenderDeviceVkImpl& m_DeviceVk; - VulkanUtilities::BufferWrapper m_VkBuffer; - VulkanUtilities::DeviceMemoryWrapper m_BufferMemory; - Uint8* m_CPUAddress; - const VkDeviceSize m_DefaultAlignment; - const Uint64 m_CommandQueueMask; - OffsetType m_TotalPeakSize = 0; -}; - - - -// Dynamic heap is used by a device context to allocate dynamic space when -// mapping a buffer or a texture. This is very similar to upload heap, -// however dynamic heap uses special persistently mapped buffer while -// upload heap uses global memory manager. -// -// The heap allocates master blocks from the global dynamic memory manager. -// The pages are released and returned to the manager at the end of every frame. -// -// _______________________________________________________________________________________________________________________________ -// | | -// | VulkanDynamicHeap | -// | | -// | || - - - - - - - - - MasterBlock[0]- - - - - - - - -|| || - - - - - - - - - MasterBlock[1]- - - - - - - - -|| | -// | || Allocation0 | Allocation1 | ... | AllocationN || || Allocation0 | Allocation1 | ... | AllocationM || ... | -// |__________|____________________________________________________________________________________________________________________| -// | A | -// | | | -// |Allocate() AllocateMasterBlock()| |FinishFrame() -// | ______|___________________V____ -// V | | -// | VulkanDynamicMemoryManager | -// | | -// | |Global dynamic buffer| | -// |______________________________| -// -class VulkanDynamicHeap -{ -public: - // clang-format off - VulkanDynamicHeap(VulkanDynamicMemoryManager& DynamicMemMgr, std::string HeapName, Uint32 PageSize) : - m_GlobalDynamicMemMgr{DynamicMemMgr}, - m_HeapName {std::move(HeapName)}, - m_MasterBlockSize (PageSize) - {} - - VulkanDynamicHeap (const VulkanDynamicHeap&) = delete; - VulkanDynamicHeap (VulkanDynamicHeap&&) = delete; - VulkanDynamicHeap& operator= (const VulkanDynamicHeap&) = delete; - VulkanDynamicHeap& operator= (VulkanDynamicHeap&&) = delete; - // clang-format on - - ~VulkanDynamicHeap(); - - VulkanDynamicAllocation Allocate(Uint32 SizeInBytes, Uint32 Alignment); - - // Releases all master blocks that are later returned to the global dynamic memory manager. - // CmdQueueMask indicates which command queues the allocations from this heap were used - // with during the last frame. - // As global dynamic memory manager is hosted by the render device, the dynamic heap can - // be destroyed before the blocks are actually returned to the global dynamic memory manager. - void ReleaseMasterBlocks(RenderDeviceVkImpl& DeviceVkImpl, Uint64 CmdQueueMask); - - using OffsetType = VulkanDynamicMemoryManager::OffsetType; - using MasterBlock = VulkanDynamicMemoryManager::MasterBlock; - - static constexpr OffsetType InvalidOffset = static_cast(-1); - - size_t GetAllocatedMasterBlockCount() const { return m_MasterBlocks.size(); } - -private: - VulkanDynamicMemoryManager& m_GlobalDynamicMemMgr; - const std::string m_HeapName; - - std::vector m_MasterBlocks; - - OffsetType m_CurrOffset = InvalidOffset; - const Uint32 m_MasterBlockSize; - Uint32 m_AvailableSize = 0; - - Uint32 m_CurrAlignedSize = 0; - Uint32 m_CurrUsedSize = 0; - Uint32 m_PeakAlignedSize = 0; - Uint32 m_PeakUsedSize = 0; - Uint32 m_CurrAllocatedSize = 0; - Uint32 m_PeakAllocatedSize = 0; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.hpp new file mode 100644 index 00000000..b9b066b5 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanDynamicHeap.hpp @@ -0,0 +1,234 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "vulkan.h" +#include "VulkanUtilities/VulkanMemoryManager.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "DynamicHeap.hpp" + +namespace Diligent +{ + +// Vulkand dynamic heap implementation consists of a number of dynamic heaps, one per context. +// Every dynamic heap suballocates chunk of memory from the global memory manager. Within +// every chunk, memory is allocated in a simple lock-free linear fashion. All used allocations are discarded +// when FinishFrame() is called + +class RenderDeviceVkImpl; +class VulkanRingBuffer; +class VulkanDynamicMemoryManager; + +// sizeof(VulkanDynamicAllocation) must be at least 16 to avoid false cache line sharing problems +struct VulkanDynamicAllocation +{ + VulkanDynamicAllocation() noexcept {} + + // clang-format off + VulkanDynamicAllocation(VulkanDynamicMemoryManager& _DynamicMemMgr, size_t _AlignedOffset, size_t _Size)noexcept : + pDynamicMemMgr{&_DynamicMemMgr}, + AlignedOffset {_AlignedOffset }, + Size {_Size } + {} + + VulkanDynamicAllocation (const VulkanDynamicAllocation&) = delete; + VulkanDynamicAllocation& operator = (const VulkanDynamicAllocation&) = delete; + + VulkanDynamicAllocation (VulkanDynamicAllocation&& rhs)noexcept : + pDynamicMemMgr{rhs.pDynamicMemMgr}, + AlignedOffset {rhs.AlignedOffset }, + Size {rhs.Size } +#ifdef DEVELOPMENT + , dvpFrameNumber{rhs.dvpFrameNumber} +#endif + { + rhs.pDynamicMemMgr = nullptr; + rhs.AlignedOffset = 0; + rhs.Size = 0; +#ifdef DEVELOPMENT + rhs.dvpFrameNumber = 0; +#endif + } + // clang-format on + + VulkanDynamicAllocation& operator=(VulkanDynamicAllocation&& rhs) noexcept // Must be noexcept on MSVC, so can't use = default + { + pDynamicMemMgr = rhs.pDynamicMemMgr; + AlignedOffset = rhs.AlignedOffset; + Size = rhs.Size; + rhs.pDynamicMemMgr = nullptr; + rhs.AlignedOffset = 0; + rhs.Size = 0; +#ifdef DEVELOPMENT + dvpFrameNumber = rhs.dvpFrameNumber; + rhs.dvpFrameNumber = 0; +#endif + return *this; + } + + VulkanDynamicMemoryManager* pDynamicMemMgr = nullptr; + size_t AlignedOffset = 0; // Offset from the start of the buffer + size_t Size = 0; // Reserved size of this allocation +#ifdef DEVELOPMENT + Int64 dvpFrameNumber = 0; +#endif +}; + + +// VulkanDynamicMemoryManager manages allocation of master blocks from global dynamic buffer +// +// _______________________________________________________________________ +// | | +// | VulkanDynamicMemoryManager | +// | | +// | || - - - - - - - - - - Dynamic Memory Buffer- - - - - - - - - -|| | +// | || MasterBlock[0] | MasterBlock[1] | ... | MasterBlock[N-1] || | +// |_______________________________________________________________________| +// +// We cannot use global memory manager for dynamic resources because they +// need to use the same Vulkan buffer +class VulkanDynamicMemoryManager : public DynamicHeap::MasterBlockListBasedManager +{ +public: + using TBase = DynamicHeap::MasterBlockListBasedManager; + using OffsetType = TBase::OffsetType; + using MasterBlock = TBase::MasterBlock; + + VulkanDynamicMemoryManager(IMemoryAllocator& Allocator, + class RenderDeviceVkImpl& DeviceVk, + Uint32 Size, + Uint64 CommandQueueMask); + ~VulkanDynamicMemoryManager(); + + // clang-format off + VulkanDynamicMemoryManager (const VulkanDynamicMemoryManager&) = delete; + VulkanDynamicMemoryManager ( VulkanDynamicMemoryManager&&) = delete; + VulkanDynamicMemoryManager& operator= (const VulkanDynamicMemoryManager&) = delete; + VulkanDynamicMemoryManager& operator= ( VulkanDynamicMemoryManager&&) = delete; + + VkBuffer GetVkBuffer() const{return m_VkBuffer;} + Uint8* GetCPUAddress()const{return m_CPUAddress;} + // clang-format on + + void Destroy(); + + static constexpr const Uint32 MasterBlockAlignment = 1024; + MasterBlock AllocateMasterBlock(OffsetType SizeInBytes, OffsetType Alignment); + +private: + RenderDeviceVkImpl& m_DeviceVk; + VulkanUtilities::BufferWrapper m_VkBuffer; + VulkanUtilities::DeviceMemoryWrapper m_BufferMemory; + Uint8* m_CPUAddress; + const VkDeviceSize m_DefaultAlignment; + const Uint64 m_CommandQueueMask; + OffsetType m_TotalPeakSize = 0; +}; + + + +// Dynamic heap is used by a device context to allocate dynamic space when +// mapping a buffer or a texture. This is very similar to upload heap, +// however dynamic heap uses special persistently mapped buffer while +// upload heap uses global memory manager. +// +// The heap allocates master blocks from the global dynamic memory manager. +// The pages are released and returned to the manager at the end of every frame. +// +// _______________________________________________________________________________________________________________________________ +// | | +// | VulkanDynamicHeap | +// | | +// | || - - - - - - - - - MasterBlock[0]- - - - - - - - -|| || - - - - - - - - - MasterBlock[1]- - - - - - - - -|| | +// | || Allocation0 | Allocation1 | ... | AllocationN || || Allocation0 | Allocation1 | ... | AllocationM || ... | +// |__________|____________________________________________________________________________________________________________________| +// | A | +// | | | +// |Allocate() AllocateMasterBlock()| |FinishFrame() +// | ______|___________________V____ +// V | | +// | VulkanDynamicMemoryManager | +// | | +// | |Global dynamic buffer| | +// |______________________________| +// +class VulkanDynamicHeap +{ +public: + // clang-format off + VulkanDynamicHeap(VulkanDynamicMemoryManager& DynamicMemMgr, std::string HeapName, Uint32 PageSize) : + m_GlobalDynamicMemMgr{DynamicMemMgr}, + m_HeapName {std::move(HeapName)}, + m_MasterBlockSize (PageSize) + {} + + VulkanDynamicHeap (const VulkanDynamicHeap&) = delete; + VulkanDynamicHeap (VulkanDynamicHeap&&) = delete; + VulkanDynamicHeap& operator= (const VulkanDynamicHeap&) = delete; + VulkanDynamicHeap& operator= (VulkanDynamicHeap&&) = delete; + // clang-format on + + ~VulkanDynamicHeap(); + + VulkanDynamicAllocation Allocate(Uint32 SizeInBytes, Uint32 Alignment); + + // Releases all master blocks that are later returned to the global dynamic memory manager. + // CmdQueueMask indicates which command queues the allocations from this heap were used + // with during the last frame. + // As global dynamic memory manager is hosted by the render device, the dynamic heap can + // be destroyed before the blocks are actually returned to the global dynamic memory manager. + void ReleaseMasterBlocks(RenderDeviceVkImpl& DeviceVkImpl, Uint64 CmdQueueMask); + + using OffsetType = VulkanDynamicMemoryManager::OffsetType; + using MasterBlock = VulkanDynamicMemoryManager::MasterBlock; + + static constexpr OffsetType InvalidOffset = static_cast(-1); + + size_t GetAllocatedMasterBlockCount() const { return m_MasterBlocks.size(); } + +private: + VulkanDynamicMemoryManager& m_GlobalDynamicMemMgr; + const std::string m_HeapName; + + std::vector m_MasterBlocks; + + OffsetType m_CurrOffset = InvalidOffset; + const Uint32 m_MasterBlockSize; + Uint32 m_AvailableSize = 0; + + Uint32 m_CurrAlignedSize = 0; + Uint32 m_CurrUsedSize = 0; + Uint32 m_PeakAlignedSize = 0; + Uint32 m_PeakUsedSize = 0; + Uint32 m_CurrAllocatedSize = 0; + Uint32 m_PeakAllocatedSize = 0; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanErrors.h b/Graphics/GraphicsEngineVulkan/include/VulkanErrors.h deleted file mode 100644 index 5cf1427e..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanErrors.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "Errors.h" -#include "DebugUtilities.h" -#include "VulkanUtilities/VulkanDebug.h" - -#define CHECK_VK_ERROR(err, ...) \ - { \ - if (err < 0) \ - { \ - Diligent::LogError(/*IsFatal=*/false, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nVK Error: ", VulkanUtilities::VkResultToString(err)); \ - UNEXPECTED("Error"); \ - } \ - } - -#define CHECK_VK_ERROR_AND_THROW(err, ...) \ - { \ - if (err < 0) \ - Diligent::LogError(/*IsFatal=*/false, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nVK Error Code: ", VulkanUtilities::VkResultToString(err)); \ - } diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanErrors.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanErrors.hpp new file mode 100644 index 00000000..69e665f0 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanErrors.hpp @@ -0,0 +1,47 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "Errors.h" +#include "DebugUtilities.h" +#include "VulkanUtilities/VulkanDebug.hpp" + +#define CHECK_VK_ERROR(err, ...) \ + { \ + if (err < 0) \ + { \ + Diligent::LogError(/*IsFatal=*/false, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nVK Error: ", VulkanUtilities::VkResultToString(err)); \ + UNEXPECTED("Error"); \ + } \ + } + +#define CHECK_VK_ERROR_AND_THROW(err, ...) \ + { \ + if (err < 0) \ + Diligent::LogError(/*IsFatal=*/false, __FUNCTION__, __FILE__, __LINE__, __VA_ARGS__, "\nVK Error Code: ", VulkanUtilities::VkResultToString(err)); \ + } diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h deleted file mode 100644 index 1f752700..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -/// \file -/// Type conversion routines - -#include -#include "GraphicsTypes.h" - -namespace Diligent -{ - -VkFormat TexFormatToVkFormat(TEXTURE_FORMAT TexFmt); -TEXTURE_FORMAT VkFormatToTexFormat(VkFormat VkFmt); - -VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); - -VkPipelineRasterizationStateCreateInfo RasterizerStateDesc_To_VkRasterizationStateCI(const RasterizerStateDesc& RasterizerDesc); -VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilStateCI(const DepthStencilStateDesc& DepthStencilDesc); - -void BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc& BSDesc, - VkPipelineColorBlendStateCreateInfo& ColorBlendStateCI, - std::vector& ColorBlendAttachments); - -void InputLayoutDesc_To_VkVertexInputStateCI(const InputLayoutDesc& LayoutDesc, - VkPipelineVertexInputStateCreateInfo& VertexInputStateCI, - std::array& BindingDescriptions, - std::array& AttributeDescription); - -void PrimitiveTopology_To_VkPrimitiveTopologyAndPatchCPCount(PRIMITIVE_TOPOLOGY PrimTopology, - VkPrimitiveTopology& VkPrimTopology, - uint32_t& PatchControlPoints); - -VkCompareOp ComparisonFuncToVkCompareOp(COMPARISON_FUNCTION CmpFunc); -VkFilter FilterTypeToVkFilter(FILTER_TYPE FilterType); -VkSamplerMipmapMode FilterTypeToVkMipmapMode(FILTER_TYPE FilterType); -VkSamplerAddressMode AddressModeToVkAddressMode(TEXTURE_ADDRESS_MODE AddressMode); -VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[]); - -VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags); -VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag); - -RESOURCE_STATE VkAccessFlagsToResourceStates(VkAccessFlags AccessFlags); -RESOURCE_STATE VkImageLayoutToResourceState(VkImageLayout Layout); - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp new file mode 100644 index 00000000..1f752700 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp @@ -0,0 +1,72 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +/// \file +/// Type conversion routines + +#include +#include "GraphicsTypes.h" + +namespace Diligent +{ + +VkFormat TexFormatToVkFormat(TEXTURE_FORMAT TexFmt); +TEXTURE_FORMAT VkFormatToTexFormat(VkFormat VkFmt); + +VkFormat TypeToVkFormat(VALUE_TYPE ValType, Uint32 NumComponents, Bool bIsNormalized); + +VkPipelineRasterizationStateCreateInfo RasterizerStateDesc_To_VkRasterizationStateCI(const RasterizerStateDesc& RasterizerDesc); +VkPipelineDepthStencilStateCreateInfo DepthStencilStateDesc_To_VkDepthStencilStateCI(const DepthStencilStateDesc& DepthStencilDesc); + +void BlendStateDesc_To_VkBlendStateCI(const BlendStateDesc& BSDesc, + VkPipelineColorBlendStateCreateInfo& ColorBlendStateCI, + std::vector& ColorBlendAttachments); + +void InputLayoutDesc_To_VkVertexInputStateCI(const InputLayoutDesc& LayoutDesc, + VkPipelineVertexInputStateCreateInfo& VertexInputStateCI, + std::array& BindingDescriptions, + std::array& AttributeDescription); + +void PrimitiveTopology_To_VkPrimitiveTopologyAndPatchCPCount(PRIMITIVE_TOPOLOGY PrimTopology, + VkPrimitiveTopology& VkPrimTopology, + uint32_t& PatchControlPoints); + +VkCompareOp ComparisonFuncToVkCompareOp(COMPARISON_FUNCTION CmpFunc); +VkFilter FilterTypeToVkFilter(FILTER_TYPE FilterType); +VkSamplerMipmapMode FilterTypeToVkMipmapMode(FILTER_TYPE FilterType); +VkSamplerAddressMode AddressModeToVkAddressMode(TEXTURE_ADDRESS_MODE AddressMode); +VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[]); + +VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags); +VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag); + +RESOURCE_STATE VkAccessFlagsToResourceStates(VkAccessFlags AccessFlags); +RESOURCE_STATE VkImageLayoutToResourceState(VkImageLayout Layout); + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h b/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h deleted file mode 100644 index ce06a912..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include "VulkanUtilities/VulkanMemoryManager.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace Diligent -{ - -// Upload heap is used by a device context to update texture and buffer regions through -// UpdateBufferRegion() and UpdateTextureRegion(). -// -// The heap allocates pages from the global memory manager. -// The pages are released and returned to the manager at the end of every frame. -// -// _______________________________________________________________________________________________________________________________ -// | | -// | VulkanUploadHeap | -// | | -// | || - - - - - - - - - - Page[0] - - - - - - - - - - -|| || - - - - - - - - - - Page[1] - - - - - - - - - - -|| | -// | || Allocation0 | Allocation1 | ... | AllocationN || || Allocation0 | Allocation1 | ... | AllocationM || ... | -// |__________|____________________________________________________________________________________________________________________| -// | A | -// | | | -// |Allocate() CreateNewPage()| |ReleaseAllocatedPages() -// | ______|___________________V____ -// V | | -// VulkanUploadAllocation | Global Memory Manager | -// | (VulkanMemoryManager) | -// | | -// |______________________________| -// -class RenderDeviceVkImpl; - -struct VulkanUploadAllocation -{ - VulkanUploadAllocation() noexcept {} - // clang-format off - VulkanUploadAllocation(void* _CPUAddress, - VkDeviceSize _Size, - VkDeviceSize _AlignedOffset, - VkBuffer _vkBuffer) noexcept : - vkBuffer {_vkBuffer }, - CPUAddress {_CPUAddress }, - Size {_Size }, - AlignedOffset{_AlignedOffset} - {} - VulkanUploadAllocation (const VulkanUploadAllocation&) = delete; - VulkanUploadAllocation& operator = (const VulkanUploadAllocation&) = delete; - VulkanUploadAllocation ( VulkanUploadAllocation&&) = default; - VulkanUploadAllocation& operator = ( VulkanUploadAllocation&&) = default; - // clang-format on - - VkBuffer vkBuffer = VK_NULL_HANDLE; // Vulkan buffer associated with this memory. - void* CPUAddress = nullptr; - VkDeviceSize Size = 0; - VkDeviceSize AlignedOffset = 0; -}; - -class VulkanUploadHeap -{ -public: - VulkanUploadHeap(RenderDeviceVkImpl& RenderDevice, - std::string HeapName, - VkDeviceSize PageSize); - - // clang-format off - VulkanUploadHeap (const VulkanUploadHeap&) = delete; - VulkanUploadHeap ( VulkanUploadHeap&&) = delete; - VulkanUploadHeap& operator= (const VulkanUploadHeap&) = delete; - VulkanUploadHeap& operator= ( VulkanUploadHeap&&) = delete; - // clang-format on - - ~VulkanUploadHeap(); - - VulkanUploadAllocation Allocate(VkDeviceSize SizeInBytes, VkDeviceSize Alignment); - - // Releases all allocated pages that are later returned to the global memory manager by the release queues. - // As global memory manager is hosted by the render device, the upload heap can be destroyed before the - // pages are actually returned to the manager. - void ReleaseAllocatedPages(Uint64 CmdQueueMask); - - size_t GetStalePagesCount() const - { - return m_Pages.size(); - } - -private: - RenderDeviceVkImpl& m_RenderDevice; - std::string m_HeapName; - const VkDeviceSize m_PageSize; - - struct UploadPageInfo - { - // clang-format off - UploadPageInfo(VulkanUtilities::VulkanMemoryAllocation&& _MemAllocation, - VulkanUtilities::BufferWrapper&& _Buffer, - Uint8* _CPUAddress) : - MemAllocation{std::move(_MemAllocation)}, - Buffer {std::move(_Buffer) }, - CPUAddress {_CPUAddress } - { - } - // clang-format on - - VulkanUtilities::VulkanMemoryAllocation MemAllocation; - VulkanUtilities::BufferWrapper Buffer; - Uint8* const CPUAddress = nullptr; - }; - std::vector m_Pages; - - struct CurrPageInfo - { - VkBuffer vkBuffer = VK_NULL_HANDLE; - Uint8* CurrCPUAddress = nullptr; - VkDeviceSize CurrOffset = 0; - VkDeviceSize AvailableSize = 0; - - void Reset(UploadPageInfo& NewPage, VkDeviceSize PageSize) - { - vkBuffer = NewPage.Buffer; - CurrCPUAddress = NewPage.CPUAddress; - CurrOffset = 0; - AvailableSize = PageSize; - } - - void Advance(VkDeviceSize SizeInBytes) - { - CurrCPUAddress += SizeInBytes; - CurrOffset += SizeInBytes; - AvailableSize -= SizeInBytes; - } - } m_CurrPage; - - VkDeviceSize m_CurrFrameSize = 0; - VkDeviceSize m_PeakFrameSize = 0; - VkDeviceSize m_CurrAllocatedSize = 0; - VkDeviceSize m_PeakAllocatedSize = 0; - - UploadPageInfo CreateNewPage(VkDeviceSize SizeInBytes) const; -}; - -} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.hpp new file mode 100644 index 00000000..0de10baf --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUploadHeap.hpp @@ -0,0 +1,170 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "VulkanUtilities/VulkanMemoryManager.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace Diligent +{ + +// Upload heap is used by a device context to update texture and buffer regions through +// UpdateBufferRegion() and UpdateTextureRegion(). +// +// The heap allocates pages from the global memory manager. +// The pages are released and returned to the manager at the end of every frame. +// +// _______________________________________________________________________________________________________________________________ +// | | +// | VulkanUploadHeap | +// | | +// | || - - - - - - - - - - Page[0] - - - - - - - - - - -|| || - - - - - - - - - - Page[1] - - - - - - - - - - -|| | +// | || Allocation0 | Allocation1 | ... | AllocationN || || Allocation0 | Allocation1 | ... | AllocationM || ... | +// |__________|____________________________________________________________________________________________________________________| +// | A | +// | | | +// |Allocate() CreateNewPage()| |ReleaseAllocatedPages() +// | ______|___________________V____ +// V | | +// VulkanUploadAllocation | Global Memory Manager | +// | (VulkanMemoryManager) | +// | | +// |______________________________| +// +class RenderDeviceVkImpl; + +struct VulkanUploadAllocation +{ + VulkanUploadAllocation() noexcept {} + // clang-format off + VulkanUploadAllocation(void* _CPUAddress, + VkDeviceSize _Size, + VkDeviceSize _AlignedOffset, + VkBuffer _vkBuffer) noexcept : + vkBuffer {_vkBuffer }, + CPUAddress {_CPUAddress }, + Size {_Size }, + AlignedOffset{_AlignedOffset} + {} + VulkanUploadAllocation (const VulkanUploadAllocation&) = delete; + VulkanUploadAllocation& operator = (const VulkanUploadAllocation&) = delete; + VulkanUploadAllocation ( VulkanUploadAllocation&&) = default; + VulkanUploadAllocation& operator = ( VulkanUploadAllocation&&) = default; + // clang-format on + + VkBuffer vkBuffer = VK_NULL_HANDLE; // Vulkan buffer associated with this memory. + void* CPUAddress = nullptr; + VkDeviceSize Size = 0; + VkDeviceSize AlignedOffset = 0; +}; + +class VulkanUploadHeap +{ +public: + VulkanUploadHeap(RenderDeviceVkImpl& RenderDevice, + std::string HeapName, + VkDeviceSize PageSize); + + // clang-format off + VulkanUploadHeap (const VulkanUploadHeap&) = delete; + VulkanUploadHeap ( VulkanUploadHeap&&) = delete; + VulkanUploadHeap& operator= (const VulkanUploadHeap&) = delete; + VulkanUploadHeap& operator= ( VulkanUploadHeap&&) = delete; + // clang-format on + + ~VulkanUploadHeap(); + + VulkanUploadAllocation Allocate(VkDeviceSize SizeInBytes, VkDeviceSize Alignment); + + // Releases all allocated pages that are later returned to the global memory manager by the release queues. + // As global memory manager is hosted by the render device, the upload heap can be destroyed before the + // pages are actually returned to the manager. + void ReleaseAllocatedPages(Uint64 CmdQueueMask); + + size_t GetStalePagesCount() const + { + return m_Pages.size(); + } + +private: + RenderDeviceVkImpl& m_RenderDevice; + std::string m_HeapName; + const VkDeviceSize m_PageSize; + + struct UploadPageInfo + { + // clang-format off + UploadPageInfo(VulkanUtilities::VulkanMemoryAllocation&& _MemAllocation, + VulkanUtilities::BufferWrapper&& _Buffer, + Uint8* _CPUAddress) : + MemAllocation{std::move(_MemAllocation)}, + Buffer {std::move(_Buffer) }, + CPUAddress {_CPUAddress } + { + } + // clang-format on + + VulkanUtilities::VulkanMemoryAllocation MemAllocation; + VulkanUtilities::BufferWrapper Buffer; + Uint8* const CPUAddress = nullptr; + }; + std::vector m_Pages; + + struct CurrPageInfo + { + VkBuffer vkBuffer = VK_NULL_HANDLE; + Uint8* CurrCPUAddress = nullptr; + VkDeviceSize CurrOffset = 0; + VkDeviceSize AvailableSize = 0; + + void Reset(UploadPageInfo& NewPage, VkDeviceSize PageSize) + { + vkBuffer = NewPage.Buffer; + CurrCPUAddress = NewPage.CPUAddress; + CurrOffset = 0; + AvailableSize = PageSize; + } + + void Advance(VkDeviceSize SizeInBytes) + { + CurrCPUAddress += SizeInBytes; + CurrOffset += SizeInBytes; + AvailableSize -= SizeInBytes; + } + } m_CurrPage; + + VkDeviceSize m_CurrFrameSize = 0; + VkDeviceSize m_PeakFrameSize = 0; + VkDeviceSize m_CurrAllocatedSize = 0; + VkDeviceSize m_PeakAllocatedSize = 0; + + UploadPageInfo CreateNewPage(VkDeviceSize SizeInBytes) const; +}; + +} // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h deleted file mode 100644 index 786a2059..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.h +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include "vulkan.h" -#include "DebugUtilities.h" - -namespace VulkanUtilities -{ - -class VulkanCommandBuffer -{ -public: - VulkanCommandBuffer(VkPipelineStageFlags EnabledGraphicsShaderStages) noexcept : - m_EnabledGraphicsShaderStages{EnabledGraphicsShaderStages} - {} - - // clang-format off - VulkanCommandBuffer (const VulkanCommandBuffer&) = delete; - VulkanCommandBuffer ( VulkanCommandBuffer&&) = delete; - VulkanCommandBuffer& operator = (const VulkanCommandBuffer&) = delete; - VulkanCommandBuffer& operator = ( VulkanCommandBuffer&&) = delete; - // clang-format on - - __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)"); - VERIFY(Subresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT, "The aspectMask of all image subresource ranges must only include VK_IMAGE_ASPECT_COLOR_BIT (17.1)"); - - vkCmdClearColorImage( - m_VkCmdBuffer, - Image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL - &Color, - 1, - &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)"); - // clang-format off - VERIFY((Subresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0 && - (Subresource.aspectMask & ~(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0, - "The aspectMask of all image subresource ranges must only include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT(17.1)"); - // clang-format on - - vkCmdClearDepthStencilImage( - m_VkCmdBuffer, - Image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL - &DepthStencil, - 1, - &Subresource); - } - - __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)"); - - vkCmdClearAttachments( - m_VkCmdBuffer, - 1, - &Attachment, - 1, - &ClearRect // The rectangular region specified by each element of pRects must be - // contained within the render area of the current render pass instance - ); - } - - __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)"); - VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); - - vkCmdDraw(m_VkCmdBuffer, VertexCount, InstanceCount, FirstVertex, 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)"); - VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); - VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound"); - - vkCmdDrawIndexed(m_VkCmdBuffer, IndexCount, InstanceCount, FirstIndex, VertexOffset, FirstInstance); - } - - __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)"); - VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); - - vkCmdDrawIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, 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)"); - VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); - VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound"); - - vkCmdDrawIndexedIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride); - } - - __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)"); - VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound"); - - vkCmdDispatch(m_VkCmdBuffer, GroupCountX, GroupCountY, GroupCountZ); - } - - __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)"); - VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound"); - - vkCmdDispatchIndirect(m_VkCmdBuffer, Buffer, Offset); - } - - __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"); - - if (m_State.RenderPass != RenderPass || m_State.Framebuffer != Framebuffer) - { - VkRenderPassBeginInfo BeginInfo; - BeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - BeginInfo.pNext = nullptr; - BeginInfo.renderPass = RenderPass; - BeginInfo.framebuffer = Framebuffer; - // The render area MUST be contained within the framebuffer dimensions (7.4) - BeginInfo.renderArea = {{0, 0}, {FramebufferWidth, FramebufferHeight}}; - BeginInfo.clearValueCount = 0; - BeginInfo.pClearValues = nullptr; // an array of VkClearValue structures that contains clear values for - // each attachment, if the attachment uses a loadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR - // or if the attachment has a depth/stencil format and uses a stencilLoadOp value of - // VK_ATTACHMENT_LOAD_OP_CLEAR. The array is indexed by attachment number. Only elements - // corresponding to cleared attachments are used. Other elements of pClearValues are - // ignored (7.4) - - vkCmdBeginRenderPass(m_VkCmdBuffer, &BeginInfo, - VK_SUBPASS_CONTENTS_INLINE // the contents of the subpass will be recorded inline in the - // primary command buffer, and secondary command buffers must not - // be executed within the subpass - ); - m_State.RenderPass = RenderPass; - m_State.Framebuffer = Framebuffer; - m_State.FramebufferWidth = FramebufferWidth; - m_State.FramebufferHeight = FramebufferHeight; - } - } - - __forceinline void EndRenderPass() - { - VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "Render pass has not been started"); - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdEndRenderPass(m_VkCmdBuffer); - m_State.RenderPass = VK_NULL_HANDLE; - m_State.Framebuffer = VK_NULL_HANDLE; - m_State.FramebufferWidth = 0; - m_State.FramebufferHeight = 0; - if (m_State.InsidePassQueries != 0) - { - LOG_ERROR_MESSAGE("Ending render pass while there are outstanding queries that have been started inside the pass, " - "but have not been ended. Vulkan requires that a query must either begin and end inside the same " - "subpass of a render pass instance, or must both begin and end outside of a render pass " - "instance (i.e. contain entire render pass instances). (17.2)"); - } - } - - __forceinline void EndCommandBuffer() - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkEndCommandBuffer(m_VkCmdBuffer); - } - - __forceinline void Reset() - { - m_VkCmdBuffer = VK_NULL_HANDLE; - m_State = StateCache{}; - } - - __forceinline void BindComputePipeline(VkPipeline ComputePipeline) - { - // 9.8 - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - if (m_State.ComputePipeline != ComputePipeline) - { - vkCmdBindPipeline(m_VkCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, ComputePipeline); - m_State.ComputePipeline = ComputePipeline; - } - } - - __forceinline void BindGraphicsPipeline(VkPipeline GraphicsPipeline) - { - // 9.8 - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - if (m_State.GraphicsPipeline != GraphicsPipeline) - { - vkCmdBindPipeline(m_VkCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, GraphicsPipeline); - m_State.GraphicsPipeline = GraphicsPipeline; - } - } - - __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); - } - - __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); - } - - __forceinline void SetStencilReference(uint32_t Reference) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdSetStencilReference(m_VkCmdBuffer, VK_STENCIL_FRONT_AND_BACK, Reference); - } - - __forceinline void SetBlendConstants(const float BlendConstants[4]) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdSetBlendConstants(m_VkCmdBuffer, BlendConstants); - } - - __forceinline void BindIndexBuffer(VkBuffer Buffer, VkDeviceSize Offset, VkIndexType IndexType) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - // clang-format off - if (m_State.IndexBuffer != Buffer || - m_State.IndexBufferOffset != Offset || - m_State.IndexType != IndexType) - { - // clang-format on - vkCmdBindIndexBuffer(m_VkCmdBuffer, Buffer, Offset, IndexType); - m_State.IndexBuffer = Buffer; - m_State.IndexBufferOffset = Offset; - m_State.IndexType = IndexType; - } - } - - __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); - } - - static void TransitionImageLayout(VkCommandBuffer CmdBuffer, - VkImage Image, - VkImageLayout OldLayout, - VkImageLayout NewLayout, - const VkImageSubresourceRange& SubresRange, - VkPipelineStageFlags EnabledGraphicsShaderStages, - 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) - { - // Image layout transitions within a render pass execute - // dependencies between attachments - EndRenderPass(); - } - TransitionImageLayout(m_VkCmdBuffer, Image, OldLayout, NewLayout, SubresRange, m_EnabledGraphicsShaderStages, SrcStages, DestStages); - } - - - static void BufferMemoryBarrier(VkCommandBuffer CmdBuffer, - VkBuffer Buffer, - VkAccessFlags srcAccessMask, - VkAccessFlags dstAccessMask, - VkPipelineStageFlags EnabledGraphicsShaderStages, - 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) - { - // Image layout transitions within a render pass execute - // dependencies between attachments - EndRenderPass(); - } - BufferMemoryBarrier(m_VkCmdBuffer, Buffer, srcAccessMask, dstAccessMask, m_EnabledGraphicsShaderStages, SrcStages, DestStages); - } - - __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); - } - - __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) - { - // Copy buffer operation must be performed outside of render pass. - EndRenderPass(); - } - vkCmdCopyBuffer(m_VkCmdBuffer, srcBuffer, dstBuffer, regionCount, 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) - { - // Copy operations must be performed outside of render pass. - EndRenderPass(); - } - - vkCmdCopyImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 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) - { - // Copy operations must be performed outside of render pass. - EndRenderPass(); - } - - vkCmdCopyBufferToImage(m_VkCmdBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, 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) - { - // Copy operations must be performed outside of render pass. - EndRenderPass(); - } - - vkCmdCopyImageToBuffer(m_VkCmdBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); - } - - __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) - { - // Blit must be performed outside of render pass. - EndRenderPass(); - } - - vkCmdBlitImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); - } - - __forceinline void ResolveImage(VkImage srcImage, - VkImageLayout srcImageLayout, - VkImage dstImage, - VkImageLayout dstImageLayout, - uint32_t regionCount, - const VkImageResolve* pRegions) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - if (m_State.RenderPass != VK_NULL_HANDLE) - { - // Resolve must be performed outside of render pass. - EndRenderPass(); - } - vkCmdResolveImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); - } - - __forceinline void BeginQuery(VkQueryPool queryPool, - uint32_t query, - VkQueryControlFlags flags, - uint32_t queryFlag) - { - // queryPool must have been created with a queryType that differs from that of any queries that - // are active within commandBuffer (17.2). In other words, only one query of given type can be active - // in the command buffer. - - if ((m_State.InsidePassQueries | m_State.OutsidePassQueries) & queryFlag) - { - LOG_ERROR_MESSAGE("Another query of the same type is already active in the command buffer. " - "Overlapping queries are not allowed in Vulkan. The command will be ignored."); - return; - } - - // A query must either begin and end inside the same subpass of a render pass instance, or must both - // begin and end outside of a render pass instance (i.e. contain entire render pass instances) (17.2). - - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdBeginQuery(m_VkCmdBuffer, queryPool, query, flags); - if (m_State.RenderPass != VK_NULL_HANDLE) - m_State.InsidePassQueries |= queryFlag; - else - m_State.OutsidePassQueries |= queryFlag; - } - - __forceinline void EndQuery(VkQueryPool queryPool, - uint32_t query, - uint32_t queryFlag) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdEndQuery(m_VkCmdBuffer, queryPool, query); - if (m_State.RenderPass != VK_NULL_HANDLE) - { - VERIFY((m_State.InsidePassQueries & queryFlag) != 0, "No active inside-pass queries found."); - m_State.InsidePassQueries &= ~queryFlag; - } - else - { - VERIFY((m_State.OutsidePassQueries & queryFlag) != 0, "No active outside-pass queries found."); - m_State.OutsidePassQueries &= ~queryFlag; - } - } - - __forceinline void WriteTimestamp(VkPipelineStageFlagBits pipelineStage, - VkQueryPool queryPool, - uint32_t query) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - vkCmdWriteTimestamp(m_VkCmdBuffer, pipelineStage, queryPool, query); - } - - __forceinline void ResetQueryPool(VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - if (m_State.RenderPass != VK_NULL_HANDLE) - { - // Query pool reset must be performed outside of render pass (17.2). - EndRenderPass(); - } - vkCmdResetQueryPool(m_VkCmdBuffer, queryPool, firstQuery, queryCount); - } - - __forceinline void CopyQueryPoolResults(VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - VkBuffer dstBuffer, - VkDeviceSize dstOffset, - VkDeviceSize stride, - VkQueryResultFlags flags) - { - VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - if (m_State.RenderPass != VK_NULL_HANDLE) - { - // Copy query results must be performed outside of render pass (17.2). - EndRenderPass(); - } - vkCmdCopyQueryPoolResults(m_VkCmdBuffer, queryPool, firstQuery, queryCount, - dstBuffer, dstOffset, stride, flags); - } - - void FlushBarriers(); - - __forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) - { - m_VkCmdBuffer = VkCmdBuffer; - } - VkCommandBuffer GetVkCmdBuffer() const { return m_VkCmdBuffer; } - - struct StateCache - { - VkRenderPass RenderPass = VK_NULL_HANDLE; - VkFramebuffer Framebuffer = VK_NULL_HANDLE; - VkPipeline GraphicsPipeline = VK_NULL_HANDLE; - VkPipeline ComputePipeline = VK_NULL_HANDLE; - VkBuffer IndexBuffer = VK_NULL_HANDLE; - VkDeviceSize IndexBufferOffset = 0; - VkIndexType IndexType = VK_INDEX_TYPE_MAX_ENUM; - uint32_t FramebufferWidth = 0; - uint32_t FramebufferHeight = 0; - uint32_t InsidePassQueries = 0; - uint32_t OutsidePassQueries = 0; - }; - - const StateCache& GetState() const { return m_State; } - -private: - StateCache m_State; - VkCommandBuffer m_VkCmdBuffer = VK_NULL_HANDLE; - const VkPipelineStageFlags m_EnabledGraphicsShaderStages; -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp new file mode 100644 index 00000000..786a2059 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp @@ -0,0 +1,566 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "vulkan.h" +#include "DebugUtilities.h" + +namespace VulkanUtilities +{ + +class VulkanCommandBuffer +{ +public: + VulkanCommandBuffer(VkPipelineStageFlags EnabledGraphicsShaderStages) noexcept : + m_EnabledGraphicsShaderStages{EnabledGraphicsShaderStages} + {} + + // clang-format off + VulkanCommandBuffer (const VulkanCommandBuffer&) = delete; + VulkanCommandBuffer ( VulkanCommandBuffer&&) = delete; + VulkanCommandBuffer& operator = (const VulkanCommandBuffer&) = delete; + VulkanCommandBuffer& operator = ( VulkanCommandBuffer&&) = delete; + // clang-format on + + __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)"); + VERIFY(Subresource.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT, "The aspectMask of all image subresource ranges must only include VK_IMAGE_ASPECT_COLOR_BIT (17.1)"); + + vkCmdClearColorImage( + m_VkCmdBuffer, + Image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL + &Color, + 1, + &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)"); + // clang-format off + VERIFY((Subresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0 && + (Subresource.aspectMask & ~(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0, + "The aspectMask of all image subresource ranges must only include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT(17.1)"); + // clang-format on + + vkCmdClearDepthStencilImage( + m_VkCmdBuffer, + Image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // must be VK_IMAGE_LAYOUT_GENERAL or VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL + &DepthStencil, + 1, + &Subresource); + } + + __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)"); + + vkCmdClearAttachments( + m_VkCmdBuffer, + 1, + &Attachment, + 1, + &ClearRect // The rectangular region specified by each element of pRects must be + // contained within the render area of the current render pass instance + ); + } + + __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)"); + VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); + + vkCmdDraw(m_VkCmdBuffer, VertexCount, InstanceCount, FirstVertex, 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)"); + VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); + VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound"); + + vkCmdDrawIndexed(m_VkCmdBuffer, IndexCount, InstanceCount, FirstIndex, VertexOffset, FirstInstance); + } + + __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)"); + VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); + + vkCmdDrawIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, 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)"); + VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); + VERIFY(m_State.IndexBuffer != VK_NULL_HANDLE, "No index buffer bound"); + + vkCmdDrawIndexedIndirect(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride); + } + + __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)"); + VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound"); + + vkCmdDispatch(m_VkCmdBuffer, GroupCountX, GroupCountY, GroupCountZ); + } + + __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)"); + VERIFY(m_State.ComputePipeline != VK_NULL_HANDLE, "No compute pipeline bound"); + + vkCmdDispatchIndirect(m_VkCmdBuffer, Buffer, Offset); + } + + __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"); + + if (m_State.RenderPass != RenderPass || m_State.Framebuffer != Framebuffer) + { + VkRenderPassBeginInfo BeginInfo; + BeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + BeginInfo.pNext = nullptr; + BeginInfo.renderPass = RenderPass; + BeginInfo.framebuffer = Framebuffer; + // The render area MUST be contained within the framebuffer dimensions (7.4) + BeginInfo.renderArea = {{0, 0}, {FramebufferWidth, FramebufferHeight}}; + BeginInfo.clearValueCount = 0; + BeginInfo.pClearValues = nullptr; // an array of VkClearValue structures that contains clear values for + // each attachment, if the attachment uses a loadOp value of VK_ATTACHMENT_LOAD_OP_CLEAR + // or if the attachment has a depth/stencil format and uses a stencilLoadOp value of + // VK_ATTACHMENT_LOAD_OP_CLEAR. The array is indexed by attachment number. Only elements + // corresponding to cleared attachments are used. Other elements of pClearValues are + // ignored (7.4) + + vkCmdBeginRenderPass(m_VkCmdBuffer, &BeginInfo, + VK_SUBPASS_CONTENTS_INLINE // the contents of the subpass will be recorded inline in the + // primary command buffer, and secondary command buffers must not + // be executed within the subpass + ); + m_State.RenderPass = RenderPass; + m_State.Framebuffer = Framebuffer; + m_State.FramebufferWidth = FramebufferWidth; + m_State.FramebufferHeight = FramebufferHeight; + } + } + + __forceinline void EndRenderPass() + { + VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "Render pass has not been started"); + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdEndRenderPass(m_VkCmdBuffer); + m_State.RenderPass = VK_NULL_HANDLE; + m_State.Framebuffer = VK_NULL_HANDLE; + m_State.FramebufferWidth = 0; + m_State.FramebufferHeight = 0; + if (m_State.InsidePassQueries != 0) + { + LOG_ERROR_MESSAGE("Ending render pass while there are outstanding queries that have been started inside the pass, " + "but have not been ended. Vulkan requires that a query must either begin and end inside the same " + "subpass of a render pass instance, or must both begin and end outside of a render pass " + "instance (i.e. contain entire render pass instances). (17.2)"); + } + } + + __forceinline void EndCommandBuffer() + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkEndCommandBuffer(m_VkCmdBuffer); + } + + __forceinline void Reset() + { + m_VkCmdBuffer = VK_NULL_HANDLE; + m_State = StateCache{}; + } + + __forceinline void BindComputePipeline(VkPipeline ComputePipeline) + { + // 9.8 + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.ComputePipeline != ComputePipeline) + { + vkCmdBindPipeline(m_VkCmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, ComputePipeline); + m_State.ComputePipeline = ComputePipeline; + } + } + + __forceinline void BindGraphicsPipeline(VkPipeline GraphicsPipeline) + { + // 9.8 + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.GraphicsPipeline != GraphicsPipeline) + { + vkCmdBindPipeline(m_VkCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, GraphicsPipeline); + m_State.GraphicsPipeline = GraphicsPipeline; + } + } + + __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); + } + + __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); + } + + __forceinline void SetStencilReference(uint32_t Reference) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdSetStencilReference(m_VkCmdBuffer, VK_STENCIL_FRONT_AND_BACK, Reference); + } + + __forceinline void SetBlendConstants(const float BlendConstants[4]) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdSetBlendConstants(m_VkCmdBuffer, BlendConstants); + } + + __forceinline void BindIndexBuffer(VkBuffer Buffer, VkDeviceSize Offset, VkIndexType IndexType) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + // clang-format off + if (m_State.IndexBuffer != Buffer || + m_State.IndexBufferOffset != Offset || + m_State.IndexType != IndexType) + { + // clang-format on + vkCmdBindIndexBuffer(m_VkCmdBuffer, Buffer, Offset, IndexType); + m_State.IndexBuffer = Buffer; + m_State.IndexBufferOffset = Offset; + m_State.IndexType = IndexType; + } + } + + __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); + } + + static void TransitionImageLayout(VkCommandBuffer CmdBuffer, + VkImage Image, + VkImageLayout OldLayout, + VkImageLayout NewLayout, + const VkImageSubresourceRange& SubresRange, + VkPipelineStageFlags EnabledGraphicsShaderStages, + 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) + { + // Image layout transitions within a render pass execute + // dependencies between attachments + EndRenderPass(); + } + TransitionImageLayout(m_VkCmdBuffer, Image, OldLayout, NewLayout, SubresRange, m_EnabledGraphicsShaderStages, SrcStages, DestStages); + } + + + static void BufferMemoryBarrier(VkCommandBuffer CmdBuffer, + VkBuffer Buffer, + VkAccessFlags srcAccessMask, + VkAccessFlags dstAccessMask, + VkPipelineStageFlags EnabledGraphicsShaderStages, + 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) + { + // Image layout transitions within a render pass execute + // dependencies between attachments + EndRenderPass(); + } + BufferMemoryBarrier(m_VkCmdBuffer, Buffer, srcAccessMask, dstAccessMask, m_EnabledGraphicsShaderStages, SrcStages, DestStages); + } + + __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); + } + + __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) + { + // Copy buffer operation must be performed outside of render pass. + EndRenderPass(); + } + vkCmdCopyBuffer(m_VkCmdBuffer, srcBuffer, dstBuffer, regionCount, 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) + { + // Copy operations must be performed outside of render pass. + EndRenderPass(); + } + + vkCmdCopyImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, 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) + { + // Copy operations must be performed outside of render pass. + EndRenderPass(); + } + + vkCmdCopyBufferToImage(m_VkCmdBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, 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) + { + // Copy operations must be performed outside of render pass. + EndRenderPass(); + } + + vkCmdCopyImageToBuffer(m_VkCmdBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions); + } + + __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) + { + // Blit must be performed outside of render pass. + EndRenderPass(); + } + + vkCmdBlitImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions, filter); + } + + __forceinline void ResolveImage(VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve* pRegions) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Resolve must be performed outside of render pass. + EndRenderPass(); + } + vkCmdResolveImage(m_VkCmdBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, pRegions); + } + + __forceinline void BeginQuery(VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags, + uint32_t queryFlag) + { + // queryPool must have been created with a queryType that differs from that of any queries that + // are active within commandBuffer (17.2). In other words, only one query of given type can be active + // in the command buffer. + + if ((m_State.InsidePassQueries | m_State.OutsidePassQueries) & queryFlag) + { + LOG_ERROR_MESSAGE("Another query of the same type is already active in the command buffer. " + "Overlapping queries are not allowed in Vulkan. The command will be ignored."); + return; + } + + // A query must either begin and end inside the same subpass of a render pass instance, or must both + // begin and end outside of a render pass instance (i.e. contain entire render pass instances) (17.2). + + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdBeginQuery(m_VkCmdBuffer, queryPool, query, flags); + if (m_State.RenderPass != VK_NULL_HANDLE) + m_State.InsidePassQueries |= queryFlag; + else + m_State.OutsidePassQueries |= queryFlag; + } + + __forceinline void EndQuery(VkQueryPool queryPool, + uint32_t query, + uint32_t queryFlag) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdEndQuery(m_VkCmdBuffer, queryPool, query); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + VERIFY((m_State.InsidePassQueries & queryFlag) != 0, "No active inside-pass queries found."); + m_State.InsidePassQueries &= ~queryFlag; + } + else + { + VERIFY((m_State.OutsidePassQueries & queryFlag) != 0, "No active outside-pass queries found."); + m_State.OutsidePassQueries &= ~queryFlag; + } + } + + __forceinline void WriteTimestamp(VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + vkCmdWriteTimestamp(m_VkCmdBuffer, pipelineStage, queryPool, query); + } + + __forceinline void ResetQueryPool(VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Query pool reset must be performed outside of render pass (17.2). + EndRenderPass(); + } + vkCmdResetQueryPool(m_VkCmdBuffer, queryPool, firstQuery, queryCount); + } + + __forceinline void CopyQueryPoolResults(VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags) + { + VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); + if (m_State.RenderPass != VK_NULL_HANDLE) + { + // Copy query results must be performed outside of render pass (17.2). + EndRenderPass(); + } + vkCmdCopyQueryPoolResults(m_VkCmdBuffer, queryPool, firstQuery, queryCount, + dstBuffer, dstOffset, stride, flags); + } + + void FlushBarriers(); + + __forceinline void SetVkCmdBuffer(VkCommandBuffer VkCmdBuffer) + { + m_VkCmdBuffer = VkCmdBuffer; + } + VkCommandBuffer GetVkCmdBuffer() const { return m_VkCmdBuffer; } + + struct StateCache + { + VkRenderPass RenderPass = VK_NULL_HANDLE; + VkFramebuffer Framebuffer = VK_NULL_HANDLE; + VkPipeline GraphicsPipeline = VK_NULL_HANDLE; + VkPipeline ComputePipeline = VK_NULL_HANDLE; + VkBuffer IndexBuffer = VK_NULL_HANDLE; + VkDeviceSize IndexBufferOffset = 0; + VkIndexType IndexType = VK_INDEX_TYPE_MAX_ENUM; + uint32_t FramebufferWidth = 0; + uint32_t FramebufferHeight = 0; + uint32_t InsidePassQueries = 0; + uint32_t OutsidePassQueries = 0; + }; + + const StateCache& GetState() const { return m_State; } + +private: + StateCache m_State; + VkCommandBuffer m_VkCmdBuffer = VK_NULL_HANDLE; + const VkPipelineStageFlags m_EnabledGraphicsShaderStages; +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.h deleted file mode 100644 index 2a43a8c8..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include -#include -#include "vulkan.h" -#include "VulkanLogicalDevice.h" -#include "VulkanObjectWrappers.h" - -namespace VulkanUtilities -{ - -class VulkanCommandBufferPool -{ -public: - VulkanCommandBufferPool(std::shared_ptr LogicalDevice, - uint32_t queueFamilyIndex, - VkCommandPoolCreateFlags flags); - - // clang-format off - VulkanCommandBufferPool (const VulkanCommandBufferPool&) = delete; - VulkanCommandBufferPool ( VulkanCommandBufferPool&&) = delete; - VulkanCommandBufferPool& operator = (const VulkanCommandBufferPool&) = delete; - VulkanCommandBufferPool& operator = ( VulkanCommandBufferPool&&) = delete; - // clang-format on - - ~VulkanCommandBufferPool(); - - VkCommandBuffer GetCommandBuffer(const char* DebugName = ""); - // The GPU must have finished with the command buffer being returned to the pool - void FreeCommandBuffer(VkCommandBuffer&& CmdBuffer); - - CommandPoolWrapper&& Release(); - -#ifdef DEVELOPMENT - int32_t DvpGetBufferCounter() const - { - return m_BuffCounter; - } -#endif - -private: - // Shared point to logical device must be defined before the command pool - std::shared_ptr m_LogicalDevice; - CommandPoolWrapper m_CmdPool; - - std::mutex m_Mutex; - std::deque m_CmdBuffers; -#ifdef DEVELOPMENT - std::atomic_int32_t m_BuffCounter; -#endif -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.hpp new file mode 100644 index 00000000..1454a0a5 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBufferPool.hpp @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include +#include +#include "vulkan.h" +#include "VulkanLogicalDevice.hpp" +#include "VulkanObjectWrappers.hpp" + +namespace VulkanUtilities +{ + +class VulkanCommandBufferPool +{ +public: + VulkanCommandBufferPool(std::shared_ptr LogicalDevice, + uint32_t queueFamilyIndex, + VkCommandPoolCreateFlags flags); + + // clang-format off + VulkanCommandBufferPool (const VulkanCommandBufferPool&) = delete; + VulkanCommandBufferPool ( VulkanCommandBufferPool&&) = delete; + VulkanCommandBufferPool& operator = (const VulkanCommandBufferPool&) = delete; + VulkanCommandBufferPool& operator = ( VulkanCommandBufferPool&&) = delete; + // clang-format on + + ~VulkanCommandBufferPool(); + + VkCommandBuffer GetCommandBuffer(const char* DebugName = ""); + // The GPU must have finished with the command buffer being returned to the pool + void FreeCommandBuffer(VkCommandBuffer&& CmdBuffer); + + CommandPoolWrapper&& Release(); + +#ifdef DEVELOPMENT + int32_t DvpGetBufferCounter() const + { + return m_BuffCounter; + } +#endif + +private: + // Shared point to logical device must be defined before the command pool + std::shared_ptr m_LogicalDevice; + CommandPoolWrapper m_CmdPool; + + std::mutex m_Mutex; + std::deque m_CmdBuffers; +#ifdef DEVELOPMENT + std::atomic_int32_t m_BuffCounter; +#endif +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.h deleted file mode 100644 index ee812f08..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once - -#include -#include "vulkan.h" - -namespace VulkanUtilities -{ - -// clang-format off -// Default validation layers -#if !PLATFORM_ANDROID -// On desktop the LunarG loaders exposes a meta layer that contains all layers -static constexpr const char* ValidationLayerNames[] = -{ - "VK_LAYER_LUNARG_standard_validation" -}; -#else -// On Android we need to explicitly select all layers -static constexpr const char *ValidationLayerNames[] = -{ - "VK_LAYER_GOOGLE_threading", - "VK_LAYER_LUNARG_parameter_validation", - "VK_LAYER_LUNARG_object_tracker", - "VK_LAYER_LUNARG_core_validation", - "VK_LAYER_LUNARG_swapchain", - "VK_LAYER_GOOGLE_unique_objects" -}; -#endif -// clang-format on - -// Load debug function pointers and set debug callback -// if callBack is NULL, default message callback will be used -void SetupDebugging(VkInstance instance, - VkDebugUtilsMessageSeverityFlagsEXT messageSeverity, - VkDebugUtilsMessageTypeFlagsEXT messageType, - void* pUserData = nullptr); -// Clear debug callback -void FreeDebugging(VkInstance instance); - -// Setup and functions for the VK_EXT_debug_marker_extension -// Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt -// Note that the extension will only be present if run from an offline debugging application -// The actual check for extension presence and enabling it on the device is done in the example base class -// See VulkanExampleBase::createInstance and VulkanExampleBase::createDevice (base/vulkanexamplebase.cpp) - -// Sets the debug name of an object -// All Objects in Vulkan are represented by their 64-bit handles which are passed into this function -// along with the object type -void SetObjectName(VkDevice device, uint64_t object, VkObjectType objectType, const char* name); - -// Set the tag for an object -void SetObjectTag(VkDevice device, uint64_t objectHandle, VkObjectType objectType, uint64_t name, size_t tagSize, const void* tag); - -// Start a new label region -void BeginCmdQueueLabelRegion(VkQueue cmdQueue, const char* pLabelName, const float* color); - -// End the label region -void EndCmdQueueLabelRegion(VkQueue cmdQueue); - -// Insert a single label -void InsertCmdQueueLabel(VkQueue cmdQueue, const char* pLabelName, const float* color); - -// Start a new label region -void BeginCmdBufferLabelRegion(VkCommandBuffer cmdBuffer, const char* pLabelName, const float* color); - -// End the label region -void EndCmdBufferLabelRegion(VkCommandBuffer cmdBuffer); - -// Insert a single label -void InsertCmdBufferLabel(VkCommandBuffer cmdBuffer, const char* pLabelName, const float* color); - -// clang-format off -// Object specific naming functions -void SetCommandPoolName (VkDevice device, VkCommandPool cmdPool, const char * name); -void SetCommandBufferName (VkDevice device, VkCommandBuffer cmdBuffer, const char * name); -void SetQueueName (VkDevice device, VkQueue queue, const char * name); -void SetImageName (VkDevice device, VkImage image, const char * name); -void SetImageViewName (VkDevice device, VkImageView imageView, const char * name); -void SetSamplerName (VkDevice device, VkSampler sampler, const char * name); -void SetBufferName (VkDevice device, VkBuffer buffer, const char * name); -void SetBufferViewName (VkDevice device, VkBufferView bufferView, const char * name); -void SetDeviceMemoryName (VkDevice device, VkDeviceMemory memory, const char * name); -void SetShaderModuleName (VkDevice device, VkShaderModule shaderModule, const char * name); -void SetPipelineName (VkDevice device, VkPipeline pipeline, const char * name); -void SetPipelineLayoutName (VkDevice device, VkPipelineLayout pipelineLayout, const char * name); -void SetRenderPassName (VkDevice device, VkRenderPass renderPass, const char * name); -void SetFramebufferName (VkDevice device, VkFramebuffer framebuffer, const char * name); -void SetDescriptorSetLayoutName (VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const char * name); -void SetDescriptorSetName (VkDevice device, VkDescriptorSet descriptorSet, const char * name); -void SetDescriptorPoolName (VkDevice device, VkDescriptorPool descriptorPool, const char * name); -void SetSemaphoreName (VkDevice device, VkSemaphore semaphore, const char * name); -void SetFenceName (VkDevice device, VkFence fence, const char * name); -void SetEventName (VkDevice device, VkEvent _event, const char * name); -void SetQueryPoolName (VkDevice device, VkQueryPool queryPool, const char * name); - -enum class VulkanHandleTypeId : uint32_t; - -template -void SetVulkanObjectName(VkDevice device, VulkanObjectType vkObject, const char * name); - -const char* VkResultToString (VkResult errorCode); -const char* VkAccessFlagBitToString(VkAccessFlagBits Bit); -const char* VkImageLayoutToString (VkImageLayout Layout); -std::string VkAccessFlagsToString (VkAccessFlags Flags); -const char* VkObjectTypeToString (VkObjectType ObjectType); -// clang-format on - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.hpp new file mode 100644 index 00000000..ee812f08 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanDebug.hpp @@ -0,0 +1,108 @@ +#pragma once + +#include +#include "vulkan.h" + +namespace VulkanUtilities +{ + +// clang-format off +// Default validation layers +#if !PLATFORM_ANDROID +// On desktop the LunarG loaders exposes a meta layer that contains all layers +static constexpr const char* ValidationLayerNames[] = +{ + "VK_LAYER_LUNARG_standard_validation" +}; +#else +// On Android we need to explicitly select all layers +static constexpr const char *ValidationLayerNames[] = +{ + "VK_LAYER_GOOGLE_threading", + "VK_LAYER_LUNARG_parameter_validation", + "VK_LAYER_LUNARG_object_tracker", + "VK_LAYER_LUNARG_core_validation", + "VK_LAYER_LUNARG_swapchain", + "VK_LAYER_GOOGLE_unique_objects" +}; +#endif +// clang-format on + +// Load debug function pointers and set debug callback +// if callBack is NULL, default message callback will be used +void SetupDebugging(VkInstance instance, + VkDebugUtilsMessageSeverityFlagsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + void* pUserData = nullptr); +// Clear debug callback +void FreeDebugging(VkInstance instance); + +// Setup and functions for the VK_EXT_debug_marker_extension +// Extension spec can be found at https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0-VK_EXT_debug_marker/doc/specs/vulkan/appendices/VK_EXT_debug_marker.txt +// Note that the extension will only be present if run from an offline debugging application +// The actual check for extension presence and enabling it on the device is done in the example base class +// See VulkanExampleBase::createInstance and VulkanExampleBase::createDevice (base/vulkanexamplebase.cpp) + +// Sets the debug name of an object +// All Objects in Vulkan are represented by their 64-bit handles which are passed into this function +// along with the object type +void SetObjectName(VkDevice device, uint64_t object, VkObjectType objectType, const char* name); + +// Set the tag for an object +void SetObjectTag(VkDevice device, uint64_t objectHandle, VkObjectType objectType, uint64_t name, size_t tagSize, const void* tag); + +// Start a new label region +void BeginCmdQueueLabelRegion(VkQueue cmdQueue, const char* pLabelName, const float* color); + +// End the label region +void EndCmdQueueLabelRegion(VkQueue cmdQueue); + +// Insert a single label +void InsertCmdQueueLabel(VkQueue cmdQueue, const char* pLabelName, const float* color); + +// Start a new label region +void BeginCmdBufferLabelRegion(VkCommandBuffer cmdBuffer, const char* pLabelName, const float* color); + +// End the label region +void EndCmdBufferLabelRegion(VkCommandBuffer cmdBuffer); + +// Insert a single label +void InsertCmdBufferLabel(VkCommandBuffer cmdBuffer, const char* pLabelName, const float* color); + +// clang-format off +// Object specific naming functions +void SetCommandPoolName (VkDevice device, VkCommandPool cmdPool, const char * name); +void SetCommandBufferName (VkDevice device, VkCommandBuffer cmdBuffer, const char * name); +void SetQueueName (VkDevice device, VkQueue queue, const char * name); +void SetImageName (VkDevice device, VkImage image, const char * name); +void SetImageViewName (VkDevice device, VkImageView imageView, const char * name); +void SetSamplerName (VkDevice device, VkSampler sampler, const char * name); +void SetBufferName (VkDevice device, VkBuffer buffer, const char * name); +void SetBufferViewName (VkDevice device, VkBufferView bufferView, const char * name); +void SetDeviceMemoryName (VkDevice device, VkDeviceMemory memory, const char * name); +void SetShaderModuleName (VkDevice device, VkShaderModule shaderModule, const char * name); +void SetPipelineName (VkDevice device, VkPipeline pipeline, const char * name); +void SetPipelineLayoutName (VkDevice device, VkPipelineLayout pipelineLayout, const char * name); +void SetRenderPassName (VkDevice device, VkRenderPass renderPass, const char * name); +void SetFramebufferName (VkDevice device, VkFramebuffer framebuffer, const char * name); +void SetDescriptorSetLayoutName (VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const char * name); +void SetDescriptorSetName (VkDevice device, VkDescriptorSet descriptorSet, const char * name); +void SetDescriptorPoolName (VkDevice device, VkDescriptorPool descriptorPool, const char * name); +void SetSemaphoreName (VkDevice device, VkSemaphore semaphore, const char * name); +void SetFenceName (VkDevice device, VkFence fence, const char * name); +void SetEventName (VkDevice device, VkEvent _event, const char * name); +void SetQueryPoolName (VkDevice device, VkQueryPool queryPool, const char * name); + +enum class VulkanHandleTypeId : uint32_t; + +template +void SetVulkanObjectName(VkDevice device, VulkanObjectType vkObject, const char * name); + +const char* VkResultToString (VkResult errorCode); +const char* VkAccessFlagBitToString(VkAccessFlagBits Bit); +const char* VkImageLayoutToString (VkImageLayout Layout); +std::string VkAccessFlagsToString (VkAccessFlags Flags); +const char* VkObjectTypeToString (VkObjectType ObjectType); +// clang-format on + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.h deleted file mode 100644 index a768eb77..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include "vulkan.h" -#include "VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" - -namespace VulkanUtilities -{ - -class VulkanFencePool -{ -public: - VulkanFencePool(std::shared_ptr LogicalDevice) noexcept; - - // clang-format off - VulkanFencePool (const VulkanFencePool&) = delete; - VulkanFencePool (VulkanFencePool&&) = delete; - VulkanFencePool& operator = (const VulkanFencePool&) = delete; - VulkanFencePool& operator = (VulkanFencePool&&) = delete; - // clang-format off - - ~VulkanFencePool(); - - FenceWrapper GetFence(); - void DisposeFence(FenceWrapper&& Fence); - -private: - // Shared pointer to logical device must be declared before fences - std::shared_ptr m_LogicalDevice; - std::vector m_Fences; -}; - -} diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.hpp new file mode 100644 index 00000000..a1402b99 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanFencePool.hpp @@ -0,0 +1,62 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include "vulkan.h" +#include "VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" + +namespace VulkanUtilities +{ + +class VulkanFencePool +{ +public: + VulkanFencePool(std::shared_ptr LogicalDevice) noexcept; + + // clang-format off + VulkanFencePool (const VulkanFencePool&) = delete; + VulkanFencePool (VulkanFencePool&&) = delete; + VulkanFencePool& operator = (const VulkanFencePool&) = delete; + VulkanFencePool& operator = (VulkanFencePool&&) = delete; + // clang-format off + + ~VulkanFencePool(); + + FenceWrapper GetFence(); + void DisposeFence(FenceWrapper&& Fence); + +private: + // Shared pointer to logical device must be declared before fences + std::shared_ptr m_LogicalDevice; + std::vector m_Fences; +}; + +} diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.h deleted file mode 100644 index 5993848c..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include "vulkan.h" - -namespace VulkanUtilities -{ - -class VulkanInstance : public std::enable_shared_from_this -{ -public: - // clang-format off - VulkanInstance (const VulkanInstance&) = delete; - VulkanInstance ( VulkanInstance&&) = delete; - VulkanInstance& operator = (const VulkanInstance&) = delete; - VulkanInstance& operator = ( VulkanInstance&&) = delete; - // clang-format on - - static std::shared_ptr Create(bool EnableValidation, - uint32_t GlobalExtensionCount, - const char* const* ppGlobalExtensionNames, - VkAllocationCallbacks* pVkAllocator); - ~VulkanInstance(); - - std::shared_ptr GetSharedPtr() - { - return shared_from_this(); - } - - std::shared_ptr GetSharedPtr() const - { - return shared_from_this(); - } - - // clang-format off - bool IsLayerAvailable (const char* LayerName) const; - bool IsExtensionAvailable(const char* ExtensionName)const; - - VkPhysicalDevice SelectPhysicalDevice()const; - - VkAllocationCallbacks* GetVkAllocator()const{return m_pVkAllocator;} - VkInstance GetVkInstance() const{return m_VkInstance; } - // clang-format on - -private: - VulkanInstance(bool EnableValidation, - uint32_t GlobalExtensionCount, - const char* const* ppGlobalExtensionNames, - VkAllocationCallbacks* pVkAllocator); - - bool m_DebugUtilsEnabled = false; - VkAllocationCallbacks* const m_pVkAllocator; - VkInstance m_VkInstance = VK_NULL_HANDLE; - - std::vector m_Layers; - std::vector m_Extensions; - std::vector m_PhysicalDevices; -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp new file mode 100644 index 00000000..5993848c --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp @@ -0,0 +1,88 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include "vulkan.h" + +namespace VulkanUtilities +{ + +class VulkanInstance : public std::enable_shared_from_this +{ +public: + // clang-format off + VulkanInstance (const VulkanInstance&) = delete; + VulkanInstance ( VulkanInstance&&) = delete; + VulkanInstance& operator = (const VulkanInstance&) = delete; + VulkanInstance& operator = ( VulkanInstance&&) = delete; + // clang-format on + + static std::shared_ptr Create(bool EnableValidation, + uint32_t GlobalExtensionCount, + const char* const* ppGlobalExtensionNames, + VkAllocationCallbacks* pVkAllocator); + ~VulkanInstance(); + + std::shared_ptr GetSharedPtr() + { + return shared_from_this(); + } + + std::shared_ptr GetSharedPtr() const + { + return shared_from_this(); + } + + // clang-format off + bool IsLayerAvailable (const char* LayerName) const; + bool IsExtensionAvailable(const char* ExtensionName)const; + + VkPhysicalDevice SelectPhysicalDevice()const; + + VkAllocationCallbacks* GetVkAllocator()const{return m_pVkAllocator;} + VkInstance GetVkInstance() const{return m_VkInstance; } + // clang-format on + +private: + VulkanInstance(bool EnableValidation, + uint32_t GlobalExtensionCount, + const char* const* ppGlobalExtensionNames, + VkAllocationCallbacks* pVkAllocator); + + bool m_DebugUtilsEnabled = false; + VkAllocationCallbacks* const m_pVkAllocator; + VkInstance m_VkInstance = VK_NULL_HANDLE; + + std::vector m_Layers; + std::vector m_Extensions; + std::vector m_PhysicalDevices; +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h deleted file mode 100644 index b580eb45..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include "vulkan.h" - -namespace VulkanUtilities -{ - -// In 32-bit version, all Vulkan handles are typedefed as uint64_t, so we have to -// use VulkanHandleTypeId to distinguish objects. -enum class VulkanHandleTypeId : uint32_t -{ - CommandPool, - CommandBuffer, - Buffer, - BufferView, - Image, - ImageView, - DeviceMemory, - Fence, - RenderPass, - Pipeline, - ShaderModule, - PipelineLayout, - Sampler, - Framebuffer, - DescriptorPool, - DescriptorSetLayout, - DescriptorSet, - Semaphore, - Queue, - Event, - QueryPool -}; - -template -class VulkanObjectWrapper; - -#define DEFINE_VULKAN_OBJECT_WRAPPER(Type) VulkanObjectWrapper -using CommandPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(CommandPool); -using BufferWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Buffer); -using BufferViewWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(BufferView); -using ImageWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Image); -using ImageViewWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(ImageView); -using DeviceMemoryWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DeviceMemory); -using FenceWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Fence); -using RenderPassWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(RenderPass); -using PipelineWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Pipeline); -using ShaderModuleWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(ShaderModule); -using PipelineLayoutWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(PipelineLayout); -using SamplerWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Sampler); -using FramebufferWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Framebuffer); -using DescriptorPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorPool); -using DescriptorSetLayoutWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorSetLayout); -using SemaphoreWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Semaphore); -using QueryPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(QueryPool); -#undef DEFINE_VULKAN_OBJECT_WRAPPER - -class VulkanLogicalDevice : public std::enable_shared_from_this -{ -public: - static std::shared_ptr Create(VkPhysicalDevice vkPhysicalDevice, - const VkDeviceCreateInfo& DeviceCI, - const VkAllocationCallbacks* vkAllocator); - - // clang-format off - VulkanLogicalDevice (const VulkanLogicalDevice&) = delete; - VulkanLogicalDevice (VulkanLogicalDevice&&) = delete; - VulkanLogicalDevice& operator = (const VulkanLogicalDevice&) = delete; - VulkanLogicalDevice& operator = (VulkanLogicalDevice&&) = delete; - // clang-format on - - ~VulkanLogicalDevice(); - - std::shared_ptr GetSharedPtr() - { - return shared_from_this(); - } - - std::shared_ptr GetSharedPtr() const - { - return shared_from_this(); - } - - VkQueue GetQueue(uint32_t queueFamilyIndex, uint32_t queueIndex); - - VkDevice GetVkDevice() const - { - return m_VkDevice; - } - - void WaitIdle() const; - - // clang-format off - CommandPoolWrapper CreateCommandPool (const VkCommandPoolCreateInfo& CmdPoolCI, const char* DebugName = "") const; - BufferWrapper CreateBuffer (const VkBufferCreateInfo& BufferCI, const char* DebugName = "") const; - BufferViewWrapper CreateBufferView (const VkBufferViewCreateInfo& BuffViewCI, const char* DebugName = "") const; - ImageWrapper CreateImage (const VkImageCreateInfo& ImageCI, const char* DebugName = "") const; - ImageViewWrapper CreateImageView (const VkImageViewCreateInfo& ImageViewCI, const char* DebugName = "") const; - SamplerWrapper CreateSampler (const VkSamplerCreateInfo& SamplerCI, const char* DebugName = "") const; - FenceWrapper CreateFence (const VkFenceCreateInfo& FenceCI, const char* DebugName = "") const; - RenderPassWrapper CreateRenderPass (const VkRenderPassCreateInfo& RenderPassCI,const char* DebugName = "") const; - DeviceMemoryWrapper AllocateDeviceMemory(const VkMemoryAllocateInfo & AllocInfo, const char* DebugName = "") const; - - PipelineWrapper CreateComputePipeline (const VkComputePipelineCreateInfo& PipelineCI, VkPipelineCache cache, const char* DebugName = "") const; - PipelineWrapper CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& PipelineCI, VkPipelineCache cache, const char* DebugName = "") const; - - ShaderModuleWrapper CreateShaderModule (const VkShaderModuleCreateInfo& ShaderModuleCI, const char* DebugName = "") const; - PipelineLayoutWrapper CreatePipelineLayout (const VkPipelineLayoutCreateInfo& LayoutCI, const char* DebugName = "") const; - FramebufferWrapper CreateFramebuffer (const VkFramebufferCreateInfo& FramebufferCI, const char* DebugName = "") const; - DescriptorPoolWrapper CreateDescriptorPool (const VkDescriptorPoolCreateInfo& DescrPoolCI, const char* DebugName = "") const; - DescriptorSetLayoutWrapper CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& LayoutCI, const char* DebugName = "") const; - - SemaphoreWrapper CreateSemaphore(const VkSemaphoreCreateInfo& SemaphoreCI, const char* DebugName = "") const; - QueryPoolWrapper CreateQueryPool(const VkQueryPoolCreateInfo& QueryPoolCI, const char* DebugName = "") const; - - VkCommandBuffer AllocateVkCommandBuffer(const VkCommandBufferAllocateInfo& AllocInfo, const char* DebugName = "") const; - VkDescriptorSet AllocateVkDescriptorSet(const VkDescriptorSetAllocateInfo& AllocInfo, const char* DebugName = "") const; - - void ReleaseVulkanObject(CommandPoolWrapper&& CmdPool) const; - void ReleaseVulkanObject(BufferWrapper&& Buffer) const; - void ReleaseVulkanObject(BufferViewWrapper&& BufferView) const; - void ReleaseVulkanObject(ImageWrapper&& Image) const; - void ReleaseVulkanObject(ImageViewWrapper&& ImageView) const; - void ReleaseVulkanObject(SamplerWrapper&& Sampler) const; - void ReleaseVulkanObject(FenceWrapper&& Fence) const; - void ReleaseVulkanObject(RenderPassWrapper&& RenderPass) const; - void ReleaseVulkanObject(DeviceMemoryWrapper&& Memory) const; - void ReleaseVulkanObject(PipelineWrapper&& Pipeline) const; - void ReleaseVulkanObject(ShaderModuleWrapper&& ShaderModule) const; - void ReleaseVulkanObject(PipelineLayoutWrapper&& PipelineLayout) const; - void ReleaseVulkanObject(FramebufferWrapper&& Framebuffer) const; - void ReleaseVulkanObject(DescriptorPoolWrapper&& DescriptorPool) const; - void ReleaseVulkanObject(DescriptorSetLayoutWrapper&& DescriptorSetLayout) const; - void ReleaseVulkanObject(SemaphoreWrapper&& Semaphore) const; - void ReleaseVulkanObject(QueryPoolWrapper&& QueryPool) const; - - void FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set) const; - - VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer vkBuffer) const; - VkMemoryRequirements GetImageMemoryRequirements (VkImage vkImage ) const; - - VkResult BindBufferMemory(VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; - VkResult BindImageMemory (VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; - // clang-format on - - VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) const; - void UnmapMemory(VkDeviceMemory memory) const; - - VkResult InvalidateMappedMemoryRanges(uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges) const; - VkResult FlushMappedMemoryRanges(uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges) const; - - VkResult GetFenceStatus(VkFence fence) const; - VkResult ResetFence(VkFence fence) const; - VkResult WaitForFences(uint32_t fenceCount, - const VkFence* pFences, - VkBool32 waitAll, - uint64_t timeout) const; - - void UpdateDescriptorSets(uint32_t descriptorWriteCount, - const VkWriteDescriptorSet* pDescriptorWrites, - uint32_t descriptorCopyCount, - const VkCopyDescriptorSet* pDescriptorCopies) const; - - VkResult ResetCommandPool(VkCommandPool vkCmdPool, - VkCommandPoolResetFlags flags = 0) const; - - VkResult ResetDescriptorPool(VkDescriptorPool descriptorPool, - VkDescriptorPoolResetFlags flags = 0) const; - - VkResult GetQueryPoolResults(VkQueryPool queryPool, - uint32_t firstQuery, - uint32_t queryCount, - size_t dataSize, - void* pData, - VkDeviceSize stride, - VkQueryResultFlags flags) const - { - return vkGetQueryPoolResults(m_VkDevice, queryPool, firstQuery, queryCount, - dataSize, pData, stride, flags); - } - - VkPipelineStageFlags GetEnabledGraphicsShaderStages() const { return m_EnabledGraphicsShaderStages; } - -private: - VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice, - const VkDeviceCreateInfo& DeviceCI, - const VkAllocationCallbacks* vkAllocator); - - template - VulkanObjectWrapper CreateVulkanObject(VkCreateObjectFuncType VkCreateObject, - const VkObjectCreateInfoType& CreateInfo, - const char* DebugName, - const char* ObjectType) const; - - VkDevice m_VkDevice = VK_NULL_HANDLE; - const VkAllocationCallbacks* const m_VkAllocator; - VkPipelineStageFlags m_EnabledGraphicsShaderStages = 0; -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp new file mode 100644 index 00000000..b580eb45 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp @@ -0,0 +1,231 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "vulkan.h" + +namespace VulkanUtilities +{ + +// In 32-bit version, all Vulkan handles are typedefed as uint64_t, so we have to +// use VulkanHandleTypeId to distinguish objects. +enum class VulkanHandleTypeId : uint32_t +{ + CommandPool, + CommandBuffer, + Buffer, + BufferView, + Image, + ImageView, + DeviceMemory, + Fence, + RenderPass, + Pipeline, + ShaderModule, + PipelineLayout, + Sampler, + Framebuffer, + DescriptorPool, + DescriptorSetLayout, + DescriptorSet, + Semaphore, + Queue, + Event, + QueryPool +}; + +template +class VulkanObjectWrapper; + +#define DEFINE_VULKAN_OBJECT_WRAPPER(Type) VulkanObjectWrapper +using CommandPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(CommandPool); +using BufferWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Buffer); +using BufferViewWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(BufferView); +using ImageWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Image); +using ImageViewWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(ImageView); +using DeviceMemoryWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DeviceMemory); +using FenceWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Fence); +using RenderPassWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(RenderPass); +using PipelineWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Pipeline); +using ShaderModuleWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(ShaderModule); +using PipelineLayoutWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(PipelineLayout); +using SamplerWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Sampler); +using FramebufferWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Framebuffer); +using DescriptorPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorPool); +using DescriptorSetLayoutWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(DescriptorSetLayout); +using SemaphoreWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(Semaphore); +using QueryPoolWrapper = DEFINE_VULKAN_OBJECT_WRAPPER(QueryPool); +#undef DEFINE_VULKAN_OBJECT_WRAPPER + +class VulkanLogicalDevice : public std::enable_shared_from_this +{ +public: + static std::shared_ptr Create(VkPhysicalDevice vkPhysicalDevice, + const VkDeviceCreateInfo& DeviceCI, + const VkAllocationCallbacks* vkAllocator); + + // clang-format off + VulkanLogicalDevice (const VulkanLogicalDevice&) = delete; + VulkanLogicalDevice (VulkanLogicalDevice&&) = delete; + VulkanLogicalDevice& operator = (const VulkanLogicalDevice&) = delete; + VulkanLogicalDevice& operator = (VulkanLogicalDevice&&) = delete; + // clang-format on + + ~VulkanLogicalDevice(); + + std::shared_ptr GetSharedPtr() + { + return shared_from_this(); + } + + std::shared_ptr GetSharedPtr() const + { + return shared_from_this(); + } + + VkQueue GetQueue(uint32_t queueFamilyIndex, uint32_t queueIndex); + + VkDevice GetVkDevice() const + { + return m_VkDevice; + } + + void WaitIdle() const; + + // clang-format off + CommandPoolWrapper CreateCommandPool (const VkCommandPoolCreateInfo& CmdPoolCI, const char* DebugName = "") const; + BufferWrapper CreateBuffer (const VkBufferCreateInfo& BufferCI, const char* DebugName = "") const; + BufferViewWrapper CreateBufferView (const VkBufferViewCreateInfo& BuffViewCI, const char* DebugName = "") const; + ImageWrapper CreateImage (const VkImageCreateInfo& ImageCI, const char* DebugName = "") const; + ImageViewWrapper CreateImageView (const VkImageViewCreateInfo& ImageViewCI, const char* DebugName = "") const; + SamplerWrapper CreateSampler (const VkSamplerCreateInfo& SamplerCI, const char* DebugName = "") const; + FenceWrapper CreateFence (const VkFenceCreateInfo& FenceCI, const char* DebugName = "") const; + RenderPassWrapper CreateRenderPass (const VkRenderPassCreateInfo& RenderPassCI,const char* DebugName = "") const; + DeviceMemoryWrapper AllocateDeviceMemory(const VkMemoryAllocateInfo & AllocInfo, const char* DebugName = "") const; + + PipelineWrapper CreateComputePipeline (const VkComputePipelineCreateInfo& PipelineCI, VkPipelineCache cache, const char* DebugName = "") const; + PipelineWrapper CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& PipelineCI, VkPipelineCache cache, const char* DebugName = "") const; + + ShaderModuleWrapper CreateShaderModule (const VkShaderModuleCreateInfo& ShaderModuleCI, const char* DebugName = "") const; + PipelineLayoutWrapper CreatePipelineLayout (const VkPipelineLayoutCreateInfo& LayoutCI, const char* DebugName = "") const; + FramebufferWrapper CreateFramebuffer (const VkFramebufferCreateInfo& FramebufferCI, const char* DebugName = "") const; + DescriptorPoolWrapper CreateDescriptorPool (const VkDescriptorPoolCreateInfo& DescrPoolCI, const char* DebugName = "") const; + DescriptorSetLayoutWrapper CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& LayoutCI, const char* DebugName = "") const; + + SemaphoreWrapper CreateSemaphore(const VkSemaphoreCreateInfo& SemaphoreCI, const char* DebugName = "") const; + QueryPoolWrapper CreateQueryPool(const VkQueryPoolCreateInfo& QueryPoolCI, const char* DebugName = "") const; + + VkCommandBuffer AllocateVkCommandBuffer(const VkCommandBufferAllocateInfo& AllocInfo, const char* DebugName = "") const; + VkDescriptorSet AllocateVkDescriptorSet(const VkDescriptorSetAllocateInfo& AllocInfo, const char* DebugName = "") const; + + void ReleaseVulkanObject(CommandPoolWrapper&& CmdPool) const; + void ReleaseVulkanObject(BufferWrapper&& Buffer) const; + void ReleaseVulkanObject(BufferViewWrapper&& BufferView) const; + void ReleaseVulkanObject(ImageWrapper&& Image) const; + void ReleaseVulkanObject(ImageViewWrapper&& ImageView) const; + void ReleaseVulkanObject(SamplerWrapper&& Sampler) const; + void ReleaseVulkanObject(FenceWrapper&& Fence) const; + void ReleaseVulkanObject(RenderPassWrapper&& RenderPass) const; + void ReleaseVulkanObject(DeviceMemoryWrapper&& Memory) const; + void ReleaseVulkanObject(PipelineWrapper&& Pipeline) const; + void ReleaseVulkanObject(ShaderModuleWrapper&& ShaderModule) const; + void ReleaseVulkanObject(PipelineLayoutWrapper&& PipelineLayout) const; + void ReleaseVulkanObject(FramebufferWrapper&& Framebuffer) const; + void ReleaseVulkanObject(DescriptorPoolWrapper&& DescriptorPool) const; + void ReleaseVulkanObject(DescriptorSetLayoutWrapper&& DescriptorSetLayout) const; + void ReleaseVulkanObject(SemaphoreWrapper&& Semaphore) const; + void ReleaseVulkanObject(QueryPoolWrapper&& QueryPool) const; + + void FreeDescriptorSet(VkDescriptorPool Pool, VkDescriptorSet Set) const; + + VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer vkBuffer) const; + VkMemoryRequirements GetImageMemoryRequirements (VkImage vkImage ) const; + + VkResult BindBufferMemory(VkBuffer buffer, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; + VkResult BindImageMemory (VkImage image, VkDeviceMemory memory, VkDeviceSize memoryOffset) const; + // clang-format on + + VkResult MapMemory(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) const; + void UnmapMemory(VkDeviceMemory memory) const; + + VkResult InvalidateMappedMemoryRanges(uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges) const; + VkResult FlushMappedMemoryRanges(uint32_t memoryRangeCount, const VkMappedMemoryRange* pMemoryRanges) const; + + VkResult GetFenceStatus(VkFence fence) const; + VkResult ResetFence(VkFence fence) const; + VkResult WaitForFences(uint32_t fenceCount, + const VkFence* pFences, + VkBool32 waitAll, + uint64_t timeout) const; + + void UpdateDescriptorSets(uint32_t descriptorWriteCount, + const VkWriteDescriptorSet* pDescriptorWrites, + uint32_t descriptorCopyCount, + const VkCopyDescriptorSet* pDescriptorCopies) const; + + VkResult ResetCommandPool(VkCommandPool vkCmdPool, + VkCommandPoolResetFlags flags = 0) const; + + VkResult ResetDescriptorPool(VkDescriptorPool descriptorPool, + VkDescriptorPoolResetFlags flags = 0) const; + + VkResult GetQueryPoolResults(VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + size_t dataSize, + void* pData, + VkDeviceSize stride, + VkQueryResultFlags flags) const + { + return vkGetQueryPoolResults(m_VkDevice, queryPool, firstQuery, queryCount, + dataSize, pData, stride, flags); + } + + VkPipelineStageFlags GetEnabledGraphicsShaderStages() const { return m_EnabledGraphicsShaderStages; } + +private: + VulkanLogicalDevice(VkPhysicalDevice vkPhysicalDevice, + const VkDeviceCreateInfo& DeviceCI, + const VkAllocationCallbacks* vkAllocator); + + template + VulkanObjectWrapper CreateVulkanObject(VkCreateObjectFuncType VkCreateObject, + const VkObjectCreateInfoType& CreateInfo, + const char* DebugName, + const char* ObjectType) const; + + VkDevice m_VkDevice = VK_NULL_HANDLE; + const VkAllocationCallbacks* const m_VkAllocator; + VkPipelineStageFlags m_EnabledGraphicsShaderStages = 0; +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h deleted file mode 100644 index 53baa84b..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include "MemoryAllocator.h" -#include "VariableSizeAllocationsManager.hpp" -#include "VulkanUtilities/VulkanPhysicalDevice.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" -#include "HashUtils.h" - -namespace VulkanUtilities -{ - -class VulkanMemoryPage; -class VulkanMemoryManager; - -struct VulkanMemoryAllocation -{ - VulkanMemoryAllocation() noexcept {} - - // clang-format off - VulkanMemoryAllocation (const VulkanMemoryAllocation&) = delete; - VulkanMemoryAllocation& operator= (const VulkanMemoryAllocation&) = delete; - - VulkanMemoryAllocation(VulkanMemoryPage* _Page, VkDeviceSize _UnalignedOffset, VkDeviceSize _Size)noexcept : - Page {_Page }, - UnalignedOffset{_UnalignedOffset}, - Size {_Size } - {} - - VulkanMemoryAllocation(VulkanMemoryAllocation&& rhs)noexcept : - Page {rhs.Page }, - UnalignedOffset{rhs.UnalignedOffset}, - Size {rhs.Size } - { - rhs.Page = nullptr; - rhs.UnalignedOffset = 0; - rhs.Size = 0; - } - - VulkanMemoryAllocation& operator= (VulkanMemoryAllocation&& rhs)noexcept - { - Page = rhs.Page; - UnalignedOffset = rhs.UnalignedOffset; - Size = rhs.Size; - - rhs.Page = nullptr; - rhs.UnalignedOffset = 0; - rhs.Size = 0; - - return *this; - } - // clang-format on - - // Destructor immediately returns the allocation to the parent page. - // The allocation must not be in use by the GPU. - ~VulkanMemoryAllocation(); - - VulkanMemoryPage* Page = nullptr; // Memory page that contains this allocation - VkDeviceSize UnalignedOffset = 0; // Unaligned offset from the start of the memory - VkDeviceSize Size = 0; // Reserved size of this allocation -}; - -class VulkanMemoryPage -{ -public: - VulkanMemoryPage(VulkanMemoryManager& ParentMemoryMgr, - VkDeviceSize PageSize, - uint32_t MemoryTypeIndex, - bool IsHostVisible) noexcept; - ~VulkanMemoryPage(); - - // clang-format off - VulkanMemoryPage(VulkanMemoryPage&& rhs)noexcept : - m_ParentMemoryMgr {rhs.m_ParentMemoryMgr }, - m_AllocationMgr {std::move(rhs.m_AllocationMgr)}, - m_VkMemory {std::move(rhs.m_VkMemory) }, - m_CPUMemory {rhs.m_CPUMemory } - { - rhs.m_CPUMemory = nullptr; - } - - VulkanMemoryPage (const VulkanMemoryPage&) = delete; - VulkanMemoryPage& operator= (VulkanMemoryPage&) = delete; - VulkanMemoryPage& operator= (VulkanMemoryPage&& rhs) = delete; - - bool IsEmpty() const { return m_AllocationMgr.IsEmpty(); } - bool IsFull() const { return m_AllocationMgr.IsFull(); } - VkDeviceSize GetPageSize() const { return m_AllocationMgr.GetMaxSize(); } - VkDeviceSize GetUsedSize() const { return m_AllocationMgr.GetUsedSize(); } - - // clang-format on - - VulkanMemoryAllocation Allocate(VkDeviceSize size, VkDeviceSize alignment); - - VkDeviceMemory GetVkMemory() const { return m_VkMemory; } - void* GetCPUMemory() const { return m_CPUMemory; } - -private: - using AllocationsMgrOffsetType = Diligent::VariableSizeAllocationsManager::OffsetType; - - friend struct VulkanMemoryAllocation; - - // Memory is reclaimed immediately. The application is responsible to ensure it is not in use by the GPU - void Free(VulkanMemoryAllocation&& Allocation); - - VulkanMemoryManager& m_ParentMemoryMgr; - std::mutex m_Mutex; - Diligent::VariableSizeAllocationsManager m_AllocationMgr; - VulkanUtilities::DeviceMemoryWrapper m_VkMemory; - void* m_CPUMemory = nullptr; -}; - -class VulkanMemoryManager -{ -public: - // clang-format off - VulkanMemoryManager(std::string MgrName, - const VulkanLogicalDevice& LogicalDevice, - const VulkanPhysicalDevice& PhysicalDevice, - Diligent::IMemoryAllocator& Allocator, - VkDeviceSize DeviceLocalPageSize, - VkDeviceSize HostVisiblePageSize, - VkDeviceSize DeviceLocalReserveSize, - VkDeviceSize HostVisibleReserveSize) : - m_MgrName {std::move(MgrName) }, - m_LogicalDevice {LogicalDevice }, - m_PhysicalDevice {PhysicalDevice }, - m_Allocator {Allocator }, - m_DeviceLocalPageSize {DeviceLocalPageSize }, - m_HostVisiblePageSize {HostVisiblePageSize }, - m_DeviceLocalReserveSize{DeviceLocalReserveSize}, - m_HostVisibleReserveSize{HostVisibleReserveSize} - {} - - - // We have to write this constructor because on msvc default - // constructor is not labeled with noexcept, which makes all - // std containers use copy instead of move - VulkanMemoryManager(VulkanMemoryManager&& rhs)noexcept : - m_MgrName {std::move(rhs.m_MgrName)}, - m_LogicalDevice {rhs.m_LogicalDevice }, - m_PhysicalDevice {rhs.m_PhysicalDevice }, - m_Allocator {rhs.m_Allocator }, - m_Pages {std::move(rhs.m_Pages) }, - - m_DeviceLocalPageSize {rhs.m_DeviceLocalPageSize }, - m_HostVisiblePageSize {rhs.m_HostVisiblePageSize }, - m_DeviceLocalReserveSize {rhs.m_DeviceLocalReserveSize}, - m_HostVisibleReserveSize {rhs.m_HostVisibleReserveSize}, - - //m_CurrUsedSize {rhs.m_CurrUsedSize}, - m_PeakUsedSize {rhs.m_PeakUsedSize }, - m_CurrAllocatedSize {rhs.m_CurrAllocatedSize}, - m_PeakAllocatedSize {rhs.m_PeakAllocatedSize} - { - // clang-format on - for (size_t i = 0; i < m_CurrUsedSize.size(); ++i) - m_CurrUsedSize[i].store(rhs.m_CurrUsedSize[i].load()); - } - - ~VulkanMemoryManager(); - - // clang-format off - VulkanMemoryManager (const VulkanMemoryManager&) = delete; - VulkanMemoryManager& operator= (const VulkanMemoryManager&) = delete; - VulkanMemoryManager& operator= (VulkanMemoryManager&&) = delete; - // clang-format on - - VulkanMemoryAllocation Allocate(VkDeviceSize Size, VkDeviceSize Alignment, uint32_t MemoryTypeIndex, bool HostVisible); - VulkanMemoryAllocation Allocate(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProps); - void ShrinkMemory(); - -protected: - friend class VulkanMemoryPage; - - virtual void OnNewPageCreated(VulkanMemoryPage& NewPage) {} - virtual void OnPageDestroy(VulkanMemoryPage& Page) {} - - std::string m_MgrName; - - const VulkanLogicalDevice& m_LogicalDevice; - const VulkanPhysicalDevice& m_PhysicalDevice; - - Diligent::IMemoryAllocator& m_Allocator; - - std::mutex m_PagesMtx; - struct MemoryPageIndex - { - const uint32_t MemoryTypeIndex; - const bool IsHostVisible; - - // clang-format off - MemoryPageIndex(uint32_t _MemoryTypeIndex, - bool _IsHostVisible) : - MemoryTypeIndex(_MemoryTypeIndex), - IsHostVisible (_IsHostVisible) - {} - - bool operator == (const MemoryPageIndex& rhs)const - { - return MemoryTypeIndex == rhs.MemoryTypeIndex && - IsHostVisible == rhs.IsHostVisible; - } - // clang-format on - - struct Hasher - { - size_t operator()(const MemoryPageIndex& PageIndex) const - { - return Diligent::ComputeHash(PageIndex.MemoryTypeIndex, PageIndex.IsHostVisible); - } - }; - }; - std::unordered_multimap m_Pages; - - const VkDeviceSize m_DeviceLocalPageSize; - const VkDeviceSize m_HostVisiblePageSize; - const VkDeviceSize m_DeviceLocalReserveSize; - const VkDeviceSize m_HostVisibleReserveSize; - - void OnFreeAllocation(VkDeviceSize Size, bool IsHostVisble); - - // 0 == Device local, 1 == Host-visible - std::array m_CurrUsedSize = {}; - std::array m_PeakUsedSize = {}; - std::array m_CurrAllocatedSize = {}; - std::array m_PeakAllocatedSize = {}; - - // If adding new member, do not forget to update move ctor -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.hpp new file mode 100644 index 00000000..afc7c423 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.hpp @@ -0,0 +1,264 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include "MemoryAllocator.h" +#include "VariableSizeAllocationsManager.hpp" +#include "VulkanUtilities/VulkanPhysicalDevice.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" +#include "HashUtils.h" + +namespace VulkanUtilities +{ + +class VulkanMemoryPage; +class VulkanMemoryManager; + +struct VulkanMemoryAllocation +{ + VulkanMemoryAllocation() noexcept {} + + // clang-format off + VulkanMemoryAllocation (const VulkanMemoryAllocation&) = delete; + VulkanMemoryAllocation& operator= (const VulkanMemoryAllocation&) = delete; + + VulkanMemoryAllocation(VulkanMemoryPage* _Page, VkDeviceSize _UnalignedOffset, VkDeviceSize _Size)noexcept : + Page {_Page }, + UnalignedOffset{_UnalignedOffset}, + Size {_Size } + {} + + VulkanMemoryAllocation(VulkanMemoryAllocation&& rhs)noexcept : + Page {rhs.Page }, + UnalignedOffset{rhs.UnalignedOffset}, + Size {rhs.Size } + { + rhs.Page = nullptr; + rhs.UnalignedOffset = 0; + rhs.Size = 0; + } + + VulkanMemoryAllocation& operator= (VulkanMemoryAllocation&& rhs)noexcept + { + Page = rhs.Page; + UnalignedOffset = rhs.UnalignedOffset; + Size = rhs.Size; + + rhs.Page = nullptr; + rhs.UnalignedOffset = 0; + rhs.Size = 0; + + return *this; + } + // clang-format on + + // Destructor immediately returns the allocation to the parent page. + // The allocation must not be in use by the GPU. + ~VulkanMemoryAllocation(); + + VulkanMemoryPage* Page = nullptr; // Memory page that contains this allocation + VkDeviceSize UnalignedOffset = 0; // Unaligned offset from the start of the memory + VkDeviceSize Size = 0; // Reserved size of this allocation +}; + +class VulkanMemoryPage +{ +public: + VulkanMemoryPage(VulkanMemoryManager& ParentMemoryMgr, + VkDeviceSize PageSize, + uint32_t MemoryTypeIndex, + bool IsHostVisible) noexcept; + ~VulkanMemoryPage(); + + // clang-format off + VulkanMemoryPage(VulkanMemoryPage&& rhs)noexcept : + m_ParentMemoryMgr {rhs.m_ParentMemoryMgr }, + m_AllocationMgr {std::move(rhs.m_AllocationMgr)}, + m_VkMemory {std::move(rhs.m_VkMemory) }, + m_CPUMemory {rhs.m_CPUMemory } + { + rhs.m_CPUMemory = nullptr; + } + + VulkanMemoryPage (const VulkanMemoryPage&) = delete; + VulkanMemoryPage& operator= (VulkanMemoryPage&) = delete; + VulkanMemoryPage& operator= (VulkanMemoryPage&& rhs) = delete; + + bool IsEmpty() const { return m_AllocationMgr.IsEmpty(); } + bool IsFull() const { return m_AllocationMgr.IsFull(); } + VkDeviceSize GetPageSize() const { return m_AllocationMgr.GetMaxSize(); } + VkDeviceSize GetUsedSize() const { return m_AllocationMgr.GetUsedSize(); } + + // clang-format on + + VulkanMemoryAllocation Allocate(VkDeviceSize size, VkDeviceSize alignment); + + VkDeviceMemory GetVkMemory() const { return m_VkMemory; } + void* GetCPUMemory() const { return m_CPUMemory; } + +private: + using AllocationsMgrOffsetType = Diligent::VariableSizeAllocationsManager::OffsetType; + + friend struct VulkanMemoryAllocation; + + // Memory is reclaimed immediately. The application is responsible to ensure it is not in use by the GPU + void Free(VulkanMemoryAllocation&& Allocation); + + VulkanMemoryManager& m_ParentMemoryMgr; + std::mutex m_Mutex; + Diligent::VariableSizeAllocationsManager m_AllocationMgr; + VulkanUtilities::DeviceMemoryWrapper m_VkMemory; + void* m_CPUMemory = nullptr; +}; + +class VulkanMemoryManager +{ +public: + // clang-format off + VulkanMemoryManager(std::string MgrName, + const VulkanLogicalDevice& LogicalDevice, + const VulkanPhysicalDevice& PhysicalDevice, + Diligent::IMemoryAllocator& Allocator, + VkDeviceSize DeviceLocalPageSize, + VkDeviceSize HostVisiblePageSize, + VkDeviceSize DeviceLocalReserveSize, + VkDeviceSize HostVisibleReserveSize) : + m_MgrName {std::move(MgrName) }, + m_LogicalDevice {LogicalDevice }, + m_PhysicalDevice {PhysicalDevice }, + m_Allocator {Allocator }, + m_DeviceLocalPageSize {DeviceLocalPageSize }, + m_HostVisiblePageSize {HostVisiblePageSize }, + m_DeviceLocalReserveSize{DeviceLocalReserveSize}, + m_HostVisibleReserveSize{HostVisibleReserveSize} + {} + + + // We have to write this constructor because on msvc default + // constructor is not labeled with noexcept, which makes all + // std containers use copy instead of move + VulkanMemoryManager(VulkanMemoryManager&& rhs)noexcept : + m_MgrName {std::move(rhs.m_MgrName)}, + m_LogicalDevice {rhs.m_LogicalDevice }, + m_PhysicalDevice {rhs.m_PhysicalDevice }, + m_Allocator {rhs.m_Allocator }, + m_Pages {std::move(rhs.m_Pages) }, + + m_DeviceLocalPageSize {rhs.m_DeviceLocalPageSize }, + m_HostVisiblePageSize {rhs.m_HostVisiblePageSize }, + m_DeviceLocalReserveSize {rhs.m_DeviceLocalReserveSize}, + m_HostVisibleReserveSize {rhs.m_HostVisibleReserveSize}, + + //m_CurrUsedSize {rhs.m_CurrUsedSize}, + m_PeakUsedSize {rhs.m_PeakUsedSize }, + m_CurrAllocatedSize {rhs.m_CurrAllocatedSize}, + m_PeakAllocatedSize {rhs.m_PeakAllocatedSize} + { + // clang-format on + for (size_t i = 0; i < m_CurrUsedSize.size(); ++i) + m_CurrUsedSize[i].store(rhs.m_CurrUsedSize[i].load()); + } + + ~VulkanMemoryManager(); + + // clang-format off + VulkanMemoryManager (const VulkanMemoryManager&) = delete; + VulkanMemoryManager& operator= (const VulkanMemoryManager&) = delete; + VulkanMemoryManager& operator= (VulkanMemoryManager&&) = delete; + // clang-format on + + VulkanMemoryAllocation Allocate(VkDeviceSize Size, VkDeviceSize Alignment, uint32_t MemoryTypeIndex, bool HostVisible); + VulkanMemoryAllocation Allocate(const VkMemoryRequirements& MemReqs, VkMemoryPropertyFlags MemoryProps); + void ShrinkMemory(); + +protected: + friend class VulkanMemoryPage; + + virtual void OnNewPageCreated(VulkanMemoryPage& NewPage) {} + virtual void OnPageDestroy(VulkanMemoryPage& Page) {} + + std::string m_MgrName; + + const VulkanLogicalDevice& m_LogicalDevice; + const VulkanPhysicalDevice& m_PhysicalDevice; + + Diligent::IMemoryAllocator& m_Allocator; + + std::mutex m_PagesMtx; + struct MemoryPageIndex + { + const uint32_t MemoryTypeIndex; + const bool IsHostVisible; + + // clang-format off + MemoryPageIndex(uint32_t _MemoryTypeIndex, + bool _IsHostVisible) : + MemoryTypeIndex(_MemoryTypeIndex), + IsHostVisible (_IsHostVisible) + {} + + bool operator == (const MemoryPageIndex& rhs)const + { + return MemoryTypeIndex == rhs.MemoryTypeIndex && + IsHostVisible == rhs.IsHostVisible; + } + // clang-format on + + struct Hasher + { + size_t operator()(const MemoryPageIndex& PageIndex) const + { + return Diligent::ComputeHash(PageIndex.MemoryTypeIndex, PageIndex.IsHostVisible); + } + }; + }; + std::unordered_multimap m_Pages; + + const VkDeviceSize m_DeviceLocalPageSize; + const VkDeviceSize m_HostVisiblePageSize; + const VkDeviceSize m_DeviceLocalReserveSize; + const VkDeviceSize m_HostVisibleReserveSize; + + void OnFreeAllocation(VkDeviceSize Size, bool IsHostVisble); + + // 0 == Device local, 1 == Host-visible + std::array m_CurrUsedSize = {}; + std::array m_PeakUsedSize = {}; + std::array m_CurrAllocatedSize = {}; + std::array m_PeakAllocatedSize = {}; + + // If adding new member, do not forget to update move ctor +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.h deleted file mode 100644 index 03d7cdf7..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include "VulkanLogicalDevice.h" - -namespace VulkanUtilities -{ - -// In 32-bit version, all Vulkan handles are typedefed as uint64_t, so we have to -// use another way to distinguish objects. -enum class VulkanHandleTypeId : uint32_t; - -template -class VulkanObjectWrapper -{ -public: - using VkObjectType = VulkanObjectType; - - // clang-format off - VulkanObjectWrapper() : - m_pLogicalDevice{nullptr }, - m_VkObject {VK_NULL_HANDLE} - {} - - VulkanObjectWrapper(std::shared_ptr pLogicalDevice, VulkanObjectType&& vkObject) : - m_pLogicalDevice{pLogicalDevice}, - m_VkObject {vkObject } - { - vkObject = VK_NULL_HANDLE; - } - // This constructor does not take ownership of the vulkan object - explicit VulkanObjectWrapper(VulkanObjectType vkObject) : - m_VkObject {vkObject} - { - } - - VulkanObjectWrapper (const VulkanObjectWrapper&) = delete; - VulkanObjectWrapper& operator = (const VulkanObjectWrapper&) = delete; - - VulkanObjectWrapper(VulkanObjectWrapper&& rhs)noexcept : - m_pLogicalDevice{std::move(rhs.m_pLogicalDevice)}, - m_VkObject {rhs.m_VkObject } - { - rhs.m_VkObject = VK_NULL_HANDLE; - } - - // clang-format on - - VulkanObjectWrapper& operator=(VulkanObjectWrapper&& rhs) noexcept - { - Release(); - m_pLogicalDevice = std::move(rhs.m_pLogicalDevice); - m_VkObject = rhs.m_VkObject; - rhs.m_VkObject = VK_NULL_HANDLE; - return *this; - } - - operator VulkanObjectType() const - { - return m_VkObject; - } - - void Release() - { - // For externally managed objects, m_pLogicalDevice is null - if (m_pLogicalDevice && m_VkObject != VK_NULL_HANDLE) - { - m_pLogicalDevice->ReleaseVulkanObject(std::move(*this)); - } - m_VkObject = VK_NULL_HANDLE; - m_pLogicalDevice.reset(); - } - - ~VulkanObjectWrapper() - { - Release(); - } - -private: - friend class VulkanLogicalDevice; - - std::shared_ptr m_pLogicalDevice; - VulkanObjectType m_VkObject; -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.hpp new file mode 100644 index 00000000..7e2f8385 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanObjectWrappers.hpp @@ -0,0 +1,113 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include "VulkanLogicalDevice.hpp" + +namespace VulkanUtilities +{ + +// In 32-bit version, all Vulkan handles are typedefed as uint64_t, so we have to +// use another way to distinguish objects. +enum class VulkanHandleTypeId : uint32_t; + +template +class VulkanObjectWrapper +{ +public: + using VkObjectType = VulkanObjectType; + + // clang-format off + VulkanObjectWrapper() : + m_pLogicalDevice{nullptr }, + m_VkObject {VK_NULL_HANDLE} + {} + + VulkanObjectWrapper(std::shared_ptr pLogicalDevice, VulkanObjectType&& vkObject) : + m_pLogicalDevice{pLogicalDevice}, + m_VkObject {vkObject } + { + vkObject = VK_NULL_HANDLE; + } + // This constructor does not take ownership of the vulkan object + explicit VulkanObjectWrapper(VulkanObjectType vkObject) : + m_VkObject {vkObject} + { + } + + VulkanObjectWrapper (const VulkanObjectWrapper&) = delete; + VulkanObjectWrapper& operator = (const VulkanObjectWrapper&) = delete; + + VulkanObjectWrapper(VulkanObjectWrapper&& rhs)noexcept : + m_pLogicalDevice{std::move(rhs.m_pLogicalDevice)}, + m_VkObject {rhs.m_VkObject } + { + rhs.m_VkObject = VK_NULL_HANDLE; + } + + // clang-format on + + VulkanObjectWrapper& operator=(VulkanObjectWrapper&& rhs) noexcept + { + Release(); + m_pLogicalDevice = std::move(rhs.m_pLogicalDevice); + m_VkObject = rhs.m_VkObject; + rhs.m_VkObject = VK_NULL_HANDLE; + return *this; + } + + operator VulkanObjectType() const + { + return m_VkObject; + } + + void Release() + { + // For externally managed objects, m_pLogicalDevice is null + if (m_pLogicalDevice && m_VkObject != VK_NULL_HANDLE) + { + m_pLogicalDevice->ReleaseVulkanObject(std::move(*this)); + } + m_VkObject = VK_NULL_HANDLE; + m_pLogicalDevice.reset(); + } + + ~VulkanObjectWrapper() + { + Release(); + } + +private: + friend class VulkanLogicalDevice; + + std::shared_ptr m_pLogicalDevice; + VulkanObjectType m_VkObject; +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h deleted file mode 100644 index 43f4be84..00000000 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2019-2020 Diligent Graphics LLC - * Copyright 2015-2019 Egor Yusov - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * In no event and under no legal theory, whether in tort (including negligence), - * contract, or otherwise, unless required by applicable law (such as deliberate - * and grossly negligent acts) or agreed to in writing, shall any Contributor be - * liable for any damages, including any direct, indirect, special, incidental, - * or consequential damages of any character arising as a result of this License or - * out of the use or inability to use the software (including but not limited to damages - * for loss of goodwill, work stoppage, computer failure or malfunction, or any and - * all other commercial damages or losses), even if such Contributor has been advised - * of the possibility of such damages. - */ - -#pragma once - -#include -#include -#include "vulkan.h" - -namespace VulkanUtilities -{ - -class VulkanPhysicalDevice -{ -public: - // clang-format off - VulkanPhysicalDevice (const VulkanPhysicalDevice&) = delete; - VulkanPhysicalDevice (VulkanPhysicalDevice&&) = delete; - VulkanPhysicalDevice& operator = (const VulkanPhysicalDevice&) = delete; - VulkanPhysicalDevice& operator = (VulkanPhysicalDevice&&) = delete; - // clang-format on - - static std::unique_ptr Create(VkPhysicalDevice vkDevice); - - // clang-format off - uint32_t FindQueueFamily (VkQueueFlags QueueFlags) const; - VkPhysicalDevice GetVkDeviceHandle () const { return m_VkDevice; } - bool IsExtensionSupported(const char* ExtensionName) const; - bool CheckPresentSupport (uint32_t queueFamilyIndex, VkSurfaceKHR VkSurface) const; - // clang-format on - - static constexpr uint32_t InvalidMemoryTypeIndex = static_cast(-1); - - uint32_t GetMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) const; - - const VkPhysicalDeviceProperties& GetProperties() const { return m_Properties; } - const VkPhysicalDeviceFeatures& GetFeatures() const { return m_Features; } - VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat) const; - -private: - VulkanPhysicalDevice(VkPhysicalDevice vkDevice); - - const VkPhysicalDevice m_VkDevice; - VkPhysicalDeviceProperties m_Properties = {}; - VkPhysicalDeviceFeatures m_Features = {}; - VkPhysicalDeviceMemoryProperties m_MemoryProperties = {}; - std::vector m_QueueFamilyProperties; - std::vector m_SupportedExtensions; -}; - -} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp new file mode 100644 index 00000000..43f4be84 --- /dev/null +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp @@ -0,0 +1,75 @@ +/* + * Copyright 2019-2020 Diligent Graphics LLC + * Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include +#include +#include "vulkan.h" + +namespace VulkanUtilities +{ + +class VulkanPhysicalDevice +{ +public: + // clang-format off + VulkanPhysicalDevice (const VulkanPhysicalDevice&) = delete; + VulkanPhysicalDevice (VulkanPhysicalDevice&&) = delete; + VulkanPhysicalDevice& operator = (const VulkanPhysicalDevice&) = delete; + VulkanPhysicalDevice& operator = (VulkanPhysicalDevice&&) = delete; + // clang-format on + + static std::unique_ptr Create(VkPhysicalDevice vkDevice); + + // clang-format off + uint32_t FindQueueFamily (VkQueueFlags QueueFlags) const; + VkPhysicalDevice GetVkDeviceHandle () const { return m_VkDevice; } + bool IsExtensionSupported(const char* ExtensionName) const; + bool CheckPresentSupport (uint32_t queueFamilyIndex, VkSurfaceKHR VkSurface) const; + // clang-format on + + static constexpr uint32_t InvalidMemoryTypeIndex = static_cast(-1); + + uint32_t GetMemoryTypeIndex(uint32_t typeBits, VkMemoryPropertyFlags properties) const; + + const VkPhysicalDeviceProperties& GetProperties() const { return m_Properties; } + const VkPhysicalDeviceFeatures& GetFeatures() const { return m_Features; } + VkFormatProperties GetPhysicalDeviceFormatProperties(VkFormat imageFormat) const; + +private: + VulkanPhysicalDevice(VkPhysicalDevice vkDevice); + + const VkPhysicalDevice m_VkDevice; + VkPhysicalDeviceProperties m_Properties = {}; + VkPhysicalDeviceFeatures m_Features = {}; + VkPhysicalDeviceMemoryProperties m_MemoryProperties = {}; + std::vector m_QueueFamilyProperties; + std::vector m_SupportedExtensions; +}; + +} // namespace VulkanUtilities diff --git a/Graphics/GraphicsEngineVulkan/include/pch.h b/Graphics/GraphicsEngineVulkan/include/pch.h index 2c193f3e..3e19eebd 100644 --- a/Graphics/GraphicsEngineVulkan/include/pch.h +++ b/Graphics/GraphicsEngineVulkan/include/pch.h @@ -73,6 +73,6 @@ template <> struct hash #include "PlatformDefinitions.h" #include "Errors.h" #include "RefCntAutoPtr.h" -#include "VulkanErrors.h" +#include "VulkanErrors.hpp" #include "RenderDeviceBase.hpp" #include "ValidatedCast.h" diff --git a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp index 7552f804..314358ef 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferViewVkImpl.cpp @@ -26,9 +26,9 @@ */ #include "pch.h" -#include "BufferViewVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "BufferVkImpl.h" +#include "BufferViewVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "BufferVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp index b36a8a76..0a71b354 100644 --- a/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/BufferVkImpl.cpp @@ -26,16 +26,16 @@ */ #include "pch.h" -#include "BufferVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "VulkanTypeConversions.h" -#include "BufferViewVkImpl.h" +#include "BufferVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "BufferViewVkImpl.hpp" #include "GraphicsAccessories.hpp" #include "EngineMemory.h" #include "StringTools.h" -#include "VulkanUtilities/VulkanDebug.h" -#include "VulkanUtilities/VulkanCommandBuffer.h" +#include "VulkanUtilities/VulkanDebug.hpp" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp index 97e67c1a..1c0f21c5 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandPoolManager.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "CommandPoolManager.h" -#include "RenderDeviceVkImpl.h" +#include "CommandPoolManager.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp index f62951e5..147e8c56 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp @@ -27,7 +27,7 @@ #include #include "pch.h" -#include "CommandQueueVkImpl.h" +#include "CommandQueueVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp index 99ae5d55..a4cf5973 100644 --- a/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DescriptorPoolManager.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "DescriptorPoolManager.h" -#include "RenderDeviceVkImpl.h" +#include "DescriptorPoolManager.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 9584d499..75b1305d 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -27,14 +27,14 @@ #include "pch.h" #include -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "PipelineStateVkImpl.h" -#include "TextureVkImpl.h" -#include "BufferVkImpl.h" -#include "VulkanTypeConversions.h" -#include "CommandListVkImpl.h" -#include "FenceVkImpl.h" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "PipelineStateVkImpl.hpp" +#include "TextureVkImpl.hpp" +#include "BufferVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "CommandListVkImpl.hpp" +#include "FenceVkImpl.hpp" #include "GraphicsAccessories.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 8614c925..b34a8689 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -31,13 +31,13 @@ #include "pch.h" #include #include "EngineFactoryVk.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "SwapChainVkImpl.h" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "SwapChainVkImpl.hpp" #include "EngineMemory.h" -#include "CommandQueueVkImpl.h" -#include "VulkanUtilities/VulkanInstance.h" -#include "VulkanUtilities/VulkanPhysicalDevice.h" +#include "CommandQueueVkImpl.hpp" +#include "VulkanUtilities/VulkanInstance.hpp" +#include "VulkanUtilities/VulkanPhysicalDevice.hpp" #include "EngineFactoryBase.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp index 6b38ac7d..8b73ea74 100644 --- a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp @@ -27,9 +27,9 @@ #include "pch.h" -#include "FenceVkImpl.h" +#include "FenceVkImpl.hpp" #include "EngineMemory.h" -#include "RenderDeviceVkImpl.h" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp index d6c84d02..a6a0fe97 100644 --- a/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FramebufferCache.cpp @@ -26,9 +26,9 @@ */ #include "pch.h" -#include "FramebufferCache.h" +#include "FramebufferCache.hpp" #include "HashUtils.h" -#include "RenderDeviceVkImpl.h" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp index 7aaa1838..dcfccc7f 100644 --- a/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp +++ b/Graphics/GraphicsEngineVulkan/src/GenerateMipsVkHelper.cpp @@ -27,13 +27,13 @@ #include "pch.h" #include -#include "GenerateMipsVkHelper.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "TextureViewVkImpl.h" -#include "TextureVkImpl.h" +#include "GenerateMipsVkHelper.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "TextureViewVkImpl.hpp" +#include "TextureVkImpl.hpp" #include "PlatformMisc.h" -#include "VulkanTypeConversions.h" +#include "VulkanTypeConversions.hpp" #include "../../GraphicsTools/interface/ShaderMacroHelper.hpp" #include "../../GraphicsTools/interface/CommonlyUsedStates.h" #include "../../GraphicsTools/interface/MapHelper.hpp" diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 81f354de..c4d1f42e 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -27,14 +27,14 @@ #include "pch.h" -#include "PipelineLayout.h" -#include "ShaderResourceLayoutVk.h" -#include "ShaderVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "TextureVkImpl.h" -#include "BufferVkImpl.h" -#include "VulkanTypeConversions.h" +#include "PipelineLayout.hpp" +#include "ShaderResourceLayoutVk.hpp" +#include "ShaderVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "TextureVkImpl.hpp" +#include "BufferVkImpl.hpp" +#include "VulkanTypeConversions.hpp" #include "HashUtils.h" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index d507bdc1..46c67a9f 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -27,12 +27,12 @@ #include "pch.h" #include -#include "PipelineStateVkImpl.h" -#include "ShaderVkImpl.h" -#include "VulkanTypeConversions.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "ShaderResourceBindingVkImpl.h" +#include "PipelineStateVkImpl.hpp" +#include "ShaderVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "ShaderResourceBindingVkImpl.hpp" #include "EngineMemory.h" #include "StringTools.h" #include "spirv-tools/optimizer.hpp" diff --git a/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp b/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp index 2cd6cff1..901f7228 100644 --- a/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/QueryManagerVk.cpp @@ -27,10 +27,10 @@ #include "pch.h" #include -#include "QueryManagerVk.h" -#include "RenderDeviceVkImpl.h" +#include "QueryManagerVk.hpp" +#include "RenderDeviceVkImpl.hpp" #include "GraphicsAccessories.hpp" -#include "VulkanUtilities/VulkanCommandBuffer.h" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp index 60f33ed9..b4464d50 100644 --- a/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/QueryVkImpl.cpp @@ -27,10 +27,10 @@ #include "pch.h" -#include "QueryVkImpl.h" +#include "QueryVkImpl.hpp" #include "EngineMemory.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index 64853356..6f81e96c 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -26,17 +26,17 @@ */ #include "pch.h" -#include "RenderDeviceVkImpl.h" -#include "PipelineStateVkImpl.h" -#include "ShaderVkImpl.h" -#include "TextureVkImpl.h" -#include "VulkanTypeConversions.h" -#include "SamplerVkImpl.h" -#include "BufferVkImpl.h" -#include "ShaderResourceBindingVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "FenceVkImpl.h" -#include "QueryVkImpl.h" +#include "RenderDeviceVkImpl.hpp" +#include "PipelineStateVkImpl.hpp" +#include "ShaderVkImpl.hpp" +#include "TextureVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "SamplerVkImpl.hpp" +#include "BufferVkImpl.hpp" +#include "ShaderResourceBindingVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "FenceVkImpl.hpp" +#include "QueryVkImpl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp index c3e61cac..7c7c404d 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderPassCache.cpp @@ -27,9 +27,9 @@ #include "pch.h" #include -#include "RenderPassCache.h" -#include "RenderDeviceVkImpl.h" -#include "PipelineStateVkImpl.h" +#include "RenderPassCache.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "PipelineStateVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/SamplerVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SamplerVkImpl.cpp index fc174461..13800f49 100644 --- a/Graphics/GraphicsEngineVulkan/src/SamplerVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SamplerVkImpl.cpp @@ -26,9 +26,9 @@ */ #include "pch.h" -#include "SamplerVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "VulkanTypeConversions.h" +#include "SamplerVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "VulkanTypeConversions.hpp" #include "GraphicsAccessories.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp index 49aa090a..da361e1a 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceBindingVkImpl.cpp @@ -26,10 +26,10 @@ */ #include "pch.h" -#include "ShaderResourceBindingVkImpl.h" -#include "PipelineStateVkImpl.h" -#include "ShaderVkImpl.h" -#include "RenderDeviceVkImpl.h" +#include "ShaderResourceBindingVkImpl.hpp" +#include "PipelineStateVkImpl.hpp" +#include "ShaderVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp index 8320bc35..1f09846a 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceCacheVk.cpp @@ -27,13 +27,13 @@ #include "pch.h" -#include "ShaderResourceCacheVk.h" -#include "DeviceContextVkImpl.h" -#include "BufferViewVkImpl.h" -#include "TextureViewVkImpl.h" -#include "TextureVkImpl.h" -#include "SamplerVkImpl.h" -#include "VulkanTypeConversions.h" +#include "ShaderResourceCacheVk.hpp" +#include "DeviceContextVkImpl.hpp" +#include "BufferViewVkImpl.hpp" +#include "TextureViewVkImpl.hpp" +#include "TextureVkImpl.hpp" +#include "SamplerVkImpl.hpp" +#include "VulkanTypeConversions.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp index fb383f37..f362c752 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderResourceLayoutVk.cpp @@ -27,18 +27,18 @@ #include "pch.h" -#include "ShaderResourceLayoutVk.h" -#include "ShaderResourceCacheVk.h" -#include "BufferVkImpl.h" +#include "ShaderResourceLayoutVk.hpp" +#include "ShaderResourceCacheVk.hpp" +#include "BufferVkImpl.hpp" #include "BufferViewVk.h" -#include "TextureVkImpl.h" -#include "TextureViewVkImpl.h" -#include "SamplerVkImpl.h" -#include "ShaderVkImpl.h" -#include "PipelineLayout.h" +#include "TextureVkImpl.hpp" +#include "TextureViewVkImpl.hpp" +#include "SamplerVkImpl.hpp" +#include "ShaderVkImpl.hpp" +#include "PipelineLayout.hpp" #include "ShaderResourceVariableBase.hpp" #include "StringTools.h" -#include "PipelineStateVkImpl.h" +#include "PipelineStateVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp index 8c8a4460..8f476082 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVariableVk.cpp @@ -27,7 +27,7 @@ #include "pch.h" -#include "ShaderVariableVk.h" +#include "ShaderVariableVk.hpp" #include "ShaderResourceVariableBase.hpp" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp index fb749ad4..da5d30e6 100644 --- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp @@ -29,8 +29,8 @@ #include #include "pch.h" -#include "ShaderVkImpl.h" -#include "RenderDeviceVkImpl.h" +#include "ShaderVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" #include "DataBlobImpl.h" #include "GLSLSourceBuilder.hpp" diff --git a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp index bd0bf0cf..2a906a2b 100644 --- a/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/SwapChainVkImpl.cpp @@ -26,11 +26,11 @@ */ #include "pch.h" -#include "SwapChainVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "VulkanTypeConversions.h" -#include "TextureVkImpl.h" +#include "SwapChainVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "TextureVkImpl.hpp" #include "EngineMemory.h" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/TextureViewVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureViewVkImpl.cpp index 2ac64270..1c65b3d5 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureViewVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureViewVkImpl.cpp @@ -26,9 +26,9 @@ */ #include "pch.h" -#include "TextureViewVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "RenderDeviceVkImpl.h" +#include "TextureViewVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp index 85686d2c..0ce92558 100644 --- a/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/TextureVkImpl.cpp @@ -26,12 +26,12 @@ */ #include "pch.h" -#include "TextureVkImpl.h" -#include "RenderDeviceVkImpl.h" -#include "DeviceContextVkImpl.h" -#include "VulkanTypeConversions.h" -#include "TextureViewVkImpl.h" -#include "VulkanTypeConversions.h" +#include "TextureVkImpl.hpp" +#include "RenderDeviceVkImpl.hpp" +#include "DeviceContextVkImpl.hpp" +#include "VulkanTypeConversions.hpp" +#include "TextureViewVkImpl.hpp" +#include "VulkanTypeConversions.hpp" #include "EngineMemory.h" #include "StringTools.h" #include "GraphicsAccessories.hpp" diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp index f158106b..c1af82ea 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanDynamicHeap.cpp @@ -28,8 +28,8 @@ #include "pch.h" #include #include -#include "VulkanDynamicHeap.h" -#include "RenderDeviceVkImpl.h" +#include "VulkanDynamicHeap.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index 5bf3ada9..bf8d8517 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -29,7 +29,7 @@ #include #include -#include "VulkanTypeConversions.h" +#include "VulkanTypeConversions.hpp" #include "PlatformMisc.h" namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp index aea4693c..5a1894c0 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUploadHeap.cpp @@ -26,8 +26,8 @@ */ #include "pch.h" -#include "VulkanUploadHeap.h" -#include "RenderDeviceVkImpl.h" +#include "VulkanUploadHeap.hpp" +#include "RenderDeviceVkImpl.hpp" namespace Diligent { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp index e14d963b..11444c33 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBuffer.cpp @@ -26,7 +26,7 @@ */ #include -#include "VulkanUtilities/VulkanCommandBuffer.h" +#include "VulkanUtilities/VulkanCommandBuffer.hpp" namespace VulkanUtilities { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBufferPool.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBufferPool.cpp index 7fa9ea7e..83e6db4f 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBufferPool.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanCommandBufferPool.cpp @@ -26,11 +26,11 @@ */ #include -#include "VulkanUtilities/VulkanCommandBufferPool.h" -#include "VulkanUtilities/VulkanDebug.h" +#include "VulkanUtilities/VulkanCommandBufferPool.hpp" +#include "VulkanUtilities/VulkanDebug.hpp" #include "Errors.h" #include "DebugUtilities.h" -#include "VulkanErrors.h" +#include "VulkanErrors.hpp" namespace VulkanUtilities { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp index 428f8ead..af5d2d64 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanDebug.cpp @@ -11,8 +11,8 @@ #include #include -#include "VulkanUtilities/VulkanDebug.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" +#include "VulkanUtilities/VulkanDebug.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" #include "Errors.h" #include "DebugUtilities.h" diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanFencePool.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanFencePool.cpp index b65efbac..8db94750 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanFencePool.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanFencePool.cpp @@ -26,7 +26,7 @@ */ #include -#include "VulkanUtilities/VulkanFencePool.h" +#include "VulkanUtilities/VulkanFencePool.hpp" #include "Errors.h" #include "DebugUtilities.h" diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp index 5392e208..9f6334a2 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp @@ -27,9 +27,9 @@ #include #include -#include "VulkanErrors.h" -#include "VulkanUtilities/VulkanInstance.h" -#include "VulkanUtilities/VulkanDebug.h" +#include "VulkanErrors.hpp" +#include "VulkanUtilities/VulkanInstance.hpp" +#include "VulkanUtilities/VulkanDebug.hpp" #if !NO_GLSLANG # include "SPIRVUtils.hpp" diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index 23fd559e..4f69421d 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -26,10 +26,10 @@ */ #include -#include "VulkanErrors.h" -#include "VulkanUtilities/VulkanLogicalDevice.h" -#include "VulkanUtilities/VulkanDebug.h" -#include "VulkanUtilities/VulkanObjectWrappers.h" +#include "VulkanErrors.hpp" +#include "VulkanUtilities/VulkanLogicalDevice.hpp" +#include "VulkanUtilities/VulkanDebug.hpp" +#include "VulkanUtilities/VulkanObjectWrappers.hpp" namespace VulkanUtilities { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp index 53bb289d..a125233f 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp @@ -27,7 +27,7 @@ #include "pch.h" #include -#include "VulkanUtilities/VulkanMemoryManager.h" +#include "VulkanUtilities/VulkanMemoryManager.hpp" namespace VulkanUtilities { diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp index 8a592044..11eb766d 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanPhysicalDevice.cpp @@ -27,8 +27,8 @@ #include #include -#include "VulkanErrors.h" -#include "VulkanUtilities/VulkanPhysicalDevice.h" +#include "VulkanErrors.hpp" +#include "VulkanUtilities/VulkanPhysicalDevice.hpp" namespace VulkanUtilities { -- cgit v1.2.3