diff options
Diffstat (limited to 'main/main.cpp')
-rw-r--r-- | main/main.cpp | 139 |
1 files changed, 91 insertions, 48 deletions
diff --git a/main/main.cpp b/main/main.cpp index 4a999ce..602b6ab 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -13,7 +13,6 @@ static OsApi* os_api; static const VkAllocationCallbacks* kVkAlloc = nullptr;
-[[nodiscard]]
StatusOr<VkInstance> CreateInstance(VulkanApi* vk)
{
const VkApplicationInfo application_info{
@@ -58,34 +57,33 @@ StatusOr<VkInstance> CreateInstance(VulkanApi* vk) return instance;
}
-StatusOr<VkPhysicalDevice> FindPhysicalDevice(VulkanApi* vk, VkInstance instance)
+StatusOr<VkSurfaceKHR> CreateSurface(VulkanApi* vk, VkInstance instance, OsWindow* window)
{
- auto temp_alloc = temp_api->Acquire();
-
- uint32_t physical_device_count = 0;
- vk->EnumeratePhysicalDevices(instance, &physical_device_count, nullptr);
- if (physical_device_count == 0)
+ const VkWin32SurfaceCreateInfoKHR create_info{
+ .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR,
+ .pNext = nullptr,
+ .flags = 0,
+ .hinstance = os_api->window->Win32Hinstance(window),
+ .hwnd = os_api->window->Win32Hwnd(window),
+ };
+
+ VkSurfaceKHR surface{};
+ const VkResult res = vk->CreateWin32SurfaceKHR(instance, &create_info, kVkAlloc, &surface);
+ if (res != VK_SUCCESS)
{
- return InternalError("No Vulkan device found");
+ return InternalError("vkCreateWin32SurfaceKHR failed");
}
- 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
- // In fact, FindQueueFamily should be done here.
- return devices[0];
+ return surface;
}
-StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_device)
+StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_device, VkSurfaceKHR surface)
{
auto temp_alloc = temp_api->Acquire();
uint32_t queue_family_count = 0;
vk->GetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
- if (queue_family_count == 0)
+ if (queue_family_count == 0)
{
return InternalError("No queue on this physical device");
}
@@ -100,7 +98,11 @@ StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_devi const auto& prps = queue_families[index];
const bool supports_graphics_compute = (prps.queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0 && (prps.queueFlags & VK_QUEUE_COMPUTE_BIT) != 0;
- const bool supports_presentation = vk->GetPhysicalDeviceWin32PresentationSupportKHR(physical_device, index) == VK_TRUE;
+
+ VkBool32 vk_supports_presentation{};
+ const VkResult presentation_res = vk->GetPhysicalDeviceSurfaceSupportKHR(physical_device, index, surface, &vk_supports_presentation);
+ const bool supports_presentation = presentation_res == VK_SUCCESS && vk_supports_presentation == VK_TRUE;
+
if (supports_graphics_compute && supports_presentation)
{
return index;
@@ -110,6 +112,59 @@ StatusOr<uint32_t> FindQueueFamily(VulkanApi* vk, VkPhysicalDevice physical_devi return InternalError("Couldn't find a suitable queue");
}
+Status FindPhysicalDevice(
+ VulkanApi* vk,
+ VkInstance instance,
+ VkSurfaceKHR surface,
+ VkPhysicalDevice* out_physical_device,
+ uint32_t* out_queue_family)
+{
+ 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 physical_devices = temp_alloc.allocator().NewArray<VkPhysicalDevice>(physical_device_count);
+ vk->EnumeratePhysicalDevices(instance, &physical_device_count, physical_devices.data());
+
+ for (VkPhysicalDevice physical_device: physical_devices)
+ {
+ {
+ 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("Trying Vulkan device $ ($, $)",
+ prps.properties.deviceName, prps12.driverName, prps12.driverInfo);
+ }
+
+ auto maybe_queue_family = FindQueueFamily(vk, physical_device, surface);
+ if (maybe_queue_family.ok())
+ {
+ log_api->LogInfo("This device is compatible, choosing it");
+ *out_physical_device = physical_device;
+ *out_queue_family = maybe_queue_family.value();
+ return {};
+ }
+
+ log_api->LogInfo("Incompatible because: $", maybe_queue_family);
+ }
+
+ return InternalError("No suitable device found");
+}
+
StatusOr<VkDevice> CreateDevice(VulkanApi* vk, VkPhysicalDevice physical_device, uint32_t queue_family)
{
const float queue_priority = 1.0F;
@@ -150,7 +205,7 @@ StatusOr<VkDevice> CreateDevice(VulkanApi* vk, VkPhysicalDevice physical_device, return device;
}
-Status InitializeVulkan(ApiRegistry* api_registry)
+Status InitializeVulkan(ApiRegistry* api_registry, OsWindow* window)
{
RegisterVulkanLoaderApi(api_registry);
auto* loader_api = api_registry->Get<VulkanLoaderApi>();
@@ -166,32 +221,19 @@ Status InitializeVulkan(ApiRegistry* api_registry) loader_api->LoadInstance(vk, instance);
- VkPhysicalDevice physical_device{};
+ VkSurfaceKHR surface{};
{
- StatusOr<VkPhysicalDevice> s = FindPhysicalDevice(vk, instance);
+ StatusOr<VkSurfaceKHR> s = CreateSurface(vk, instance, window);
if (!s.ok()) { return s.status(); }
- physical_device = s.value();
+ surface = s.value();
+ log_api->LogInfo("Vulkan surface created");
}
+ VkPhysicalDevice physical_device{};
+ uint32_t queue_family{};
{
- 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();
+ Status s = FindPhysicalDevice(vk, instance, surface, &physical_device, &queue_family);
+ if (!s.ok()) { return s; }
log_api->LogInfo("Vulkan queue family: $", queue_family);
}
@@ -210,6 +252,7 @@ Status InitializeVulkan(ApiRegistry* api_registry) Ensures(queue != VK_NULL_HANDLE);
vk->DestroyDevice(device, kVkAlloc);
+ vk->DestroySurfaceKHR(instance, surface, kVkAlloc);
vk->DestroyInstance(instance, kVkAlloc);
return {};
@@ -235,19 +278,19 @@ int main(int /* argc */, char* /* argv */[]) window = s.value();
}
- while (!os_api->window->QuitRequested(window))
- {
- os_api->window->Update(window);
- }
-
- const Status s = InitializeVulkan(api_registry);
+ const Status s = InitializeVulkan(api_registry, window);
if (!s.ok())
{
log_api->LogError("Vulkan initializaiton error: $", s);
return 1;
} - log_api->LogInfo("OK");
+ while (!os_api->window->QuitRequested(window))
+ {
+ os_api->window->Update(window);
+ }
+
+ log_api->LogInfo("Goodbye");
return 0;
}
|