nvnflinger: allow locking framerate during video playback

master
Liam 2023-06-08 01:15:51 +07:00
parent 9c6fc44a59
commit 6c34adb1de
11 changed files with 48 additions and 24 deletions

@ -47,12 +47,4 @@ AudioRenderer::ADSP::ADSP& AudioCore::GetADSP() {
return *adsp; return *adsp;
} }
void AudioCore::SetNVDECActive(bool active) {
nvdec_active = active;
}
bool AudioCore::IsNVDECActive() const {
return nvdec_active;
}
} // namespace AudioCore } // namespace AudioCore

@ -57,18 +57,6 @@ public:
*/ */
AudioRenderer::ADSP::ADSP& GetADSP(); AudioRenderer::ADSP::ADSP& GetADSP();
/**
* Toggle NVDEC state, used to avoid stall in playback.
*
* @param active - Set true if nvdec is active, otherwise false.
*/
void SetNVDECActive(bool active);
/**
* Get NVDEC state.
*/
bool IsNVDECActive() const;
private: private:
/** /**
* Create the sinks on startup. * Create the sinks on startup.
@ -83,8 +71,6 @@ private:
std::unique_ptr<Sink::Sink> input_sink; std::unique_ptr<Sink::Sink> input_sink;
/// The ADSP in the sysmodule /// The ADSP in the sysmodule
std::unique_ptr<AudioRenderer::ADSP::ADSP> adsp; std::unique_ptr<AudioRenderer::ADSP::ADSP> adsp;
/// Is NVDec currently active?
bool nvdec_active{false};
}; };
} // namespace AudioCore } // namespace AudioCore

@ -235,6 +235,7 @@ void RestoreGlobalState(bool is_powered_on) {
values.bg_green.SetGlobal(true); values.bg_green.SetGlobal(true);
values.bg_blue.SetGlobal(true); values.bg_blue.SetGlobal(true);
values.enable_compute_pipelines.SetGlobal(true); values.enable_compute_pipelines.SetGlobal(true);
values.use_video_framerate.SetGlobal(true);
// System // System
values.language_index.SetGlobal(true); values.language_index.SetGlobal(true);

@ -482,6 +482,7 @@ struct Values {
SwitchableSetting<AstcRecompression, true> astc_recompression{ SwitchableSetting<AstcRecompression, true> astc_recompression{
AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3, AstcRecompression::Uncompressed, AstcRecompression::Uncompressed, AstcRecompression::Bc3,
"astc_recompression"}; "astc_recompression"};
SwitchableSetting<bool> use_video_framerate{false, "use_video_framerate"};
SwitchableSetting<u8> bg_red{0, "bg_red"}; SwitchableSetting<u8> bg_red{0, "bg_red"};
SwitchableSetting<u8> bg_green{0, "bg_green"}; SwitchableSetting<u8> bg_green{0, "bg_green"};

@ -216,6 +216,14 @@ struct System::Impl {
} }
} }
void SetNVDECActive(bool is_nvdec_active) {
nvdec_active = is_nvdec_active;
}
bool GetNVDECActive() {
return nvdec_active;
}
void InitializeDebugger(System& system, u16 port) { void InitializeDebugger(System& system, u16 port) {
debugger = std::make_unique<Debugger>(system, port); debugger = std::make_unique<Debugger>(system, port);
} }
@ -485,6 +493,8 @@ struct System::Impl {
std::atomic_bool is_powered_on{}; std::atomic_bool is_powered_on{};
bool exit_lock = false; bool exit_lock = false;
bool nvdec_active{};
Reporter reporter; Reporter reporter;
std::unique_ptr<Memory::CheatEngine> cheat_engine; std::unique_ptr<Memory::CheatEngine> cheat_engine;
std::unique_ptr<Tools::Freezer> memory_freezer; std::unique_ptr<Tools::Freezer> memory_freezer;
@ -594,6 +604,14 @@ void System::UnstallApplication() {
impl->UnstallApplication(); impl->UnstallApplication();
} }
void System::SetNVDECActive(bool is_nvdec_active) {
impl->SetNVDECActive(is_nvdec_active);
}
bool System::GetNVDECActive() {
return impl->GetNVDECActive();
}
void System::InitializeDebugger() { void System::InitializeDebugger() {
impl->InitializeDebugger(*this, Settings::values.gdbstub_port.GetValue()); impl->InitializeDebugger(*this, Settings::values.gdbstub_port.GetValue());
} }

@ -189,6 +189,9 @@ public:
std::unique_lock<std::mutex> StallApplication(); std::unique_lock<std::mutex> StallApplication();
void UnstallApplication(); void UnstallApplication();
void SetNVDECActive(bool is_nvdec_active);
[[nodiscard]] bool GetNVDECActive();
/** /**
* Initialize the debugger. * Initialize the debugger.
*/ */

