diff --git a/app/src/main/cpp/skyline/gpu.cpp b/app/src/main/cpp/skyline/gpu.cpp index 6d190d67..5630cb49 100644 --- a/app/src/main/cpp/skyline/gpu.cpp +++ b/app/src/main/cpp/skyline/gpu.cpp @@ -122,7 +122,7 @@ namespace skyline::gpu { vk::raii::Device GPU::CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) { auto properties{physicalDevice.getProperties()}; - auto deviceFeatures2{physicalDevice.getFeatures2()}; + auto deviceFeatures2{physicalDevice.getFeatures2()}; decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features #define FEAT_REQ(structName, feature) \ @@ -202,5 +202,5 @@ namespace skyline::gpu { }); } - 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), shader(state) {} + 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), shader(state, *this) {} } diff --git a/app/src/main/cpp/skyline/gpu/quirk_manager.cpp b/app/src/main/cpp/skyline/gpu/quirk_manager.cpp index 159032fe..8b91c6f1 100644 --- a/app/src/main/cpp/skyline/gpu/quirk_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/quirk_manager.cpp @@ -5,6 +5,8 @@ namespace skyline::gpu { QuirkManager::QuirkManager(const vk::PhysicalDeviceProperties &properties, const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector &deviceExtensions, std::vector> &enabledExtensions) { + bool hasShaderAtomicInt64{}, hasShaderFloat16Int8Ext{}; + for (auto &extension : deviceExtensions) { #define EXT_SET(name, property) \ case util::Hash(name): \ @@ -27,6 +29,10 @@ namespace skyline::gpu { switch (util::Hash(extensionName)) { EXT_SET("VK_EXT_provoking_vertex", supportsLastProvokingVertex); EXT_SET("VK_EXT_vertex_attribute_divisor", supportsVertexAttributeDivisor); + EXT_SET("VK_KHR_spirv_1_4", supportsSpirv14); + EXT_SET("VK_KHR_shader_atomic_int64", hasShaderAtomicInt64); + EXT_SET("VK_KHR_shader_float16_int8", hasShaderFloat16Int8Ext); + EXT_SET("VK_KHR_shader_float_controls", supportsFloatControls); } #undef EXT_SET @@ -41,6 +47,9 @@ namespace skyline::gpu { FEAT_SET(vk::PhysicalDeviceFeatures2, features.logicOp, supportsLogicOp) FEAT_SET(vk::PhysicalDeviceFeatures2, features.multiViewport, supportsMultipleViewports) + FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderInt16, supportsInt16) + FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderInt64, supportsInt64) + FEAT_SET(vk::PhysicalDeviceFeatures2, features.shaderStorageImageReadWithoutFormat, supportsImageReadWithoutFormat) if (supportsVertexAttributeDivisor) { FEAT_SET(vk::PhysicalDeviceVertexAttributeDivisorFeaturesEXT, vertexAttributeInstanceRateDivisor, supportsVertexAttributeDivisor) @@ -49,10 +58,24 @@ namespace skyline::gpu { enabledFeatures2.unlink(); } + auto& shaderAtomicFeatures{deviceFeatures2.get()}; + if (hasShaderAtomicInt64 && shaderAtomicFeatures.shaderBufferInt64Atomics && shaderAtomicFeatures.shaderSharedInt64Atomics) { + supportsAtomicInt64 = true; + } else { + enabledFeatures2.unlink(); + } + + if (hasShaderFloat16Int8Ext) { + FEAT_SET(vk::PhysicalDeviceShaderFloat16Int8Features, shaderFloat16, supportsFloat16) + FEAT_SET(vk::PhysicalDeviceShaderFloat16Int8Features, shaderInt8, supportsInt8) + } else { + enabledFeatures2.unlink(); + } + #undef FEAT_SET } std::string QuirkManager::Summary() { - return fmt::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: {}", supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports); + return fmt::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 SPIR-V 1.4: {}\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: {}", supportsLastProvokingVertex, supportsLogicOp, supportsVertexAttributeDivisor, supportsVertexAttributeZeroDivisor, supportsMultipleViewports, supportsSpirv14, supportsFloat16, supportsInt8, supportsInt16, supportsInt64, supportsAtomicInt64, supportsFloatControls, supportsImageReadWithoutFormat); } } diff --git a/app/src/main/cpp/skyline/gpu/quirk_manager.h b/app/src/main/cpp/skyline/gpu/quirk_manager.h index 7841f169..e08b2e78 100644 --- a/app/src/main/cpp/skyline/gpu/quirk_manager.h +++ b/app/src/main/cpp/skyline/gpu/quirk_manager.h @@ -17,10 +17,18 @@ namespace skyline::gpu { bool supportsVertexAttributeDivisor{}; //!< If the device supports a divisor for instance-rate vertex attributes (with VK_EXT_vertex_attribute_divisor) bool supportsVertexAttributeZeroDivisor{}; //!< If the device supports a zero divisor for instance-rate vertex attributes (with VK_EXT_vertex_attribute_divisor) bool supportsMultipleViewports{}; //!< If the device supports more than one viewport + bool supportsSpirv14{}; //!< If SPIR-V 1.4 is supported (with VK_KHR_spirv_1_4) + bool supportsFloat16{}; //!< If 16-bit floating point integers are supported in shaders + bool supportsInt8{}; //!< If 8-bit integers are supported in shaders + bool supportsInt16{}; //!< If 16-bit integers are supported in shaders + bool supportsInt64{}; //!< If 64-bit integers are supported in shaders + bool supportsAtomicInt64{}; //!< If atomic operations on 64-bit integers are supported in shaders + bool supportsFloatControls{}; //!< If extensive control over FP behavior is exposed (with VK_KHR_shader_float_controls) + bool supportsImageReadWithoutFormat{}; //!< If a storage image can be read without a format QuirkManager() = default; - using DeviceFeatures2 = vk::StructureChain; + using DeviceFeatures2 = vk::StructureChain; QuirkManager(const vk::PhysicalDeviceProperties &properties, const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector &deviceExtensions, std::vector> &enabledExtensions); diff --git a/app/src/main/cpp/skyline/gpu/shader_manager.cpp b/app/src/main/cpp/skyline/gpu/shader_manager.cpp index ba4ac297..448b1a38 100644 --- a/app/src/main/cpp/skyline/gpu/shader_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/shader_manager.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) +#include #include #include #include "shader_manager.h" @@ -20,7 +21,37 @@ namespace Shader::Log { } namespace skyline::gpu { - ShaderManager::ShaderManager(const DeviceState &state) { + ShaderManager::ShaderManager(const DeviceState &state, GPU &gpu) : gpu(gpu) { + auto& quirks{gpu.quirks}; + hostTranslateInfo = Shader::HostTranslateInfo{ + .support_float16 = quirks.supportsFloat16, + .support_int64 = quirks.supportsInt64, + .needs_demote_reorder = false, + }; + + profile = Shader::Profile{ + .supported_spirv = quirks.supportsSpirv14 ? 0x00010400U : 0x00010000U, + .unified_descriptor_binding = true, + .support_descriptor_aliasing = true, + .support_int8 = quirks.supportsInt8, + .support_int16 = quirks.supportsInt16, + .support_int64 = quirks.supportsInt64, + .support_vertex_instance_id = false, + .support_float_controls = quirks.supportsFloatControls, + // TODO: Float control specifics + .support_vote = true, + .support_viewport_index_layer_non_geometry = false, + .support_viewport_mask = false, + .support_typeless_image_loads = quirks.supportsImageReadWithoutFormat, + .support_demote_to_helper_invocation = true, + .support_int64_atomics = false, + .support_derivative_control = true, + .support_geometry_shader_passthrough = false, + // TODO: Warp size property + .lower_left_origin_mode = false, + .need_declared_frag_colors = false, + }; + Shader::Settings::values = { .disable_shader_loop_safety_checks = false, .renderer_debug = true, diff --git a/app/src/main/cpp/skyline/gpu/shader_manager.h b/app/src/main/cpp/skyline/gpu/shader_manager.h index 7c78d798..06d775d0 100644 --- a/app/src/main/cpp/skyline/gpu/shader_manager.h +++ b/app/src/main/cpp/skyline/gpu/shader_manager.h @@ -4,6 +4,8 @@ #pragma once #include +#include +#include #include namespace skyline::gpu { @@ -11,7 +13,12 @@ namespace skyline::gpu { * @brief The Shader Manager is responsible for caching and looking up shaders alongside handling compilation of shaders when not found in any cache */ class ShaderManager { + private: + GPU &gpu; + Shader::HostTranslateInfo hostTranslateInfo; + Shader::Profile profile; + public: - ShaderManager(const DeviceState& state); + ShaderManager(const DeviceState& state, GPU &gpu); }; }