MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ create_logical_device()

bool MayaFlux::Core::VKDevice::create_logical_device ( vk::Instance  instance,
const GraphicsBackendInfo &  backend_info 
)
private

Create the logical device and retrieve queue handles.

Parameters
instanceVulkan instance
backend_infoGraphics backend configuration
Returns
true if logical device creation succeeded

Definition at line 605 of file VKDevice.cpp.

606{
607 if (!m_queue_families.graphics_family.has_value()) {
609 std::source_location::current(),
610 "No graphics queue family found!");
611 }
612
613 std::set<uint32_t> unique_queue_families;
614 unique_queue_families.insert(m_queue_families.graphics_family.value());
615
616 if (m_queue_families.compute_family.has_value()) {
617 unique_queue_families.insert(m_queue_families.compute_family.value());
618 }
619
621 unique_queue_families.insert(m_queue_families.transfer_family.value());
622 }
623
624 for (uint32_t f = 0; f < QueueFamilyIndices::MAX_TRACKED_FAMILIES; ++f) {
626 unique_queue_families.insert(f);
627 }
628
629 std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
630 float queue_priority = 1.0F;
631
632 for (uint32_t queue_family : unique_queue_families) {
633 vk::DeviceQueueCreateInfo queue_create_info {};
634 queue_create_info.queueFamilyIndex = queue_family;
635 queue_create_info.queueCount = 1;
636 queue_create_info.pQueuePriorities = &queue_priority;
637 queue_create_infos.push_back(queue_create_info);
638 }
639
640 vk::PhysicalDeviceFeatures device_features {};
641 device_features.samplerAnisotropy = backend_info.required_features.sampler_anisotropy;
642 device_features.geometryShader = backend_info.required_features.geometry_shaders;
643 device_features.tessellationShader = backend_info.required_features.tessellation_shaders;
644 device_features.multiViewport = backend_info.required_features.multi_viewport;
645 device_features.fillModeNonSolid = m_physical_device.getFeatures().fillModeNonSolid;
646 device_features.shaderSampledImageArrayDynamicIndexing = m_physical_device.getFeatures().shaderSampledImageArrayDynamicIndexing;
647
648 std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
649
650 auto supported_extensions = m_physical_device.enumerateDeviceExtensionProperties();
651
652 auto is_supported = [&supported_extensions](std::string_view name) {
653 return std::ranges::any_of(supported_extensions, [name](const auto& ext) {
654 return name == ext.extensionName.data();
655 });
656 };
657
658#ifdef MAYAFLUX_PLATFORM_MACOS
659 if (is_supported("VK_KHR_portability_subset")) {
660 device_extensions.push_back("VK_KHR_portability_subset");
661 }
662
663 auto feature_chain = vk::StructureChain {
664 vk::PhysicalDeviceFeatures2 {},
665 vk::PhysicalDeviceVulkan13Features {},
666 vk::PhysicalDeviceVulkan12Features {}
667 };
668
669#else
671 device_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME);
672 }
673
674 auto feature_chain = vk::StructureChain {
675 vk::PhysicalDeviceFeatures2 {},
676 vk::PhysicalDeviceVulkan13Features {},
677 vk::PhysicalDeviceVulkan12Features {},
678 vk::PhysicalDeviceMeshShaderFeaturesEXT {}
679 };
680
682 feature_chain.unlink<vk::PhysicalDeviceMeshShaderFeaturesEXT>();
683 } else {
684 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().taskShader = VK_TRUE;
685 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().meshShader = VK_TRUE;
686 }
687#endif
688
689 feature_chain.get<vk::PhysicalDeviceFeatures2>().features = device_features;
690 feature_chain.get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering = VK_TRUE;
691 feature_chain.get<vk::PhysicalDeviceVulkan13Features>().synchronization2 = VK_TRUE;
692 feature_chain.get<vk::PhysicalDeviceVulkan12Features>().bufferDeviceAddress = VK_TRUE;
693
694 std::vector<std::string> missing_required;
695
696 for (const auto& ext : backend_info.required_extensions) {
697 if (is_supported(ext)) {
698 device_extensions.push_back(ext.c_str());
699 } else {
700 missing_required.push_back(ext);
701 }
702 }
703
704 if (!missing_required.empty()) {
705 std::string names;
706 for (const auto& ext : missing_required) {
707 if (!names.empty())
708 names += ", ";
709 names += ext;
710 }
711
713 std::source_location::current(),
714 "Device '{}' does not support required extension(s): {}",
715 m_device_name, names);
716 }
717
718 for (const auto& ext : backend_info.optional_extensions) {
719 if (is_supported(ext)) {
720 device_extensions.push_back(ext.c_str());
721 } else {
723 "Device '{}' does not support optional extension '{}'; skipping",
724 m_device_name, ext);
725 }
726 }
727
728 vk::DeviceCreateInfo create_info {};
729 create_info.queueCreateInfoCount = static_cast<uint32_t>(queue_create_infos.size());
730 create_info.pQueueCreateInfos = queue_create_infos.data();
731 create_info.pNext = &feature_chain.get<vk::PhysicalDeviceFeatures2>();
732 create_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
733 create_info.ppEnabledExtensionNames = device_extensions.data();
734
735 try {
736 m_logical_device = m_physical_device.createDevice(create_info);
737 VULKAN_HPP_DEFAULT_DISPATCHER.init(m_logical_device);
738
739 } catch (const std::exception& e) {
741 std::source_location::current(),
742 "Failed to create logical device: {}", e.what());
743 }
744
746
747 if (backend_info.enable_compute_queue && m_queue_families.compute_family.has_value()) {
749 } else {
751 }
752
753 if (backend_info.enable_transfer_queue && m_queue_families.transfer_family.has_value()) {
755 } else {
757 }
758
759 for (uint32_t f = 0; f < QueueFamilyIndices::MAX_TRACKED_FAMILIES; ++f) {
761 m_present_queues[f] = m_logical_device.getQueue(f, 0);
762 }
763
764 return true;
765}
#define MF_WARN(comp, ctx,...)
std::string name
Definition VKDevice.cpp:123
bool m_supports_mesh_shaders
Whether the device supports mesh shaders.
Definition VKDevice.hpp:209
vk::PhysicalDevice m_physical_device
Selected physical device (GPU)
Definition VKDevice.hpp:172
vk::Queue m_compute_queue
Compute queue handle.
Definition VKDevice.hpp:176
vk::Queue m_transfer_queue
Transfer queue handle.
Definition VKDevice.hpp:177
vk::Device m_logical_device
Logical device handle.
Definition VKDevice.hpp:173
std::unordered_map< uint32_t, vk::Queue > m_present_queues
One queue per presentation-capable family.
Definition VKDevice.hpp:206
std::string m_device_name
Selected device name, cached for logging.
Definition VKDevice.hpp:207
vk::Queue m_graphics_queue
Graphics queue handle.
Definition VKDevice.hpp:175
QueueFamilyIndices m_queue_families
Indices of required queue families.
Definition VKDevice.hpp:179
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
void error_rethrow(Component component, Context context, std::source_location location=std::source_location::current(), std::string_view additional_context="")
Catch and log an exception, then rethrow it.
@ Core
Core engine, backend, subsystems.
static constexpr uint32_t MAX_TRACKED_FAMILIES
Width of present_family_mask.
Definition VKDevice.hpp:18
bool can_present(uint32_t index) const
Whether family index can present.
Definition VKDevice.hpp:33
std::optional< uint32_t > transfer_family
Definition VKDevice.hpp:22
std::optional< uint32_t > graphics_family
Definition VKDevice.hpp:20
std::optional< uint32_t > compute_family
Definition VKDevice.hpp:21

