Support loading a user-selected driver during vulkan initialization

This commit is contained in:
lynxnb 2022-07-30 17:29:40 +02:00 committed by Mark Collins
parent c812de48ea
commit 240e7033d7
5 changed files with 31 additions and 20 deletions

View File

@ -36,6 +36,8 @@ namespace skyline {
systemLanguage = ktSettings.GetInt<skyline::language::SystemLanguage>("systemLanguage"); systemLanguage = ktSettings.GetInt<skyline::language::SystemLanguage>("systemLanguage");
forceTripleBuffering = ktSettings.GetBool("forceTripleBuffering"); forceTripleBuffering = ktSettings.GetBool("forceTripleBuffering");
disableFrameThrottling = ktSettings.GetBool("disableFrameThrottling"); disableFrameThrottling = ktSettings.GetBool("disableFrameThrottling");
gpuDriver = ktSettings.GetString("gpuDriver");
gpuDriverLibraryName = ktSettings.GetString("gpuDriverLibraryName");
}; };
}; };
} }

View File

@ -67,6 +67,10 @@ namespace skyline {
Setting<bool> forceTripleBuffering; //!< If the presentation engine should always triple buffer even if the swapchain supports double buffering Setting<bool> forceTripleBuffering; //!< If the presentation engine should always triple buffer even if the swapchain supports double buffering
Setting<bool> disableFrameThrottling; //!< Allow the guest to submit frames without any blocking calls Setting<bool> disableFrameThrottling; //!< Allow the guest to submit frames without any blocking calls
// GPU
Setting<std::string> gpuDriver; //!< The label of the GPU driver to use
Setting<std::string> gpuDriverLibraryName; //!< The name of the GPU driver library to use
Settings() = default; Settings() = default;
virtual ~Settings() = default; virtual ~Settings() = default;

View File

@ -5,6 +5,7 @@
#include <adrenotools/driver.h> #include <adrenotools/driver.h>
#include <os.h> #include <os.h>
#include <jvm.h> #include <jvm.h>
#include <common/settings.h>
#include "gpu.h" #include "gpu.h"
namespace skyline::gpu { namespace skyline::gpu {
@ -332,30 +333,29 @@ namespace skyline::gpu {
} }
static PFN_vkGetInstanceProcAddr LoadVulkanDriver(const DeviceState &state) { static PFN_vkGetInstanceProcAddr LoadVulkanDriver(const DeviceState &state) {
// Try turnip first, if not then fallback to regular with file redirect then plain dlopen void *libvulkanHandle{};
auto libvulkanHandle{adrenotools_open_libvulkan(
RTLD_NOW, // If the user has selected a custom driver, try to load it
ADRENOTOOLS_DRIVER_CUSTOM, if (!(*state.settings->gpuDriver).empty()) {
nullptr, // We require Android 10 so don't need to supply
state.os->nativeLibraryPath.c_str(),
(state.os->privateAppFilesPath + "gpu/turnip/").c_str(),
"libvulkan_freedreno.so",
nullptr
)};
if (!libvulkanHandle) {
libvulkanHandle = adrenotools_open_libvulkan( libvulkanHandle = adrenotools_open_libvulkan(
RTLD_NOW, RTLD_NOW,
ADRENOTOOLS_DRIVER_FILE_REDIRECT, ADRENOTOOLS_DRIVER_FILE_REDIRECT | ADRENOTOOLS_DRIVER_CUSTOM,
nullptr, // We require Android 10 so don't need to supply nullptr, // We require Android 10 so don't need to supply
state.os->nativeLibraryPath.c_str(), state.os->nativeLibraryPath.c_str(),
nullptr, (state.os->privateAppFilesPath + "gpu_drivers/" + *state.settings->gpuDriver + "/").c_str(),
nullptr, (*state.settings->gpuDriverLibraryName).c_str(),
(state.os->publicAppFilesPath + "gpu/vk_file_redirect/").c_str() (state.os->publicAppFilesPath + "gpu/vk_file_redirect/").c_str()
); );
if (!libvulkanHandle)
libvulkanHandle = dlopen("libvulkan.so", RTLD_NOW); if (!libvulkanHandle) {
char *error = dlerror();
Logger::Warn("Failed to load custom Vulkan driver {}/{}: {}", *state.settings->gpuDriver, *state.settings->gpuDriverLibraryName, error ? error : "");
}
} }
if (!libvulkanHandle)
libvulkanHandle = dlopen("libvulkan.so", RTLD_NOW);
return reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libvulkanHandle, "vkGetInstanceProcAddr")); return reinterpret_cast<PFN_vkGetInstanceProcAddr>(dlsym(libvulkanHandle, "vkGetInstanceProcAddr"));
} }

