From 3fedcc2f6e001f0ed1fd791de4f9692570359eef Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 20 Apr 2020 02:16:56 -0400 Subject: [PATCH 1/4] DMAPusher: Propagate multimethod writes into the engines. --- src/video_core/dma_pusher.cpp | 28 ++++++++---- src/video_core/dma_pusher.h | 1 + src/video_core/engines/fermi_2d.cpp | 6 +++ src/video_core/engines/fermi_2d.h | 3 ++ src/video_core/engines/kepler_compute.cpp | 6 +++ src/video_core/engines/kepler_compute.h | 3 ++ src/video_core/engines/kepler_memory.cpp | 6 +++ src/video_core/engines/kepler_memory.h | 3 ++ src/video_core/engines/maxwell_3d.cpp | 52 +++++++++++++++++++++++ src/video_core/engines/maxwell_3d.h | 4 ++ src/video_core/engines/maxwell_dma.cpp | 6 +++ src/video_core/engines/maxwell_dma.h | 3 ++ src/video_core/gpu.cpp | 47 ++++++++++++++++++-- src/video_core/gpu.h | 8 +++- 14 files changed, 163 insertions(+), 13 deletions(-) diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 324dafdcda..16311f05e2 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -71,16 +71,22 @@ bool DmaPusher::Step() { gpu.MemoryManager().ReadBlockUnsafe(dma_get, command_headers.data(), command_list_header.size * sizeof(u32)); - for (const CommandHeader& command_header : command_headers) { + for (std::size_t index = 0; index < command_headers.size();) { + const CommandHeader& command_header = command_headers[index]; - // now, see if we're in the middle of a command - if (dma_state.length_pending) { - // Second word of long non-inc methods command - method count - dma_state.length_pending = 0; - dma_state.method_count = command_header.method_count_; - } else if (dma_state.method_count) { + if (dma_state.method_count) { // Data word of methods command - CallMethod(command_header.argument); + if (dma_state.non_incrementing) { + const u32 max_write = static_cast( + std::min(index + dma_state.method_count, command_headers.size()) - + index); + CallMultiMethod(&command_header.argument, max_write); + dma_state.method_count -= max_write; + index += max_write; + continue; + } else { + CallMethod(command_header.argument); + } if (!dma_state.non_incrementing) { dma_state.method++; @@ -120,6 +126,7 @@ bool DmaPusher::Step() { break; } } + index++; } if (!non_main) { @@ -140,4 +147,9 @@ void DmaPusher::CallMethod(u32 argument) const { gpu.CallMethod({dma_state.method, argument, dma_state.subchannel, dma_state.method_count}); } +void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const { + gpu.CallMultiMethod(dma_state.method, dma_state.subchannel, base_start, num_methods, + dma_state.method_count); +} + } // namespace Tegra diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index d6188614a8..6cef713062 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h @@ -75,6 +75,7 @@ private: void SetState(const CommandHeader& command_header); void CallMethod(u32 argument) const; + void CallMultiMethod(const u32* base_start, u32 num_methods) const; std::vector command_headers; ///< Buffer for list of commands fetched at once diff --git a/src/video_core/engines/fermi_2d.cpp b/src/video_core/engines/fermi_2d.cpp index bace6affb9..8a47614d26 100644 --- a/src/video_core/engines/fermi_2d.cpp +++ b/src/video_core/engines/fermi_2d.cpp @@ -28,6 +28,12 @@ void Fermi2D::CallMethod(const GPU::MethodCall& method_call) { } } +void Fermi2D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); + } +} + static std::pair DelimitLine(u32 src_1, u32 src_2, u32 dst_1, u32 dst_2, u32 src_line) { const u32 line_a = src_2 - src_1; const u32 line_b = dst_2 - dst_1; diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index dba342c70e..939a5966db 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -39,6 +39,9 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Write multiple values to the register identified by method. + void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); + enum class Origin : u32 { Center = 0, Corner = 1, diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 368c75a662..894300f57c 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -51,6 +51,12 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) { } } +void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); + } +} + Texture::FullTextureInfo KeplerCompute::GetTexture(std::size_t offset) const { const std::bitset<8> cbuf_mask = launch_description.const_buffer_enable_mask.Value(); ASSERT(cbuf_mask[regs.tex_cb_index]); diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h index eeb79c56fc..fe55fdfd0a 100644 --- a/src/video_core/engines/kepler_compute.h +++ b/src/video_core/engines/kepler_compute.h @@ -202,6 +202,9 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Write multiple values to the register identified by method. + void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); + Texture::FullTextureInfo GetTexture(std::size_t offset) const; /// Given a texture handle, returns the TSC and TIC entries. diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index 597872e439..e906a11240 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp @@ -41,4 +41,10 @@ void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) { } } +void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); + } +} + } // namespace Tegra::Engines diff --git a/src/video_core/engines/kepler_memory.h b/src/video_core/engines/kepler_memory.h index 396fb6e86a..bb26fb0304 100644 --- a/src/video_core/engines/kepler_memory.h +++ b/src/video_core/engines/kepler_memory.h @@ -40,6 +40,9 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Write multiple values to the register identified by method. + void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); + struct Regs { static constexpr size_t NUM_REGS = 0x7F; diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 2824ed707d..879ce542a9 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -280,6 +280,36 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { } } +void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { + switch (method) { + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { + ProcessCBMultiData(method, base_start, amount); + break; + } + default: { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); + } + } + } + +} + void Maxwell3D::StepInstance(const MMEDrawMode expected_mode, const u32 count) { if (mme_draw.current_mode == MMEDrawMode::Undefined) { if (mme_draw.gl_begin_consume) { @@ -570,6 +600,28 @@ void Maxwell3D::StartCBData(u32 method) { ProcessCBData(regs.const_buffer.cb_data[cb_data_state.id]); } +void Maxwell3D::ProcessCBMultiData(u32 method, const u32* start_base, u32 amount) { + if (cb_data_state.current != method) { + if (cb_data_state.current != null_cb_data) { + FinishCBData(); + } + constexpr u32 first_cb_data = MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]); + cb_data_state.start_pos = regs.const_buffer.cb_pos; + cb_data_state.id = method - first_cb_data; + cb_data_state.current = method; + cb_data_state.counter = 0; + } + const std::size_t id = cb_data_state.id; + const std::size_t size = amount; + std::size_t i = 0; + for (; i < size; i++) { + cb_data_state.buffer[id][cb_data_state.counter] = start_base[i]; + cb_data_state.counter++; + } + // Increment the current buffer position. + regs.const_buffer.cb_pos = regs.const_buffer.cb_pos + 4 * amount; +} + void Maxwell3D::FinishCBData() { // Write the input value to the current const buffer at the current position. const GPUVAddr buffer_address = regs.const_buffer.BufferAddress(); diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 59d5752d26..cfcda4f53b 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -1358,6 +1358,9 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Write multiple values to the register identified by method. + void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); + /// Write the value to the register identified by method. void CallMethodFromMME(const GPU::MethodCall& method_call); @@ -1511,6 +1514,7 @@ private: /// Handles a write to the CB_DATA[i] register. void StartCBData(u32 method); void ProcessCBData(u32 value); + void ProcessCBMultiData(u32 method, const u32* start_base, u32 amount); void FinishCBData(); /// Handles a write to the CB_BIND register. diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 3bfed6ab81..51e606a100 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -36,6 +36,12 @@ void MaxwellDMA::CallMethod(const GPU::MethodCall& method_call) { #undef MAXWELLDMA_REG_INDEX } +void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); + } +} + void MaxwellDMA::HandleCopy() { LOG_TRACE(HW_GPU, "Requested a DMA copy"); diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 4f40d1d1f5..c43ed81948 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h @@ -35,6 +35,9 @@ public: /// Write the value to the register identified by method. void CallMethod(const GPU::MethodCall& method_call); + /// Write multiple values to the register identified by method. + void CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending); + struct Regs { static constexpr std::size_t NUM_REGS = 0x1D6; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 3b7572d61a..54e7876a64 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -209,16 +209,31 @@ void GPU::CallMethod(const MethodCall& method_call) { ASSERT(method_call.subchannel < bound_engines.size()); - if (ExecuteMethodOnEngine(method_call)) { + if (ExecuteMethodOnEngine(method_call.method)) { CallEngineMethod(method_call); } else { CallPullerMethod(method_call); } } -bool GPU::ExecuteMethodOnEngine(const MethodCall& method_call) { - const auto method = static_cast(method_call.method); - return method >= BufferMethods::NonPullerMethods; +void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { + LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, + subchannel); + + ASSERT(subchannel < bound_engines.size()); + + if (ExecuteMethodOnEngine(method)) { + CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending); + } else { + for (std::size_t i = 0; i < amount; i++) { + CallPullerMethod({method, base_start[i], subchannel, methods_pending - static_cast(i)}); + } + } +} + +bool GPU::ExecuteMethodOnEngine(u32 method) { + const auto buffer_method = static_cast(method); + return buffer_method >= BufferMethods::NonPullerMethods; } void GPU::CallPullerMethod(const MethodCall& method_call) { @@ -298,6 +313,30 @@ void GPU::CallEngineMethod(const MethodCall& method_call) { } } +void GPU::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { + const EngineID engine = bound_engines[subchannel]; + + switch (engine) { + case EngineID::FERMI_TWOD_A: + fermi_2d->CallMultiMethod(method, base_start, amount, methods_pending); + break; + case EngineID::MAXWELL_B: + maxwell_3d->CallMultiMethod(method, base_start, amount, methods_pending); + break; + case EngineID::KEPLER_COMPUTE_B: + kepler_compute->CallMultiMethod(method, base_start, amount, methods_pending); + break; + case EngineID::MAXWELL_DMA_COPY_A: + maxwell_dma->CallMultiMethod(method, base_start, amount, methods_pending); + break; + case EngineID::KEPLER_INLINE_TO_MEMORY_B: + kepler_memory->CallMultiMethod(method, base_start, amount, methods_pending); + break; + default: + UNIMPLEMENTED_MSG("Unimplemented engine"); + } +} + void GPU::ProcessBindMethod(const MethodCall& method_call) { // Bind the current subchannel to the desired engine id. LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 5e3eb94e95..4d7e2651c7 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -155,6 +155,9 @@ public: /// Calls a GPU method. void CallMethod(const MethodCall& method_call); + /// Calls a GPU multivalue method. + void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending); + /// Flush all current written commands into the host GPU for execution. void FlushCommands(); /// Synchronizes CPU writes with Host GPU memory. @@ -309,8 +312,11 @@ private: /// Calls a GPU engine method. void CallEngineMethod(const MethodCall& method_call); + /// Calls a GPU engine multivalue method. + void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending); + /// Determines where the method should be executed. - bool ExecuteMethodOnEngine(const MethodCall& method_call); + bool ExecuteMethodOnEngine(u32 method); protected: std::unique_ptr dma_pusher; From 18a88d19dc3672a7d49b2eb646ac7067167294b4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 20 Apr 2020 12:27:57 -0400 Subject: [PATCH 2/4] Maxwell3D: Process Macros on MultiMethod. --- src/video_core/engines/maxwell_3d.cpp | 72 +++++++++++++++++---------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 879ce542a9..39e3b66a23 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -280,34 +280,56 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { } } -void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { - switch (method) { - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): - case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { - ProcessCBMultiData(method, base_start, amount); - break; +void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount, + u32 methods_pending) { + // Methods after 0xE00 are special, they're actually triggers for some microcode that was + // uploaded to the GPU during initialization. + if (method >= MacroRegistersStart) { + // We're trying to execute a macro + if (executing_macro == 0) { + // A macro call must begin by writing the macro method's register, not its argument. + ASSERT_MSG((method % 2) == 0, + "Can't start macro execution by writing to the ARGS register"); + executing_macro = method; } - default: { - for (std::size_t i = 0; i < amount; i++) { - CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); - } + + for (std::size_t i = 0; i < amount; i++) { + macro_params.push_back(base_start[i]); + } + + // Call the macro when there are no more parameters in the command buffer + if (amount == methods_pending) { + CallMacroMethod(executing_macro, macro_params.size(), macro_params.data()); + macro_params.clear(); + } + return; + } + switch (method) { + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[0]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[1]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[2]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[3]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[4]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[5]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[6]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[7]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[8]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[9]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[10]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[11]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[12]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[13]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[14]): + case MAXWELL3D_REG_INDEX(const_buffer.cb_data[15]): { + ProcessCBMultiData(method, base_start, amount); + break; + } + default: { + for (std::size_t i = 0; i < amount; i++) { + CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); } } - + } } void Maxwell3D::StepInstance(const MMEDrawMode expected_mode, const u32 count) { From b8aef40c56588c999b15a63516b5d68958f667df Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 20 Apr 2020 13:20:52 -0400 Subject: [PATCH 3/4] GPU: Add Fast GPU Time Option. --- src/core/settings.h | 1 + src/video_core/gpu.cpp | 6 +++++- src/yuzu/configuration/config.cpp | 2 ++ src/yuzu/configuration/configure_graphics_advanced.cpp | 2 ++ src/yuzu/configuration/configure_graphics_advanced.ui | 7 +++++++ src/yuzu_cmd/config.cpp | 2 ++ src/yuzu_tester/config.cpp | 2 ++ 7 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/core/settings.h b/src/core/settings.h index 7d09253f58..163900f0be 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -446,6 +446,7 @@ struct Values { bool use_asynchronous_gpu_emulation; bool use_vsync; bool force_30fps_mode; + bool use_fast_gpu_time; float bg_red; float bg_green; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 54e7876a64..d2bd3cc9d5 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -9,6 +9,7 @@ #include "core/core_timing_util.h" #include "core/frontend/emu_window.h" #include "core/memory.h" +#include "core/settings.h" #include "video_core/engines/fermi_2d.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/kepler_memory.h" @@ -154,7 +155,10 @@ u64 GPU::GetTicks() const { constexpr u64 gpu_ticks_den = 625; const u64 cpu_ticks = system.CoreTiming().GetTicks(); - const u64 nanoseconds = Core::Timing::CyclesToNs(cpu_ticks).count(); + u64 nanoseconds = Core::Timing::CyclesToNs(cpu_ticks).count(); + if (Settings::values.use_fast_gpu_time) { + nanoseconds /= 256; + } const u64 nanoseconds_num = nanoseconds / gpu_ticks_den; const u64 nanoseconds_rem = nanoseconds % gpu_ticks_den; return nanoseconds_num * gpu_ticks_num + (nanoseconds_rem * gpu_ticks_num) / gpu_ticks_den; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 196a3a1168..c7c11b9dde 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -644,6 +644,7 @@ void Config::ReadRendererValues() { Settings::values.use_asynchronous_gpu_emulation = ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool(); Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool(); + Settings::values.use_fast_gpu_time = ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool(); Settings::values.force_30fps_mode = ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool(); @@ -1085,6 +1086,7 @@ void Config::SaveRendererValues() { WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"), Settings::values.use_asynchronous_gpu_emulation, false); WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); + WriteSetting(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, true); WriteSetting(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, false); // Cast to double because Qt's written float values are not human-readable diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 0a3f47339d..5bb2ae5554 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -22,6 +22,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { ui->gpu_accuracy->setCurrentIndex(static_cast(Settings::values.gpu_accuracy)); ui->use_vsync->setEnabled(runtime_lock); ui->use_vsync->setChecked(Settings::values.use_vsync); + ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time); ui->force_30fps_mode->setEnabled(runtime_lock); ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode); ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); @@ -32,6 +33,7 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { auto gpu_accuracy = static_cast(ui->gpu_accuracy->currentIndex()); Settings::values.gpu_accuracy = gpu_accuracy; Settings::values.use_vsync = ui->use_vsync->isChecked(); + Settings::values.use_fast_gpu_time = ui->use_fast_gpu_time->isChecked(); Settings::values.force_30fps_mode = ui->force_30fps_mode->isChecked(); Settings::values.max_anisotropy = ui->anisotropic_filtering_combobox->currentIndex(); } diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 0c7b383e00..770b80c50d 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -69,6 +69,13 @@ + + + + Use Fast GPU Time + + + diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index d1ac354bf1..8476a5a168 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -394,6 +394,8 @@ void Config::ReadValues() { sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); Settings::values.use_vsync = static_cast(sdl2_config->GetInteger("Renderer", "use_vsync", 1)); + Settings::values.use_fast_gpu_time = + sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true); Settings::values.bg_red = static_cast(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); Settings::values.bg_green = diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp index c0325cc3ca..3be58b15da 100644 --- a/src/yuzu_tester/config.cpp +++ b/src/yuzu_tester/config.cpp @@ -130,6 +130,8 @@ void Config::ReadValues() { Settings::values.gpu_accuracy = static_cast(gpu_accuracy_level); Settings::values.use_asynchronous_gpu_emulation = sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); + Settings::values.use_fast_gpu_time = + sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true); Settings::values.bg_red = static_cast(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); Settings::values.bg_green = From 5c9feaebb6bfa34bb275ffa59ca823003de20422 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 20 Apr 2020 13:42:14 -0400 Subject: [PATCH 4/4] Clang Format. --- src/video_core/engines/kepler_compute.cpp | 3 ++- src/video_core/engines/kepler_memory.cpp | 3 ++- src/video_core/engines/maxwell_dma.cpp | 3 ++- src/video_core/gpu.cpp | 12 +++++++----- src/video_core/gpu.h | 6 ++++-- src/yuzu/configuration/config.cpp | 3 ++- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 894300f57c..00a12175f1 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -51,7 +51,8 @@ void KeplerCompute::CallMethod(const GPU::MethodCall& method_call) { } } -void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { +void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amount, + u32 methods_pending) { for (std::size_t i = 0; i < amount; i++) { CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); } diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp index e906a11240..586ff15dc9 100644 --- a/src/video_core/engines/kepler_memory.cpp +++ b/src/video_core/engines/kepler_memory.cpp @@ -41,7 +41,8 @@ void KeplerMemory::CallMethod(const GPU::MethodCall& method_call) { } } -void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { +void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount, + u32 methods_pending) { for (std::size_t i = 0; i < amount; i++) { CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); } diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 51e606a100..6630005b0d 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -36,7 +36,8 @@ void MaxwellDMA::CallMethod(const GPU::MethodCall& method_call) { #undef MAXWELLDMA_REG_INDEX } -void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, u32 methods_pending) { +void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, + u32 methods_pending) { for (std::size_t i = 0; i < amount; i++) { CallMethod({method, base_start[i], 0, methods_pending - static_cast(i)}); } diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index d2bd3cc9d5..b87fd873d0 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -220,9 +220,9 @@ void GPU::CallMethod(const MethodCall& method_call) { } } -void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { - LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, - subchannel); +void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, + u32 methods_pending) { + LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, subchannel); ASSERT(subchannel < bound_engines.size()); @@ -230,7 +230,8 @@ void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending); } else { for (std::size_t i = 0; i < amount; i++) { - CallPullerMethod({method, base_start[i], subchannel, methods_pending - static_cast(i)}); + CallPullerMethod( + {method, base_start[i], subchannel, methods_pending - static_cast(i)}); } } } @@ -317,7 +318,8 @@ void GPU::CallEngineMethod(const MethodCall& method_call) { } } -void GPU::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { +void GPU::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, + u32 methods_pending) { const EngineID engine = bound_engines[subchannel]; switch (engine) { diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 4d7e2651c7..dd51c95b7f 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -156,7 +156,8 @@ public: void CallMethod(const MethodCall& method_call); /// Calls a GPU multivalue method. - void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending); + void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, + u32 methods_pending); /// Flush all current written commands into the host GPU for execution. void FlushCommands(); @@ -313,7 +314,8 @@ private: void CallEngineMethod(const MethodCall& method_call); /// Calls a GPU engine multivalue method. - void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending); + void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, + u32 methods_pending); /// Determines where the method should be executed. bool ExecuteMethodOnEngine(u32 method); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index c7c11b9dde..59c003f380 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -644,7 +644,8 @@ void Config::ReadRendererValues() { Settings::values.use_asynchronous_gpu_emulation = ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool(); Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool(); - Settings::values.use_fast_gpu_time = ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool(); + Settings::values.use_fast_gpu_time = + ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool(); Settings::values.force_30fps_mode = ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool();