From 89ae6838075f3579a85d7824d49a051b90c8ed92 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Tue, 30 Apr 2024 22:20:36 +0200 Subject: Vulkan device & queue creation --- deimos/vulkan/BUILD | 1 + deimos/vulkan/vulkan.h | 2 + deimos/vulkan/vulkan_device_functions.inc | 4 ++ deimos/vulkan/vulkan_instance_functions.inc | 2 + deimos/vulkan/vulkan_loader.cpp | 11 ++++++ main/main.cpp | 61 +++++++++++++++++++++++++++-- 6 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 deimos/vulkan/vulkan_device_functions.inc diff --git a/deimos/vulkan/BUILD b/deimos/vulkan/BUILD index 8f0a79e..5eae9ef 100644 --- a/deimos/vulkan/BUILD +++ b/deimos/vulkan/BUILD @@ -8,6 +8,7 @@ cc_library( "vulkan_bootstrap_functions.inc", "vulkan_entry_functions.inc", "vulkan_instance_functions.inc", + "vulkan_device_functions.inc", ], deps = [ "//deimos/core", diff --git a/deimos/vulkan/vulkan.h b/deimos/vulkan/vulkan.h index 4315230..f116fc0 100644 --- a/deimos/vulkan/vulkan.h +++ b/deimos/vulkan/vulkan.h @@ -23,6 +23,7 @@ struct VulkanApi #include "deimos/vulkan/vulkan_bootstrap_functions.inc" #include "deimos/vulkan/vulkan_entry_functions.inc" #include "deimos/vulkan/vulkan_instance_functions.inc" +#include "deimos/vulkan/vulkan_device_functions.inc" #undef FN }; @@ -38,6 +39,7 @@ public: virtual VulkanApi* LoadEntry() = 0; virtual void LoadInstance(VulkanApi*, VkInstance) = 0; + virtual void LoadDevice(VulkanApi*, VkDevice) = 0; }; void RegisterVulkanLoaderApi(ApiRegistry*); diff --git a/deimos/vulkan/vulkan_device_functions.inc b/deimos/vulkan/vulkan_device_functions.inc new file mode 100644 index 0000000..8267fb9 --- /dev/null +++ b/deimos/vulkan/vulkan_device_functions.inc @@ -0,0 +1,4 @@ +// NOLINTBEGIN +FN(DestroyDevice) +FN(GetDeviceQueue) +// NOLINTEND diff --git a/deimos/vulkan/vulkan_instance_functions.inc b/deimos/vulkan/vulkan_instance_functions.inc index 34535ad..c9862a5 100644 --- a/deimos/vulkan/vulkan_instance_functions.inc +++ b/deimos/vulkan/vulkan_instance_functions.inc @@ -3,4 +3,6 @@ FN(EnumeratePhysicalDevices) FN(GetPhysicalDeviceProperties2) FN(GetPhysicalDeviceQueueFamilyProperties) FN(DestroyInstance) +FN(CreateDevice) +FN(GetDeviceProcAddr) // NOLINTEND diff --git a/deimos/vulkan/vulkan_loader.cpp b/deimos/vulkan/vulkan_loader.cpp index 0760c67..b9980af 100644 --- a/deimos/vulkan/vulkan_loader.cpp +++ b/deimos/vulkan/vulkan_loader.cpp @@ -55,6 +55,17 @@ public: #define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetInstanceProcAddr(instance, "vk" #NAME); #include "deimos/vulkan/vulkan_instance_functions.inc" +#undef FN + } + + void LoadDevice(VulkanApi* api, VkDevice device) override + { + Expects(api != nullptr); + Expects(device != VK_NULL_HANDLE); + Expects(api->GetDeviceProcAddr != nullptr); + +#define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetDeviceProcAddr(device, "vk" #NAME); +#include "deimos/vulkan/vulkan_device_functions.inc" #undef FN } }; 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 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 FindQueueFamily(VulkanApi* vk, VkPhysicalDevice device) return InternalError("Couldn't find a suitable queue"); } +StatusOr 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 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 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