@ -69,7 +69,7 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> in
void nvhost_nvdec::OnOpen(DeviceFD fd) { void nvhost_nvdec::OnOpen(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream started"); LOG_INFO(Service_NVDRV, "NVDEC video stream started");
system.AudioCore().SetNVDECActive(true); system.SetNVDECActive(true);
} }
void nvhost_nvdec::OnClose(DeviceFD fd) { void nvhost_nvdec::OnClose(DeviceFD fd) {
@ -79,7 +79,7 @@ void nvhost_nvdec::OnClose(DeviceFD fd) {
if (iter != host1x_file.fd_to_id.end()) { if (iter != host1x_file.fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second); system.GPU().ClearCdmaInstance(iter->second);
} }
system.AudioCore().SetNVDECActive(false); system.SetNVDECActive(false);
} }
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

@ -324,6 +324,10 @@ s64 Nvnflinger::GetNextTicks() const {
speed_scale = 0.01f; speed_scale = 0.01f;
} }
} }
if (system.GetNVDECActive() && settings.use_video_framerate.GetValue()) {
// Run at intended presentation rate during video playback.
speed_scale = 1.f;
}
// As an extension, treat nonpositive swap interval as framerate multiplier. // As an extension, treat nonpositive swap interval as framerate multiplier.
const f32 effective_fps = swap_interval <= 0 ? 120.f * static_cast<f32>(1 - swap_interval) const f32 effective_fps = swap_interval <= 0 ? 120.f * static_cast<f32>(1 - swap_interval)

@ -42,6 +42,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
Settings::values.use_vulkan_driver_pipeline_cache.GetValue()); Settings::values.use_vulkan_driver_pipeline_cache.GetValue());
ui->enable_compute_pipelines_checkbox->setChecked( ui->enable_compute_pipelines_checkbox->setChecked(
Settings::values.enable_compute_pipelines.GetValue()); Settings::values.enable_compute_pipelines.GetValue());
ui->use_video_framerate_checkbox->setChecked(Settings::values.use_video_framerate.GetValue());
if (Settings::IsConfiguringGlobal()) { if (Settings::IsConfiguringGlobal()) {
ui->gpu_accuracy->setCurrentIndex( ui->gpu_accuracy->setCurrentIndex(
@ -91,6 +92,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines, ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_compute_pipelines,
ui->enable_compute_pipelines_checkbox, ui->enable_compute_pipelines_checkbox,
enable_compute_pipelines); enable_compute_pipelines);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_video_framerate,
ui->use_video_framerate_checkbox, use_video_framerate);
} }
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@ -125,6 +128,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
Settings::values.max_anisotropy.UsingGlobal()); Settings::values.max_anisotropy.UsingGlobal());
ui->enable_compute_pipelines_checkbox->setEnabled( ui->enable_compute_pipelines_checkbox->setEnabled(
Settings::values.enable_compute_pipelines.UsingGlobal()); Settings::values.enable_compute_pipelines.UsingGlobal());
ui->use_video_framerate_checkbox->setEnabled(
Settings::values.use_video_framerate.UsingGlobal());
return; return;
} }
@ -149,6 +154,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox, ConfigurationShared::SetColoredTristate(ui->enable_compute_pipelines_checkbox,
Settings::values.enable_compute_pipelines, Settings::values.enable_compute_pipelines,
enable_compute_pipelines); enable_compute_pipelines);
ConfigurationShared::SetColoredTristate(ui->use_video_framerate_checkbox,
Settings::values.use_video_framerate,
use_video_framerate);
ConfigurationShared::SetColoredComboBox( ConfigurationShared::SetColoredComboBox(
ui->gpu_accuracy, ui->label_gpu_accuracy, ui->gpu_accuracy, ui->label_gpu_accuracy,
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true))); static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));

@ -47,6 +47,7 @@ private:
ConfigurationShared::CheckState use_fast_gpu_time; ConfigurationShared::CheckState use_fast_gpu_time;
ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache;
ConfigurationShared::CheckState enable_compute_pipelines; ConfigurationShared::CheckState enable_compute_pipelines;
ConfigurationShared::CheckState use_video_framerate;
const Core::System& system; const Core::System& system;
}; };

@ -191,6 +191,16 @@ Compute pipelines are always enabled on all other drivers.</string>
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="use_video_framerate_checkbox">
<property name="toolTip">
<string>Run the game at normal speed during video playback, even when the framerate is unlocked.</string>
</property>
<property name="text">
<string>Sync to framerate of video playback</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="af_layout" native="true"> <widget class="QWidget" name="af_layout" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_1"> <layout class="QHBoxLayout" name="horizontalLayout_1">