View File

@ -28,16 +28,16 @@ import emu.skyline.applet.swkbd.SoftwareKeyboardDialog
import emu.skyline.databinding.EmuActivityBinding import emu.skyline.databinding.EmuActivityBinding
import emu.skyline.input.* import emu.skyline.input.*
import emu.skyline.loader.getRomFormat import emu.skyline.loader.getRomFormat
import emu.skyline.utils.PreferenceSettings
import emu.skyline.utils.ByteBufferSerializable import emu.skyline.utils.ByteBufferSerializable
import emu.skyline.utils.GpuDriverHelper
import emu.skyline.utils.NativeSettings import emu.skyline.utils.NativeSettings
import emu.skyline.utils.PreferenceSettings
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder
import java.util.concurrent.FutureTask import java.util.concurrent.FutureTask
import javax.inject.Inject import javax.inject.Inject
import kotlin.math.abs import kotlin.math.abs
@AndroidEntryPoint @AndroidEntryPoint
class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTouchListener, DisplayManager.DisplayListener { class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTouchListener, DisplayManager.DisplayListener {
companion object { companion object {
@ -248,8 +248,9 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
val romType = getRomFormat(rom, contentResolver).ordinal val romType = getRomFormat(rom, contentResolver).ordinal
val romFd = contentResolver.openFileDescriptor(rom, "r")!! val romFd = contentResolver.openFileDescriptor(rom, "r")!!
GpuDriverHelper.ensureFileRedirectDir(this)
emulationThread = Thread { emulationThread = Thread {
executeApplication(rom.toString(), romType, romFd.detachFd(), NativeSettings(preferenceSettings), applicationContext.getPublicFilesDir().canonicalPath + "/", applicationContext.filesDir.canonicalPath + "/", applicationInfo.nativeLibraryDir + "/", assets) executeApplication(rom.toString(), romType, romFd.detachFd(), NativeSettings(this, preferenceSettings), applicationContext.getPublicFilesDir().canonicalPath + "/", applicationContext.filesDir.canonicalPath + "/", applicationInfo.nativeLibraryDir + "/", assets)
returnFromEmulation() returnFromEmulation()
} }

View File

@ -5,15 +5,19 @@
package emu.skyline.utils package emu.skyline.utils
import android.content.Context
/** /**
* The settings that will be passed to libskyline when running and executable * The settings that will be passed to libskyline when running and executable
*/ */
class NativeSettings(pref: PreferenceSettings) { class NativeSettings(context : Context, pref : PreferenceSettings) {
var isDocked : Boolean = pref.isDocked var isDocked : Boolean = pref.isDocked
var usernameValue : String = pref.usernameValue var usernameValue : String = pref.usernameValue
var systemLanguage : Int = pref.systemLanguage var systemLanguage : Int = pref.systemLanguage
var forceTripleBuffering : Boolean = pref.forceTripleBuffering var forceTripleBuffering : Boolean = pref.forceTripleBuffering
var disableFrameThrottling : Boolean = pref.disableFrameThrottling var disableFrameThrottling : Boolean = pref.disableFrameThrottling
var gpuDriver : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else pref.gpuDriver
var gpuDriverLibraryName : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else GpuDriverHelper.getLibraryName(context, pref.gpuDriver)
/** /**
* Updates settings in libskyline during emulation * Updates settings in libskyline during emulation