mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 11:31:51 +01:00
Introduce QuirkManager
for runtime GPU quirk tracking
We require a way to track certain host GPU features that are optional such as Vulkan extensions, this is what the `QuirkManager` class does as it checks for all quirks and holds them allowing other components to branch based off these quirks.
This commit is contained in:
parent
8803616673
commit
8ef225a37d
@ -129,6 +129,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/skyline/audio/resampler.cpp
|
||||
${source_DIR}/skyline/audio/adpcm_decoder.cpp
|
||||
${source_DIR}/skyline/gpu.cpp
|
||||
${source_DIR}/skyline/gpu/quirk_manager.cpp
|
||||
${source_DIR}/skyline/gpu/memory_manager.cpp
|
||||
${source_DIR}/skyline/gpu/texture_manager.cpp
|
||||
${source_DIR}/skyline/gpu/command_scheduler.cpp
|
||||
|
@ -119,17 +119,18 @@ namespace skyline::gpu {
|
||||
return std::move(vk::raii::PhysicalDevices(instance).front()); // We just select the first device as we aren't expecting multiple GPUs
|
||||
}
|
||||
|
||||
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex) {
|
||||
auto properties{physicalDevice.getProperties()}; // We should check for required properties here, if/when we have them
|
||||
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager& quirks) {
|
||||
auto properties{physicalDevice.getProperties()};
|
||||
auto features{physicalDevice.getFeatures2()};
|
||||
auto extensions{physicalDevice.enumerateDeviceExtensionProperties()};
|
||||
|
||||
// auto features{physicalDevice.getFeatures()}; // Same as above
|
||||
quirks = QuirkManager(properties, features, extensions);
|
||||
|
||||
constexpr std::array<const char *, 1> requiredDeviceExtensions{
|
||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||
};
|
||||
auto deviceExtensions{physicalDevice.enumerateDeviceExtensionProperties()};
|
||||
for (const auto &requiredExtension : requiredDeviceExtensions) {
|
||||
if (!std::any_of(deviceExtensions.begin(), deviceExtensions.end(), [&](const vk::ExtensionProperties &deviceExtension) {
|
||||
if (!std::any_of(extensions.begin(), extensions.end(), [&](const vk::ExtensionProperties &deviceExtension) {
|
||||
return std::string_view(deviceExtension.extensionName) == std::string_view(requiredExtension);
|
||||
}))
|
||||
throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension);
|
||||
@ -155,7 +156,7 @@ namespace skyline::gpu {
|
||||
|
||||
if (Logger::configLevel >= Logger::LogLevel::Info) {
|
||||
std::string extensionString;
|
||||
for (const auto &extension : deviceExtensions)
|
||||
for (const auto &extension : extensions)
|
||||
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;
|
||||
@ -174,5 +175,5 @@ namespace skyline::gpu {
|
||||
});
|
||||
}
|
||||
|
||||
GPU::GPU(const DeviceState &state) : vkInstance(CreateInstance(state, vkContext)), vkDebugReportCallback(CreateDebugReportCallback(vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(vkInstance)), vkDevice(CreateDevice(vkPhysicalDevice, vkQueueFamilyIndex)), vkQueue(vkDevice, vkQueueFamilyIndex, 0), memory(*this), scheduler(*this), presentation(state, *this), texture(*this) {}
|
||||
GPU::GPU(const DeviceState &state) : vkInstance(CreateInstance(state, vkContext)), vkDebugReportCallback(CreateDebugReportCallback(vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(vkInstance)), vkDevice(CreateDevice(vkPhysicalDevice, vkQueueFamilyIndex, quirks)), vkQueue(vkDevice, vkQueueFamilyIndex, 0), memory(*this), scheduler(*this), presentation(state, *this), texture(*this) {}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gpu/quirk_manager.h"
|
||||
#include "gpu/memory_manager.h"
|
||||
#include "gpu/command_scheduler.h"
|
||||
#include "gpu/presentation_engine.h"
|
||||
@ -22,7 +23,7 @@ namespace skyline::gpu {
|
||||
|
||||
static vk::raii::PhysicalDevice CreatePhysicalDevice(const vk::raii::Instance &instance);
|
||||
|
||||
static vk::raii::Device CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount)& queueConfiguration);
|
||||
static vk::raii::Device CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount)& queueConfiguration, QuirkManager& quirks);
|
||||
|
||||
public:
|
||||
static constexpr u32 VkApiVersion{VK_API_VERSION_1_1}; //!< The version of core Vulkan that we require
|
||||
@ -36,6 +37,8 @@ namespace skyline::gpu {
|
||||
std::mutex queueMutex; //!< Synchronizes access to the queue as it is externally synchronized
|
||||
vk::raii::Queue vkQueue; //!< A Vulkan Queue supporting graphics and compute operations
|
||||
|
||||
QuirkManager quirks;
|
||||
|
||||
memory::MemoryManager memory;
|
||||
CommandScheduler scheduler;
|
||||
PresentationEngine presentation;
|
||||
|
@ -68,7 +68,6 @@ namespace skyline::gpu::memory {
|
||||
.vulkanApiVersion = GPU::VkApiVersion,
|
||||
};
|
||||
ThrowOnFail(vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator));
|
||||
// TODO: Use VK_KHR_dedicated_allocation when available (Should be on Adreno GPUs)
|
||||
}
|
||||
|
||||
MemoryManager::~MemoryManager() {
|
||||
|
31
app/src/main/cpp/skyline/gpu/quirk_manager.cpp
Normal file
31
app/src/main/cpp/skyline/gpu/quirk_manager.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include "quirk_manager.h"
|
||||
|
||||
namespace skyline {
|
||||
QuirkManager::QuirkManager(vk::PhysicalDeviceProperties properties, vk::PhysicalDeviceFeatures2 features, const std::vector<vk::ExtensionProperties> &extensions) {
|
||||
for (auto &extension : extensions) {
|
||||
#define EXT_SET(name, property) \
|
||||
case util::Hash(name): \
|
||||
if (name == extensionName) \
|
||||
property = true; \
|
||||
break
|
||||
|
||||
#define EXT_SET_V(name, property, version) \
|
||||
case util::Hash(name): \
|
||||
if (name == extensionName && extensionVersion >= version) \
|
||||
property = true; \
|
||||
break
|
||||
|
||||
std::string_view extensionName{extension.extensionName};
|
||||
auto extensionVersion{extension.specVersion};
|
||||
switch (util::Hash(extensionName)) {
|
||||
EXT_SET("VK_EXT_provoking_vertex", supportsLastProvokingVertex);
|
||||
}
|
||||
|
||||
#undef EXT_SET
|
||||
#undef EXT_SET_V
|
||||
}
|
||||
}
|
||||
}
|
21
app/src/main/cpp/skyline/gpu/quirk_manager.h
Normal file
21
app/src/main/cpp/skyline/gpu/quirk_manager.h
Normal file
@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <common.h>
|
||||
|
||||
namespace skyline {
|
||||
/**
|
||||
* @brief Checks and stores all the quirks of the host GPU discovered at runtime
|
||||
*/
|
||||
class QuirkManager {
|
||||
public:
|
||||
bool supportsLastProvokingVertex{}; //!< If the device supports setting the last vertex as the provoking vertex (with VK_EXT_provoking_vertex)
|
||||
|
||||
QuirkManager() = default;
|
||||
|
||||
QuirkManager(vk::PhysicalDeviceProperties properties, vk::PhysicalDeviceFeatures2 features, const std::vector<vk::ExtensionProperties>& extensions);
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user