mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 11:11:49 +01:00
Dynamically apply GPU turbo clocks only when GPU submissions are queued
Allows for the GPU to clock down in cases where it's idle for most of the time, while still forcing maximum clocks when we care.
This commit is contained in:
parent
81f3ff348c
commit
28b2a7a8a1
@ -43,6 +43,7 @@ namespace skyline {
|
||||
executorSlotCountScale = ktSettings.GetInt<u32>("executorSlotCountScale");
|
||||
executorFlushThreshold = ktSettings.GetInt<u32>("executorFlushThreshold");
|
||||
useDirectMemoryImport = ktSettings.GetBool("useDirectMemoryImport");
|
||||
forceMaxGpuClocks = ktSettings.GetBool("forceMaxGpuClocks");
|
||||
enableFastGpuReadbackHack = ktSettings.GetBool("enableFastGpuReadbackHack");
|
||||
isAudioOutputDisabled = ktSettings.GetBool("isAudioOutputDisabled");
|
||||
validationLayer = ktSettings.GetBool("validationLayer");
|
||||
|
@ -75,6 +75,7 @@ namespace skyline {
|
||||
Setting<u32> executorSlotCountScale; //!< Number of GPU executor slots that can be used concurrently
|
||||
Setting<u32> executorFlushThreshold; //!< Number of commands that need to accumulate before they're flushed to the GPU
|
||||
Setting<bool> useDirectMemoryImport; //!< If buffer emulation should be done by importing guest buffer mappings
|
||||
Setting<bool> forceMaxGpuClocks; //!< If the GPU should be forced to run at maximum clocks
|
||||
|
||||
// Hacks
|
||||
Setting<bool> enableFastGpuReadbackHack; //!< If the CPU texture readback skipping hack should be used
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <range/v3/view.hpp>
|
||||
#include <adrenotools/driver.h>
|
||||
#include <common/settings.h>
|
||||
#include <loader/loader.h>
|
||||
#include <gpu.h>
|
||||
@ -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::shared_ptr<FenceCycle>, std::function<void()>> 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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -256,8 +256,6 @@ 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)
|
||||
|
||||
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user