Enable Quirk + Required VkDevice Extensions

Implements the infrastructure required to enable optional extensions set in `QuirkManager` alongside the required extensions in the `GPU` class. All extensions should be correctly resolved now and according to what the device supports.
This commit is contained in:
PixelyIon 2021-11-14 21:57:23 +05:30
parent 6099b1ead5
commit 081d3277c1
3 changed files with 35 additions and 23 deletions

View File

@ -122,20 +122,29 @@ 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 features{physicalDevice.getFeatures2()};
auto extensions{physicalDevice.enumerateDeviceExtensionProperties()}; auto deviceExtensions{physicalDevice.enumerateDeviceExtensionProperties()};
quirks = QuirkManager(properties, features, extensions); std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> enabledExtensions{
{
constexpr std::array<const char *, 1> requiredDeviceExtensions{ // Required Extensions
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
}
}; };
for (const auto &requiredExtension : requiredDeviceExtensions) {
if (!std::any_of(extensions.begin(), extensions.end(), [&](const vk::ExtensionProperties &deviceExtension) { for (const auto &requiredExtension : enabledExtensions) {
return std::string_view(deviceExtension.extensionName) == std::string_view(requiredExtension); if (!std::any_of(deviceExtensions.begin(), deviceExtensions.end(), [&](const vk::ExtensionProperties &deviceExtension) {
return std::string_view(deviceExtension.extensionName) == std::string_view(requiredExtension.data());
})) }))
throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension); throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension.data());
} }
quirks = QuirkManager(properties, features, deviceExtensions, enabledExtensions);
std::vector<const char*> pEnabledExtensions;
pEnabledExtensions.reserve(enabledExtensions.size());
for (auto& extension : enabledExtensions)
pEnabledExtensions.push_back(extension.data());
auto queueFamilies{physicalDevice.getQueueFamilyProperties()}; auto queueFamilies{physicalDevice.getQueueFamilyProperties()};
float queuePriority{1.0f}; //!< The priority of the only queue we use, it's set to the maximum of 1.0 float queuePriority{1.0f}; //!< The priority of the only queue we use, it's set to the maximum of 1.0
vk::DeviceQueueCreateInfo queue{[&] { vk::DeviceQueueCreateInfo queue{[&] {
@ -156,7 +165,7 @@ namespace skyline::gpu {
if (Logger::configLevel >= Logger::LogLevel::Info) { if (Logger::configLevel >= Logger::LogLevel::Info) {
std::string extensionString; std::string extensionString;
for (const auto &extension : extensions) for (const auto &extension : deviceExtensions)
extensionString += util::Format("\n* {} (v{}.{}.{})", extension.extensionName, VK_VERSION_MAJOR(extension.specVersion), VK_VERSION_MINOR(extension.specVersion), VK_VERSION_PATCH(extension.specVersion)); extensionString += util::Format("\n* {} (v{}.{}.{})", extension.extensionName, VK_VERSION_MAJOR(extension.specVersion), VK_VERSION_MINOR(extension.specVersion), VK_VERSION_PATCH(extension.specVersion));
std::string queueString; std::string queueString;
@ -175,8 +184,8 @@ namespace skyline::gpu {
.pNext = &features, .pNext = &features,
.queueCreateInfoCount = 1, .queueCreateInfoCount = 1,
.pQueueCreateInfos = &queue, .pQueueCreateInfos = &queue,
.enabledExtensionCount = requiredDeviceExtensions.size(), .enabledExtensionCount = static_cast<uint32_t>(pEnabledExtensions.size()),
.ppEnabledExtensionNames = requiredDeviceExtensions.data(), .ppEnabledExtensionNames = pEnabledExtensions.data(),
}); });
} }

View File

@ -4,18 +4,21 @@
#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> &extensions) { 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) {
for (auto &extension : extensions) { for (auto &extension : deviceExtensions) {
#define EXT_SET(name, property) \ #define EXT_SET(name, property) \
case util::Hash(name): \ case util::Hash(name): \
if (name == extensionName) \ if (name == extensionName) { \
property = true; \ property = true; \
enabledExtensions.push_back(std::array<char, VK_MAX_EXTENSION_NAME_SIZE>{name}); \
} \
break break
#define EXT_SET_V(name, property, version) \ #define EXT_SET_V(name, property, version) \
case util::Hash(name): \ case util::Hash(name): \
if (name == extensionName && extensionVersion >= version) \ if (name == extensionName && extensionVersion >= version) \
property = true; \ property = true; \
enabledExtensions.push_back(std::array<char, VK_MAX_EXTENSION_NAME_SIZE>{name}); \
break break
std::string_view extensionName{extension.extensionName}; std::string_view extensionName{extension.extensionName};

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> &extensions); 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);
/** /**
* @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