diff options
| author | 2023-02-18 23:42:07 -0800 | |
|---|---|---|
| committer | 2023-06-03 00:05:31 -0700 | |
| commit | 4c38220a644f8292f4915eaabb2f80d3d0badab0 (patch) | |
| tree | d6a2291e26e3723ec0e3124f9bb117487dd3966c /src | |
| parent | core: frontend: Refactor GraphicsContext to its own module. (diff) | |
| download | yuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.tar.gz yuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.tar.xz yuzu-4c38220a644f8292f4915eaabb2f80d3d0badab0.zip | |
android: native: Add support for custom Vulkan driver loading.
Diffstat (limited to 'src')
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.java | 2 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/emu_window/emu_window.cpp | 39 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/emu_window/emu_window.h | 41 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/native.cpp | 64 | ||||
| -rw-r--r-- | src/android/app/src/main/jni/native.h | 5 | ||||
| -rw-r--r-- | src/core/frontend/graphics_context.h | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 2 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_library.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_library.h | 6 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_graphics.cpp | 4 | ||||
| -rw-r--r-- | src/yuzu/startup_checks.cpp | 4 |
14 files changed, 146 insertions, 76 deletions
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 a0f6c1f7b..e56196310 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 { | |||
| 181 | 181 | ||
| 182 | public static native void SetAppDirectory(String directory); | 182 | public static native void SetAppDirectory(String directory); |
| 183 | 183 | ||
| 184 | public static native void SetGpuDriverParameters(String hookLibDir, String customDriverDir, String customDriverName, String fileRedirectDir); | ||
| 185 | |||
| 184 | public static native boolean ReloadKeys(); | 186 | public static native boolean ReloadKeys(); |
| 185 | 187 | ||
| 186 | // Create the config.ini file. | 188 | // 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 e5c9d57f2..f80c166f4 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 | |||
| 13 | set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) | 13 | set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) |
| 14 | 14 | ||
| 15 | target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) | 15 | target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) |
| 16 | target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log) | 16 | target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics adrenotools log) |
| 17 | 17 | ||
| 18 | set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} yuzu-android) | 18 | 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 2beba6804..ad17cf129 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 @@ | |||
| 7 | #include "jni/emu_window/emu_window.h" | 7 | #include "jni/emu_window/emu_window.h" |
| 8 | 8 | ||
| 9 | void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { | 9 | void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { |
| 10 | render_window = surface; | 10 | m_render_window = surface; |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { | 13 | void EmuWindow_Android::OnTouchPressed(int id, float x, float y) { |
| 14 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); | 14 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); |
| 15 | input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); | 15 | m_input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id); |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { | 18 | void EmuWindow_Android::OnTouchMoved(int id, float x, float y) { |
| 19 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); | 19 | const auto [touch_x, touch_y] = MapToTouchScreen(x, y); |
| 20 | input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); | 20 | m_input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id); |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | void EmuWindow_Android::OnTouchReleased(int id) { | 23 | void EmuWindow_Android::OnTouchReleased(int id) { |
| 24 | input_subsystem->GetTouchScreen()->TouchReleased(id); | 24 | m_input_subsystem->GetTouchScreen()->TouchReleased(id); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) { | 27 | void EmuWindow_Android::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) { |
| 28 | input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed); | 28 | m_input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { | 31 | void EmuWindow_Android::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) { |
| 32 | input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); | 32 | m_input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, | 35 | void EmuWindow_Android::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, |
| 36 | float gyro_y, float gyro_z, float accel_x, | 36 | float gyro_y, float gyro_z, float accel_x, |
| 37 | float accel_y, float accel_z) { | 37 | float accel_y, float accel_z) { |
| 38 | input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, | 38 | m_input_subsystem->GetVirtualGamepad()->SetMotionState( |
| 39 | gyro_y, gyro_z, accel_x, accel_y, accel_z); | 39 | player_index, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, | 42 | EmuWindow_Android::EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem, |
| 43 | ANativeWindow* surface_) | 43 | ANativeWindow* surface, |
| 44 | : input_subsystem{input_subsystem_} { | 44 | std::shared_ptr<Common::DynamicLibrary> driver_library) |
| 45 | : m_input_subsystem{input_subsystem}, m_driver_library{driver_library} { | ||
| 45 | LOG_INFO(Frontend, "initializing"); | 46 | LOG_INFO(Frontend, "initializing"); |
| 46 | 47 | ||
| 47 | if (!surface_) { | 48 | if (!surface) { |
| 48 | LOG_CRITICAL(Frontend, "surface is nullptr"); | 49 | LOG_CRITICAL(Frontend, "surface is nullptr"); |
| 49 | return; | 50 | return; |
| 50 | } | 51 | } |
| 51 | 52 | ||
| 52 | window_width = ANativeWindow_getWidth(surface_); | 53 | m_window_width = ANativeWindow_getWidth(surface); |
| 53 | window_height = ANativeWindow_getHeight(surface_); | 54 | m_window_height = ANativeWindow_getHeight(surface); |
| 54 | 55 | ||
| 55 | // Ensures that we emulate with the correct aspect ratio. | 56 | // Ensures that we emulate with the correct aspect ratio. |
| 56 | UpdateCurrentFramebufferLayout(window_width, window_height); | 57 | UpdateCurrentFramebufferLayout(m_window_width, m_window_height); |
| 57 | 58 | ||
| 58 | host_window = surface_; | 59 | m_host_window = surface; |
| 59 | window_info.type = Core::Frontend::WindowSystemType::Android; | 60 | window_info.type = Core::Frontend::WindowSystemType::Android; |
| 60 | window_info.render_surface = reinterpret_cast<void*>(host_window); | 61 | window_info.render_surface = reinterpret_cast<void*>(m_host_window); |
| 61 | 62 | ||
| 62 | input_subsystem->Initialize(); | 63 | m_input_subsystem->Initialize(); |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | EmuWindow_Android::~EmuWindow_Android() { | 66 | EmuWindow_Android::~EmuWindow_Android() { |
| 66 | input_subsystem->Shutdown(); | 67 | m_input_subsystem->Shutdown(); |
| 67 | } | 68 | } |
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 544924caa..1c1edf62c 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 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <memory> | ||
| 4 | |||
| 3 | #include "core/frontend/emu_window.h" | 5 | #include "core/frontend/emu_window.h" |
| 6 | #include "core/frontend/graphics_context.h" | ||
| 4 | #include "input_common/main.h" | 7 | #include "input_common/main.h" |
| 5 | 8 | ||
| 6 | struct ANativeWindow; | 9 | struct ANativeWindow; |
| 7 | 10 | ||
| 8 | class SharedContext_Android : public Core::Frontend::GraphicsContext { | 11 | class GraphicsContext_Android final : public Core::Frontend::GraphicsContext { |
| 9 | public: | 12 | public: |
| 10 | SharedContext_Android() = default; | 13 | explicit GraphicsContext_Android(std::shared_ptr<Common::DynamicLibrary> driver_library) |
| 11 | ~SharedContext_Android() = default; | 14 | : m_driver_library{driver_library} {} |
| 12 | void MakeCurrent() override {} | 15 | |
| 13 | void DoneCurrent() override {} | 16 | ~GraphicsContext_Android() = default; |
| 17 | |||
| 18 | std::shared_ptr<Common::DynamicLibrary> GetDriverLibrary() override { | ||
| 19 | return m_driver_library; | ||
| 20 | } | ||
| 21 | |||
| 22 | private: | ||
| 23 | std::shared_ptr<Common::DynamicLibrary> m_driver_library; | ||
| 14 | }; | 24 | }; |
| 15 | 25 | ||
| 16 | class EmuWindow_Android : public Core::Frontend::EmuWindow { | 26 | class EmuWindow_Android final : public Core::Frontend::EmuWindow { |
| 27 | |||
| 17 | public: | 28 | public: |
| 18 | EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem_, ANativeWindow* surface_); | 29 | EmuWindow_Android(InputCommon::InputSubsystem* input_subsystem, ANativeWindow* surface, |
| 30 | std::shared_ptr<Common::DynamicLibrary> driver_library); | ||
| 31 | |||
| 19 | ~EmuWindow_Android(); | 32 | ~EmuWindow_Android(); |
| 20 | 33 | ||
| 21 | void OnSurfaceChanged(ANativeWindow* surface); | 34 | void OnSurfaceChanged(ANativeWindow* surface); |
| @@ -29,18 +42,20 @@ public: | |||
| 29 | void OnFrameDisplayed() override {} | 42 | void OnFrameDisplayed() override {} |
| 30 | 43 | ||
| 31 | std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override { | 44 | std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override { |
| 32 | return {std::make_unique<SharedContext_Android>()}; | 45 | return {std::make_unique<GraphicsContext_Android>(m_driver_library)}; |
| 33 | } | 46 | } |
| 34 | bool IsShown() const override { | 47 | bool IsShown() const override { |
| 35 | return true; | 48 | return true; |
| 36 | }; | 49 | }; |
| 37 | 50 | ||
| 38 | private: | 51 | private: |
| 39 | InputCommon::InputSubsystem* input_subsystem{}; | 52 | InputCommon::InputSubsystem* m_input_subsystem{}; |
| 53 | |||
| 54 | ANativeWindow* m_render_window{}; | ||
| 55 | ANativeWindow* m_host_window{}; | ||
| 40 | 56 | ||
| 41 | ANativeWindow* render_window{}; | 57 | float m_window_width{}; |
| 42 | ANativeWindow* host_window{}; | 58 | float m_window_height{}; |
| 43 | 59 | ||
| 44 | float window_width{}; | 60 | std::shared_ptr<Common::DynamicLibrary> m_driver_library; |
| 45 | float window_height{}; | ||
| 46 | }; | 61 | }; |
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 0a2a65721..a8f3d135e 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp | |||
| @@ -5,11 +5,15 @@ | |||
| 5 | #include <locale> | 5 | #include <locale> |
| 6 | #include <string> | 6 | #include <string> |
| 7 | #include <string_view> | 7 | #include <string_view> |
| 8 | #include <dlfcn.h> | ||
| 9 | |||
| 10 | #include <adrenotools/driver.h> | ||
| 8 | 11 | ||
| 9 | #include <android/api-level.h> | 12 | #include <android/api-level.h> |
| 10 | #include <android/native_window_jni.h> | 13 | #include <android/native_window_jni.h> |
| 11 | 14 | ||
| 12 | #include "common/detached_tasks.h" | 15 | #include "common/detached_tasks.h" |
| 16 | #include "common/dynamic_library.h" | ||
| 13 | #include "common/fs/path_util.h" | 17 | #include "common/fs/path_util.h" |
| 14 | #include "common/logging/backend.h" | 18 | #include "common/logging/backend.h" |
| 15 | #include "common/logging/log.h" | 19 | #include "common/logging/log.h" |
| @@ -70,6 +74,29 @@ public: | |||
| 70 | m_native_window = m_native_window_; | 74 | m_native_window = m_native_window_; |
| 71 | } | 75 | } |
| 72 | 76 | ||
| 77 | void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir, | ||
| 78 | const std::string& custom_driver_name, | ||
| 79 | const std::string& file_redirect_dir) { | ||
| 80 | void* handle{}; | ||
| 81 | |||
| 82 | // Try to load a custom driver. | ||
| 83 | if (custom_driver_name.size()) { | ||
| 84 | handle = adrenotools_open_libvulkan( | ||
| 85 | RTLD_NOW, ADRENOTOOLS_DRIVER_CUSTOM | ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr, | ||
| 86 | hook_lib_dir.c_str(), custom_driver_dir.c_str(), custom_driver_name.c_str(), | ||
| 87 | file_redirect_dir.c_str(), nullptr); | ||
| 88 | } | ||
| 89 | |||
| 90 | // Try to load the system driver. | ||
| 91 | if (!handle) { | ||
| 92 | handle = adrenotools_open_libvulkan(RTLD_NOW, ADRENOTOOLS_DRIVER_FILE_REDIRECT, nullptr, | ||
| 93 | hook_lib_dir.c_str(), nullptr, nullptr, | ||
| 94 | file_redirect_dir.c_str(), nullptr); | ||
| 95 | } | ||
| 96 | |||
| 97 | m_vulkan_library = std::make_shared<Common::DynamicLibrary>(handle); | ||
| 98 | } | ||
| 99 | |||
| 73 | bool IsRunning() const { | 100 | bool IsRunning() const { |
| 74 | std::scoped_lock lock(m_mutex); | 101 | std::scoped_lock lock(m_mutex); |
| 75 | return m_is_running; | 102 | return m_is_running; |
| @@ -94,7 +121,8 @@ public: | |||
| 94 | Config{}; | 121 | Config{}; |
| 95 | 122 | ||
| 96 | // Create the render window. | 123 | // Create the render window. |
| 97 | m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window); | 124 | m_window = std::make_unique<EmuWindow_Android>(&m_input_subsystem, m_native_window, |
| 125 | m_vulkan_library); | ||
| 98 | 126 | ||
| 99 | // Initialize system. | 127 | // Initialize system. |
| 100 | m_system.SetShuttingDown(false); | 128 | m_system.SetShuttingDown(false); |
| @@ -242,6 +270,9 @@ private: | |||
| 242 | Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; | 270 | Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized}; |
| 243 | bool m_is_running{}; | 271 | bool m_is_running{}; |
| 244 | 272 | ||
| 273 | // GPU driver parameters | ||
| 274 | std::shared_ptr<Common::DynamicLibrary> m_vulkan_library; | ||
| 275 | |||
| 245 | // Synchronization | 276 | // Synchronization |
| 246 | std::condition_variable_any m_cv; | 277 | std::condition_variable_any m_cv; |
| 247 | mutable std::mutex m_perf_stats_mutex; | 278 | mutable std::mutex m_perf_stats_mutex; |
| @@ -327,6 +358,14 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_SetAppDirectory(JNIEnv* env, | |||
| 327 | Common::FS::SetAppDirectory(GetJString(env, j_directory)); | 358 | Common::FS::SetAppDirectory(GetJString(env, j_directory)); |
| 328 | } | 359 | } |
| 329 | 360 | ||
| 361 | void JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver( | ||
| 362 | JNIEnv* env, [[maybe_unused]] jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir, | ||
| 363 | jstring custom_driver_name, jstring file_redirect_dir) { | ||
| 364 | EmulationSession::GetInstance().InitializeGpuDriver( | ||
| 365 | GetJString(env, hook_lib_dir), GetJString(env, custom_driver_dir), | ||
| 366 | GetJString(env, custom_driver_name), GetJString(env, file_redirect_dir)); | ||
| 367 | } | ||
| 368 | |||
| 330 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, | 369 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, |
| 331 | [[maybe_unused]] jclass clazz) { | 370 | [[maybe_unused]] jclass clazz) { |
| 332 | Core::Crypto::KeyManager::Instance().ReloadKeys(); | 371 | Core::Crypto::KeyManager::Instance().ReloadKeys(); |
| @@ -363,7 +402,8 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadButtonEvent([[maybe_unus | |||
| 363 | [[maybe_unused]] jint j_device, | 402 | [[maybe_unused]] jint j_device, |
| 364 | jint j_button, jint action) { | 403 | jint j_button, jint action) { |
| 365 | if (EmulationSession::GetInstance().IsRunning()) { | 404 | if (EmulationSession::GetInstance().IsRunning()) { |
| 366 | EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device,j_button, action != 0); | 405 | EmulationSession::GetInstance().Window().OnGamepadButtonEvent(j_device, j_button, |
| 406 | action != 0); | ||
| 367 | } | 407 | } |
| 368 | return static_cast<jboolean>(true); | 408 | return static_cast<jboolean>(true); |
| 369 | } | 409 | } |
| @@ -373,31 +413,33 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadJoystickEvent([[maybe_un | |||
| 373 | jint j_device, jint stick_id, | 413 | jint j_device, jint stick_id, |
| 374 | jfloat x, jfloat y) { | 414 | jfloat x, jfloat y) { |
| 375 | if (EmulationSession::GetInstance().IsRunning()) { | 415 | if (EmulationSession::GetInstance().IsRunning()) { |
| 376 | EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device,stick_id, x, y); | 416 | EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(j_device, stick_id, x, y); |
| 377 | } | 417 | } |
| 378 | return static_cast<jboolean>(true); | 418 | return static_cast<jboolean>(true); |
| 379 | } | 419 | } |
| 380 | 420 | ||
| 381 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent([[maybe_unused]] JNIEnv* env, | 421 | jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_onGamePadMotionEvent( |
| 382 | [[maybe_unused]] jclass clazz, jint j_device,jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, | 422 | [[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint j_device, |
| 383 | jfloat gyro_z, jfloat accel_x, jfloat accel_y, jfloat accel_z){ | 423 | jlong delta_timestamp, jfloat gyro_x, jfloat gyro_y, jfloat gyro_z, jfloat accel_x, |
| 424 | jfloat accel_y, jfloat accel_z) { | ||
| 384 | if (EmulationSession::GetInstance().IsRunning()) { | 425 | if (EmulationSession::GetInstance().IsRunning()) { |
| 385 | EmulationSession::GetInstance().Window().OnGamepadMotionEvent(j_device,delta_timestamp, gyro_x, gyro_y,gyro_z,accel_x,accel_y,accel_z); | 426 | EmulationSession::GetInstance().Window().OnGamepadMotionEvent( |
| 427 | j_device, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z); | ||
| 386 | } | 428 | } |
| 387 | return static_cast<jboolean>(true); | 429 | return static_cast<jboolean>(true); |
| 388 | } | 430 | } |
| 389 | 431 | ||
| 390 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchPressed([[maybe_unused]] JNIEnv* env, | 432 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchPressed([[maybe_unused]] JNIEnv* env, |
| 391 | [[maybe_unused]] jclass clazz, jint id, jfloat x, | 433 | [[maybe_unused]] jclass clazz, jint id, |
| 392 | jfloat y) { | 434 | jfloat x, jfloat y) { |
| 393 | if (EmulationSession::GetInstance().IsRunning()) { | 435 | if (EmulationSession::GetInstance().IsRunning()) { |
| 394 | EmulationSession::GetInstance().Window().OnTouchPressed(id, x, y); | 436 | EmulationSession::GetInstance().Window().OnTouchPressed(id, x, y); |
| 395 | } | 437 | } |
| 396 | } | 438 | } |
| 397 | 439 | ||
| 398 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env, | 440 | void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchMoved([[maybe_unused]] JNIEnv* env, |
| 399 | [[maybe_unused]] jclass clazz, jint id, jfloat x, | 441 | [[maybe_unused]] jclass clazz, jint id, |
| 400 | jfloat y) { | 442 | jfloat x, jfloat y) { |
| 401 | if (EmulationSession::GetInstance().IsRunning()) { | 443 | if (EmulationSession::GetInstance().IsRunning()) { |
| 402 | EmulationSession::GetInstance().Window().OnTouchMoved(id, x, y); | 444 | EmulationSession::GetInstance().Window().OnTouchMoved(id, x, y); |
| 403 | } | 445 | } |
diff --git a/src/android/app/src/main/jni/native.h b/src/android/app/src/main/jni/native.h index bbc783aa8..f799560e4 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 | |||
| 71 | jclass clazz, | 71 | jclass clazz, |
| 72 | jstring j_directory); | 72 | jstring j_directory); |
| 73 | 73 | ||
| 74 | JNIEXPORT void JNICALL | ||
| 75 | Java_org_yuzu_yuzu_1emu_NativeLibrary_Java_org_yuzu_yuzu_1emu_NativeLibrary_InitializeGpuDriver( | ||
| 76 | JNIEnv* env, jclass clazz, jstring hook_lib_dir, jstring custom_driver_dir, | ||
| 77 | jstring custom_driver_name, jstring file_redirect_dir); | ||
| 78 | |||
| 74 | JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, | 79 | JNIEXPORT jboolean JNICALL Java_org_yuzu_yuzu_1emu_NativeLibrary_ReloadKeys(JNIEnv* env, |
| 75 | jclass clazz); | 80 | jclass clazz); |
| 76 | 81 | ||
diff --git a/src/core/frontend/graphics_context.h b/src/core/frontend/graphics_context.h index 064b19a96..7554c1583 100644 --- a/src/core/frontend/graphics_context.h +++ b/src/core/frontend/graphics_context.h | |||
| @@ -3,8 +3,9 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <optional> | 6 | #include <memory> |
| 7 | #include <string> | 7 | |
| 8 | #include "common/dynamic_library.h" | ||
| 8 | 9 | ||
| 9 | namespace Core::Frontend { | 10 | namespace Core::Frontend { |
| 10 | 11 | ||
| @@ -24,16 +25,8 @@ public: | |||
| 24 | /// Releases (dunno if this is the "right" word) the context from the caller thread | 25 | /// Releases (dunno if this is the "right" word) the context from the caller thread |
| 25 | virtual void DoneCurrent() {} | 26 | virtual void DoneCurrent() {} |
| 26 | 27 | ||
| 27 | /// Parameters used to configure custom drivers (used by Android only) | 28 | /// Gets the GPU driver library (used by Android only) |
| 28 | struct CustomDriverParameters { | 29 | virtual std::shared_ptr<Common::DynamicLibrary> GetDriverLibrary() { |
| 29 | std::string hook_lib_dir; | ||
| 30 | std::string custom_driver_dir; | ||
| 31 | std::string custom_driver_name; | ||
| 32 | std::string file_redirect_dir; | ||
| 33 | }; | ||
| 34 | |||
| 35 | /// Gets custom driver parameters configured by the frontend (used by Android only) | ||
| 36 | virtual std::optional<CustomDriverParameters> GetCustomDriverParameters() { | ||
| 37 | return {}; | 30 | return {}; |
| 38 | } | 31 | } |
| 39 | 32 | ||
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index fbcf4c1d3..30dc69f13 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_, | |||
| 84 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, | 84 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, |
| 85 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) try | 85 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) try |
| 86 | : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_), | 86 | : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_), |
| 87 | cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary()), | 87 | cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())), |
| 88 | instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, | 88 | instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, |
| 89 | Settings::values.renderer_debug.GetValue())), | 89 | Settings::values.renderer_debug.GetValue())), |
| 90 | debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), | 90 | debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), |
| 91 | surface(CreateSurface(instance, render_window.GetWindowInfo())), | 91 | 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 f44367cb2..3c63a2004 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -63,7 +63,7 @@ private: | |||
| 63 | Core::Memory::Memory& cpu_memory; | 63 | Core::Memory::Memory& cpu_memory; |
| 64 | Tegra::GPU& gpu; | 64 | Tegra::GPU& gpu; |
| 65 | 65 | ||
| 66 | Common::DynamicLibrary library; | 66 | std::shared_ptr<Common::DynamicLibrary> library; |
| 67 | vk::InstanceDispatch dld; | 67 | vk::InstanceDispatch dld; |
| 68 | 68 | ||
| 69 | vk::Instance instance; | 69 | vk::Instance instance; |
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 63e1c7d63..40cdf2fde 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 | |||
| 314 | const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; | 314 | const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; |
| 315 | const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; | 315 | const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY; |
| 316 | const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; | 316 | const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK; |
| 317 | const bool is_adreno = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; | 317 | const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY; |
| 318 | const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; | 318 | const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP; |
| 319 | 319 | ||
| 320 | if ((is_mvk || is_adreno) && !is_suitable) { | 320 | if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) { |
| 321 | LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); | 321 | LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway"); |
| 322 | } else if (!is_suitable) { | 322 | } else if (!is_suitable) { |
| 323 | throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); | 323 | throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER); |
| @@ -362,14 +362,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 362 | CollectToolingInfo(); | 362 | CollectToolingInfo(); |
| 363 | 363 | ||
| 364 | #ifdef ANDROID | 364 | #ifdef ANDROID |
| 365 | if (is_adreno) { | 365 | if (is_qualcomm) { |
| 366 | must_emulate_scaled_formats = true; | 366 | must_emulate_scaled_formats = true; |
| 367 | 367 | ||
| 368 | LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); | 368 | LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state"); |
| 369 | extensions.extended_dynamic_state = false; | 369 | extensions.extended_dynamic_state = false; |
| 370 | loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); | 370 | loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); |
| 371 | 371 | ||
| 372 | LOG_WARNING(Render_Vulkan, "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); | 372 | LOG_WARNING(Render_Vulkan, |
| 373 | "Adreno drivers have a slow VK_KHR_push_descriptor implementation"); | ||
| 373 | extensions.push_descriptor = false; | 374 | extensions.push_descriptor = false; |
| 374 | loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); | 375 | loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); |
| 375 | 376 | ||
| @@ -392,6 +393,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 392 | } | 393 | } |
| 393 | } | 394 | } |
| 394 | 395 | ||
| 396 | const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY; | ||
| 395 | if (is_arm) { | 397 | if (is_arm) { |
| 396 | must_emulate_scaled_formats = true; | 398 | must_emulate_scaled_formats = true; |
| 397 | 399 | ||
| @@ -513,7 +515,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 513 | LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); | 515 | LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits"); |
| 514 | cant_blit_msaa = true; | 516 | cant_blit_msaa = true; |
| 515 | } | 517 | } |
| 516 | if (is_intel_anv || is_adreno) { | 518 | if (is_intel_anv || is_qualcomm) { |
| 517 | LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); | 519 | LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format"); |
| 518 | must_emulate_bgr565 = true; | 520 | must_emulate_bgr565 = true; |
| 519 | } | 521 | } |
diff --git a/src/video_core/vulkan_common/vulkan_library.cpp b/src/video_core/vulkan_common/vulkan_library.cpp index 4eb3913ee..9a7d369f3 100644 --- a/src/video_core/vulkan_common/vulkan_library.cpp +++ b/src/video_core/vulkan_common/vulkan_library.cpp | |||
| @@ -10,29 +10,35 @@ | |||
| 10 | 10 | ||
| 11 | namespace Vulkan { | 11 | namespace Vulkan { |
| 12 | 12 | ||
| 13 | Common::DynamicLibrary OpenLibrary() { | 13 | std::shared_ptr<Common::DynamicLibrary> OpenLibrary( |
| 14 | [[maybe_unused]] Core::Frontend::GraphicsContext* context) { | ||
| 14 | LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); | 15 | LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); |
| 15 | Common::DynamicLibrary library; | 16 | #ifdef ANDROID |
| 17 | // Android manages its Vulkan driver from the frontend. | ||
| 18 | return context->GetDriverLibrary(); | ||
| 19 | #else | ||
| 20 | auto library = std::make_shared<Common::DynamicLibrary>(); | ||
| 16 | #ifdef __APPLE__ | 21 | #ifdef __APPLE__ |
| 17 | // Check if a path to a specific Vulkan library has been specified. | 22 | // Check if a path to a specific Vulkan library has been specified. |
| 18 | char* const libvulkan_env = std::getenv("LIBVULKAN_PATH"); | 23 | char* const libvulkan_env = std::getenv("LIBVULKAN_PATH"); |
| 19 | if (!libvulkan_env || !library.Open(libvulkan_env)) { | 24 | if (!libvulkan_env || !library->Open(libvulkan_env)) { |
| 20 | // Use the libvulkan.dylib from the application bundle. | 25 | // Use the libvulkan.dylib from the application bundle. |
| 21 | const auto filename = | 26 | const auto filename = |
| 22 | Common::FS::GetBundleDirectory() / "Contents/Frameworks/libvulkan.dylib"; | 27 | Common::FS::GetBundleDirectory() / "Contents/Frameworks/libvulkan.dylib"; |
| 23 | void(library.Open(Common::FS::PathToUTF8String(filename).c_str())); | 28 | void(library->Open(Common::FS::PathToUTF8String(filename).c_str())); |
| 24 | } | 29 | } |
| 25 | #else | 30 | #else |
| 26 | std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); | 31 | std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); |
| 27 | LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename); | 32 | LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename); |
| 28 | if (!library.Open(filename.c_str())) { | 33 | if (!library->Open(filename.c_str())) { |
| 29 | // Android devices may not have libvulkan.so.1, only libvulkan.so. | 34 | // Android devices may not have libvulkan.so.1, only libvulkan.so. |
| 30 | filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); | 35 | filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); |
| 31 | LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename); | 36 | LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename); |
| 32 | void(library.Open(filename.c_str())); | 37 | void(library->Open(filename.c_str())); |
| 33 | } | 38 | } |
| 34 | #endif | 39 | #endif |
| 35 | return library; | 40 | return library; |
| 41 | #endif | ||
| 36 | } | 42 | } |
| 37 | 43 | ||
| 38 | } // namespace Vulkan | 44 | } // namespace Vulkan |
diff --git a/src/video_core/vulkan_common/vulkan_library.h b/src/video_core/vulkan_common/vulkan_library.h index 364ca979b..e1734525e 100644 --- a/src/video_core/vulkan_common/vulkan_library.h +++ b/src/video_core/vulkan_common/vulkan_library.h | |||
| @@ -3,10 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <memory> | ||
| 7 | |||
| 6 | #include "common/dynamic_library.h" | 8 | #include "common/dynamic_library.h" |
| 9 | #include "core/frontend/graphics_context.h" | ||
| 7 | 10 | ||
| 8 | namespace Vulkan { | 11 | namespace Vulkan { |
| 9 | 12 | ||
| 10 | Common::DynamicLibrary OpenLibrary(); | 13 | std::shared_ptr<Common::DynamicLibrary> OpenLibrary( |
| 14 | [[maybe_unused]] Core::Frontend::GraphicsContext* context = nullptr); | ||
| 11 | 15 | ||
| 12 | } // namespace Vulkan | 16 | } // namespace Vulkan |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index f316b598c..431585216 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -515,8 +515,8 @@ void ConfigureGraphics::RetrieveVulkanDevices() try { | |||
| 515 | auto wsi = QtCommon::GetWindowSystemInfo(window); | 515 | auto wsi = QtCommon::GetWindowSystemInfo(window); |
| 516 | 516 | ||
| 517 | vk::InstanceDispatch dld; | 517 | vk::InstanceDispatch dld; |
| 518 | const Common::DynamicLibrary library = OpenLibrary(); | 518 | const auto library = OpenLibrary(); |
| 519 | const vk::Instance instance = CreateInstance(library, dld, VK_API_VERSION_1_1, wsi.type); | 519 | const vk::Instance instance = CreateInstance(*library, dld, VK_API_VERSION_1_1, wsi.type); |
| 520 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); | 520 | const std::vector<VkPhysicalDevice> physical_devices = instance.EnumeratePhysicalDevices(); |
| 521 | vk::SurfaceKHR surface = CreateSurface(instance, wsi); | 521 | vk::SurfaceKHR surface = CreateSurface(instance, wsi); |
| 522 | 522 | ||
diff --git a/src/yuzu/startup_checks.cpp b/src/yuzu/startup_checks.cpp index 5e1f76339..6eefc94ed 100644 --- a/src/yuzu/startup_checks.cpp +++ b/src/yuzu/startup_checks.cpp | |||
| @@ -25,9 +25,9 @@ void CheckVulkan() { | |||
| 25 | // Just start the Vulkan loader, this will crash if something is wrong | 25 | // Just start the Vulkan loader, this will crash if something is wrong |
| 26 | try { | 26 | try { |
| 27 | Vulkan::vk::InstanceDispatch dld; | 27 | Vulkan::vk::InstanceDispatch dld; |
| 28 | const Common::DynamicLibrary library = Vulkan::OpenLibrary(); | 28 | const auto library = Vulkan::OpenLibrary(); |
| 29 | const Vulkan::vk::Instance instance = | 29 | const Vulkan::vk::Instance instance = |
| 30 | Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_1); | 30 | Vulkan::CreateInstance(*library, dld, VK_API_VERSION_1_1); |
| 31 | 31 | ||
| 32 | } catch (const Vulkan::vk::Exception& exception) { | 32 | } catch (const Vulkan::vk::Exception& exception) { |
| 33 | fmt::print(stderr, "Failed to initialize Vulkan: {}\n", exception.what()); | 33 | fmt::print(stderr, "Failed to initialize Vulkan: {}\n", exception.what()); |