summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/main.cpp119
1 files changed, 110 insertions, 9 deletions
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<VkInstance> CreateInstance(VulkanApi* vk)
@@ -26,6 +29,7 @@ StatusOr<VkInstance> 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<VkInstance> 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<VkInstance> CreateInstance(VulkanApi* vk)
return instance;
}
+StatusOr<VkPhysicalDevice> 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<VkPhysicalDevice>(physical_device_count);
+ vk->EnumeratePhysicalDevices(instance, &physical_device_count, devices.data());
+
+ // @Todo Physical device selection
+ return devices[0];
+}
+
+StatusOr<uint32_t> 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<VkQueueFamilyProperties>(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<VulkanLoaderApi>();
+ auto* vk = loader_api->LoadEntry();
+
+ VkInstance instance{};
+ {
+ StatusOr<VkInstance> 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<VkPhysicalDevice> 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<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);
+
+ vk->DestroyInstance(instance, kVkAlloc);
+ return {};
+}
+
int main(int /* argc */, char* /* argv */[])
{
auto* api_registry = InitializeGlobalApiRegistry();
log_api = api_registry->Get<LogApi>();
- log_api->LogInfo("Base APIs registered");
-
- RegisterVulkanLoaderApi(api_registry);
- auto* vulkan_loader_api = api_registry->Get<VulkanLoaderApi>();
- auto* vk = vulkan_loader_api->LoadEntry();
+ temp_api = api_registry->Get<TempAllocatorApi>();
+ log_api->LogInfo("Base APIs registered");
- const StatusOr<VkInstance> 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");