Create the logical device and retrieve queue handles.
241{
244 std::source_location::current(),
245 "No graphics queue family found!");
246 }
247
248 std::set<uint32_t> unique_queue_families;
250
253 }
254
257 }
258
259 std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
260 float queue_priority = 1.0F;
261
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);
268 }
269
270 vk::PhysicalDeviceFeatures device_features {};
271 device_features.samplerAnisotropy = backend_info.required_features.sampler_anisotropy;
272 device_features.geometryShader = backend_info.required_features.geometry_shaders;
273 device_features.tessellationShader = backend_info.required_features.tessellation_shaders;
274 device_features.multiViewport = backend_info.required_features.multi_viewport;
275 device_features.fillModeNonSolid = backend_info.required_features.fill_mode_non_solid;
276
277 std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
278
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;
283 })) {
284 device_extensions.push_back("VK_KHR_portability_subset");
285 }
286
287 auto feature_chain = vk::StructureChain {
288 vk::PhysicalDeviceFeatures2 {},
289 vk::PhysicalDeviceVulkan13Features {},
290 vk::PhysicalDeviceVulkan12Features {}
291 };
292
293#else
295 device_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME);
296 }
297
298 auto feature_chain = vk::StructureChain {
299 vk::PhysicalDeviceFeatures2 {},
300 vk::PhysicalDeviceVulkan13Features {},
301 vk::PhysicalDeviceVulkan12Features {},
302 vk::PhysicalDeviceMeshShaderFeaturesEXT {}
303 };
304
306 feature_chain.unlink<vk::PhysicalDeviceMeshShaderFeaturesEXT>();
307 } else {
308 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().taskShader = VK_TRUE;
309 feature_chain.get<vk::PhysicalDeviceMeshShaderFeaturesEXT>().meshShader = VK_TRUE;
310 }
311#endif
312
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;
317
318 for (const auto& ext : backend_info.required_extensions) {
319 device_extensions.push_back(ext.c_str());
320 }
321
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();
328
329 try {
332
333 } catch (const std::exception& e) {
335 std::source_location::current(),
336 "Failed to create logical device: {}", e.what());
337 }
338
340
343 } else {
345 }
346
349 } else {
351 }
352
353 return true;
354}
bool m_supports_mesh_shaders
Whether the device supports mesh shaders.
vk::PhysicalDevice m_physical_device
Selected physical device (GPU)
vk::Queue m_compute_queue
Compute queue handle.
vk::Queue m_transfer_queue
Transfer queue handle.
vk::Device m_logical_device
Logical device handle.
vk::Queue m_graphics_queue
Graphics queue handle.
QueueFamilyIndices m_queue_families
Indices of required queue families.
@ 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.
std::optional< uint32_t > transfer_family
std::optional< uint32_t > graphics_family
std::optional< uint32_t > compute_family