Add a setting to force maximum GPU clocks on KGSL devices

This commit is contained in:
Billy Laws 2022-12-24 20:38:51 +00:00
parent 83ecc33a77
commit 77214a98dd
8 changed files with 64 additions and 6 deletions

View File

@ -5,6 +5,7 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <vulkan/vulkan_raii.hpp>
#include <adrenotools/driver.h>
#include "skyline/common/signal.h"
#include "skyline/common/utils.h"
@ -28,9 +29,22 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_emu_skyline_utils_GpuDriverHelper
return array;
}
extern "C" JNIEXPORT jboolean JNICALL Java_emu_skyline_utils_GpuDriverHelper_00024Companion_supportsCustomDriverLoading(JNIEnv *env, jobject instance) {
// Check if the Qualcomm KGSL (Kernel Graphics Support Layer) device exists, this indicates that custom drivers can be loaded
static bool CheckKgslPresent() {
constexpr auto KgslPath{"/dev/kgsl-3d0"};
return access(KgslPath, F_OK) == 0;
}
extern "C" JNIEXPORT jboolean JNICALL Java_emu_skyline_utils_GpuDriverHelper_00024Companion_supportsCustomDriverLoading(JNIEnv *env, jobject instance) {
// If the KGSL device exists custom drivers can be loaded using adrenotools
return CheckKgslPresent();
}
extern "C" JNIEXPORT jboolean JNICALL Java_emu_skyline_utils_GpuDriverHelper_00024Companion_supportsForceMaxGpuClocks(JNIEnv *env, jobject instance) {
// If the KGSL device exists adrenotools can be used to set GPU turbo mode
return CheckKgslPresent();
}
extern "C" JNIEXPORT void JNICALL Java_emu_skyline_utils_GpuDriverHelper_00024Companion_forceMaxGpuClocks(JNIEnv *env, jobject instance, jboolean enable) {
adrenotools_set_turbo(enable);
}

View File

@ -256,6 +256,8 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
force60HzRefreshRate(!preferenceSettings.maxRefreshRate)
getSystemService<DisplayManager>()?.registerDisplayListener(this, null)
if (preferenceSettings.forceMaxGpuClocks)
GpuDriverHelper.forceMaxGpuClocks(true)
binding.gameView.setOnTouchListener(this)
@ -280,12 +282,18 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
override fun onPause() {
super.onPause()
if (preferenceSettings.forceMaxGpuClocks)
GpuDriverHelper.forceMaxGpuClocks(false)
changeAudioStatus(false)
}
override fun onResume() {
super.onResume()
if (preferenceSettings.forceMaxGpuClocks)
GpuDriverHelper.forceMaxGpuClocks(true)
changeAudioStatus(true)
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
@ -314,13 +322,15 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
super.onDestroy()
shouldFinish = false
stopEmulation(false)
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
vibrators.clear()
// Stop forcing 60Hz on exit to allow the skyline UI to run at high refresh rates
getSystemService<DisplayManager>()?.unregisterDisplayListener(this)
force60HzRefreshRate(false)
if (preferenceSettings.forceMaxGpuClocks)
GpuDriverHelper.forceMaxGpuClocks(false)
stopEmulation(false)
vibrators.forEach { (_, vibrator) -> vibrator.cancel() }
vibrators.clear()
}
override fun surfaceCreated(holder : SurfaceHolder) {

View File

@ -36,6 +36,7 @@ import emu.skyline.loader.AppEntry
import emu.skyline.loader.LoaderResult
import emu.skyline.loader.RomFormat
import emu.skyline.provider.DocumentsProvider
import emu.skyline.utils.GpuDriverHelper
import emu.skyline.utils.PreferenceSettings
import emu.skyline.utils.WindowInsetsHelper
import javax.inject.Inject
@ -278,6 +279,10 @@ class MainActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
// Try to return to normal GPU clocks upon resuming back to main activity, to avoid GPU being stuck at max clocks after a crash
if (preferenceSettings.forceMaxGpuClocks)
GpuDriverHelper.forceMaxGpuClocks(false)
var layoutTypeChanged = false
for (appViewItem in adapter.allItems.filterIsInstance(AppViewItem::class.java)) {
if (layoutType != appViewItem.layoutType) {

View File

@ -16,7 +16,9 @@ import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import emu.skyline.databinding.SettingsActivityBinding
import emu.skyline.preference.IntegerListPreference
import emu.skyline.utils.GpuDriverHelper
import emu.skyline.utils.WindowInsetsHelper
import emu.skyline.utils.sharedPreferences
class SettingsActivity : AppCompatActivity() {
val binding by lazy { SettingsActivityBinding.inflate(layoutInflater) }
@ -108,6 +110,13 @@ class SettingsActivity : AppCompatActivity() {
findPreference<Preference>("category_debug")?.isVisible = true
if (!GpuDriverHelper.supportsForceMaxGpuClocks()) {
val forceMaxGpuClocksPref = findPreference<CheckBoxPreference>("force_max_gpu_clocks")!!
forceMaxGpuClocksPref.isSelectable = false
forceMaxGpuClocksPref.isChecked = false
forceMaxGpuClocksPref.summary = context!!.getString(R.string.force_max_gpu_clocks_desc_unsupported)
}
resources.getStringArray(R.array.credits_entries).asIterable().shuffled().forEach {
findPreference<PreferenceCategory>("category_credits")?.addPreference(Preference(context!!).apply {
title = it

View File

@ -36,6 +36,17 @@ interface GpuDriverHelper {
*/
external fun supportsCustomDriverLoading() : Boolean
/**
* Queries the driver for manual max clock forcing support
*/
external fun supportsForceMaxGpuClocks() : Boolean
/**
* Calls into the driver to force the GPU to run at the maximum possible clock speed
* @param force Whether to enable or disable the forced clocks
*/
external fun forceMaxGpuClocks(enable : Boolean)
/**
* Returns the list of installed gpu drivers.
* @return A map from the folder the driver is installed to the metadata of the driver

View File

@ -40,6 +40,7 @@ class PreferenceSettings @Inject constructor(@ApplicationContext private val con
// GPU
var gpuDriver by sharedPreferences(context, SYSTEM_GPU_DRIVER)
var executorSlotCountScale by sharedPreferences(context, 6)
var forceMaxGpuClocks by sharedPreferences(context, false)
// Hacks
var enableFastGpuReadbackHack by sharedPreferences(context, false)

View File

@ -77,6 +77,9 @@
<string name="respect_display_cutout_disabled">Allow UI elements to be drawn in the cutout area</string>
<string name="executor_slot_count_scale">Executor Slot Count Scale</string>
<string name="executor_slot_count_scale_desc">Scale controlling the maximum number of simultaneous GPU executions (Higher may sometimes perform better but will use more RAM)</string>
<string name="force_max_gpu_clocks">Force Maximum GPU Clocks</string>
<string name="force_max_gpu_clocks_desc">Forces the GPU to run at its maximum possible clock speed (May cause excessive heating and power usage)</string>
<string name="force_max_gpu_clocks_desc_unsupported">Your device does not support forcing maximum GPU clocks</string>
<!-- Settings - Hacks -->
<string name="hacks">Hacks</string>
<string name="enable_fast_gpu_readback">Enable fast GPU readback</string>

View File

@ -138,6 +138,11 @@
app:key="executor_slot_count_scale"
app:title="@string/executor_slot_count_scale"
app:showSeekBarValue="true" />
<CheckBoxPreference
android:defaultValue="false"
android:summary="@string/force_max_gpu_clocks_desc"
app:key="force_max_gpu_clocks"
app:title="@string/force_max_gpu_clocks" />
</PreferenceCategory>
<PreferenceCategory
android:key="category_hacks"