15 : m_physical_device(other.m_physical_device)
16 , m_logical_device(other.m_logical_device)
17 , m_graphics_queue(other.m_graphics_queue)
18 , m_compute_queue(other.m_compute_queue)
19 , m_transfer_queue(other.m_transfer_queue)
20 , m_queue_families(other.m_queue_families)
22 other.m_physical_device = VK_NULL_HANDLE;
23 other.m_logical_device = VK_NULL_HANDLE;
24 other.m_graphics_queue = VK_NULL_HANDLE;
25 other.m_compute_queue = VK_NULL_HANDLE;
26 other.m_transfer_queue = VK_NULL_HANDLE;
33 m_physical_device = other.m_physical_device;
34 m_logical_device = other.m_logical_device;
35 m_graphics_queue = other.m_graphics_queue;
36 m_compute_queue = other.m_compute_queue;
37 m_transfer_queue = other.m_transfer_queue;
38 m_queue_families = other.m_queue_families;
40 other.m_physical_device = VK_NULL_HANDLE;
41 other.m_logical_device = VK_NULL_HANDLE;
42 other.m_graphics_queue = VK_NULL_HANDLE;
43 other.m_compute_queue = VK_NULL_HANDLE;
44 other.m_transfer_queue = VK_NULL_HANDLE;
74 vk::Instance vk_instance(instance);
75 auto devices = vk_instance.enumeratePhysicalDevices();
77 if (devices.empty()) {
79 std::source_location::current(),
80 "Failed to find GPUs with Vulkan support!");
83 for (
const auto& device : devices) {
87 auto available_extensions = device.enumerateDeviceExtensionProperties();
88 bool supports_swapchain =
false;
89 bool supports_mesh_shader =
false;
91 for (
const auto& ext : available_extensions) {
92 if (strcmp(ext.extensionName, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
93 supports_swapchain =
true;
95 if (strcmp(ext.extensionName, VK_EXT_MESH_SHADER_EXTENSION_NAME) == 0) {
96 supports_mesh_shader =
true;
100 if (!supports_swapchain) {
102 "Physical device {} does not support VK_KHR_swapchain - skipping",
103 device.getProperties().deviceName.data());
107 if (!supports_mesh_shader) {
109 "Physical device {} does not support VK_EXT_mesh_shader - "
110 "mesh shading features will be unavailable",
111 device.getProperties().deviceName.data());
113 vk::PhysicalDeviceMeshShaderFeaturesEXT mesh_features;
114 vk::PhysicalDeviceFeatures2 temp_features;
115 temp_features.pNext = &mesh_features;
116 device.getFeatures2(&temp_features);
118 if (mesh_features.meshShader == VK_FALSE || mesh_features.taskShader == VK_FALSE) {
120 "Physical device {} supports VK_EXT_mesh_shader extension but features disabled",
121 device.getProperties().deviceName.data());
122 supports_mesh_shader =
false;
130 vk::PhysicalDeviceProperties props = device.getProperties();
132 "Selected GPU: {}", props.deviceName.data());
138 std::source_location::current(),
139 "Failed to find a suitable GPU!");
146 auto queue_families = device.getQueueFamilyProperties();
149 for (
const auto& queue_family : queue_families) {
150 if (queue_family.queueCount > 0 && queue_family.queueFlags & vk::QueueFlagBits::eGraphics) {
154 if (queue_family.queueCount > 0 && queue_family.queueFlags & vk::QueueFlagBits::eCompute && !(queue_family.queueFlags & vk::QueueFlagBits::eGraphics)) {
158 if (queue_family.queueCount > 0 && queue_family.queueFlags & vk::QueueFlagBits::eTransfer && !(queue_family.queueFlags & vk::QueueFlagBits::eGraphics) && !(queue_family.queueFlags & vk::QueueFlagBits::eCompute)) {
162 if (surface && queue_family.queueCount > 0) {
163 vk::Bool32 presentSupport = device.getSurfaceSupportKHR(i, surface);
164 if (presentSupport) {
167 "Found presentation support in queue family {}", i);
244 std::source_location::current(),
245 "No graphics queue family found!");
248 std::set<uint32_t> unique_queue_families;
259 std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
260 float queue_priority = 1.0F;
262 for (uint32_t queue_family : unique_queue_families) {
263 vk::DeviceQueueCreateInfo queue_create_info {};
264 queue_create_info.queueFamilyIndex = queue_family;
265 queue_create_info.queueCount = 1;
266 queue_create_info.pQueuePriorities = &queue_priority;
267 queue_create_infos.push_back(queue_create_info);
270 vk::PhysicalDeviceFeatures device_features {};
277 std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
279#ifdef MAYAFLUX_PLATFORM_MACOS
281 if (std::ranges::any_of(available_exts, [](
const auto& ext) {
282 return strcmp(ext.extensionName,
"VK_KHR_portability_subset") == 0;
284 device_extensions.push_back(
"VK_KHR_portability_subset");
287 auto feature_chain = vk::StructureChain {
288 vk::PhysicalDeviceFeatures2 {},
289 vk::PhysicalDeviceVulkan13Features {},
290 vk::PhysicalDeviceVulkan12Features {}
295 device_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME);
298 auto feature_chain = vk::StructureChain {
299 vk::PhysicalDeviceFeatures2 {},
300 vk::PhysicalDeviceVulkan13Features {},
301 vk::PhysicalDeviceVulkan12Features {},
302 vk::PhysicalDeviceMeshShaderFeaturesEXT {}
306 feature_chain.unlink<vk::PhysicalDeviceMeshShaderFeaturesEXT>();
308 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().taskShader = VK_TRUE;
309 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().meshShader = VK_TRUE;
313 feature_chain.get<vk::PhysicalDeviceFeatures2>().features = device_features;
314 feature_chain.get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering = VK_TRUE;
315 feature_chain.get<vk::PhysicalDeviceVulkan13Features>().synchronization2 = VK_TRUE;
316 feature_chain.get<vk::PhysicalDeviceVulkan12Features>().bufferDeviceAddress = VK_TRUE;
319 device_extensions.push_back(ext.c_str());
322 vk::DeviceCreateInfo create_info {};
323 create_info.queueCreateInfoCount =
static_cast<uint32_t
>(queue_create_infos.size());
324 create_info.pQueueCreateInfos = queue_create_infos.data();
325 create_info.pNext = &feature_chain.get<vk::PhysicalDeviceFeatures2>();
326 create_info.enabledExtensionCount =
static_cast<uint32_t
>(device_extensions.size());
327 create_info.ppEnabledExtensionNames = device_extensions.data();
333 }
catch (
const std::exception& e) {
335 std::source_location::current(),
336 "Failed to create logical device: {}", e.what());