Add Required VkDevice Features

A prior commit added the ability to utilize features with quirks but this implements the ability to require a feature be present on the host or an exception will be thrown. It allows us to make useful assumptions that result in a better architecture in certain cases.
This commit is contained in:
PixelyIon 2021-11-15 00:25:14 +05:30
parent 081d3277c1
commit cd737fbdd8
3 changed files with 22 additions and 15 deletions

View File

@ -121,9 +121,19 @@ namespace skyline::gpu {
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) { vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) {
auto properties{physicalDevice.getProperties()}; auto properties{physicalDevice.getProperties()};
auto features{physicalDevice.getFeatures2()};
auto deviceExtensions{physicalDevice.enumerateDeviceExtensionProperties()};
auto deviceFeatures2{physicalDevice.getFeatures2()};
vk::PhysicalDeviceFeatures2 enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features
#define FEAT_REQ(feature) \
if (deviceFeatures2.features.feature) \
enabledFeatures2.features.feature = true; \
else \
throw exception("Vulkan device doesn't support required feature: " #feature)
#undef FEAT_REQ
auto deviceExtensions{physicalDevice.enumerateDeviceExtensionProperties()};
std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> enabledExtensions{ std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> enabledExtensions{
{ {
// Required Extensions // Required Extensions
@ -138,11 +148,11 @@ namespace skyline::gpu {
throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension.data()); throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension.data());
} }
quirks = QuirkManager(properties, features, deviceExtensions, enabledExtensions); quirks = QuirkManager(properties, deviceFeatures2, enabledFeatures2, deviceExtensions, enabledExtensions);
std::vector<const char*> pEnabledExtensions; std::vector<const char *> pEnabledExtensions;
pEnabledExtensions.reserve(enabledExtensions.size()); pEnabledExtensions.reserve(enabledExtensions.size());
for (auto& extension : enabledExtensions) for (auto &extension : enabledExtensions)
pEnabledExtensions.push_back(extension.data()); pEnabledExtensions.push_back(extension.data());
auto queueFamilies{physicalDevice.getQueueFamilyProperties()}; auto queueFamilies{physicalDevice.getQueueFamilyProperties()};
@ -181,7 +191,7 @@ namespace skyline::gpu {
} }
return vk::raii::Device(physicalDevice, vk::DeviceCreateInfo{ return vk::raii::Device(physicalDevice, vk::DeviceCreateInfo{
.pNext = &features, .pNext = &enabledFeatures2,
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.pQueueCreateInfos = &queue, .pQueueCreateInfos = &queue,
.enabledExtensionCount = static_cast<uint32_t>(pEnabledExtensions.size()), .enabledExtensionCount = static_cast<uint32_t>(pEnabledExtensions.size()),

View File

@ -4,7 +4,7 @@
#include "quirk_manager.h" #include "quirk_manager.h"
namespace skyline { namespace skyline {
QuirkManager::QuirkManager(const vk::PhysicalDeviceProperties &properties, vk::PhysicalDeviceFeatures2 &features2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions) { QuirkManager::QuirkManager(const vk::PhysicalDeviceProperties &properties, const vk::PhysicalDeviceFeatures2 &deviceFeatures2, vk::PhysicalDeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions) {
for (auto &extension : deviceExtensions) { for (auto &extension : deviceExtensions) {
#define EXT_SET(name, property) \ #define EXT_SET(name, property) \
case util::Hash(name): \ case util::Hash(name): \
@ -31,13 +31,10 @@ namespace skyline {
#undef EXT_SET_V #undef EXT_SET_V
} }
auto deviceFeatures2{features2}; #define FEAT_SET(feature, property) \
features2 = vk::PhysicalDeviceFeatures2{}; // We only want to enable features we required due to potential overhead from unused features if (deviceFeatures2.features.feature) { \
property = true; \
#define FEAT_SET(feature, property) \ enabledFeatures2.features.feature = true; \
if (deviceFeatures2.features.feature) { \
property = true; \
features2.features.feature = true; \
} }
FEAT_SET(logicOp, supportsLogicOp) FEAT_SET(logicOp, supportsLogicOp)

View File

@ -17,7 +17,7 @@ namespace skyline {
QuirkManager() = default; QuirkManager() = default;
QuirkManager(const vk::PhysicalDeviceProperties &properties, vk::PhysicalDeviceFeatures2 &features, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions); QuirkManager(const vk::PhysicalDeviceProperties &properties, const vk::PhysicalDeviceFeatures2 &deviceFeatures2, vk::PhysicalDeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions);
/** /**
* @return A summary of all the GPU quirks as a human-readable string * @return A summary of all the GPU quirks as a human-readable string