From e02f9fd89b059919baf3a8d8bf8b783470976a27 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sat, 27 Apr 2024 01:16:21 +0200 Subject: Some work on Vulkan initialization --- main/main.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 9 deletions(-) (limited to 'main/main.cpp') diff --git a/main/main.cpp b/main/main.cpp index ca1e063..34d0276 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -7,6 +7,9 @@ using namespace deimos; static LogApi* log_api; +static TempAllocatorApi* temp_api; + +static const VkAllocationCallbacks* kVkAlloc = nullptr; [[nodiscard]] StatusOr CreateInstance(VulkanApi* vk) @@ -26,6 +29,7 @@ StatusOr CreateInstance(VulkanApi* vk) "VK_KHR_win32_surface", }; + // @Todo Select layers & extensions based on config const char* layers[]{ "VK_LAYER_KHRONOS_validation", "VK_LAYER_LUNARG_monitor", @@ -43,7 +47,7 @@ StatusOr CreateInstance(VulkanApi* vk) }; VkInstance instance{}; - const VkResult res = vk->CreateInstance(&create_info, nullptr, &instance); + const VkResult res = vk->CreateInstance(&create_info, kVkAlloc, &instance); if (res != VK_SUCCESS) { return InternalError("vkCreateInstance failed"); @@ -52,21 +56,118 @@ StatusOr CreateInstance(VulkanApi* vk) return instance; } +StatusOr FindPhysicalDevice(VulkanApi* vk, VkInstance instance) +{ + auto temp_alloc = temp_api->Acquire(); + + uint32_t physical_device_count = 0; + vk->EnumeratePhysicalDevices(instance, &physical_device_count, nullptr); + if (physical_device_count == 0) + { + return InternalError("No Vulkan device found"); + } + + log_api->LogInfo("Found $ physical devices", physical_device_count); + + auto devices = temp_alloc.allocator().NewArray(physical_device_count); + vk->EnumeratePhysicalDevices(instance, &physical_device_count, devices.data()); + + // @Todo Physical device selection + return devices[0]; +} + +StatusOr FindQueueFamily(VulkanApi* vk, VkPhysicalDevice device) +{ + auto temp_alloc = temp_api->Acquire(); + + uint32_t queue_family_count = 0; + vk->GetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, nullptr); + if (queue_family_count == 0) + { + return InternalError("No queue on this physical device??"); + } + + log_api->LogInfo("Physical device has $ queue families", queue_family_count); + + auto queue_families = temp_alloc.allocator().NewArray(queue_family_count); + vk->GetPhysicalDeviceQueueFamilyProperties(device, &queue_family_count, queue_families.data()); + + for (uint32_t index = 0; index < queue_family_count; ++index) + { + const auto& prps = queue_families[index]; + if ((prps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0 && (prps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0) + { + return index; + } + } + + return InternalError("Couldn't find a suitable queue"); +} + +Status InitializeVulkan(ApiRegistry* api_registry) +{ + RegisterVulkanLoaderApi(api_registry); + auto* loader_api = api_registry->Get(); + auto* vk = loader_api->LoadEntry(); + + VkInstance instance{}; + { + StatusOr s = CreateInstance(vk); + if (!s.ok()) { return s.status(); } + instance = s.value(); + log_api->LogInfo("Vulkan instance created"); + } + + loader_api->LoadInstance(vk, instance); + + VkPhysicalDevice physical_device{}; + { + StatusOr s = FindPhysicalDevice(vk, instance); + if (!s.ok()) { return s.status(); } + physical_device = s.value(); + } + + { + + VkPhysicalDeviceVulkan12Properties prps12{}; + prps12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES; + prps12.pNext = nullptr; + + VkPhysicalDeviceProperties2 prps{}; + prps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; + prps.pNext = &prps12; + + vk->GetPhysicalDeviceProperties2(physical_device, &prps); + log_api->LogInfo("Vulkan device: $", prps.properties.deviceName); + log_api->LogInfo("Vulkan driver: $, $", prps12.driverName, prps12.driverInfo); + } + + uint32_t queue_family = 0; + { + StatusOr s = FindQueueFamily(vk, physical_device); + if (!s.ok()) { return s.status(); } + queue_family = s.value(); + } + + log_api->LogInfo("Vulkan queue family: $", queue_family); + + vk->DestroyInstance(instance, kVkAlloc); + return {}; +} + int main(int /* argc */, char* /* argv */[]) { auto* api_registry = InitializeGlobalApiRegistry(); log_api = api_registry->Get(); - log_api->LogInfo("Base APIs registered"); - - RegisterVulkanLoaderApi(api_registry); - auto* vulkan_loader_api = api_registry->Get(); - auto* vk = vulkan_loader_api->LoadEntry(); + temp_api = api_registry->Get(); + log_api->LogInfo("Base APIs registered"); - const StatusOr s = CreateInstance(vk); + const Status s = InitializeVulkan(api_registry); if (!s.ok()) { - log_api->LogError("$", s); - } + log_api->LogError("Vulkan initializaiton error: $", s); + } + log_api->LogInfo("OK"); -- cgit