References MayaFlux::Core::QueueFamilyIndices::can_present(), MayaFlux::Core::QueueFamilyIndices::compute_family, MayaFlux::Journal::Core, MayaFlux::Core::GraphicsBackendInfo::enable_compute_queue, MayaFlux::Core::GraphicsBackendInfo::enable_transfer_queue, MayaFlux::Core::GraphicsBackendInfo::geometry_shaders, MayaFlux::Core::QueueFamilyIndices::graphics_family, MayaFlux::Journal::GraphicsBackend, m_compute_queue, m_device_name, m_graphics_queue, m_logical_device, m_physical_device, m_present_queues, m_queue_families, m_supports_mesh_shaders, m_transfer_queue, MayaFlux::Core::QueueFamilyIndices::MAX_TRACKED_FAMILIES, MF_WARN, MayaFlux::Core::GraphicsBackendInfo::multi_viewport, name, MayaFlux::Core::GraphicsBackendInfo::optional_extensions, MayaFlux::Core::GraphicsBackendInfo::required_extensions, MayaFlux::Core::GraphicsBackendInfo::required_features, MayaFlux::Core::GraphicsBackendInfo::sampler_anisotropy, MayaFlux::Core::GraphicsBackendInfo::tessellation_shaders, and MayaFlux::Core::QueueFamilyIndices::transfer_family.

Referenced by initialize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: