git.s-ol.nu forks/DiligentCore / 7b13811
External Vulkan Device support s-ol authored 2 years ago s-ol committed 2 years ago
8 changed file(s) with 151 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
5353 CommandQueueVkImpl(IReferenceCounters* pRefCounters,
5454 std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
5555 uint32_t QueueFamilyIndex);
56 CommandQueueVkImpl(IReferenceCounters* pRefCounters,
57 std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
58 const VkQueue& Queue,
59 uint32_t QueueFamilyIndex);
5660 ~CommandQueueVkImpl();
5761
5862 IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_CommandQueueVk, TBase)
4848 uint32_t GlobalExtensionCount,
4949 const char* const* ppGlobalExtensionNames,
5050 VkAllocationCallbacks* pVkAllocator);
51
52 static std::shared_ptr<VulkanInstance> Create(const VkInstance& vkInstance,
53 VkAllocationCallbacks* pVkAllocator);
5154 ~VulkanInstance();
5255
5356 std::shared_ptr<VulkanInstance> GetSharedPtr()
7881 uint32_t GlobalExtensionCount,
7982 const char* const* ppGlobalExtensionNames,
8083 VkAllocationCallbacks* pVkAllocator);
84 VulkanInstance(const VkInstance& vkInstance,
85 VkAllocationCallbacks* pVkAllocator);
8186
82 bool m_DebugUtilsEnabled = false;
87 bool m_DebugUtilsEnabled = false;
88 bool m_InitializedExternally = false;
8389 VkAllocationCallbacks* const m_pVkAllocator;
8490 VkInstance m_VkInstance = VK_NULL_HANDLE;
8591 uint32_t m_VkVersion = VK_API_VERSION_1_0;
9494 const ExtensionFeatures& EnabledExtFeatures,
9595 const VkAllocationCallbacks* vkAllocator);
9696
97 static std::shared_ptr<VulkanLogicalDevice> Create(const VulkanPhysicalDevice& PhysicalDevice,
98 const VkDevice& Device,
99 VkPipelineStageFlags EnabledShaderStages,
100 const VkAllocationCallbacks* vkAllocator);
101
97102 // clang-format off
98103 VulkanLogicalDevice (const VulkanLogicalDevice&) = delete;
99104 VulkanLogicalDevice (VulkanLogicalDevice&&) = delete;
230235 const VkDeviceCreateInfo& DeviceCI,
231236 const ExtensionFeatures& EnabledExtFeatures,
232237 const VkAllocationCallbacks* vkAllocator);
238 VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice,
239 const VkDevice& Device,
240 VkPipelineStageFlags EnabledShaderStages,
241 const VkAllocationCallbacks* vkAllocator);
233242
234243 template <typename VkObjectType,
235244 VulkanHandleTypeId VkTypeId,
7979 IRenderDevice** ppDevice,
8080 IDeviceContext** ppContexts) PURE;
8181
82 VIRTUAL void METHOD(AttachToVulkanDevice)(THIS_
83 const VkInstance REF Instance,
84 const VkPhysicalDevice REF PhysicalDevice,
85 const VkDevice REF LogicalDevice,
86 const VkQueue REF Queue,
87 uint32_t QueueFamilyIndex,
88 const EngineVkCreateInfo REF EngineCI,
89 IRenderDevice** ppDevice,
90 IDeviceContext** ppContexts) PURE;
8291
8392 /// Creates a swap chain for Vulkan-based engine implementation
8493
106115 // clang-format off
107116
108117 # define IEngineFactoryVk_CreateDeviceAndContextsVk(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, CreateDeviceAndContextsVk, This, __VA_ARGS__)
118 # define IEngineFactoryVk_AttachToVulkanDevice(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, AttachToVulkanDevice, This, __VA_ARGS__)
109119 # define IEngineFactoryVk_CreateSwapChainVk(This, ...) CALL_IFACE_METHOD(EngineFactoryVk, CreateSwapChainVk, This, __VA_ARGS__)
110120
111121 // clang-format on
4242 TBase{pRefCounters},
4343 m_LogicalDevice {LogicalDevice},
4444 m_VkQueue {LogicalDevice->GetQueue(QueueFamilyIndex, 0)},
45 m_QueueFamilyIndex {QueueFamilyIndex},
46 m_NextFenceValue {1}
47 // clang-format on
48 {
49 }
50
51 CommandQueueVkImpl::CommandQueueVkImpl(IReferenceCounters* pRefCounters,
52 std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
53 const VkQueue& Queue,
54 uint32_t QueueFamilyIndex) :
55 // clang-format off
56 TBase{pRefCounters},
57 m_LogicalDevice {LogicalDevice},
58 m_VkQueue {Queue},
4559 m_QueueFamilyIndex {QueueFamilyIndex},
4660 m_NextFenceValue {1}
4761 // clang-format on
6565 IRenderDevice** ppDevice,
6666 IDeviceContext** ppContexts) override final;
6767
68 virtual void DILIGENT_CALL_TYPE AttachToVulkanDevice(const VkInstance& Instance,
69 const VkPhysicalDevice& PhysicalDevice,
70 const VkDevice& LogicalDevice,
71 const VkQueue& Queue,
72 uint32_t QueueFamilyIndex,
73 const EngineVkCreateInfo& EngineCI,
74 IRenderDevice** ppDevice,
75 IDeviceContext** ppContexts) override final;
76
6877 virtual void DILIGENT_CALL_TYPE AttachToVulkanDevice(std::shared_ptr<VulkanUtilities::VulkanInstance> Instance,
6978 std::unique_ptr<VulkanUtilities::VulkanPhysicalDevice> PhysicalDevice,
7079 std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> LogicalDevice,
531540 }
532541 }
533542
543 void EngineFactoryVkImpl::AttachToVulkanDevice(const VkInstance& Instance,
544 const VkPhysicalDevice& PhysicalDevice,
545 const VkDevice& LogicalDevice,
546 const VkQueue& Queue,
547 uint32_t QueueFamilyIndex,
548 const EngineVkCreateInfo& EngineCI,
549 IRenderDevice** ppDevice,
550 IDeviceContext** ppContexts)
551 {
552 auto& RawMemAllocator = GetRawAllocator();
553
554 auto VulkanInstance = VulkanUtilities::VulkanInstance::Create(Instance, nullptr);
555 auto VulkanPhysicalDevice = VulkanUtilities::VulkanPhysicalDevice::Create(PhysicalDevice, *VulkanInstance);
556
557 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;
558 auto VulkanLogicalDevice = VulkanUtilities::VulkanLogicalDevice::Create(*VulkanPhysicalDevice, LogicalDevice, PipelineStages, nullptr);
559 RefCntAutoPtr<CommandQueueVkImpl> pCmdQueueVk{
560 NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(VulkanLogicalDevice, Queue, QueueFamilyIndex)};
561 std::array<ICommandQueueVk*, 1> CommandQueues = {{pCmdQueueVk}};
562
563 OnRenderDeviceCreated = [&](RenderDeviceVkImpl* pRenderDeviceVk)
564 {
565 FenceDesc Desc;
566 Desc.Name = "Command queue internal fence";
567 constexpr bool IsDeviceInternal = false;
568
569 RefCntAutoPtr<FenceVkImpl> pFenceVk{
570 NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal)};
571 pCmdQueueVk->SetFence(std::move(pFenceVk));
572 };
573
574 AttachToVulkanDevice(
575 VulkanInstance,
576 std::move(VulkanPhysicalDevice),
577 VulkanLogicalDevice,
578 CommandQueues.size(), CommandQueues.data(),
579 EngineCI,
580 ppDevice,
581 ppContexts
582 );
583 }
584
534585 /// Attaches to existing Vulkan device
535586
536587 /// \param [in] Instance - shared pointer to a VulkanUtilities::VulkanInstance object
8888 return std::shared_ptr<VulkanInstance>{Instance};
8989 }
9090
91 std::shared_ptr<VulkanInstance> VulkanInstance::Create(const VkInstance& vkInstance,
92 VkAllocationCallbacks* pVkAllocator)
93 {
94 auto Instance = new VulkanInstance{vkInstance, pVkAllocator};
95 return std::shared_ptr<VulkanInstance>{Instance};
96 }
97
9198 VulkanInstance::VulkanInstance(uint32_t ApiVersion,
9299 bool EnableValidation,
93100 uint32_t GlobalExtensionCount,
290297 #endif
291298 }
292299
300 VulkanInstance::VulkanInstance(const VkInstance& vkInstance,
301 VkAllocationCallbacks* pVkAllocator) :
302 m_pVkAllocator{pVkAllocator},
303 m_VkInstance{vkInstance},
304 m_InitializedExternally{true}
305 {
306 #if DILIGENT_USE_VOLK
307 if (volkInitialize() != VK_SUCCESS)
308 {
309 LOG_ERROR_AND_THROW("Failed to load Vulkan.");
310 }
311 volkLoadInstance(m_VkInstance);
312 #endif
313 #if !DILIGENT_NO_GLSLANG
314 Diligent::GLSLangUtils::InitializeGlslang();
315 #endif
316 }
317
293318 VulkanInstance::~VulkanInstance()
294319 {
295320 if (m_DebugUtilsEnabled)
296321 {
297322 VulkanUtilities::FreeDebugging(m_VkInstance);
298323 }
299 vkDestroyInstance(m_VkInstance, m_pVkAllocator);
324 if (!m_InitializedExternally)
325 {
326 vkDestroyInstance(m_VkInstance, m_pVkAllocator);
327 }
300328
301329 #if !DILIGENT_NO_GLSLANG
302330 Diligent::GLSLangUtils::FinalizeGlslang();
4242 return std::shared_ptr<VulkanLogicalDevice>{LogicalDevice};
4343 }
4444
45 std::shared_ptr<VulkanLogicalDevice> VulkanLogicalDevice::Create(const VulkanPhysicalDevice& PhysicalDevice,
46 const VkDevice& Device,
47 VkPipelineStageFlags EnabledShaderStages,
48 const VkAllocationCallbacks* vkAllocator)
49 {
50 auto* LogicalDevice = new VulkanLogicalDevice{PhysicalDevice, Device, EnabledShaderStages, vkAllocator};
51 return std::shared_ptr<VulkanLogicalDevice>{LogicalDevice};
52 }
53
4554 VulkanLogicalDevice::~VulkanLogicalDevice()
4655 {
4756 vkDestroyDevice(m_VkDevice, m_VkAllocator);
7584 m_EnabledShaderStages |= VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
7685 }
7786
87 VulkanLogicalDevice::VulkanLogicalDevice(const VulkanPhysicalDevice& PhysicalDevice,
88 const VkDevice& Device,
89 VkPipelineStageFlags EnabledShaderStages,
90 const VkAllocationCallbacks* vkAllocator) :
91 m_VkDevice{Device},
92 m_VkAllocator{vkAllocator},
93 m_EnabledShaderStages{EnabledShaderStages},
94 m_EnabledFeatures{},
95 m_EnabledExtFeatures{}
96 {
97 #if DILIGENT_USE_VOLK
98 // Since we only use one device at this time, load device function entries
99 // https://github.com/zeux/volk#optimizing-device-calls
100 volkLoadDevice(m_VkDevice);
101 #endif
102 }
103
104
78105 VkQueue VulkanLogicalDevice::GetQueue(uint32_t queueFamilyIndex, uint32_t queueIndex)
79106 {
80107 VkQueue vkQueue = VK_NULL_HANDLE;