From 940b725c1d2933f95a8a41248a8b20c27d880ad3 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 29 Apr 2020 20:00:22 +1000 Subject: [PATCH] Settings: Make DMA performance parameters tweakable --- src/core/dma.cpp | 6 +- src/core/dma.h | 2 + src/core/host_interface.cpp | 5 +- src/core/settings.cpp | 7 ++- src/core/settings.h | 8 ++- src/duckstation-sdl/sdl_host_interface.cpp | 67 +++++++++++++++------- 6 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/core/dma.cpp b/src/core/dma.cpp index 1eedcf41b..da4742267 100644 --- a/src/core/dma.cpp +++ b/src/core/dma.cpp @@ -25,6 +25,10 @@ void DMA::Initialize(System* system, Bus* bus, InterruptController* interrupt_co m_cdrom = cdrom; m_spu = spu; m_mdec = mdec; + + m_max_slice_ticks = system->GetSettings().dma_max_slice_ticks; + m_halt_ticks = system->GetSettings().dma_halt_ticks; + m_transfer_buffer.resize(32); m_unhalt_event = system->CreateTimingEvent("DMA Transfer Unhalt", 1, m_max_slice_ticks, std::bind(&DMA::UnhaltTransfer, this, std::placeholders::_1), false); @@ -306,7 +310,7 @@ bool DMA::TransferChannel(Channel channel) if (used_ticks >= m_max_slice_ticks) { // stall the transfer for a bit if we ran for too long - //Log_WarningPrintf("breaking dma chain at 0x%08X", current_address); + // Log_WarningPrintf("breaking dma chain at 0x%08X", current_address); HaltTransfer(m_halt_ticks); return false; } diff --git a/src/core/dma.h b/src/core/dma.h index 27ceda41f..2f6558611 100644 --- a/src/core/dma.h +++ b/src/core/dma.h @@ -50,6 +50,8 @@ public: // changing interfaces void SetGPU(GPU* gpu) { m_gpu = gpu; } + void SetMaxSliceTicks(TickCount ticks) { m_max_slice_ticks = ticks; } + void SetHaltTicks(TickCount ticks) { m_halt_ticks = ticks; } private: static constexpr PhysicalMemoryAddress BASE_ADDRESS_MASK = UINT32_C(0x00FFFFFF); diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 4379b2ea9..fc41d49c6 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -983,7 +983,7 @@ void HostInterface::UpdateSettings(const std::function& apply_callback) const GPURenderer old_gpu_renderer = m_settings.gpu_renderer; const u32 old_gpu_resolution_scale = m_settings.gpu_resolution_scale; const u32 old_gpu_fifo_size = m_settings.gpu_fifo_size; - const u32 old_gpu_max_run_ahead = m_settings.gpu_max_run_ahead; + const TickCount old_gpu_max_run_ahead = m_settings.gpu_max_run_ahead; const bool old_gpu_true_color = m_settings.gpu_true_color; const bool old_gpu_scaled_dithering = m_settings.gpu_scaled_dithering; const bool old_gpu_texture_filtering = m_settings.gpu_texture_filtering; @@ -1058,6 +1058,9 @@ void HostInterface::UpdateSettings(const std::function& apply_callback) if (m_settings.memory_card_types != old_memory_card_types || m_settings.memory_card_paths != old_memory_card_paths) m_system->UpdateMemoryCards(); + + m_system->GetDMA()->SetMaxSliceTicks(m_settings.dma_max_slice_ticks); + m_system->GetDMA()->SetHaltTicks(m_settings.dma_halt_ticks); } bool controllers_updated = false; diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 429e96e10..8c5c68f5c 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -23,8 +23,6 @@ void Settings::Load(SettingsInterface& si) gpu_renderer = ParseRendererName(si.GetStringValue("GPU", "Renderer", GetRendererName(DEFAULT_GPU_RENDERER)).c_str()) .value_or(DEFAULT_GPU_RENDERER); gpu_resolution_scale = static_cast(si.GetIntValue("GPU", "ResolutionScale", 1)); - gpu_fifo_size = static_cast(si.GetIntValue("GPU", "FIFOSize", 128)); - gpu_max_run_ahead = static_cast(si.GetIntValue("GPU", "MaxRunAhead", 128)); gpu_use_debug_device = si.GetBoolValue("GPU", "UseDebugDevice", false); gpu_true_color = si.GetBoolValue("GPU", "TrueColor", true); gpu_scaled_dithering = si.GetBoolValue("GPU", "ScaledDithering", false); @@ -54,6 +52,11 @@ void Settings::Load(SettingsInterface& si) audio_sync_enabled = si.GetBoolValue("Audio", "Sync", true); audio_dump_on_boot = si.GetBoolValue("Audio", "DumpOnBoot", false); + dma_max_slice_ticks = si.GetIntValue("Hacks", "DMAMaxSliceTicks", 1000); + dma_halt_ticks = si.GetIntValue("Hacks", "DMAHaltTicks", 100); + gpu_fifo_size = static_cast(si.GetIntValue("Hacks", "GPUFIFOSize", 128)); + gpu_max_run_ahead = si.GetIntValue("Hacks", "GPUMaxRunAhead", 128); + bios_path = si.GetStringValue("BIOS", "Path", "bios/scph1001.bin"); bios_patch_tty_enable = si.GetBoolValue("BIOS", "PatchTTYEnable", true); bios_patch_fast_boot = si.GetBoolValue("BIOS", "PatchFastBoot", false); diff --git a/src/core/settings.h b/src/core/settings.h index a79032f45..389c672e6 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -47,8 +47,6 @@ struct Settings GPURenderer gpu_renderer = GPURenderer::Software; u32 gpu_resolution_scale = 1; - u32 gpu_fifo_size = 128; - u32 gpu_max_run_ahead = 128; bool gpu_use_debug_device = false; bool gpu_true_color = true; bool gpu_scaled_dithering = false; @@ -71,6 +69,12 @@ struct Settings bool audio_sync_enabled = true; bool audio_dump_on_boot = true; + // timing hacks section + TickCount dma_max_slice_ticks = 1000; + TickCount dma_halt_ticks = 100; + u32 gpu_fifo_size = 128; + TickCount gpu_max_run_ahead = 128; + struct DebugSettings { bool show_vram = false; diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp index 6bce5acee..8b115bba1 100644 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ b/src/duckstation-sdl/sdl_host_interface.cpp @@ -1210,30 +1210,55 @@ void SDLHostInterface::DrawSettingsWindow() settings_changed |= ImGui::Checkbox("Force NTSC Timings", &m_settings_copy.gpu_force_ntsc_timings); } - if (DrawSettingsSectionHeader("Advanced")) + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem("Advanced")) + { + ImGui::Text("These options are tweakable to improve performance/game compatibility."); + ImGui::Text("They will not be automatically saved to the settings INI file."); + ImGui::Text("Use at your own risk, modified values will not be supported."); + ImGui::NewLine(); + + ImGui::Text("DMA Max Slice Ticks:"); + ImGui::SameLine(indent); + + int dma_max_slice_ticks = static_cast(m_settings_copy.dma_max_slice_ticks); + if (ImGui::SliderInt("##dma_max_slice_ticks", &dma_max_slice_ticks, 100, 10000)) { - ImGui::Text("FIFO Size:"); - ImGui::SameLine(indent); - - int fifo_size = static_cast(m_settings_copy.gpu_fifo_size); - if (ImGui::SliderInt("##fifo_size", &fifo_size, 16, GPU::MAX_FIFO_SIZE)) - { - m_settings_copy.gpu_fifo_size = fifo_size; - settings_changed = true; - } - - ImGui::Text("Max Run-Ahead:"); - ImGui::SameLine(indent); - - int max_run_ahead = static_cast(m_settings_copy.gpu_max_run_ahead); - if (ImGui::SliderInt("##max_run_ahead", &max_run_ahead, 0, 1000)) - { - m_settings_copy.gpu_max_run_ahead = max_run_ahead; - settings_changed = true; - } + m_settings_copy.dma_max_slice_ticks = dma_max_slice_ticks; + settings_changed = true; } - ImGui::EndTabItem(); + ImGui::Text("DMA Halt Ticks:"); + ImGui::SameLine(indent); + + int dma_halt_ticks = static_cast(m_settings_copy.dma_halt_ticks); + if (ImGui::SliderInt("##dma_halt_ticks", &dma_halt_ticks, 100, 10000)) + { + m_settings_copy.dma_halt_ticks = dma_halt_ticks; + settings_changed = true; + } + + ImGui::Text("FIFO Size:"); + ImGui::SameLine(indent); + + int gpu_fifo_size = static_cast(m_settings_copy.gpu_fifo_size); + if (ImGui::SliderInt("##gpu_fifo_size", &gpu_fifo_size, 16, GPU::MAX_FIFO_SIZE)) + { + m_settings_copy.gpu_fifo_size = gpu_fifo_size; + settings_changed = true; + } + + ImGui::Text("Max Run-Ahead:"); + ImGui::SameLine(indent); + + int gpu_max_run_ahead = static_cast(m_settings_copy.gpu_max_run_ahead); + if (ImGui::SliderInt("##gpu_max_run_ahead", &gpu_max_run_ahead, 0, 1000)) + { + m_settings_copy.gpu_max_run_ahead = gpu_max_run_ahead; + settings_changed = true; + } } ImGui::EndTabBar();