ctx - physical device
All checks were successful
Build / Build (push) Successful in 3m14s

This commit is contained in:
2026-04-13 17:41:56 -04:00
parent 7d50f6c148
commit bd6c4523dd
3 changed files with 89 additions and 3 deletions

View File

@@ -1,8 +1,12 @@
#include "ctx.h" #include "ctx.h"
#include <cstdint>
namespace Oatmeal { namespace Oatmeal {
ctx::ctx(GLFWwindow *window) { createInstance(); } ctx::ctx(GLFWwindow *window) {
createInstance();
m_window = window;
createSurface();
pickPhysicalDevice();
}
ctx::~ctx() {} ctx::~ctx() {}

View File

@@ -0,0 +1,83 @@
#include <algorithm>
#include <cstdint>
#include <map>
#include <stdexcept>
#include <utility>
#include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_raii.hpp>
#include "ctx.h"
#include "vulkan/vulkan.hpp"
namespace Oatmeal {
void ctx::pickPhysicalDevice() {
std::vector<vk::raii::PhysicalDevice> physicalDevices = m_instance.enumeratePhysicalDevices();
std::vector<vk::raii::PhysicalDevice> 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<uint32_t, vk::raii::PhysicalDevice> 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<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceVulkan13Features,
vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>();
bool supportsRequiredFeatures =
features.template get<vk::PhysicalDeviceFeatures2>().features.samplerAnisotropy &&
features.template get<vk::PhysicalDeviceVulkan13Features>().dynamicRendering &&
features.template get<vk::PhysicalDeviceVulkan13Features>().synchronization2 &&
features.template get<vk::PhysicalDeviceExtendedDynamicStateFeaturesEXT>().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

View File

@@ -5,7 +5,6 @@
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <vulkan/vulkan_raii.hpp> #include <vulkan/vulkan_raii.hpp>
namespace Oatmeal { namespace Oatmeal {
void ctx::createSurface() { void ctx::createSurface() {