diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2021-03-17 17:00:10 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2021-03-27 08:58:09 +0000 |
| commit | 7b13811c90256c1c87d7b04fb07e34828a6709a4 (patch) | |
| tree | cf92e89a21cde2dcf69a662da0ef35fb7ff206cd /Graphics/GraphicsEngineVulkan | |
| parent | Fixed issue with stale descriptor sets in Vulkan (diff) | |
| download | DiligentCore-7b13811c90256c1c87d7b04fb07e34828a6709a4.tar.gz DiligentCore-7b13811c90256c1c87d7b04fb07e34828a6709a4.zip | |
External Vulkan Device support
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
8 files changed, 151 insertions, 2 deletions
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<VulkanUtilities::VulkanLogicalDevice> LogicalDevice, uint32_t QueueFamilyIndex); + CommandQueueVkImpl(IReferenceCounters* pRefCounters, + std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> 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<VulkanInstance> Create(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator); ~VulkanInstance(); std::shared_ptr<VulkanInstance> 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<VulkanLogicalDevice> 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 <typename VkObjectType, VulkanHandleTypeId VkTypeId, diff --git a/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h b/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h index 49389265..61210e74 100644 --- a/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h +++ b/Graphics/GraphicsEngineVulkan/interface/EngineFactoryVk.h @@ -80,6 +80,15 @@ DILIGENT_BEGIN_INTERFACE(IEngineFactoryVk, IEngineFactory) IRenderDevice** ppDevice, IDeviceContext** ppContexts) PURE; + VIRTUAL void METHOD(AttachToVulkanDevice)(THIS_ + const VkInstance REF Instance, + const VkPhysicalDevice REF PhysicalDevice, + const VkDevice REF LogicalDevice, + const VkQueue REF Queue, + uint32_t QueueFamilyIndex, + const EngineVkCreateInfo REF EngineCI, + IRenderDevice** ppDevice, + IDeviceContext** ppContexts) PURE; /// Creates a swap chain for Vulkan-based engine implementation @@ -107,6 +116,7 @@ DILIGENT_END_INTERFACE // clang-format off # define IEngineFactoryVk_CreateDeviceAndContextsVk(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, CreateDeviceAndContextsVk, This, __VA_ARGS__) +# define IEngineFactoryVk_AttachToVulkanDevice(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, AttachToVulkanDevice, This, __VA_ARGS__) # define IEngineFactoryVk_CreateSwapChainVk(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, CreateSwapChainVk, This, __VA_ARGS__) // clang-format on diff --git a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp index 3b725dd8..32a2501b 100644 --- a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp @@ -49,6 +49,20 @@ CommandQueueVkImpl::CommandQueueVkImpl(IReferenceCounters* { } +CommandQueueVkImpl::CommandQueueVkImpl(IReferenceCounters* pRefCounters, + std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> 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<VulkanUtilities::VulkanInstance> Instance, std::unique_ptr<VulkanUtilities::VulkanPhysicalDevice> PhysicalDevice, std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> 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<CommandQueueVkImpl> pCmdQueueVk{ + NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(VulkanLogicalDevice, Queue, QueueFamilyIndex)}; + std::array<ICommandQueueVk*, 1> CommandQueues = {{pCmdQueueVk}}; + + OnRenderDeviceCreated = [&](RenderDeviceVkImpl* pRenderDeviceVk) + { + FenceDesc Desc; + Desc.Name = "Command queue internal fence"; + constexpr bool IsDeviceInternal = false; + + RefCntAutoPtr<FenceVkImpl> 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> VulkanInstance::Create(uint32_t Ap return std::shared_ptr<VulkanInstance>{Instance}; } +std::shared_ptr<VulkanInstance> VulkanInstance::Create(const VkInstance& vkInstance, + VkAllocationCallbacks* pVkAllocator) +{ + auto Instance = new VulkanInstance{vkInstance, pVkAllocator}; + return std::shared_ptr<VulkanInstance>{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> VulkanLogicalDevice::Create(const VulkanPhy return std::shared_ptr<VulkanLogicalDevice>{LogicalDevice}; } +std::shared_ptr<VulkanLogicalDevice> 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<VulkanLogicalDevice>{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; |
