From 175ba11f0759196e257d6e093c2a923d1a229dbb Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 12 Jan 2022 20:45:05 +0000 Subject: [PATCH] Integrate BCeNabler support into QuirkManager Allows using BCn format textures on devices where they are unsupported by the driver. --- .gitmodules | 8 ++++++ app/CMakeLists.txt | 5 +++- app/libraries/adrenotools | 1 + app/src/main/cpp/skyline/gpu.cpp | 8 ++++-- app/src/main/cpp/skyline/gpu.h | 4 +-- .../main/cpp/skyline/gpu/memory_manager.cpp | 2 +- .../main/cpp/skyline/gpu/quirk_manager.cpp | 26 +++++++++++++++++++ app/src/main/cpp/skyline/gpu/quirk_manager.h | 7 ++++- 8 files changed, 54 insertions(+), 7 deletions(-) create mode 160000 app/libraries/adrenotools diff --git a/.gitmodules b/.gitmodules index 4dd238f3..6b96dbce 100644 --- a/.gitmodules +++ b/.gitmodules @@ -51,3 +51,11 @@ [submodule "Shader Compiler"] path = app/libraries/shader-compiler url = https://github.com/skyline-emu/shader-compiler.git +[submodule "libadrenotools"] + path = app/libraries/adrenotools + url = https://github.com/bylaws/libadrenotools/ + branch = master +[submodule "app/libraries/adrenotools"] + path = app/libraries/adrenotools + url = https://github.com/bylaws/libadrenotools/ + branch = master diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index ab2eecdc..a4ee15bc 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -104,6 +104,9 @@ add_subdirectory("libraries/range") # Sirit add_subdirectory("libraries/sirit") +# libadrenotools +add_subdirectory("libraries/adrenotools") + # Build Skyline with full debugging data and -Og for debug builds set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3 -glldb -gdwarf-5") @@ -305,4 +308,4 @@ target_include_directories(skyline PRIVATE ${source_DIR}/skyline) target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field -Wno-dangling-else -Wconversion -fsigned-bitfields) target_link_libraries(skyline PRIVATE shader_recompiler) -target_link_libraries_system(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::intrusive Boost::container range-v3) +target_link_libraries_system(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::intrusive Boost::container range-v3 adrenotools) diff --git a/app/libraries/adrenotools b/app/libraries/adrenotools new file mode 160000 index 00000000..526ed967 --- /dev/null +++ b/app/libraries/adrenotools @@ -0,0 +1 @@ +Subproject commit 526ed96751ab7c83959e51ecf594f004341a7ae8 diff --git a/app/src/main/cpp/skyline/gpu.cpp b/app/src/main/cpp/skyline/gpu.cpp index 164ec9dd..b5729066 100644 --- a/app/src/main/cpp/skyline/gpu.cpp +++ b/app/src/main/cpp/skyline/gpu.cpp @@ -119,7 +119,10 @@ namespace skyline::gpu { return std::move(vk::raii::PhysicalDevices(instance).front()); // We just select the first device as we aren't expecting multiple GPUs } - static vk::raii::Device CreateDevice(const vk::raii::PhysicalDevice &physicalDevice, decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, QuirkManager &quirks) { + static vk::raii::Device CreateDevice(const vk::raii::Context &context, + const vk::raii::PhysicalDevice &physicalDevice, + decltype(vk::DeviceQueueCreateInfo::queueCount) &vkQueueFamilyIndex, + QuirkManager &quirks) { auto deviceFeatures2{physicalDevice.getFeatures2()}; decltype(deviceFeatures2) enabledFeatures2{}; // We only want to enable features we required due to potential overhead from unused features @@ -152,6 +155,7 @@ namespace skyline::gpu { auto deviceProperties2{physicalDevice.getProperties2()}; quirks = QuirkManager(deviceFeatures2, enabledFeatures2, deviceExtensions, enabledExtensions, deviceProperties2); + quirks.ApplyDriverPatches(context); std::vector pEnabledExtensions; pEnabledExtensions.reserve(enabledExtensions.size()); @@ -207,7 +211,7 @@ namespace skyline::gpu { : vkInstance(CreateInstance(state, vkContext)), vkDebugReportCallback(CreateDebugReportCallback(vkInstance)), vkPhysicalDevice(CreatePhysicalDevice(vkInstance)), - vkDevice(CreateDevice(vkPhysicalDevice, vkQueueFamilyIndex, quirks)), + vkDevice(CreateDevice(vkContext, vkPhysicalDevice, vkQueueFamilyIndex, quirks)), vkQueue(vkDevice, vkQueueFamilyIndex, 0), memory(*this), scheduler(*this), diff --git a/app/src/main/cpp/skyline/gpu.h b/app/src/main/cpp/skyline/gpu.h index 4153cae6..e5445304 100644 --- a/app/src/main/cpp/skyline/gpu.h +++ b/app/src/main/cpp/skyline/gpu.h @@ -13,13 +13,13 @@ #include "gpu/shader_manager.h" namespace skyline::gpu { + static constexpr u32 VkApiVersion{VK_API_VERSION_1_1}; //!< The version of core Vulkan that we require + /** * @brief An interface to host GPU structures, anything concerning host GPU/Presentation APIs is encapsulated by this */ class GPU { public: - static constexpr u32 VkApiVersion{VK_API_VERSION_1_1}; //!< The version of core Vulkan that we require - vk::raii::Context vkContext; vk::raii::Instance vkInstance; vk::raii::DebugReportCallbackEXT vkDebugReportCallback; //!< An RAII Vulkan debug report manager which calls into 'GPU::DebugCallback' diff --git a/app/src/main/cpp/skyline/gpu/memory_manager.cpp b/app/src/main/cpp/skyline/gpu/memory_manager.cpp index 6e132ac0..9f3a6d10 100644 --- a/app/src/main/cpp/skyline/gpu/memory_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/memory_manager.cpp @@ -65,7 +65,7 @@ namespace skyline::gpu::memory { .device = *gpu.vkDevice, .instance = *gpu.vkInstance, .pVulkanFunctions = &vulkanFunctions, - .vulkanApiVersion = GPU::VkApiVersion, + .vulkanApiVersion = VkApiVersion, }; ThrowOnFail(vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator)); } diff --git a/app/src/main/cpp/skyline/gpu/quirk_manager.cpp b/app/src/main/cpp/skyline/gpu/quirk_manager.cpp index 19de2cab..8ff20248 100644 --- a/app/src/main/cpp/skyline/gpu/quirk_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/quirk_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 "quirk_manager.h" namespace skyline::gpu { @@ -103,6 +104,31 @@ namespace skyline::gpu { subgroupSize = deviceProperties2.get().subgroupSize; } + void QuirkManager::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 + vk::ApplicationInfo applicationInfo{ + .apiVersion = VK_API_VERSION_1_0, + }; + + auto instance{vk::raii::Instance(context, vk::InstanceCreateInfo{ + .pApplicationInfo = &applicationInfo + })}; + + auto physicalDevice{std::move(instance.enumeratePhysicalDevices().front())}; + auto properties{physicalDevice.getProperties()}; + + // Apply BCeNabler for Adreno devices + auto type{adrenotools_get_bcn_type( VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion), properties.vendorID)}; + if (type == ADRENOTOOLS_BCN_PATCH) { + if (adrenotools_patch_bcn(reinterpret_cast(physicalDevice.getDispatcher()->vkGetPhysicalDeviceFormatProperties))) + Logger::Info("Applied BCeNabler patch"); + else + throw exception("Failed to apply BCeNabler patch!"); + } else if (type == ADRENOTOOLS_BCN_BLOB) { + 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: {}", diff --git a/app/src/main/cpp/skyline/gpu/quirk_manager.h b/app/src/main/cpp/skyline/gpu/quirk_manager.h index 4914c24a..efd42e9e 100644 --- a/app/src/main/cpp/skyline/gpu/quirk_manager.h +++ b/app/src/main/cpp/skyline/gpu/quirk_manager.h @@ -3,7 +3,7 @@ #pragma once -#include +#include #include namespace skyline::gpu { @@ -43,6 +43,11 @@ namespace skyline::gpu { QuirkManager(const DeviceFeatures2 &deviceFeatures2, DeviceFeatures2 &enabledFeatures2, const std::vector &deviceExtensions, std::vector> &enabledExtensions, const DeviceProperties2 &deviceProperties2); + /** + * @brief Applies driver specific binary patches to the driver (e.g. BCeNabler) + */ + void ApplyDriverPatches(const vk::raii::Context &context); + /** * @return A summary of all the GPU quirks as a human-readable string */