Rename QuirkManager to TraitManager

Quirk terminology was deemed to be inappropriate for describing the features/extensions of a device. It has been replaced with traits which is far more fitting but quirks will be used as a terminology for errata in devices.
This commit is contained in:
PixelyIon 2022-01-22 20:15:28 +05:30
parent 0b2ce6a8f3
commit ddb2ba8a1b
7 changed files with 58 additions and 58 deletions

View File

@ -157,7 +157,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/trait_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/buffer_manager.cpp ${source_DIR}/skyline/gpu/buffer_manager.cpp

View File

@ -122,7 +122,7 @@ namespace skyline::gpu {
static vk::raii::Device CreateDevice(const vk::raii::Context &context, static vk::raii::Device CreateDevice(const vk::raii::Context &context,
const vk::raii::PhysicalDevice &physicalDevice, const vk::raii::PhysicalDevice &physicalDevice,
decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex,
QuirkManager &quirks) { TraitManager &traits) {
auto deviceFeatures2{physicalDevice.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features, vk::PhysicalDeviceUniformBufferStandardLayoutFeatures>()}; auto deviceFeatures2{physicalDevice.getFeatures2<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features, vk::PhysicalDeviceUniformBufferStandardLayoutFeatures>()};
decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features
@ -154,8 +154,8 @@ namespace skyline::gpu {
auto deviceProperties2{physicalDevice.getProperties2<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>()}; auto deviceProperties2{physicalDevice.getProperties2<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>()};
quirks = QuirkManager(deviceFeatures2, enabledFeatures2, deviceExtensions, enabledExtensions, deviceProperties2); traits = TraitManager(deviceFeatures2, enabledFeatures2, deviceExtensions, enabledExtensions, deviceProperties2);
quirks.ApplyDriverPatches(context); traits.ApplyDriverPatches(context);
std::vector<const char *> pEnabledExtensions; std::vector<const char *> pEnabledExtensions;
pEnabledExtensions.reserve(enabledExtensions.size()); pEnabledExtensions.reserve(enabledExtensions.size());
@ -191,11 +191,11 @@ namespace skyline::gpu {
queueString += util::Format("\n* {}x{}{}{}{}{}: TSB{} MIG({}x{}x{}){}", queueFamily.queueCount, queueFamily.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eProtected ? 'P' : '-', queueFamily.timestampValidBits, queueFamily.minImageTransferGranularity.width, queueFamily.minImageTransferGranularity.height, queueFamily.minImageTransferGranularity.depth, familyIndex++ == vkQueueFamilyIndex ? " <--" : ""); queueString += util::Format("\n* {}x{}{}{}{}{}: TSB{} MIG({}x{}x{}){}", queueFamily.queueCount, queueFamily.queueFlags & vk::QueueFlagBits::eGraphics ? 'G' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eCompute ? 'C' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eTransfer ? 'T' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eSparseBinding ? 'S' : '-', queueFamily.queueFlags & vk::QueueFlagBits::eProtected ? 'P' : '-', queueFamily.timestampValidBits, queueFamily.minImageTransferGranularity.width, queueFamily.minImageTransferGranularity.height, queueFamily.minImageTransferGranularity.depth, familyIndex++ == vkQueueFamilyIndex ? " <--" : "");
auto properties{deviceProperties2.get<vk::PhysicalDeviceProperties2>().properties}; auto properties{deviceProperties2.get<vk::PhysicalDeviceProperties2>().properties};
Logger::Info("Vulkan Device:\nName: {}\nType: {}\nVulkan Version: {}.{}.{}\nDriver Version: {}.{}.{}\nQueues:{}\nExtensions:{}\nQuirks:{}", Logger::Info("Vulkan Device:\nName: {}\nType: {}\nVulkan Version: {}.{}.{}\nDriver Version: {}.{}.{}\nQueues:{}\nExtensions:{}\nTraits:{}",
properties.deviceName, vk::to_string(properties.deviceType), properties.deviceName, vk::to_string(properties.deviceType),
VK_API_VERSION_MAJOR(properties.apiVersion), VK_API_VERSION_MINOR(properties.apiVersion), VK_API_VERSION_PATCH(properties.apiVersion), VK_API_VERSION_MAJOR(properties.apiVersion), VK_API_VERSION_MINOR(properties.apiVersion), VK_API_VERSION_PATCH(properties.apiVersion),
VK_API_VERSION_MAJOR(properties.driverVersion), VK_API_VERSION_MINOR(properties.driverVersion), VK_API_VERSION_PATCH(properties.driverVersion), VK_API_VERSION_MAJOR(properties.driverVersion), VK_API_VERSION_MINOR(properties.driverVersion), VK_API_VERSION_PATCH(properties.driverVersion),
queueString, extensionString, quirks.Summary()); queueString, extensionString, traits.Summary());
} }
return vk::raii::Device(physicalDevice, vk::DeviceCreateInfo{ return vk::raii::Device(physicalDevice, vk::DeviceCreateInfo{
@ -211,7 +211,7 @@ namespace skyline::gpu {
: vkInstance(CreateInstance(state, vkContext)), : vkInstance(CreateInstance(state, vkContext)),
vkDebugReportCallback(CreateDebugReportCallback(vkInstance)), vkDebugReportCallback(CreateDebugReportCallback(vkInstance)),
vkPhysicalDevice(CreatePhysicalDevice(vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(vkInstance)),
vkDevice(CreateDevice(vkContext, vkPhysicalDevice, vkQueueFamilyIndex, quirks)), vkDevice(CreateDevice(vkContext, vkPhysicalDevice, vkQueueFamilyIndex, traits)),
vkQueue(vkDevice, vkQueueFamilyIndex, 0), vkQueue(vkDevice, vkQueueFamilyIndex, 0),
memory(*this), memory(*this),
scheduler(*this), scheduler(*this),

View File

@ -3,7 +3,7 @@
#pragma once #pragma once
#include "gpu/quirk_manager.h" #include "gpu/trait_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"
@ -25,7 +25,7 @@ namespace skyline::gpu {
vk::raii::DebugReportCallbackEXT vkDebugReportCallback; //!< An RAII Vulkan debug report manager which calls into 'GPU::DebugCallback' vk::raii::DebugReportCallbackEXT vkDebugReportCallback; //!< An RAII Vulkan debug report manager which calls into 'GPU::DebugCallback'
vk::raii::PhysicalDevice vkPhysicalDevice; vk::raii::PhysicalDevice vkPhysicalDevice;
u32 vkQueueFamilyIndex{}; u32 vkQueueFamilyIndex{};
QuirkManager quirks; TraitManager traits;
vk::raii::Device vkDevice; vk::raii::Device vkDevice;
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

View File

@ -67,7 +67,7 @@ namespace skyline::gpu::interconnect {
for (auto &rtBlendState : independentRtBlendState) for (auto &rtBlendState : independentRtBlendState)
rtBlendState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA; rtBlendState.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
if (!gpu.quirks.supportsLastProvokingVertex) if (!gpu.traits.supportsLastProvokingVertex)
rasterizerState.unlink<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>(); rasterizerState.unlink<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>();
} }
@ -1121,7 +1121,7 @@ namespace skyline::gpu::interconnect {
void SetProvokingVertex(bool isLast) { void SetProvokingVertex(bool isLast) {
if (isLast) { if (isLast) {
if (!gpu.quirks.supportsLastProvokingVertex) if (!gpu.traits.supportsLastProvokingVertex)
Logger::Warn("Cannot set provoking vertex to last without host GPU support"); Logger::Warn("Cannot set provoking vertex to last without host GPU support");
rasterizerState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = vk::ProvokingVertexModeEXT::eLastVertex; rasterizerState.get<vk::PipelineRasterizationProvokingVertexStateCreateInfoEXT>().provokingVertexMode = vk::ProvokingVertexModeEXT::eLastVertex;
} else { } else {
@ -1167,7 +1167,7 @@ namespace skyline::gpu::interconnect {
public: public:
void SetBlendLogicOpEnable(bool enabled) { void SetBlendLogicOpEnable(bool enabled) {
if (!gpu.quirks.supportsLogicOp && enabled) { if (!gpu.traits.supportsLogicOp && enabled) {
Logger::Warn("Cannot enable framebuffer logical operation without host GPU support"); Logger::Warn("Cannot enable framebuffer logical operation without host GPU support");
return; return;
} }
@ -1468,9 +1468,9 @@ namespace skyline::gpu::interconnect {
} }
void SetVertexBufferDivisor(u32 index, u32 divisor) { void SetVertexBufferDivisor(u32 index, u32 divisor) {
if (!gpu.quirks.supportsVertexAttributeDivisor) if (!gpu.traits.supportsVertexAttributeDivisor)
Logger::Warn("Cannot set vertex attribute divisor without host GPU support"); Logger::Warn("Cannot set vertex attribute divisor without host GPU support");
else if (divisor == 0 && !gpu.quirks.supportsVertexAttributeZeroDivisor) else if (divisor == 0 && !gpu.traits.supportsVertexAttributeZeroDivisor)
Logger::Warn("Cannot set vertex attribute divisor to zero without host GPU support"); Logger::Warn("Cannot set vertex attribute divisor to zero without host GPU support");
vertexBuffers[index].bindingDivisorDescription.divisor = divisor; vertexBuffers[index].bindingDivisorDescription.divisor = divisor;
} }
@ -2007,7 +2007,7 @@ namespace skyline::gpu::interconnect {
auto convertAddressModeWithCheck{[&](TextureSamplerControl::AddressMode mode) { auto convertAddressModeWithCheck{[&](TextureSamplerControl::AddressMode mode) {
auto vkMode{ConvertSamplerAddressMode(mode)}; auto vkMode{ConvertSamplerAddressMode(mode)};
if (vkMode == vk::SamplerAddressMode::eMirrorClampToEdge && !gpu.quirks.supportsSamplerMirrorClampToEdge) [[unlikely]] { if (vkMode == vk::SamplerAddressMode::eMirrorClampToEdge && !gpu.traits.supportsSamplerMirrorClampToEdge) [[unlikely]] {
Logger::Warn("Cannot use Mirror Clamp To Edge as Sampler Address Mode without host GPU support"); Logger::Warn("Cannot use Mirror Clamp To Edge as Sampler Address Mode without host GPU support");
return vk::SamplerAddressMode::eClampToEdge; // We use a normal clamp to edge to approximate it return vk::SamplerAddressMode::eClampToEdge; // We use a normal clamp to edge to approximate it
} }
@ -2039,11 +2039,11 @@ namespace skyline::gpu::interconnect {
}, },
}; };
if (!gpu.quirks.supportsSamplerReductionMode) if (!gpu.traits.supportsSamplerReductionMode)
samplerInfo.unlink<vk::SamplerReductionModeCreateInfoEXT>(); samplerInfo.unlink<vk::SamplerReductionModeCreateInfoEXT>();
vk::BorderColor &borderColor{samplerInfo.get<vk::SamplerCreateInfo>().borderColor}; vk::BorderColor &borderColor{samplerInfo.get<vk::SamplerCreateInfo>().borderColor};
if (gpu.quirks.supportsCustomBorderColor) { if (gpu.traits.supportsCustomBorderColor) {
borderColor = ConvertBorderColorWithCustom(samplerControl.borderColorR, samplerControl.borderColorG, samplerControl.borderColorB, samplerControl.borderColorA); borderColor = ConvertBorderColorWithCustom(samplerControl.borderColorR, samplerControl.borderColorG, samplerControl.borderColorB, samplerControl.borderColorA);
if (borderColor != vk::BorderColor::eFloatCustomEXT) if (borderColor != vk::BorderColor::eFloatCustomEXT)
samplerInfo.unlink<vk::SamplerCustomBorderColorCreateInfoEXT>(); samplerInfo.unlink<vk::SamplerCustomBorderColorCreateInfoEXT>();
@ -2090,7 +2090,7 @@ namespace skyline::gpu::interconnect {
} }
}(); }();
if (indexBuffer.type == vk::IndexType::eUint8EXT && !gpu.quirks.supportsUint8Indices) if (indexBuffer.type == vk::IndexType::eUint8EXT && !gpu.traits.supportsUint8Indices)
throw exception("Cannot use U8 index buffer without host GPU support"); throw exception("Cannot use U8 index buffer without host GPU support");
indexBuffer.view.reset(); indexBuffer.view.reset();
@ -2395,7 +2395,7 @@ namespace skyline::gpu::interconnect {
auto storage{std::make_shared<Storage>(std::move(pipelineLayout), std::move(descriptorSet))}; auto storage{std::make_shared<Storage>(std::move(pipelineLayout), std::move(descriptorSet))};
// Submit Draw // Submit Draw
executor.AddSubpass([=, &vkDevice = gpu.vkDevice, shaderModules = programState.shaderModules, shaderStages = programState.shaderStages, inputAssemblyState = inputAssemblyState, multiViewport = gpu.quirks.supportsMultipleViewports, viewports = viewports, scissors = scissors, rasterizerState = rasterizerState, multisampleState = multisampleState, depthState = depthState, blendState = blendState, storage = std::move(storage), supportsVertexAttributeDivisor = gpu.quirks.supportsVertexAttributeDivisor, vertexBufferHandles = std::move(vertexBufferHandles), vertexBufferOffsets = std::move(vertexBufferOffsets), pipelineCache = *pipelineCache](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &, vk::RenderPass renderPass, u32 subpassIndex) mutable { executor.AddSubpass([=, &vkDevice = gpu.vkDevice, shaderModules = programState.shaderModules, shaderStages = programState.shaderStages, inputAssemblyState = inputAssemblyState, multiViewport = gpu.traits.supportsMultipleViewports, viewports = viewports, scissors = scissors, rasterizerState = rasterizerState, multisampleState = multisampleState, depthState = depthState, blendState = blendState, storage = std::move(storage), supportsVertexAttributeDivisor = gpu.traits.supportsVertexAttributeDivisor, vertexBufferHandles = std::move(vertexBufferHandles), vertexBufferOffsets = std::move(vertexBufferOffsets), pipelineCache = *pipelineCache](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &, vk::RenderPass renderPass, u32 subpassIndex) mutable {
vk::StructureChain<vk::PipelineVertexInputStateCreateInfo, vk::PipelineVertexInputDivisorStateCreateInfoEXT> vertexState{ vk::StructureChain<vk::PipelineVertexInputStateCreateInfo, vk::PipelineVertexInputDivisorStateCreateInfoEXT> vertexState{
vk::PipelineVertexInputStateCreateInfo{ vk::PipelineVertexInputStateCreateInfo{
.pVertexBindingDescriptions = vertexBindingDescriptions.data(), .pVertexBindingDescriptions = vertexBindingDescriptions.data(),

View File

@ -24,42 +24,42 @@ namespace Shader::Log {
namespace skyline::gpu { namespace skyline::gpu {
ShaderManager::ShaderManager(const DeviceState &state, GPU &gpu) : gpu(gpu) { ShaderManager::ShaderManager(const DeviceState &state, GPU &gpu) : gpu(gpu) {
auto &quirks{gpu.quirks}; auto &traits{gpu.traits};
hostTranslateInfo = Shader::HostTranslateInfo{ hostTranslateInfo = Shader::HostTranslateInfo{
.support_float16 = quirks.supportsFloat16, .support_float16 = traits.supportsFloat16,
.support_int64 = quirks.supportsInt64, .support_int64 = traits.supportsInt64,
.needs_demote_reorder = false, .needs_demote_reorder = false,
}; };
constexpr u32 TegraX1WarpSize{32}; //!< The amount of threads in a warp on the Tegra X1 constexpr u32 TegraX1WarpSize{32}; //!< The amount of threads in a warp on the Tegra X1
profile = Shader::Profile{ profile = Shader::Profile{
.supported_spirv = quirks.supportsSpirv14 ? 0x00010400U : 0x00010000U, .supported_spirv = traits.supportsSpirv14 ? 0x00010400U : 0x00010000U,
.unified_descriptor_binding = true, .unified_descriptor_binding = true,
.support_descriptor_aliasing = true, .support_descriptor_aliasing = true,
.support_int8 = quirks.supportsInt8, .support_int8 = traits.supportsInt8,
.support_int16 = quirks.supportsInt16, .support_int16 = traits.supportsInt16,
.support_int64 = quirks.supportsInt64, .support_int64 = traits.supportsInt64,
.support_vertex_instance_id = false, .support_vertex_instance_id = false,
.support_float_controls = quirks.supportsFloatControls, .support_float_controls = traits.supportsFloatControls,
.support_separate_denorm_behavior = quirks.floatControls.denormBehaviorIndependence == vk::ShaderFloatControlsIndependence::eAll, .support_separate_denorm_behavior = traits.floatControls.denormBehaviorIndependence == vk::ShaderFloatControlsIndependence::eAll,
.support_separate_rounding_mode = quirks.floatControls.roundingModeIndependence == vk::ShaderFloatControlsIndependence::eAll, .support_separate_rounding_mode = traits.floatControls.roundingModeIndependence == vk::ShaderFloatControlsIndependence::eAll,
.support_fp16_denorm_preserve = static_cast<bool>(quirks.floatControls.shaderDenormPreserveFloat16), .support_fp16_denorm_preserve = static_cast<bool>(traits.floatControls.shaderDenormPreserveFloat16),
.support_fp32_denorm_preserve = static_cast<bool>(quirks.floatControls.shaderDenormPreserveFloat32), .support_fp32_denorm_preserve = static_cast<bool>(traits.floatControls.shaderDenormPreserveFloat32),
.support_fp16_denorm_flush = static_cast<bool>(quirks.floatControls.shaderDenormFlushToZeroFloat16), .support_fp16_denorm_flush = static_cast<bool>(traits.floatControls.shaderDenormFlushToZeroFloat16),
.support_fp32_denorm_flush = static_cast<bool>(quirks.floatControls.shaderDenormFlushToZeroFloat32), .support_fp32_denorm_flush = static_cast<bool>(traits.floatControls.shaderDenormFlushToZeroFloat32),
.support_fp16_signed_zero_nan_preserve = static_cast<bool>(quirks.floatControls.shaderSignedZeroInfNanPreserveFloat16), .support_fp16_signed_zero_nan_preserve = static_cast<bool>(traits.floatControls.shaderSignedZeroInfNanPreserveFloat16),
.support_fp32_signed_zero_nan_preserve = static_cast<bool>(quirks.floatControls.shaderSignedZeroInfNanPreserveFloat32), .support_fp32_signed_zero_nan_preserve = static_cast<bool>(traits.floatControls.shaderSignedZeroInfNanPreserveFloat32),
.support_fp64_signed_zero_nan_preserve = static_cast<bool>(quirks.floatControls.shaderSignedZeroInfNanPreserveFloat64), .support_fp64_signed_zero_nan_preserve = static_cast<bool>(traits.floatControls.shaderSignedZeroInfNanPreserveFloat64),
.support_explicit_workgroup_layout = false, .support_explicit_workgroup_layout = false,
.support_vote = quirks.supportsSubgroupVote, .support_vote = traits.supportsSubgroupVote,
.support_viewport_index_layer_non_geometry = quirks.supportsShaderViewportIndexLayer, .support_viewport_index_layer_non_geometry = traits.supportsShaderViewportIndexLayer,
.support_viewport_mask = false, .support_viewport_mask = false,
.support_typeless_image_loads = quirks.supportsImageReadWithoutFormat, .support_typeless_image_loads = traits.supportsImageReadWithoutFormat,
.support_demote_to_helper_invocation = quirks.supportsShaderDemoteToHelper, .support_demote_to_helper_invocation = traits.supportsShaderDemoteToHelper,
.support_int64_atomics = quirks.supportsAtomicInt64, .support_int64_atomics = traits.supportsAtomicInt64,
.support_derivative_control = true, .support_derivative_control = true,
.support_geometry_shader_passthrough = false, .support_geometry_shader_passthrough = false,
.warp_size_potentially_larger_than_guest = TegraX1WarpSize < quirks.subgroupSize, .warp_size_potentially_larger_than_guest = TegraX1WarpSize < traits.subgroupSize,
.lower_left_origin_mode = false, .lower_left_origin_mode = false,
.need_declared_frag_colors = false, .need_declared_frag_colors = false,
}; };

View File

@ -2,10 +2,10 @@
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) // Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <adrenotools/bcenabler.h> #include <adrenotools/bcenabler.h>
#include "quirk_manager.h" #include "trait_manager.h"
namespace skyline::gpu { namespace skyline::gpu {
QuirkManager::QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2) { TraitManager::TraitManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2) {
bool hasCustomBorderColorExtension{}, hasShaderAtomicInt64{}, hasShaderFloat16Int8Ext{}, hasShaderDemoteToHelper{}; bool hasCustomBorderColorExtension{}, hasShaderAtomicInt64{}, hasShaderFloat16Int8Ext{}, hasShaderDemoteToHelper{};
bool supportsUniformBufferStandardLayout{}; // We require VK_KHR_uniform_buffer_standard_layout but assume it is implicitly supported even when not present bool supportsUniformBufferStandardLayout{}; // We require VK_KHR_uniform_buffer_standard_layout but assume it is implicitly supported even when not present
@ -114,7 +114,14 @@ namespace skyline::gpu {
subgroupSize = deviceProperties2.get<vk::PhysicalDeviceSubgroupProperties>().subgroupSize; subgroupSize = deviceProperties2.get<vk::PhysicalDeviceSubgroupProperties>().subgroupSize;
} }
void QuirkManager::ApplyDriverPatches(const vk::raii::Context &context) { std::string TraitManager::Summary() {
return fmt::format(
"\n* Supports U8 Indices: {}\n* Supports Sampler Mirror Clamp To Edge: {}\n* Supports Sampler Reduction Mode: {}\n* Supports Custom Border Color (Without Format): {}\n* Supports Last Provoking Vertex: {}\n* Supports Logical Operations: {}\n* Supports Vertex Attribute Divisor: {}\n* Supports Vertex Attribute Zero Divisor: {}\n* Supports Multiple Viewports: {}\n* Supports Shader Viewport Index: {}\n* Supports SPIR-V 1.4: {}\n* Supports Shader Invocation Demotion: {}\n* Supports 16-bit FP: {}\n* Supports 8-bit Integers: {}\n* Supports 16-bit Integers: {}\n* Supports 64-bit Integers: {}\n* Supports Atomic 64-bit Integers: {}\n* Supports Floating Point Behavior Control: {}\n* Supports Image Read Without Format: {}\n* Supports Subgroup Vote: {}\n* Subgroup Size: {}",
supportsUint8Indices, supportsSamplerMirrorClampToEdge, supportsSamplerReductionMode, supportsCustomBorderColor, supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports, supportsShaderViewportIndexLayer, supportsSpirv14, supportsShaderDemoteToHelper, supportsFloat16, supportsInt8, supportsInt16, supportsInt64, supportsAtomicInt64, supportsFloatControls, supportsImageReadWithoutFormat, supportsSubgroupVote, subgroupSize
);
}
void TraitManager::ApplyDriverPatches(const vk::raii::Context &context) {
// Create an instance without validation layers in order to get pointers to the functions we need to patch from the driver // Create an instance without validation layers in order to get pointers to the functions we need to patch from the driver
vk::ApplicationInfo applicationInfo{ vk::ApplicationInfo applicationInfo{
.apiVersion = VK_API_VERSION_1_0, .apiVersion = VK_API_VERSION_1_0,
@ -128,7 +135,7 @@ namespace skyline::gpu {
auto properties{physicalDevice.getProperties()}; auto properties{physicalDevice.getProperties()};
// Apply BCeNabler for Adreno devices // Apply BCeNabler for Adreno devices
auto type{adrenotools_get_bcn_type( VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion), properties.vendorID)}; auto type{adrenotools_get_bcn_type(VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion), properties.vendorID)};
if (type == ADRENOTOOLS_BCN_PATCH) { if (type == ADRENOTOOLS_BCN_PATCH) {
if (adrenotools_patch_bcn(reinterpret_cast<void *>(physicalDevice.getDispatcher()->vkGetPhysicalDeviceFormatProperties))) if (adrenotools_patch_bcn(reinterpret_cast<void *>(physicalDevice.getDispatcher()->vkGetPhysicalDeviceFormatProperties)))
Logger::Info("Applied BCeNabler patch"); Logger::Info("Applied BCeNabler patch");
@ -138,11 +145,4 @@ namespace skyline::gpu {
Logger::Info("BCeNabler skipped, blob BCN support is present"); Logger::Info("BCeNabler skipped, blob BCN support is present");
} }
} }
std::string QuirkManager::Summary() {
return fmt::format(
"\n* Supports U8 Indices: {}\n* Supports Sampler Mirror Clamp To Edge: {}\n* Supports Sampler Reduction Mode: {}\n* Supports Custom Border Color (Without Format): {}\n* Supports Last Provoking Vertex: {}\n* Supports Logical Operations: {}\n* Supports Vertex Attribute Divisor: {}\n* Supports Vertex Attribute Zero Divisor: {}\n* Supports Multiple Viewports: {}\n* Supports Shader Viewport Index: {}\n* Supports SPIR-V 1.4: {}\n* Supports Shader Invocation Demotion: {}\n* Supports 16-bit FP: {}\n* Supports 8-bit Integers: {}\n* Supports 16-bit Integers: {}\n* Supports 64-bit Integers: {}\n* Supports Atomic 64-bit Integers: {}\n* Supports Floating Point Behavior Control: {}\n* Supports Image Read Without Format: {}\n* Supports Subgroup Vote: {}\n* Subgroup Size: {}",
supportsUint8Indices, supportsSamplerMirrorClampToEdge, supportsSamplerReductionMode, supportsCustomBorderColor, supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports, supportsShaderViewportIndexLayer, supportsSpirv14, supportsShaderDemoteToHelper, supportsFloat16, supportsInt8, supportsInt16, supportsInt64, supportsAtomicInt64, supportsFloatControls, supportsImageReadWithoutFormat, supportsSubgroupVote, subgroupSize
);
}
} }

View File

@ -8,9 +8,9 @@
namespace skyline::gpu { namespace skyline::gpu {
/** /**
* @brief Checks and stores all the quirks of the host GPU discovered at runtime * @brief Checks and stores all the traits of the host GPU discovered at runtime
*/ */
class QuirkManager { class TraitManager {
public: public:
bool supportsUint8Indices{}; //!< If the device supports using uint8 indices in index buffers (with VK_EXT_index_type_uint8) bool supportsUint8Indices{}; //!< If the device supports using uint8 indices in index buffers (with VK_EXT_index_type_uint8)
bool supportsSamplerMirrorClampToEdge{}; //!< If the device supports a mirrored clamp to edge as a sampler address mode (with VK_KHR_sampler_mirror_clamp_to_edge) bool supportsSamplerMirrorClampToEdge{}; //!< If the device supports a mirrored clamp to edge as a sampler address mode (with VK_KHR_sampler_mirror_clamp_to_edge)
@ -35,13 +35,13 @@ namespace skyline::gpu {
bool supportsSubgroupVote{}; //!< If subgroup votes are supported in shaders with SPV_KHR_subgroup_vote bool supportsSubgroupVote{}; //!< If subgroup votes are supported in shaders with SPV_KHR_subgroup_vote
u32 subgroupSize{}; //!< Size of a subgroup on the host GPU u32 subgroupSize{}; //!< Size of a subgroup on the host GPU
QuirkManager() = default; TraitManager() = default;
using DeviceProperties2 = vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>; using DeviceProperties2 = vk::StructureChain<vk::PhysicalDeviceProperties2, vk::PhysicalDeviceFloatControlsProperties, vk::PhysicalDeviceSubgroupProperties>;
using DeviceFeatures2 = vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features, vk::PhysicalDeviceUniformBufferStandardLayoutFeatures>; using DeviceFeatures2 = vk::StructureChain<vk::PhysicalDeviceFeatures2, vk::PhysicalDeviceCustomBorderColorFeaturesEXT, vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vk::PhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT, vk::PhysicalDeviceShaderFloat16Int8Features, vk::PhysicalDeviceShaderAtomicInt64Features, vk::PhysicalDeviceUniformBufferStandardLayoutFeatures>;
QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2); TraitManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector<vk::ExtensionProperties> &deviceExtensions, std::vector<std::array<char, VK_MAX_EXTENSION_NAME_SIZE>> &enabledExtensions, const DeviceProperties2 &deviceProperties2);
/** /**
* @brief Applies driver specific binary patches to the driver (e.g. BCeNabler) * @brief Applies driver specific binary patches to the driver (e.g. BCeNabler)
@ -49,7 +49,7 @@ namespace skyline::gpu {
void ApplyDriverPatches(const vk::raii::Context &context); void ApplyDriverPatches(const vk::raii::Context &context);
/** /**
* @return A summary of all the GPU quirks as a human-readable string * @return A summary of all the GPU traits as a human-readable string
*/ */
std::string Summary(); std::string Summary();
}; };