From 89ae6838075f3579a85d7824d49a051b90c8ed92 Mon Sep 17 00:00:00 2001
From: Steven Le Rouzic <steven.lerouzic@gmail.com>
Date: Tue, 30 Apr 2024 22:20:36 +0200
Subject: Vulkan device & queue creation

---
 main/main.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 3 deletions(-)

(limited to 'main')

diff --git a/main/main.cpp b/main/main.cpp
index 34d0276..e740c36 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -25,8 +25,8 @@ StatusOr<VkInstance> CreateInstance(VulkanApi* vk)
     };
 
     const char* extensions[]{
-        "VK_KHR_surface",
-        "VK_KHR_win32_surface",
+        VK_KHR_SURFACE_EXTENSION_NAME,
+        VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
     };
 
     // @Todo Select layers & extensions based on config
@@ -104,6 +104,46 @@ StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice device)
     return InternalError("Couldn't find a suitable queue");
 }
 
+StatusOr<VkDevice> CreateDevice(VulkanApi* vk, VkPhysicalDevice gpu, uint32_t queue_family)
+{
+    const float queue_priority = 1.0F;
+    
+    VkDeviceQueueCreateInfo queue_create_info{
+        .sType                    = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
+        .pNext                    = nullptr,
+        .flags                    = 0,
+        .queueFamilyIndex         = queue_family,
+        .queueCount               = 1,
+        .pQueuePriorities         = &queue_priority,
+    };
+    
+    const char* extensions[]{
+        VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+    };
+    
+    VkDeviceCreateInfo create_info{
+        .sType                    = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+        .pNext                    = nullptr,
+        .flags                    = 0,
+        .queueCreateInfoCount     = 1,
+        .pQueueCreateInfos        = &queue_create_info,
+        .enabledLayerCount        = 0,
+        .ppEnabledLayerNames      = nullptr,
+        .enabledExtensionCount    = ArraySize(extensions),
+        .ppEnabledExtensionNames  = extensions,
+        .pEnabledFeatures         = nullptr,
+    };
+
+    VkDevice device = VK_NULL_HANDLE;
+    VkResult res = vk->CreateDevice(gpu, &create_info, kVkAlloc, &device);
+    if (res != VK_SUCCESS)
+    {
+        return InternalError("vkCreateDeviceFailed");
+    }
+
+    return device;
+}
+
 Status InitializeVulkan(ApiRegistry* api_registry)
 {
     RegisterVulkanLoaderApi(api_registry);
@@ -147,11 +187,26 @@ Status InitializeVulkan(ApiRegistry* api_registry)
         StatusOr<uint32_t> s = FindQueueFamily(vk, physical_device);
         if (!s.ok()) { return s.status(); }
         queue_family = s.value();
+        log_api->LogInfo("Vulkan queue family: $", queue_family);
+    }
+
+    VkDevice device = VK_NULL_HANDLE;
+    {
+        StatusOr<VkDevice> s = CreateDevice(vk, physical_device, queue_family);
+        if (!s.ok()) { return s.status(); }
+        device = s.value();
+        log_api->LogInfo("Vulkan device created");
     }
 
-    log_api->LogInfo("Vulkan queue family: $", queue_family);
+    loader_api->LoadDevice(vk, device);
 
+    VkQueue queue = VK_NULL_HANDLE;
+    vk->GetDeviceQueue(device, queue_family, 0, &queue);
+    Ensures(queue != VK_NULL_HANDLE);
+
+    vk->DestroyDevice(device, kVkAlloc);
     vk->DestroyInstance(instance, kVkAlloc);
+    
     return {};
 }
 
-- 
cgit