This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
#include "ctx.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace Oatmeal {
|
||||
ctx::ctx(GLFWwindow *window) { createInstance(); }
|
||||
ctx::ctx(GLFWwindow *window) {
|
||||
createInstance();
|
||||
m_window = window;
|
||||
createSurface();
|
||||
pickPhysicalDevice();
|
||||
}
|
||||
|
||||
ctx::~ctx() {}
|
||||
|
||||
|
||||
83
oatmeal/src/ctx_physicalDevice.cpp
Normal file
83
oatmeal/src/ctx_physicalDevice.cpp
Normal 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
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <vulkan/vulkan_core.h>
|
||||
#include <vulkan/vulkan_raii.hpp>
|
||||
|
||||
|
||||
namespace Oatmeal {
|
||||
|
||||
void ctx::createSurface() {
|
||||
|
||||
Reference in New Issue
Block a user