From b3a74d7f73f1749c05ce9706fdb8788097a0cad6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 8 Jan 2023 00:05:56 -0800 Subject: video_core: vulkan_device: Device initialization for Adreno. --- src/video_core/vulkan_common/vulkan_device.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index aea677cb37..9ab8e46a1d 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -310,8 +310,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; + const bool is_adreno = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; - if (is_mvk && !is_suitable) { + if ((is_mvk || is_adreno) && !is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); } else if (!is_suitable) { throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); @@ -467,8 +468,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); cant_blit_msaa = true; } - if (is_intel_anv) { - LOG_WARNING(Render_Vulkan, "ANV driver does not support native BGR format"); + if (is_intel_anv || is_adreno) { + LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); must_emulate_bgr565 = true; } if (extensions.push_descriptor && is_intel_anv) { -- cgit v1.2.3 From 46927d217c1a8d8ede26f9bf3523e208f8563d28 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 1 Jan 2023 18:34:38 -0500 Subject: externals: add adrenotools for bcenabler --- .gitmodules | 3 +++ externals/CMakeLists.txt | 4 ++++ externals/libadrenotools | 1 + src/video_core/CMakeLists.txt | 4 ++++ src/video_core/vulkan_common/vulkan_device.cpp | 30 ++++++++++++++++++++++++++ 5 files changed, 42 insertions(+) create mode 160000 externals/libadrenotools (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/.gitmodules b/.gitmodules index 75c7b5fe05..ad7a9b9701 100644 --- a/.gitmodules +++ b/.gitmodules @@ -49,3 +49,6 @@ [submodule "cpp-jwt"] path = externals/cpp-jwt url = https://github.com/arun11299/cpp-jwt.git +[submodule "externals/libadrenotools"] + path = externals/libadrenotools + url = https://github.com/bylaws/libadrenotools diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index d78d101478..2bd7b457a8 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -147,3 +147,7 @@ endif() add_library(stb stb/stb_dxt.cpp) target_include_directories(stb PUBLIC ./stb) + +if (ANDROID) + add_subdirectory(libadrenotools) +endif() diff --git a/externals/libadrenotools b/externals/libadrenotools new file mode 160000 index 0000000000..a6c0947df6 --- /dev/null +++ b/externals/libadrenotools @@ -0,0 +1 @@ +Subproject commit a6c0947df6b152b350342f5191b3082768e15e38 diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 027259f572..05aa5cfe26 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -345,3 +345,7 @@ endif() if (YUZU_ENABLE_LTO) set_property(TARGET video_core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) endif() + +if (ANDROID) + target_link_libraries(video_core PRIVATE adrenotools) +endif() diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9ab8e46a1d..8847c6aa35 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -18,6 +18,10 @@ #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" +#ifdef ANDROID +#include +#endif + namespace Vulkan { using namespace Common::Literals; namespace { @@ -356,6 +360,32 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR CollectPhysicalMemoryInfo(); CollectToolingInfo(); +#ifdef ANDROID + if (is_adreno) { + LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); + extensions.extended_dynamic_state = false; + loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + + // Patch the driver to enable BCn textures. + const auto major = (properties.properties.driverVersion >> 24) << 2; + const auto minor = (properties.properties.driverVersion >> 12) & 0xFFFU; + const auto vendor = properties.properties.vendorID; + const auto patch_status = adrenotools_get_bcn_type(major, minor, vendor); + + if (patch_status == ADRENOTOOLS_BCN_PATCH) { + LOG_INFO(Render_Vulkan, "Patching Adreno driver to support BCn texture formats"); + if (!adrenotools_patch_bcn( + reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) { + LOG_ERROR(Render_Vulkan, "Patch failed! Driver code may now crash"); + } + } else if (patch_status == ADRENOTOOLS_BCN_BLOB) { + LOG_INFO(Render_Vulkan, "Adreno driver supports BCn textures without patches"); + } else { + LOG_WARNING(Render_Vulkan, "Adreno driver can't be patched to enable BCn textures"); + } + } +#endif // ANDROID + if (is_nvidia) { const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff; const auto arch = GetNvidiaArchitecture(physical, supported_extensions); -- cgit v1.2.3 From ca2c3a6d5a42dc21604ab02cd1758633d8df358a Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 18 Feb 2023 17:43:53 +0000 Subject: Disable VK_EXT_extended_dynamic_state on mali --- src/video_core/vulkan_common/vulkan_device.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 8847c6aa35..0e182b4a0c 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -315,6 +315,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_adreno = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; + const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if ((is_mvk || is_adreno) && !is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); @@ -384,6 +385,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING(Render_Vulkan, "Adreno driver can't be patched to enable BCn textures"); } } + + if (is_arm) { + LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state"); + extensions.extended_dynamic_state = false; + loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + } #endif // ANDROID if (is_nvidia) { -- cgit v1.2.3 From 58d420937cae48a709d83c971e2dc2b36aa0ecb7 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 18 Feb 2023 17:44:06 +0000 Subject: Disable push descriptors on adreno drivers Regular descriptors are around 1.5x faster to update. --- src/video_core/vulkan_common/vulkan_device.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 0e182b4a0c..01540c10b3 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -367,6 +367,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR extensions.extended_dynamic_state = false; loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + LOG_WARNING(Render_Vulkan, "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); + extensions.push_descriptor = false; + loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + // Patch the driver to enable BCn textures. const auto major = (properties.properties.driverVersion >> 24) << 2; const auto minor = (properties.properties.driverVersion >> 12) & 0xFFFU; -- cgit v1.2.3 From 2beb3051c16d0064c5a7f5c7c256fda6e9c0f136 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Sat, 18 Feb 2023 18:23:36 +0000 Subject: Implement scaled vertex buffer format emulation These formats are unsupported by mobile GPUs so they need to be emulated in shaders instead. --- .../backend/spirv/emit_spirv_context_get_set.cpp | 44 ++++++---------- .../backend/spirv/spirv_emit_context.cpp | 61 ++++++++++++++-------- .../backend/spirv/spirv_emit_context.h | 16 +++++- src/shader_recompiler/profile.h | 1 + src/shader_recompiler/runtime_info.h | 2 + src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 8 +++ .../renderer_vulkan/vk_pipeline_cache.cpp | 7 ++- src/video_core/vulkan_common/vulkan_device.cpp | 4 ++ src/video_core/vulkan_common/vulkan_device.h | 5 ++ 9 files changed, 97 insertions(+), 51 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 07c2b7b8ad..2868fc57d1 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -10,27 +10,6 @@ namespace Shader::Backend::SPIRV { namespace { -struct AttrInfo { - Id pointer; - Id id; - bool needs_cast; -}; - -std::optional AttrTypes(EmitContext& ctx, u32 index) { - const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; - switch (type) { - case AttributeType::Float: - return AttrInfo{ctx.input_f32, ctx.F32[1], false}; - case AttributeType::UnsignedInt: - return AttrInfo{ctx.input_u32, ctx.U32[1], true}; - case AttributeType::SignedInt: - return AttrInfo{ctx.input_s32, ctx.TypeInt(32, true), true}; - case AttributeType::Disabled: - return std::nullopt; - } - throw InvalidArgument("Invalid attribute type {}", type); -} - template Id AttrPointer(EmitContext& ctx, Id pointer_type, Id vertex, Id base, Args&&... args) { switch (ctx.stage) { @@ -302,15 +281,26 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) { const u32 element{static_cast(attr) % 4}; if (IR::IsGeneric(attr)) { const u32 index{IR::GenericAttributeIndex(attr)}; - const std::optional type{AttrTypes(ctx, index)}; - if (!type || !ctx.runtime_info.previous_stage_stores.Generic(index, element)) { + const auto& generic{ctx.input_generics.at(index)}; + if (!ValidId(generic.id)) { // Attribute is disabled or varying component is not written return ctx.Const(element == 3 ? 1.0f : 0.0f); } - const Id generic_id{ctx.input_generics.at(index)}; - const Id pointer{AttrPointer(ctx, type->pointer, vertex, generic_id, ctx.Const(element))}; - const Id value{ctx.OpLoad(type->id, pointer)}; - return type->needs_cast ? ctx.OpBitcast(ctx.F32[1], value) : value; + const Id pointer{ + AttrPointer(ctx, generic.pointer_type, vertex, generic.id, ctx.Const(element))}; + const Id value{ctx.OpLoad(generic.component_type, pointer)}; + return [&ctx, generic, value]() { + switch (generic.load_op) { + case InputGenericLoadOp::Bitcast: + return ctx.OpBitcast(ctx.F32[1], value); + case InputGenericLoadOp::SToF: + return ctx.OpConvertSToF(ctx.F32[1], value); + case InputGenericLoadOp::UToF: + return ctx.OpConvertUToF(ctx.F32[1], value); + default: + return value; + }; + }(); } switch (attr) { case IR::Attribute::PrimitiveId: diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 47739794fa..fd15f47eaf 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -25,12 +25,6 @@ enum class Operation { FPMax, }; -struct AttrInfo { - Id pointer; - Id id; - bool needs_cast; -}; - Id ImageType(EmitContext& ctx, const TextureDescriptor& desc) { const spv::ImageFormat format{spv::ImageFormat::Unknown}; const Id type{ctx.F32[1]}; @@ -206,23 +200,37 @@ Id GetAttributeType(EmitContext& ctx, AttributeType type) { return ctx.TypeVector(ctx.TypeInt(32, true), 4); case AttributeType::UnsignedInt: return ctx.U32[4]; + case AttributeType::SignedScaled: + return ctx.profile.support_scaled_attributes ? ctx.F32[4] + : ctx.TypeVector(ctx.TypeInt(32, true), 4); + case AttributeType::UnsignedScaled: + return ctx.profile.support_scaled_attributes ? ctx.F32[4] : ctx.U32[4]; case AttributeType::Disabled: break; } throw InvalidArgument("Invalid attribute type {}", type); } -std::optional AttrTypes(EmitContext& ctx, u32 index) { - const AttributeType type{ctx.runtime_info.generic_input_types.at(index)}; +InputGenericInfo GetAttributeInfo(EmitContext& ctx, AttributeType type, Id id) { switch (type) { case AttributeType::Float: - return AttrInfo{ctx.input_f32, ctx.F32[1], false}; + return InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None}; case AttributeType::UnsignedInt: - return AttrInfo{ctx.input_u32, ctx.U32[1], true}; + return InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::Bitcast}; case AttributeType::SignedInt: - return AttrInfo{ctx.input_s32, ctx.TypeInt(32, true), true}; + return InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), + InputGenericLoadOp::Bitcast}; + case AttributeType::SignedScaled: + return ctx.profile.support_scaled_attributes + ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} + : InputGenericInfo{id, ctx.input_s32, ctx.TypeInt(32, true), + InputGenericLoadOp::SToF}; + case AttributeType::UnsignedScaled: + return ctx.profile.support_scaled_attributes + ? InputGenericInfo{id, ctx.input_f32, ctx.F32[1], InputGenericLoadOp::None} + : InputGenericInfo{id, ctx.input_u32, ctx.U32[1], InputGenericLoadOp::UToF}; case AttributeType::Disabled: - return std::nullopt; + return InputGenericInfo{}; } throw InvalidArgument("Invalid attribute type {}", type); } @@ -746,18 +754,29 @@ void EmitContext::DefineAttributeMemAccess(const Info& info) { continue; } AddLabel(labels[label_index]); - const auto type{AttrTypes(*this, static_cast(index))}; - if (!type) { + const auto& generic{input_generics.at(index)}; + const Id generic_id{generic.id}; + if (!ValidId(generic_id)) { OpReturnValue(Const(0.0f)); ++label_index; continue; } - const Id generic_id{input_generics.at(index)}; - const Id pointer{is_array - ? OpAccessChain(type->pointer, generic_id, vertex, masked_index) - : OpAccessChain(type->pointer, generic_id, masked_index)}; - const Id value{OpLoad(type->id, pointer)}; - const Id result{type->needs_cast ? OpBitcast(F32[1], value) : value}; + const Id pointer{ + is_array ? OpAccessChain(generic.pointer_type, generic_id, vertex, masked_index) + : OpAccessChain(generic.pointer_type, generic_id, masked_index)}; + const Id value{OpLoad(generic.component_type, pointer)}; + const Id result{[this, generic, value]() { + switch (generic.load_op) { + case InputGenericLoadOp::Bitcast: + return OpBitcast(F32[1], value); + case InputGenericLoadOp::SToF: + return OpConvertSToF(F32[1], value); + case InputGenericLoadOp::UToF: + return OpConvertUToF(F32[1], value); + default: + return value; + }; + }()}; OpReturnValue(result); ++label_index; } @@ -1457,7 +1476,7 @@ void EmitContext::DefineInputs(const IR::Program& program) { const Id id{DefineInput(*this, type, true)}; Decorate(id, spv::Decoration::Location, static_cast(index)); Name(id, fmt::format("in_attr{}", index)); - input_generics[index] = id; + input_generics[index] = GetAttributeInfo(*this, input_type, id); if (info.passthrough.Generic(index) && profile.support_geometry_shader_passthrough) { Decorate(id, spv::Decoration::PassthroughNV); diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index 768a4fbb5a..e63330f112 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -95,6 +95,20 @@ struct StorageDefinitions { Id U32x4{}; }; +enum class InputGenericLoadOp { + None, + Bitcast, + SToF, + UToF, +}; + +struct InputGenericInfo { + Id id; + Id pointer_type; + Id component_type; + InputGenericLoadOp load_op; +}; + struct GenericElementInfo { Id id{}; u32 first_element{}; @@ -283,7 +297,7 @@ public: bool need_input_position_indirect{}; Id input_position{}; - std::array input_generics{}; + std::array input_generics{}; Id output_point_size{}; Id output_position{}; diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index 9f88fb4407..3bb4a7e6fc 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -43,6 +43,7 @@ struct Profile { bool support_gl_variable_aoffi{}; bool support_gl_sparse_textures{}; bool support_gl_derivative_control{}; + bool support_scaled_attributes{}; bool warp_size_potentially_larger_than_guest{}; diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h index 549b81ef75..3b63c249f5 100644 --- a/src/shader_recompiler/runtime_info.h +++ b/src/shader_recompiler/runtime_info.h @@ -17,6 +17,8 @@ enum class AttributeType : u8 { Float, SignedInt, UnsignedInt, + SignedScaled, + UnsignedScaled, Disabled, }; diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index b75d7220df..9a0b105683 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -347,6 +347,14 @@ VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const Device& device, VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, Maxwell::VertexAttribute::Size size) { + if (device.MustEmulateScaledFormats()) { + if (type == Maxwell::VertexAttribute::Type::SScaled) { + type = Maxwell::VertexAttribute::Type::SInt; + } else if (type == Maxwell::VertexAttribute::Type::UScaled) { + type = Maxwell::VertexAttribute::Type::UInt; + } + } + const VkFormat format{([&]() { switch (type) { case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ec55e11b18..e397137612 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -114,14 +114,16 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut return Shader::AttributeType::Disabled; case Maxwell::VertexAttribute::Type::SNorm: case Maxwell::VertexAttribute::Type::UNorm: - case Maxwell::VertexAttribute::Type::UScaled: - case Maxwell::VertexAttribute::Type::SScaled: case Maxwell::VertexAttribute::Type::Float: return Shader::AttributeType::Float; case Maxwell::VertexAttribute::Type::SInt: return Shader::AttributeType::SignedInt; case Maxwell::VertexAttribute::Type::UInt: return Shader::AttributeType::UnsignedInt; + case Maxwell::VertexAttribute::Type::UScaled: + return Shader::AttributeType::UnsignedScaled; + case Maxwell::VertexAttribute::Type::SScaled: + return Shader::AttributeType::SignedScaled; } return Shader::AttributeType::Float; } @@ -331,6 +333,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device .support_derivative_control = true, .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), .support_native_ndc = device.IsExtDepthClipControlSupported(), + .support_scaled_attributes = !device.MustEmulateScaledFormats(), .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 01540c10b3..63e1c7d63d 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -363,6 +363,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR #ifdef ANDROID if (is_adreno) { + must_emulate_scaled_formats = true; + LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); extensions.extended_dynamic_state = false; loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); @@ -391,6 +393,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_arm) { + must_emulate_scaled_formats = true; + LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state"); extensions.extended_dynamic_state = false; loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 5f1c63ff91..f9d8c47ba5 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -551,6 +551,10 @@ public: return cant_blit_msaa; } + bool MustEmulateScaledFormats() const { + return must_emulate_scaled_formats; + } + bool MustEmulateBGR565() const { return must_emulate_bgr565; } @@ -666,6 +670,7 @@ private: bool has_nsight_graphics{}; ///< Has Nsight Graphics attached bool supports_d24_depth{}; ///< Supports D24 depth buffers. bool cant_blit_msaa{}; ///< Does not support MSAA<->MSAA blitting. + bool must_emulate_scaled_formats{}; ///< Requires scaled vertex format emulation bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format. bool dynamic_state3_blending{}; ///< Has all blending features of dynamic_state3. bool dynamic_state3_enables{}; ///< Has all enables features of dynamic_state3. -- cgit v1.2.3 From 74e76421e64a21e1eef14c614b32a97bbab62db2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 18 Feb 2023 23:42:07 -0800 Subject: android: native: Add support for custom Vulkan driver loading. --- .../main/java/org/yuzu/yuzu_emu/NativeLibrary.java | 2 + src/android/app/src/main/jni/CMakeLists.txt | 2 +- .../app/src/main/jni/emu_window/emu_window.cpp | 39 ++++++------- .../app/src/main/jni/emu_window/emu_window.h | 41 +++++++++----- src/android/app/src/main/jni/native.cpp | 64 ++++++++++++++++++---- src/android/app/src/main/jni/native.h | 5 ++ src/core/frontend/graphics_context.h | 17 ++---- src/video_core/renderer_vulkan/renderer_vulkan.cpp | 4 +- src/video_core/renderer_vulkan/renderer_vulkan.h | 2 +- src/video_core/vulkan_common/vulkan_device.cpp | 14 +++-- src/video_core/vulkan_common/vulkan_library.cpp | 18 ++++-- src/video_core/vulkan_common/vulkan_library.h | 6 +- src/yuzu/configuration/configure_graphics.cpp | 4 +- src/yuzu/startup_checks.cpp | 4 +- 14 files changed, 146 insertions(+), 76 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java index a0f6c1f7bc..e56196310d 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java @@ -181,6 +181,8 @@ public final class NativeLibrary { public static native void SetAppDirectory(String directory); + public static native void SetGpuDriverParameters(String hookLibDir, String customDriverDir, String customDriverName, String fileRedirectDir); + public static native boolean ReloadKeys(); // Create the config.ini file. diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index e5c9d57f29..f80c166f4c 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -13,6 +13,6 @@ add_library(yuzu-android SHARED set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) -target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log) +target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics adrenotools log) set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} yuzu-android) diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp index 2beba6804c..ad17cf1296 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.cpp +++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp @@ -7,61 +7,62 @@ #include "jni/emu_window/emu_window.h" void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { - render_window = surface; + m_render_window = surface; } void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { const auto [touch_x, touch_y] = MapToTouchScreen(x, y); - input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); + m_input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); } void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { const auto [touch_x, touch_y] = MapToTouchScreen(x, y); - input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); + m_input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); } void EmuWindow_Android::OnTouchReleased(int id) { - input_subsystem->GetTouchScreen()->TouchReleased(id); + m_input_subsystem->GetTouchScreen()->TouchReleased(id); } void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) { - input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed); + m_input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed); } void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { - input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); + m_input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); } void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, float gyro_y, float gyro_z, float accel_x, float accel_y, float accel_z) { - input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, - gyro_y, gyro_z, accel_x, accel_y, accel_z); + m_input_subsystem->GetVirtualGamepad()->SetMotionState( + player_index, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z); } -EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, - ANativeWindow* surface_) - : input_subsystem{input_subsystem_} { +EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem, + ANativeWindow* surface, + std::shared_ptr driver_library) + : m_input_subsystem{input_subsystem}, m_driver_library{driver_library} { LOG_INFO(Frontend, "initializing"); - if (!surface_) { + if (!surface) { LOG_CRITICAL(Frontend, "surface is nullptr"); return; } - window_width = ANativeWindow_getWidth(surface_); - window_height = ANativeWindow_getHeight(surface_); + m_window_width = ANativeWindow_getWidth(surface); + m_window_height = ANativeWindow_getHeight(surface); // Ensures that we emulate with the correct aspect ratio. - UpdateCurrentFramebufferLayout(window_width, window_height); + UpdateCurrentFramebufferLayout(m_window_width, m_window_height); - host_window = surface_; + m_host_window = surface; window_info.type = Core::Frontend::WindowSystemType::Android; - window_info.render_surface = reinterpret_cast(host_window); + window_info.render_surface = reinterpret_cast(m_host_window); - input_subsystem->Initialize(); + m_input_subsystem->Initialize(); } EmuWindow_Android::~EmuWindow_Android() { - input_subsystem->Shutdown(); + m_input_subsystem->Shutdown(); } diff --git a/src/android/app/src/main/jni/emu_window/emu_window.h b/src/android/app/src/main/jni/emu_window/emu_window.h index 544924caa1..1c1edf62c6 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.h +++ b/src/android/app/src/main/jni/emu_window/emu_window.h @@ -1,21 +1,34 @@ #pragma once +#include + #include "core/frontend/emu_window.h" +#include "core/frontend/graphics_context.h" #include "input_common/main.h" struct ANativeWindow; -class SharedContext_Android : public Core::Frontend::GraphicsContext { +class GraphicsContext_Android final : public Core::Frontend::GraphicsContext { public: - SharedContext_Android() = default; - ~SharedContext_Android() = default; - void MakeCurrent() override {} - void DoneCurrent() override {} + explicit GraphicsContext_Android(std::shared_ptr driver_library) + : m_driver_library{driver_library} {} + + ~GraphicsContext_Android() = default; + + std::shared_ptr GetDriverLibrary() override { + return m_driver_library; + } + +private: + std::shared_ptr m_driver_library; }; -class EmuWindow_Android : public Core::Frontend::EmuWindow { +class EmuWindow_Android final : public Core::Frontend::EmuWindow { + public: - EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, ANativeWindow* surface_); + EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem, ANativeWindow* surface, + std::shared_ptr driver_library); + ~EmuWindow_Android(); void OnSurfaceChanged(ANativeWindow* surface); @@ -29,18 +42,20 @@ public: void OnFrameDisplayed() override {} std::unique_ptr CreateSharedContext() const override { - return {std::make_unique()}; + return {std::make_unique(m_driver_library)}; } bool IsShown() const override { return true; }; private: - InputCommon::InputSubsystem* input_subsystem{}; + InputCommon::InputSubsystem* m_input_subsystem{}; + + ANativeWindow* m_render_window{}; + ANativeWindow* m_host_window{}; - ANativeWindow* render_window{}; - ANativeWindow* host_window{}; + float m_window_width{}; + float m_window_height{}; - float window_width{}; - float window_height{}; + std::shared_ptr m_driver_library; }; diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 0a2a657216..a8f3d135e0 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -5,11 +5,15 @@ #include #include #include +#include + +#include #include #include #include "common/detached_tasks.h" +#include "common/dynamic_library.h" #include "common/fs/path_util.h" #include "common/logging/backend.h" #include "common/logging/log.h" @@ -70,6 +74,29 @@ public: m_native_window = m_native_window_; } + void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir, + const std::string& custom_driver_name, + const std::string& file_redirect_dir) { + void* handle{}; + + // Try to load a custom driver. + if (custom_driver_name.size()) { + handle = adrenotools_open_libvulkan( + RTLD_NOW, ADRENOTOOLS_DRIVER_CUSTOM | ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr, + hook_lib_dir.c_str(), custom_driver_dir.c_str(), custom_driver_name.c_str(), + file_redirect_dir.c_str(), nullptr); + } + + // Try to load the system driver. + if (!handle) { + handle = adrenotools_open_libvulkan(RTLD_NOW, ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr, + hook_lib_dir.c_str(), nullptr, nullptr, + file_redirect_dir.c_str(), nullptr); + } + + m_vulkan_library = std::make_shared(handle); + } + bool IsRunning() const { std::scoped_lock lock(m_mutex); return m_is_running; @@ -94,7 +121,8 @@ public: Config{}; // Create the render window. - m_window = std::make_unique(&m_input_subsystem, m_native_window); + m_window = std::make_unique(&m_input_subsystem, m_native_window, + m_vulkan_library); // Initialize system. m_system.SetShuttingDown(false); @@ -242,6 +270,9 @@ private: Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; bool m_is_running{}; + // GPU driver parameters + std::shared_ptr m_vulkan_library; + // Synchronization std::condition_variable_any m_cv; mutable std::mutex m_perf_stats_mutex; @@ -327,6 +358,14 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNIEnv* env, Common::FS::SetAppDirectory(GetJString(env, j_directory)); } +void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver( + JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir, + jstring custom_driver_name, jstring file_redirect_dir) { + EmulationSession::GetInstance().InitializeGpuDriver( + GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir), + GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir)); +} + jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, [[maybe_unused]] jclass clazz) { Core::Crypto::KeyManager::Instance().ReloadKeys(); @@ -363,7 +402,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadButtonEvent([[maybe_unus [[maybe_unused]] jint j_device, jint j_button, jint action) { if (EmulationSession::GetInstance().IsRunning()) { - EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device,j_button, action != 0); + EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device, j_button, + action != 0); } return static_cast(true); } @@ -373,31 +413,33 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadJoystickEvent([[maybe_un jint j_device, jint stick_id, jfloat x, jfloat y) { if (EmulationSession::GetInstance().IsRunning()) { - EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device,stick_id, x, y); + EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device, stick_id, x, y); } return static_cast(true); } -jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent([[maybe_unused]] JNIEnv* env, - [[maybe_unused]] jclass clazz, jint j_device,jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, - jfloat gyro_z, jfloat accel_x, jfloat accel_y, jfloat accel_z){ +jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent( + [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device, + jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, jfloat gyro_z, jfloat accel_x, + jfloat accel_y, jfloat accel_z) { if (EmulationSession::GetInstance().IsRunning()) { - EmulationSession::GetInstance().Window().OnGamepadMotionEvent(j_device,delta_timestamp, gyro_x, gyro_y,gyro_z,accel_x,accel_y,accel_z); + EmulationSession::GetInstance().Window().OnGamepadMotionEvent( + j_device, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z); } return static_cast(true); } void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchPressed([[maybe_unused]] JNIEnv* env, - [[maybe_unused]] jclass clazz, jint id, jfloat x, - jfloat y) { + [[maybe_unused]] jclass clazz, jint id, + jfloat x, jfloat y) { if (EmulationSession::GetInstance().IsRunning()) { EmulationSession::GetInstance().Window().OnTouchPressed(id, x, y); } } void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env, - [[maybe_unused]] jclass clazz, jint id, jfloat x, - jfloat y) { + [[maybe_unused]] jclass clazz, jint id, + jfloat x, jfloat y) { if (EmulationSession::GetInstance().IsRunning()) { EmulationSession::GetInstance().Window().OnTouchMoved(id, x, y); } diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index bbc783aa87..f799560e47 100644 --- a/src/android/app/src/main/jni/native.h +++ b/src/android/app/src/main/jni/native.h @@ -71,6 +71,11 @@ JNIEXPORT void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNI jclass clazz, jstring j_directory); +JNIEXPORT void JNICALL +Java_org_yuzu_yuzu_1emu_NativeLibrary_Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver( + JNIEnv* env, jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir, + jstring custom_driver_name, jstring file_redirect_dir); + JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, jclass clazz); diff --git a/src/core/frontend/graphics_context.h b/src/core/frontend/graphics_context.h index 064b19a965..7554c15833 100644 --- a/src/core/frontend/graphics_context.h +++ b/src/core/frontend/graphics_context.h @@ -3,8 +3,9 @@ #pragma once -#include -#include +#include + +#include "common/dynamic_library.h" namespace Core::Frontend { @@ -24,16 +25,8 @@ public: /// Releases (dunno if this is the "right" word) the context from the caller thread virtual void DoneCurrent() {} - /// Parameters used to configure custom drivers (used by Android only) - struct CustomDriverParameters { - std::string hook_lib_dir; - std::string custom_driver_dir; - std::string custom_driver_name; - std::string file_redirect_dir; - }; - - /// Gets custom driver parameters configured by the frontend (used by Android only) - virtual std::optional GetCustomDriverParameters() { + /// Gets the GPU driver library (used by Android only) + virtual std::shared_ptr GetDriverLibrary() { return {}; } diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index fbcf4c1d36..30dc69f130 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -84,8 +84,8 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, std::unique_ptr context_) try : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_), - cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary()), - instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, + cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())), + instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, Settings::values.renderer_debug.GetValue())), debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), surface(CreateSurface(instance, render_window.GetWindowInfo())), diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index f44367cb25..3c63a2004a 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -63,7 +63,7 @@ private: Core::Memory::Memory& cpu_memory; Tegra::GPU& gpu; - Common::DynamicLibrary library; + std::shared_ptr library; vk::InstanceDispatch dld; vk::Instance instance; diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 63e1c7d63d..40cdf2fde0 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -314,10 +314,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; - const bool is_adreno = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; - const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; + const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; + const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; - if ((is_mvk || is_adreno) && !is_suitable) { + if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); } else if (!is_suitable) { throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); @@ -362,14 +362,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR CollectToolingInfo(); #ifdef ANDROID - if (is_adreno) { + if (is_qualcomm) { must_emulate_scaled_formats = true; LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); extensions.extended_dynamic_state = false; loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); - LOG_WARNING(Render_Vulkan, "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); + LOG_WARNING(Render_Vulkan, + "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); extensions.push_descriptor = false; loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); @@ -392,6 +393,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } } + const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; if (is_arm) { must_emulate_scaled_formats = true; @@ -513,7 +515,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); cant_blit_msaa = true; } - if (is_intel_anv || is_adreno) { + if (is_intel_anv || is_qualcomm) { LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); must_emulate_bgr565 = true; } diff --git a/src/video_core/vulkan_common/vulkan_library.cpp b/src/video_core/vulkan_common/vulkan_library.cpp index 4eb3913ee1..9a7d369f32 100644 --- a/src/video_core/vulkan_common/vulkan_library.cpp +++ b/src/video_core/vulkan_common/vulkan_library.cpp @@ -10,29 +10,35 @@ namespace Vulkan { -Common::DynamicLibrary OpenLibrary() { +std::shared_ptr OpenLibrary( + [[maybe_unused]] Core::Frontend::GraphicsContext* context) { LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); - Common::DynamicLibrary library; +#ifdef ANDROID + // Android manages its Vulkan driver from the frontend. + return context->GetDriverLibrary(); +#else + auto library = std::make_shared(); #ifdef __APPLE__ // Check if a path to a specific Vulkan library has been specified. char* const libvulkan_env = std::getenv("LIBVULKAN_PATH"); - if (!libvulkan_env || !library.Open(libvulkan_env)) { + if (!libvulkan_env || !library->Open(libvulkan_env)) { // Use the libvulkan.dylib from the application bundle. const auto filename = Common::FS::GetBundleDirectory() / "Contents/Frameworks/libvulkan.dylib"; - void(library.Open(Common::FS::PathToUTF8String(filename).c_str())); + void(library->Open(Common::FS::PathToUTF8String(filename).c_str())); } #else std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename); - if (!library.Open(filename.c_str())) { + if (!library->Open(filename.c_str())) { // Android devices may not have libvulkan.so.1, only libvulkan.so. filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename); - void(library.Open(filename.c_str())); + void(library->Open(filename.c_str())); } #endif return library; +#endif } } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_library.h b/src/video_core/vulkan_common/vulkan_library.h index 364ca979b6..e1734525ee 100644 --- a/src/video_core/vulkan_common/vulkan_library.h +++ b/src/video_core/vulkan_common/vulkan_library.h @@ -3,10 +3,14 @@ #pragma once +#include + #include "common/dynamic_library.h" +#include "core/frontend/graphics_context.h" namespace Vulkan { -Common::DynamicLibrary OpenLibrary(); +std::shared_ptr OpenLibrary( + [[maybe_unused]] Core::Frontend::GraphicsContext* context = nullptr); } // namespace Vulkan diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index f316b598cc..4315852160 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -515,8 +515,8 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { auto wsi = QtCommon::GetWindowSystemInfo(window); vk::InstanceDispatch dld; - const Common::DynamicLibrary library = OpenLibrary(); - const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_1, wsi.type); + const auto library = OpenLibrary(); + const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); const std::vector physical_devices = instance.EnumeratePhysicalDevices(); vk::SurfaceKHR surface = CreateSurface(instance, wsi); diff --git a/src/yuzu/startup_checks.cpp b/src/yuzu/startup_checks.cpp index 5e1f763392..6eefc94ed0 100644 --- a/src/yuzu/startup_checks.cpp +++ b/src/yuzu/startup_checks.cpp @@ -25,9 +25,9 @@ void CheckVulkan() { // Just start the Vulkan loader, this will crash if something is wrong try { Vulkan::vk::InstanceDispatch dld; - const Common::DynamicLibrary library = Vulkan::OpenLibrary(); + const auto library = Vulkan::OpenLibrary(); const Vulkan::vk::Instance instance = - Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_1); + Vulkan::CreateInstance(*library, dld, VK_API_VERSION_1_1); } catch (const Vulkan::vk::Exception& exception) { fmt::print(stderr, "Failed to initialize Vulkan: {}\n", exception.what()); -- cgit v1.2.3 From 6ae51eff8a4593f1028de6ad060828a39765e11d Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 19 Feb 2023 01:19:53 -0800 Subject: android: vulkan_device: Disable VK_EXT_extended_dynamic_state2 on Qualcomm. - Newer drivers report this as supported, but it is broken. --- src/video_core/vulkan_common/vulkan_device.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 40cdf2fde0..79686a1766 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -365,12 +365,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_qualcomm) { must_emulate_scaled_formats = true; - LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); + LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_extended_dynamic_state"); extensions.extended_dynamic_state = false; loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); LOG_WARNING(Render_Vulkan, - "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); + "Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); extensions.push_descriptor = false; loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); @@ -436,7 +436,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } } - if (extensions.extended_dynamic_state2 && is_radv) { + if (extensions.extended_dynamic_state2 && (is_radv || is_qualcomm)) { const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(0, 22, 3, 1)) { LOG_WARNING( -- cgit v1.2.3 From 27250ee9ada06bf13d691e6a22df9690f0bf8fd1 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 19 Feb 2023 02:19:21 -0800 Subject: android: vulkan: Implement adrenotools turbo mode. --- .../features/settings/ui/SettingsFragmentPresenter.java | 2 ++ .../yuzu/yuzu_emu/features/settings/utils/SettingsFile.java | 1 + src/android/app/src/main/jni/config.cpp | 5 ++++- src/android/app/src/main/jni/default_ini.h | 4 ++++ src/android/app/src/main/res/values/strings.xml | 2 ++ src/video_core/renderer_vulkan/vk_turbo_mode.cpp | 12 +++++++++++- src/video_core/vulkan_common/vulkan_device.cpp | 4 +++- 7 files changed, 27 insertions(+), 3 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java index 71ae03ca11..f924a167d8 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.java @@ -160,12 +160,14 @@ public final class SettingsFragmentPresenter { Setting rendererAccuracy = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ACCURACY); Setting rendererReolution = rendererSection.getSetting(SettingsFile.KEY_RENDERER_RESOLUTION); Setting rendererAspectRation = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASPECT_RATIO); + Setting rendererForceMaxClocks = rendererSection.getSetting(SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK); Setting rendererAsynchronousShaders = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS); sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_BACKEND, Settings.SECTION_RENDERER, R.string.renderer_api, 0, R.array.rendererApiNames, R.array.rendererApiValues, 1, rendererBackend)); sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_ACCURACY, Settings.SECTION_RENDERER, R.string.renderer_accuracy, 0, R.array.rendererAccuracyNames, R.array.rendererAccuracyValues, 1, rendererAccuracy)); sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_RESOLUTION, Settings.SECTION_RENDERER, R.string.renderer_resolution, 0, R.array.rendererResolutionNames, R.array.rendererResolutionValues, 2, rendererReolution)); sl.add(new SingleChoiceSetting(SettingsFile.KEY_RENDERER_ASPECT_RATIO, Settings.SECTION_RENDERER, R.string.renderer_aspect_ratio, 0, R.array.rendererAspectRatioNames, R.array.rendererAspectRatioValues, 0, rendererAspectRation)); + sl.add(new CheckBoxSetting(SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK, Settings.SECTION_RENDERER, R.string.renderer_force_max_clock, R.string.renderer_force_max_clock_description, true, rendererForceMaxClocks)); sl.add(new CheckBoxSetting(SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS, Settings.SECTION_RENDERER, R.string.renderer_asynchronous_shaders, R.string.renderer_asynchronous_shaders_description, false, rendererAsynchronousShaders)); } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java index 392c2e62d8..12bc03ffa6 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.java @@ -47,6 +47,7 @@ public final class SettingsFile { public static final String KEY_RENDERER_ASPECT_RATIO = "aspect_ratio"; public static final String KEY_RENDERER_ACCURACY = "gpu_accuracy"; public static final String KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders"; + public static final String KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock"; public static final String KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit"; public static final String KEY_RENDERER_SPEED_LIMIT = "speed_limit"; // Audio diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 0a3cb9162c..d197413b98 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp @@ -192,7 +192,6 @@ void Config::ReadValues() { // Renderer ReadSetting("Renderer", Settings::values.renderer_backend); - ReadSetting("Renderer", Settings::values.renderer_force_max_clock); ReadSetting("Renderer", Settings::values.renderer_debug); ReadSetting("Renderer", Settings::values.renderer_shader_feedback); ReadSetting("Renderer", Settings::values.enable_nsight_aftermath); @@ -223,6 +222,10 @@ void Config::ReadValues() { ReadSetting("Renderer", Settings::values.bg_green); ReadSetting("Renderer", Settings::values.bg_blue); + // Enable force_max_clock by default on Android + Settings::values.renderer_force_max_clock = + config->GetBoolean("Renderer", "force_max_clock", true); + // Audio ReadSetting("Audio", Settings::values.sink_id); ReadSetting("Audio", Settings::values.audio_output_device_id); diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index eecda4756b..25ec140de6 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -247,6 +247,10 @@ cpuopt_unsafe_ignore_global_monitor = # 0: OpenGL (unsupported), 1 (default): Vulkan, 2: Null backend = +# Enable graphics API debugging mode. +# 0 (default): Disabled, 1: Enabled +force_max_clock = + # Enable graphics API debugging mode. # 0 (default): Disabled, 1: Enabled debug = diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 27749b2875..bdaaa76507 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -29,6 +29,8 @@ Accuracy level Resolution Aspect Ratio + Force maximum clocks (Adreno only) + Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). Use asynchronous shaders Compiles shaders asynchronously, which will reduce stutter but may introduce glitches. diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp index db04943eba..29751e6b4c 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp @@ -1,6 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#ifdef ANDROID +#include +#endif + #include "common/literals.h" #include "video_core/host_shaders/vulkan_turbo_mode_comp_spv.h" #include "video_core/renderer_vulkan/renderer_vulkan.h" @@ -144,6 +148,9 @@ void TurboMode::Run(std::stop_token stop_token) { auto cmdbuf = vk::CommandBuffer{cmdbufs[0], m_device.GetDispatchLoader()}; while (!stop_token.stop_requested()) { +#ifdef ANDROID + adrenotools_set_turbo(true); +#else // Reset the fence. fence.Reset(); @@ -209,7 +216,7 @@ void TurboMode::Run(std::stop_token stop_token) { // Wait for completion. fence.Wait(); - +#endif // Wait for the next graphics queue submission if necessary. std::unique_lock lk{m_submission_lock}; Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { @@ -217,6 +224,9 @@ void TurboMode::Run(std::stop_token stop_token) { std::chrono::milliseconds{100}; }); } +#ifdef ANDROID + adrenotools_set_turbo(false); +#endif } } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 79686a1766..70ee60a967 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -681,7 +681,9 @@ bool Device::ShouldBoostClocks() const { driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE || driver_id == VK_DRIVER_ID_MESA_RADV || driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY || driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS || - driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; + driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA || + driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || + driver_id == VK_DRIVER_ID_MESA_TURNIP; const bool is_steam_deck = vendor_id == 0x1002 && device_id == 0x163F; -- cgit v1.2.3 From ea54161dbf43c718922ef4a7319baaf48a000173 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 20 Feb 2023 02:04:13 -0800 Subject: video_core: vulkan_device: Correct error message for unsuitable driver. --- src/video_core/vulkan_common/vulkan_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 70ee60a967..52455dbeb4 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -318,7 +318,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { - LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); + LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway"); } else if (!is_suitable) { throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); } -- cgit v1.2.3 From 44a629e584ea6af4b37df47505d7e2a9d1574292 Mon Sep 17 00:00:00 2001 From: liushuyu Date: Sat, 4 Mar 2023 00:16:20 -0700 Subject: video_core: fix clang-format errors --- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 4 ++-- src/video_core/vulkan_common/vulkan_device.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index e506a8b301..48820b8905 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -351,8 +351,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device .has_broken_signed_operations = false, .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, .ignore_nan_fp_comparisons = false, - .has_broken_spirv_subgroup_mask_vector_extract_dynamic = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY - }; + .has_broken_spirv_subgroup_mask_vector_extract_dynamic = + driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY}; host_info = Shader::HostTranslateInfo{ .support_float16 = device.IsFloat16Supported(), .support_int64 = device.IsShaderInt64Supported(), diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 52455dbeb4..06efa1a6c8 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -682,8 +682,7 @@ bool Device::ShouldBoostClocks() const { driver_id == VK_DRIVER_ID_MESA_RADV || driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY || driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS || driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA || - driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || - driver_id == VK_DRIVER_ID_MESA_TURNIP; + driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY || driver_id == VK_DRIVER_ID_MESA_TURNIP; const bool is_steam_deck = vendor_id == 0x1002 && device_id == 0x163F; -- cgit v1.2.3 From d54605d1a5af9640dcac97d76e0bac4a59be10a4 Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 16 Mar 2023 11:56:51 -0400 Subject: build: only enable adrenotools on arm64 --- CMakeLists.txt | 16 ++++++++++++---- externals/CMakeLists.txt | 4 +++- src/android/app/build.gradle | 5 ++--- src/android/app/src/main/jni/CMakeLists.txt | 5 ++++- src/android/app/src/main/jni/native.cpp | 4 ++++ src/video_core/CMakeLists.txt | 2 +- src/video_core/renderer_vulkan/vk_turbo_mode.cpp | 6 +++--- src/video_core/vulkan_common/vulkan_device.cpp | 4 +++- src/video_core/vulkan_common/vulkan_library.cpp | 2 +- 9 files changed, 33 insertions(+), 15 deletions(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d25cc3a98..1771b063ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,12 +106,20 @@ endif() if (YUZU_USE_BUNDLED_VCPKG) if (ANDROID) - set(VCPKG_TARGET_TRIPLET "arm64-android") set(ENV{ANDROID_NDK_HOME} "${ANDROID_NDK}") - # this is to avoid CMake using the host pkg-config to find the host - # libraries when building for Android targets - set(PKG_CONFIG_EXECUTABLE "aarch64-none-linux-android-pkg-config" CACHE FILEPATH "" FORCE) list(APPEND VCPKG_MANIFEST_FEATURES "android") + + if (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + set(VCPKG_TARGET_TRIPLET "arm64-android") + # this is to avoid CMake using the host pkg-config to find the host + # libraries when building for Android targets + set(PKG_CONFIG_EXECUTABLE "aarch64-none-linux-android-pkg-config" CACHE FILEPATH "" FORCE) + elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") + set(VCPKG_TARGET_TRIPLET "x64-android") + set(PKG_CONFIG_EXECUTABLE "x86_64-none-linux-android-pkg-config" CACHE FILEPATH "" FORCE) + else() + message(FATAL_ERROR "Unsupported Android architecture ${CMAKE_ANDROID_ARCH_ABI}") + endif() endif() if (YUZU_TESTS) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 2bd7b457a8..500eb21e39 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -149,5 +149,7 @@ add_library(stb stb/stb_dxt.cpp) target_include_directories(stb PUBLIC ./stb) if (ANDROID) - add_subdirectory(libadrenotools) + if (ARCHITECTURE_arm64) + add_subdirectory(libadrenotools) + endif() endif() diff --git a/src/android/app/build.gradle b/src/android/app/build.gradle index 8b621f5d50..7e2717b11b 100644 --- a/src/android/app/build.gradle +++ b/src/android/app/build.gradle @@ -10,7 +10,6 @@ plugins { */ def autoVersion = (int) (((new Date().getTime() / 1000) - 1451606400) / 10) def buildType -def abiFilter = "arm64-v8a" //, "x86" android { namespace 'org.yuzu.yuzu_emu' @@ -44,7 +43,7 @@ android { targetSdkVersion 33 versionCode autoVersion versionName getVersion() - ndk.abiFilters abiFilter + ndk.abiFilters "arm64-v8a", "x86_64" } signingConfigs { @@ -115,7 +114,7 @@ android { "-DYUZU_USE_BUNDLED_VCPKG=ON", "-DYUZU_USE_BUNDLED_FFMPEG=ON" - abiFilters abiFilter + abiFilters "arm64-v8a", "x86_64" } } } diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt index f80c166f4c..21c27d4ee3 100644 --- a/src/android/app/src/main/jni/CMakeLists.txt +++ b/src/android/app/src/main/jni/CMakeLists.txt @@ -13,6 +13,9 @@ add_library(yuzu-android SHARED set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) -target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics adrenotools log) +target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log) +if (ARCHITECTURE_arm64) + target_link_libraries(yuzu-android PRIVATE adrenotools) +endif() set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} yuzu-android) diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 3cfbec87cb..6e670e8992 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -7,7 +7,9 @@ #include #include +#ifdef ARCHITECTURE_arm64 #include +#endif #include #include @@ -76,6 +78,7 @@ public: void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir, const std::string& custom_driver_name, const std::string& file_redirect_dir) { +#ifdef ARCHITECTURE_arm64 void* handle{}; const char* file_redirect_dir_{}; int featureFlags{}; @@ -101,6 +104,7 @@ public: } m_vulkan_library = std::make_shared(handle); +#endif } bool IsRunning() const { diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 05aa5cfe26..94e3000bad 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -346,6 +346,6 @@ if (YUZU_ENABLE_LTO) set_property(TARGET video_core PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) endif() -if (ANDROID) +if (ANDROID AND ARCHITECTURE_arm64) target_link_libraries(video_core PRIVATE adrenotools) endif() diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp index 29751e6b4c..22dbf272e7 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp @@ -1,7 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#ifdef ANDROID +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) #include #endif @@ -148,7 +148,7 @@ void TurboMode::Run(std::stop_token stop_token) { auto cmdbuf = vk::CommandBuffer{cmdbufs[0], m_device.GetDispatchLoader()}; while (!stop_token.stop_requested()) { -#ifdef ANDROID +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) adrenotools_set_turbo(true); #else // Reset the fence. @@ -224,7 +224,7 @@ void TurboMode::Run(std::stop_token stop_token) { std::chrono::milliseconds{100}; }); } -#ifdef ANDROID +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) adrenotools_set_turbo(false); #endif } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 06efa1a6c8..9e2dee0972 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -18,7 +18,7 @@ #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" -#ifdef ANDROID +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) #include #endif @@ -374,6 +374,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR extensions.push_descriptor = false; loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); +#ifdef ARCHITECTURE_arm64 // Patch the driver to enable BCn textures. const auto major = (properties.properties.driverVersion >> 24) << 2; const auto minor = (properties.properties.driverVersion >> 12) & 0xFFFU; @@ -391,6 +392,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } else { LOG_WARNING(Render_Vulkan, "Adreno driver can't be patched to enable BCn textures"); } +#endif // ARCHITECTURE_arm64 } const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; diff --git a/src/video_core/vulkan_common/vulkan_library.cpp b/src/video_core/vulkan_common/vulkan_library.cpp index 9a7d369f32..47f6f2a036 100644 --- a/src/video_core/vulkan_common/vulkan_library.cpp +++ b/src/video_core/vulkan_common/vulkan_library.cpp @@ -13,7 +13,7 @@ namespace Vulkan { std::shared_ptr OpenLibrary( [[maybe_unused]] Core::Frontend::GraphicsContext* context) { LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); -#ifdef ANDROID +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) // Android manages its Vulkan driver from the frontend. return context->GetDriverLibrary(); #else -- cgit v1.2.3 From bf598273e9b4538c6674ff821d687e76303f5250 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 1 Apr 2023 16:15:57 -0700 Subject: android: vulkan_device: Disable VK_EXT_custom_border_color on Adreno. - Causes crashes on sampler creation with Super Mario Odyssey. --- src/video_core/vulkan_common/vulkan_device.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 9e2dee0972..8aba29245d 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -362,6 +362,13 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR CollectToolingInfo(); #ifdef ANDROID + if (is_qualcomm || is_turnip) { + LOG_WARNING(Render_Vulkan, + "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); + extensions.custom_border_color = false; + loaded_extensions.erase(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + } + if (is_qualcomm) { must_emulate_scaled_formats = true; -- cgit v1.2.3 From 2810793b17369ecb836e5f8a66a95b3dda69adb2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 16 Apr 2023 00:56:00 -0700 Subject: android: vulkan: Disable vertex_input_dynamic_state on Qualcomm. --- src/video_core/vulkan_common/vulkan_device.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 8aba29245d..de9b0d25d6 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -472,7 +472,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR dynamic_state3_enables = false; } } - if (extensions.vertex_input_dynamic_state && is_radv) { + if (extensions.vertex_input_dynamic_state && (is_radv || is_qualcomm)) { + // Qualcomm S8gen2 drivers do not properly support vertex_input_dynamic_state. // TODO(ameerj): Blacklist only offending driver versions // TODO(ameerj): Confirm if RDNA1 is affected const bool is_rdna2 = -- cgit v1.2.3 From 5d9250daf461f00fb87d3add0c2a263637d7add0 Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 22 Mar 2023 10:33:59 -0400 Subject: android: remove spurious warnings about BCn formats when patched with adrenotools --- src/video_core/vulkan_common/vulkan_device.cpp | 28 +++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index de9b0d25d6..1eec4afb08 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -266,6 +266,30 @@ std::unordered_map GetFormatProperties(vk::Physica return format_properties; } +void OverrideBcnFormats(std::unordered_map& format_properties) { + // These properties are extracted from Adreno driver 512.687.0 + constexpr VkFormatFeatureFlags tiling_features{ + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | + VK_FORMAT_FEATURE_TRANSFER_DST_BIT}; + + constexpr VkFormatFeatureFlags buffer_features{VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT}; + + static constexpr std::array bcn_formats{ + VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK, + VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, + VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK, + VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC6H_UFLOAT_BLOCK, + VK_FORMAT_BC7_SRGB_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, + }; + + for (const auto format : bcn_formats) { + format_properties[format].linearTilingFeatures = tiling_features; + format_properties[format].optimalTilingFeatures = tiling_features; + format_properties[format].bufferFeatures = buffer_features; + } +} + NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, const std::set>& exts) { if (exts.contains(VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME)) { @@ -390,8 +414,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (patch_status == ADRENOTOOLS_BCN_PATCH) { LOG_INFO(Render_Vulkan, "Patching Adreno driver to support BCn texture formats"); - if (!adrenotools_patch_bcn( + if (adrenotools_patch_bcn( reinterpret_cast(dld.vkGetPhysicalDeviceFormatProperties))) { + OverrideBcnFormats(format_properties); + } else { LOG_ERROR(Render_Vulkan, "Patch failed! Driver code may now crash"); } } else if (patch_status == ADRENOTOOLS_BCN_BLOB) { -- cgit v1.2.3 From 4e2cdf74a328eb66a75b9097752e8b674e7642b6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 7 May 2023 18:41:26 -0700 Subject: android: vulkan_device: Only compile OverrideBcnFormats when used. --- src/video_core/vulkan_common/vulkan_device.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 1eec4afb08..75c4503657 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -266,6 +266,7 @@ std::unordered_map GetFormatProperties(vk::Physica return format_properties; } +#if defined(ANDROID) && defined(ARCHITECTURE_arm64) void OverrideBcnFormats(std::unordered_map& format_properties) { // These properties are extracted from Adreno driver 512.687.0 constexpr VkFormatFeatureFlags tiling_features{ @@ -289,6 +290,7 @@ void OverrideBcnFormats(std::unordered_map& format format_properties[format].bufferFeatures = buffer_features; } } +#endif NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical, const std::set>& exts) { -- cgit v1.2.3 From c55db7e03d0bea040e323419cafb7d40c217dab7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 9 May 2023 23:37:57 -0700 Subject: android: vulkan_device: Skip BGR565 emulation on S8gen2. --- src/video_core/vulkan_common/vulkan_device.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/video_core/vulkan_common/vulkan_device.cpp') diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 75c4503657..0158b6b0d3 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -332,6 +332,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_suitable = GetSuitability(surface != nullptr); const VkDriverId driver_id = properties.driver.driverID; + const auto device_id = properties.properties.deviceID; const bool is_radv = driver_id == VK_DRIVER_ID_MESA_RADV; const bool is_amd_driver = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; @@ -342,6 +343,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; + const bool is_s8gen2 = device_id == 0x43050a01; if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { LOG_WARNING(Render_Vulkan, "Unsuitable driver, continuing anyway"); @@ -553,7 +555,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); cant_blit_msaa = true; } - if (is_intel_anv || is_qualcomm) { + if (is_intel_anv || (is_qualcomm && !is_s8gen2)) { LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); must_emulate_bgr565 = true; } -- cgit v1.2.3