Create the logical device and retrieve queue handles.
201{
204 std::source_location::current(),
205 "No graphics queue family found!");
206 }
207
208 std::set<uint32_t> unique_queue_families;
210
213 }
214
217 }
218
219 std::vector<vk::DeviceQueueCreateInfo> queue_create_infos;
220 float queue_priority = 1.0F;
221
222 for (uint32_t queue_family : unique_queue_families) {
223 vk::DeviceQueueCreateInfo queue_create_info {};
224 queue_create_info.queueFamilyIndex = queue_family;
225 queue_create_info.queueCount = 1;
226 queue_create_info.pQueuePriorities = &queue_priority;
227 queue_create_infos.push_back(queue_create_info);
228 }
229
230 vk::PhysicalDeviceFeatures device_features {};
231 device_features.samplerAnisotropy = backend_info.required_features.sampler_anisotropy;
232 device_features.geometryShader = backend_info.required_features.geometry_shaders;
233 device_features.tessellationShader = backend_info.required_features.tessellation_shaders;
234 device_features.multiViewport = backend_info.required_features.multi_viewport;
235 device_features.fillModeNonSolid = backend_info.required_features.fill_mode_non_solid;
236
237 vk::PhysicalDeviceFeatures2 features2 {};
238 features2.features = device_features;
239
240 vk::PhysicalDeviceVulkan13Features vulkan_13_features {};
241 vulkan_13_features.dynamicRendering = VK_TRUE;
242 vulkan_13_features.synchronization2 = VK_TRUE;
243
244 features2.pNext = &vulkan_13_features;
245
246 std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
247
248#ifdef MAYAFLUX_PLATFORM_MACOS
250 bool has_portability = std::ranges::any_of(available_exts,
251 [](const auto& ext) {
252 return strcmp(ext.extensionName, "VK_KHR_portability_subset") == 0;
253 });
254
255 if (has_portability) {
256 device_extensions.push_back("VK_KHR_portability_subset");
257 }
258#endif
259
260 for (const auto& ext : backend_info.required_extensions) {
261 device_extensions.push_back(ext.c_str());
262 }
263
264 vk::DeviceCreateInfo create_info {};
265 create_info.queueCreateInfoCount = static_cast<uint32_t>(queue_create_infos.size());
266 create_info.pQueueCreateInfos = queue_create_infos.data();
267 create_info.pNext = &features2;
268 create_info.enabledExtensionCount = static_cast<uint32_t>(device_extensions.size());
269 create_info.ppEnabledExtensionNames = device_extensions.data();
270
271
272 try {
274 } catch (const std::exception& e) {
276 std::source_location::current(),
277 "Failed to create logical device: {}", e.what());
278 }
279
281
284 } else {
286 }
287
290 } else {
292 }
293
294 return true;
295}
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