diff --git a/oatmeal/src/ctx.cpp b/oatmeal/src/ctx.cpp index 20662c2..929088d 100644 --- a/oatmeal/src/ctx.cpp +++ b/oatmeal/src/ctx.cpp @@ -1,8 +1,12 @@ #include "ctx.h" -#include namespace Oatmeal { - ctx::ctx(GLFWwindow *window) { createInstance(); } + ctx::ctx(GLFWwindow *window) { + createInstance(); + m_window = window; + createSurface(); + pickPhysicalDevice(); + } ctx::~ctx() {} diff --git a/oatmeal/src/ctx_physicalDevice.cpp b/oatmeal/src/ctx_physicalDevice.cpp new file mode 100644 index 0000000..e318338 --- /dev/null +++ b/oatmeal/src/ctx_physicalDevice.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include +#include "ctx.h" +#include "vulkan/vulkan.hpp" + +namespace Oatmeal { + + void ctx::pickPhysicalDevice() { + std::vector physicalDevices = m_instance.enumeratePhysicalDevices(); + std::vector supportedDevices{}; + + for (const auto device: physicalDevices) { + if (isPhysicalDeviceSupported(device)) { + supportedDevices.emplace_back(device); + } + } + if (supportedDevices.empty()) { + throw std::runtime_error("Failed to find a supported device"); + } + + std::multimap scores; + for (const auto device: supportedDevices) { + uint32_t score = scorePhysicalDevice(device); + scores.insert(std::make_pair(score, device)); + } + m_physicalDevice = scores.rbegin()->second; + } + + bool ctx::isPhysicalDeviceSupported(vk::raii::PhysicalDevice device) { + // Check for vulkan 1.4 support + bool supportsVulkan14 = device.getProperties().apiVersion >= VK_API_VERSION_1_4; + + // Check for graphics queue support + auto queueFamilies = device.getQueueFamilyProperties(); + bool supportsGraphics = std::ranges::any_of( + queueFamilies, [](auto const &qfp) { return !!(qfp.queueFlags & vk::QueueFlagBits::eGraphics); }); + + // Check for extension support + auto availableDeviceExtensions = device.enumerateDeviceExtensionProperties(); + bool supportsAllRequiredExtensions = std::ranges::all_of( + requiredDeviceExtensions, [&availableDeviceExtensions](auto const &requiredDeviceExtension) { + return std::ranges::any_of( + availableDeviceExtensions, [requiredDeviceExtension](auto const &availableDeviceExtension) { + return strcmp(availableDeviceExtension.extensionName, requiredDeviceExtension) == 0; + }); + }); + + + // Check for feature support + auto features = device.template getFeatures2(); + + bool supportsRequiredFeatures = + features.template get().features.samplerAnisotropy && + features.template get().dynamicRendering && + features.template get().synchronization2 && + features.template get().extendedDynamicState; + + return supportsVulkan14 && supportsGraphics && supportsAllRequiredExtensions && supportsRequiredFeatures; + } + + + uint32_t ctx::scorePhysicalDevice(vk::raii::PhysicalDevice device) { + uint32_t score = 0; + vk::PhysicalDeviceProperties physicalDeviceProperties = device.getProperties(); + + if (physicalDeviceProperties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) { + score += 100; + } else if (physicalDeviceProperties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu) { + score += 50; + } else if (physicalDeviceProperties.deviceType == vk::PhysicalDeviceType::eVirtualGpu) { + score += 10; + } + + return score; + } + +} // namespace Oatmeal diff --git a/oatmeal/src/ctx_surface.cpp b/oatmeal/src/ctx_surface.cpp index 89119e4..0c9d944 100644 --- a/oatmeal/src/ctx_surface.cpp +++ b/oatmeal/src/ctx_surface.cpp @@ -5,7 +5,6 @@ #include #include - namespace Oatmeal { void ctx::createSurface() {