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);
190 "No surface provided for presentation support check");
196 for (uint32_t i = 0; i < queue_families.size(); i++) {
197 if (queue_families[i].queueCount > 0) {
199 if (presentSupport) {
204 "Graphics queue family {} supports presentation", i);
211 for (uint32_t i = 0; i < queue_families.size(); i++) {
212 if (queue_families[i].queueCount > 0) {
214 if (presentSupport) {
218 "Found presentation support in queue family {}", i);
225 "No queue family with presentation support found!");
231 std::vector<vk::ExtensionProperties> availableExtensions =
m_physical_device.enumerateDeviceExtensionProperties();
234 for (
const auto& extension : availableExtensions) {
235 std::cout <<
"\t- " << extension.extensionName <<
" (Version: " << extension.specVersion <<
")\n";
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 vk::PhysicalDeviceFeatures2 features2 {};
278 features2.features = device_features;
280 vk::PhysicalDeviceVulkan13Features vulkan_13_features {};
281 vulkan_13_features.dynamicRendering = VK_TRUE;
282 vulkan_13_features.synchronization2 = VK_TRUE;
284 std::vector<const char*> device_extensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
286#ifdef MAYAFLUX_PLATFORM_MACOS
288 bool has_portability = std::ranges::any_of(available_exts,
289 [](
const auto& ext) {
290 return strcmp(ext.extensionName,
"VK_KHR_portability_subset") == 0;
293 if (has_portability) {
294 device_extensions.push_back(
"VK_KHR_portability_subset");
297 vk::PhysicalDeviceMeshShaderFeaturesEXT mesh_shader_features {};
299 device_extensions.push_back(VK_EXT_MESH_SHADER_EXTENSION_NAME);
301 mesh_shader_features.taskShader = VK_TRUE;
302 mesh_shader_features.meshShader = VK_TRUE;
304 vulkan_13_features.pNext = &mesh_shader_features;
308 features2.pNext = &vulkan_13_features;
311 device_extensions.push_back(ext.c_str());
314 vk::DeviceCreateInfo create_info {};
315 create_info.queueCreateInfoCount =
static_cast<uint32_t
>(queue_create_infos.size());
316 create_info.pQueueCreateInfos = queue_create_infos.data();
317 create_info.pNext = &features2;
318 create_info.enabledExtensionCount =
static_cast<uint32_t
>(device_extensions.size());
319 create_info.ppEnabledExtensionNames = device_extensions.data();
325 }
catch (
const std::exception& e) {
327 std::source_location::current(),
328 "Failed to create logical device: {}", e.what());
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_PRINT(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
void query_supported_extensions()
Query and log supported device extensions.
bool pick_physical_device(vk::Instance instance, vk::SurfaceKHR temp_surface)
Pick a suitable physical device (GPU)
void cleanup()
Cleanup device resources.
bool m_supports_mesh_shaders
Whether the device supports mesh shaders.
VKDevice & operator=(const VKDevice &)=delete
vk::PhysicalDevice m_physical_device
Selected physical device (GPU)
vk::Queue m_compute_queue
Compute queue handle.
bool create_logical_device(vk::Instance instance, const GraphicsBackendInfo &backend_info)
Create the logical device and retrieve queue handles.
vk::Queue m_transfer_queue
Transfer queue handle.
vk::Device m_logical_device
Logical device handle.
QueueFamilyIndices find_queue_families(vk::PhysicalDevice device, vk::SurfaceKHR surface=nullptr)
Find queue families on the given physical device.
bool update_presentation_queue(vk::SurfaceKHR surface)
Update presentation queue family for a specific surface.
bool m_presentation_initialized
Whether presentation support has been initialized.
vk::Queue m_graphics_queue
Graphics queue handle.
bool initialize(vk::Instance instance, vk::SurfaceKHR temp_surface, const GraphicsBackendInfo &backend_info)
Initialize device (pick physical device and create logical device)
QueueFamilyIndices m_queue_families
Indices of required queue families.
Manages Vulkan physical device selection and logical device creation.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.
bool enable_compute_queue
Enable compute queue (separate from graphics)
std::vector< std::string > required_extensions
Backend-specific extensions to request.
bool enable_transfer_queue
Enable transfer queue (separate from graphics)
struct MayaFlux::Core::GraphicsBackendInfo::@0 required_features
Required device features (Vulkan-specific)
bool tessellation_shaders
Configuration for graphics API backend (Vulkan/OpenGL/etc.)
std::optional< uint32_t > transfer_family
std::optional< uint32_t > graphics_family
std::optional< uint32_t > present_family
std::optional< uint32_t > compute_family
Stores indices of queue families we need.