From 7b13811c90256c1c87d7b04fb07e34828a6709a4 Mon Sep 17 00:00:00 2001 From: s-ol Date: Wed, 17 Mar 2021 18:00:10 +0100 Subject: External Vulkan Device support --- .../include/CommandQueueVkImpl.hpp | 4 ++ .../include/VulkanUtilities/VulkanInstance.hpp | 8 +++- .../VulkanUtilities/VulkanLogicalDevice.hpp | 9 ++++ .../interface/EngineFactoryVk.h | 10 +++++ .../src/CommandQueueVkImpl.cpp | 14 ++++++ .../GraphicsEngineVulkan/src/EngineFactoryVk.cpp | 51 ++++++++++++++++++++++ .../src/VulkanUtilities/VulkanInstance.cpp | 30 ++++++++++++- .../src/VulkanUtilities/VulkanLogicalDevice.cpp | 27 ++++++++++++ 8 files changed, 151 insertions(+), 2 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp index d07ce349..53080b26 100644 --- a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.hpp @@ -54,6 +54,10 @@ public: CommandQueueVkImpl(IReferenceCounters* pRefCounters, std::shared_ptr LogicalDevice, uint32_t QueueFamilyIndex); + CommandQueueVkImpl(IReferenceCounters* pRefCounters, + std::shared_ptr LogicalDevice, + const VkQueue& Queue, + uint32_t QueueFamilyIndex); ~CommandQueueVkImpl(); IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_CommandQueueVk, TBase) diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp index 3a418279..e8a7b00e 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanInstance.hpp @@ -49,6 +49,9 @@ public: uint32_t GlobalExtensionCount, const char* const* ppGlobalExtensionNames, VkAllocationCallbacks* pVkAllocator); + + static std::shared_ptr Create(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator); ~VulkanInstance(); std::shared_ptr GetSharedPtr() @@ -79,8 +82,11 @@ private: uint32_t GlobalExtensionCount, const char* const* ppGlobalExtensionNames, VkAllocationCallbacks* pVkAllocator); + VulkanInstance(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator); - bool m_DebugUtilsEnabled = false; + bool m_DebugUtilsEnabled = false; + bool m_InitializedExternally = false; VkAllocationCallbacks* const m_pVkAllocator; VkInstance m_VkInstance = VK_NULL_HANDLE; uint32_t m_VkVersion = VK_API_VERSION_1_0; diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp index 57779dbc..34639140 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanLogicalDevice.hpp @@ -95,6 +95,11 @@ public: const ExtensionFeatures& EnabledExtFeatures, const VkAllocationCallbacks* vkAllocator); + static std::shared_ptr Create(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + VkPipelineStageFlags EnabledShaderStages, + const VkAllocationCallbacks* vkAllocator); + // clang-format off VulkanLogicalDevice (const VulkanLogicalDevice&) = delete; VulkanLogicalDevice (VulkanLogicalDevice&&) = delete; @@ -231,6 +236,10 @@ private: const VkDeviceCreateInfo& DeviceCI, const ExtensionFeatures& EnabledExtFeatures, const VkAllocationCallbacks* vkAllocator); + VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + VkPipelineStageFlags EnabledShaderStages, + const VkAllocationCallbacks* vkAllocator); template LogicalDevice, + const VkQueue& Queue, + uint32_t QueueFamilyIndex) : + // clang-format off + TBase{pRefCounters}, + m_LogicalDevice {LogicalDevice}, + m_VkQueue {Queue}, + m_QueueFamilyIndex {QueueFamilyIndex}, + m_NextFenceValue {1} +// clang-format on +{ +} + CommandQueueVkImpl::~CommandQueueVkImpl() { // Queues are created along with the logical device during vkCreateDevice. diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index f44d3677..b5d06700 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -66,6 +66,15 @@ public: IRenderDevice** ppDevice, IDeviceContext** ppContexts) override final; + virtual void DILIGENT_CALL_TYPE AttachToVulkanDevice(const VkInstance& Instance, + const VkPhysicalDevice& PhysicalDevice, + const VkDevice& LogicalDevice, + const VkQueue& Queue, + uint32_t QueueFamilyIndex, + const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts) override final; + virtual void DILIGENT_CALL_TYPE AttachToVulkanDevice(std::shared_ptr Instance, std::unique_ptr PhysicalDevice, std::shared_ptr LogicalDevice, @@ -532,6 +541,48 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E } } +void EngineFactoryVkImpl::AttachToVulkanDevice(const VkInstance& Instance, + const VkPhysicalDevice& PhysicalDevice, + const VkDevice& LogicalDevice, + const VkQueue& Queue, + uint32_t QueueFamilyIndex, + const EngineVkCreateInfo& EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts) +{ + auto& RawMemAllocator = GetRawAllocator(); + + auto VulkanInstance = VulkanUtilities::VulkanInstance::Create(Instance, nullptr); + auto VulkanPhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(PhysicalDevice, *VulkanInstance); + + VkPipelineStageFlags PipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT | VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT; + auto VulkanLogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*VulkanPhysicalDevice, LogicalDevice, PipelineStages, nullptr); + RefCntAutoPtr pCmdQueueVk{ + NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(VulkanLogicalDevice, Queue, QueueFamilyIndex)}; + std::array CommandQueues = {{pCmdQueueVk}}; + + OnRenderDeviceCreated = [&](RenderDeviceVkImpl* pRenderDeviceVk) + { + FenceDesc Desc; + Desc.Name = "Command queue internal fence"; + constexpr bool IsDeviceInternal = false; + + RefCntAutoPtr pFenceVk{ + NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal)}; + pCmdQueueVk->SetFence(std::move(pFenceVk)); + }; + + AttachToVulkanDevice( + VulkanInstance, + std::move(VulkanPhysicalDevice), + VulkanLogicalDevice, + CommandQueues.size(), CommandQueues.data(), + EngineCI, + ppDevice, + ppContexts + ); +} + /// Attaches to existing Vulkan device /// \param [in] Instance - shared pointer to a VulkanUtilities::VulkanInstance object diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp index 4c617995..3d92aac2 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanInstance.cpp @@ -89,6 +89,13 @@ std::shared_ptr VulkanInstance::Create(uint32_t Ap return std::shared_ptr{Instance}; } +std::shared_ptr VulkanInstance::Create(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator) +{ + auto Instance = new VulkanInstance{vkInstance, pVkAllocator}; + return std::shared_ptr{Instance}; +} + VulkanInstance::VulkanInstance(uint32_t ApiVersion, bool EnableValidation, uint32_t GlobalExtensionCount, @@ -291,13 +298,34 @@ VulkanInstance::VulkanInstance(uint32_t ApiVersion, #endif } +VulkanInstance::VulkanInstance(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator) : + m_pVkAllocator{pVkAllocator}, + m_VkInstance{vkInstance}, + m_InitializedExternally{true} +{ +#if DILIGENT_USE_VOLK + if (volkInitialize() != VK_SUCCESS) + { + LOG_ERROR_AND_THROW("Failed to load Vulkan."); + } + volkLoadInstance(m_VkInstance); +#endif +#if !DILIGENT_NO_GLSLANG + Diligent::GLSLangUtils::InitializeGlslang(); +#endif +} + VulkanInstance::~VulkanInstance() { if (m_DebugUtilsEnabled) { VulkanUtilities::FreeDebugging(m_VkInstance); } - vkDestroyInstance(m_VkInstance, m_pVkAllocator); + if (!m_InitializedExternally) + { + vkDestroyInstance(m_VkInstance, m_pVkAllocator); + } #if !DILIGENT_NO_GLSLANG Diligent::GLSLangUtils::FinalizeGlslang(); diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp index 5b4b6f5d..b9d986fa 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanLogicalDevice.cpp @@ -43,6 +43,15 @@ std::shared_ptr VulkanLogicalDevice::Create(const VulkanPhy return std::shared_ptr{LogicalDevice}; } +std::shared_ptr VulkanLogicalDevice::Create(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + VkPipelineStageFlags EnabledShaderStages, + const VkAllocationCallbacks* vkAllocator) +{ + auto* LogicalDevice = new VulkanLogicalDevice{PhysicalDevice, Device, EnabledShaderStages, vkAllocator}; + return std::shared_ptr{LogicalDevice}; +} + VulkanLogicalDevice::~VulkanLogicalDevice() { vkDestroyDevice(m_VkDevice, m_VkAllocator); @@ -76,6 +85,24 @@ VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDe m_EnabledShaderStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR; } +VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice, + const VkDevice& Device, + VkPipelineStageFlags EnabledShaderStages, + const VkAllocationCallbacks* vkAllocator) : + m_VkDevice{Device}, + m_VkAllocator{vkAllocator}, + m_EnabledShaderStages{EnabledShaderStages}, + m_EnabledFeatures{}, + m_EnabledExtFeatures{} +{ +#if DILIGENT_USE_VOLK + // Since we only use one device at this time, load device function entries + // https://github.com/zeux/volk#optimizing-device-calls + volkLoadDevice(m_VkDevice); +#endif +} + + VkQueue VulkanLogicalDevice::GetQueue(uint32_t queueFamilyIndex, uint32_t queueIndex) { VkQueue vkQueue = VK_NULL_HANDLE; -- cgit v1.2.3