mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 11:51:47 +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/resampler.cpp
|
||||||
${source_DIR}/skyline/audio/adpcm_decoder.cpp
|
${source_DIR}/skyline/audio/adpcm_decoder.cpp
|
||||||
${source_DIR}/skyline/gpu.cpp
|
${source_DIR}/skyline/gpu.cpp
|
||||||
|
${source_DIR}/skyline/gpu/quirk_manager.cpp
|
||||||
${source_DIR}/skyline/gpu/memory_manager.cpp
|
${source_DIR}/skyline/gpu/memory_manager.cpp
|
||||||
${source_DIR}/skyline/gpu/texture_manager.cpp
|
${source_DIR}/skyline/gpu/texture_manager.cpp
|
||||||
${source_DIR}/skyline/gpu/command_scheduler.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
|
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) {
|
vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, typeof(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager& quirks) {
|
||||||
auto properties{physicalDevice.getProperties()}; // We should check for required properties here, if/when we have them
|
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{
|
constexpr std::array<const char *, 1> requiredDeviceExtensions{
|
||||||
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
||||||
};
|
};
|
||||||
auto deviceExtensions{physicalDevice.enumerateDeviceExtensionProperties()};
|
|
||||||
for (const auto &requiredExtension : requiredDeviceExtensions) {
|
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);
|
return std::string_view(deviceExtension.extensionName) == std::string_view(requiredExtension);
|
||||||
}))
|
}))
|
||||||
throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension);
|
throw exception("Cannot find Vulkan device extension: \"{}\"", requiredExtension);
|
||||||
@ -155,7 +156,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 : 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));
|
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;
|
||||||
@ -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
|
#pragma once
|
||||||
|
|
||||||
|
#include "gpu/quirk_manager.h"
|
||||||
#include "gpu/memory_manager.h"
|
#include "gpu/memory_manager.h"
|
||||||
#include "gpu/command_scheduler.h"
|
#include "gpu/command_scheduler.h"
|
||||||
#include "gpu/presentation_engine.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::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:
|
public:
|
||||||
static constexpr u32 VkApiVersion{VK_API_VERSION_1_1}; //!< The version of core Vulkan that we require
|
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
|
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
|
vk::raii::Queue vkQueue; //!< A Vulkan Queue supporting graphics and compute operations
|
||||||
|
|
||||||
|
QuirkManager quirks;
|
||||||
|
|
||||||
memory::MemoryManager memory;
|
memory::MemoryManager memory;
|
||||||
CommandScheduler scheduler;
|
CommandScheduler scheduler;
|
||||||
PresentationEngine presentation;
|
PresentationEngine presentation;
|
||||||
|
@ -68,7 +68,6 @@ namespace skyline::gpu::memory {
|
|||||||
.vulkanApiVersion = GPU::VkApiVersion,
|
.vulkanApiVersion = GPU::VkApiVersion,
|
||||||
};
|
};
|
||||||
ThrowOnFail(vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator));
|
ThrowOnFail(vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator));
|
||||||
// TODO: Use VK_KHR_dedicated_allocation when available (Should be on Adreno GPUs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryManager::~MemoryManager() {
|
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