diff --git a/app/src/main/cpp/skyline/common/android_settings.h b/app/src/main/cpp/skyline/common/android_settings.h index 1c27f543..ca7e7553 100644 --- a/app/src/main/cpp/skyline/common/android_settings.h +++ b/app/src/main/cpp/skyline/common/android_settings.h @@ -43,6 +43,7 @@ namespace skyline { executorSlotCountScale = ktSettings.GetInt("executorSlotCountScale"); executorFlushThreshold = ktSettings.GetInt("executorFlushThreshold"); useDirectMemoryImport = ktSettings.GetBool("useDirectMemoryImport"); + forceMaxGpuClocks = ktSettings.GetBool("forceMaxGpuClocks"); enableFastGpuReadbackHack = ktSettings.GetBool("enableFastGpuReadbackHack"); isAudioOutputDisabled = ktSettings.GetBool("isAudioOutputDisabled"); validationLayer = ktSettings.GetBool("validationLayer"); diff --git a/app/src/main/cpp/skyline/common/settings.h b/app/src/main/cpp/skyline/common/settings.h index cee2c07a..9079c71d 100644 --- a/app/src/main/cpp/skyline/common/settings.h +++ b/app/src/main/cpp/skyline/common/settings.h @@ -75,6 +75,7 @@ namespace skyline { Setting executorSlotCountScale; //!< Number of GPU executor slots that can be used concurrently Setting executorFlushThreshold; //!< Number of commands that need to accumulate before they're flushed to the GPU Setting useDirectMemoryImport; //!< If buffer emulation should be done by importing guest buffer mappings + Setting forceMaxGpuClocks; //!< If the GPU should be forced to run at maximum clocks // Hacks Setting enableFastGpuReadbackHack; //!< If the CPU texture readback skipping hack should be used diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp index de510eb3..c259c634 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.cpp @@ -2,6 +2,7 @@ // Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/) #include +#include #include #include #include @@ -195,13 +196,29 @@ namespace skyline::gpu::interconnect { void ExecutionWaiterThread::Run() { signal::SetSignalHandler({SIGSEGV}, nce::NCE::HostSignalHandler); // We may access NCE trapped memory + // Enable turbo clocks to begin with if requested + if (*state.settings->forceMaxGpuClocks) + adrenotools_set_turbo(true); + while (true) { std::pair, std::function> item{}; { std::unique_lock lock{mutex}; - idle = true; - condition.wait(lock, [this] { return !pendingSignalQueue.empty(); }); - idle = false; + if (pendingSignalQueue.empty()) { + idle = true; + + // Don't force turbo clocks when the GPU is idle + if (*state.settings->forceMaxGpuClocks) + adrenotools_set_turbo(false); + + condition.wait(lock, [this] { return !pendingSignalQueue.empty(); }); + + // Once we have work to do, force turbo clocks is enabled + if (*state.settings->forceMaxGpuClocks) + adrenotools_set_turbo(true); + + idle = false; + } item = std::move(pendingSignalQueue.front()); pendingSignalQueue.pop(); } @@ -216,7 +233,7 @@ namespace skyline::gpu::interconnect { } } - ExecutionWaiterThread::ExecutionWaiterThread() : thread{&ExecutionWaiterThread::Run, this} {} + ExecutionWaiterThread::ExecutionWaiterThread(const DeviceState &state) : state{state}, thread{&ExecutionWaiterThread::Run, this} {} bool ExecutionWaiterThread::IsIdle() const { return idle; @@ -232,6 +249,7 @@ namespace skyline::gpu::interconnect { : state{state}, gpu{*state.gpu}, recordThread{state}, + waiterThread{state}, tag{AllocateTag()} { RotateRecordSlot(); } diff --git a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h index fbb79840..4fd4d0bd 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/command_executor.h @@ -97,6 +97,7 @@ namespace skyline::gpu::interconnect { */ class ExecutionWaiterThread { private: + const DeviceState &state; std::thread thread; std::mutex mutex; std::condition_variable condition; @@ -106,7 +107,7 @@ namespace skyline::gpu::interconnect { void Run(); public: - ExecutionWaiterThread(); + ExecutionWaiterThread(const DeviceState &state); bool IsIdle() const; diff --git a/app/src/main/java/emu/skyline/EmulationActivity.kt b/app/src/main/java/emu/skyline/EmulationActivity.kt index a7daacf1..a7644ba3 100644 --- a/app/src/main/java/emu/skyline/EmulationActivity.kt +++ b/app/src/main/java/emu/skyline/EmulationActivity.kt @@ -256,8 +256,6 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo force60HzRefreshRate(!preferenceSettings.maxRefreshRate) getSystemService()?.registerDisplayListener(this, null) - if (preferenceSettings.forceMaxGpuClocks) - GpuDriverHelper.forceMaxGpuClocks(true) binding.gameView.setOnTouchListener(this) @@ -291,9 +289,6 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo override fun onResume() { super.onResume() - if (preferenceSettings.forceMaxGpuClocks) - GpuDriverHelper.forceMaxGpuClocks(true) - changeAudioStatus(true) if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { diff --git a/app/src/main/java/emu/skyline/utils/NativeSettings.kt b/app/src/main/java/emu/skyline/utils/NativeSettings.kt index 2f63da16..253a2917 100644 --- a/app/src/main/java/emu/skyline/utils/NativeSettings.kt +++ b/app/src/main/java/emu/skyline/utils/NativeSettings.kt @@ -29,6 +29,7 @@ class NativeSettings(context : Context, pref : PreferenceSettings) { var executorSlotCountScale : Int = pref.executorSlotCountScale var executorFlushThreshold : Int = pref.executorFlushThreshold var useDirectMemoryImport : Boolean = pref.useDirectMemoryImport + var forceMaxGpuClocks : Boolean = pref.forceMaxGpuClocks // Hacks var enableFastGpuReadbackHack : Boolean = pref.enableFastGpuReadbackHack