diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 05:46:58 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 20:49:47 -0400 |
| commit | 9c0f7e8ad45200d09052a368a42d4e21a8d99ec4 (patch) | |
| tree | cfe5380a4307a3daba57f1490a70750f991be2ec /src | |
| parent | 544977c085fe912818022acc36b6e4c05015a727 (diff) | |
video_core: copy whole macro calls to the stack
Nearly every macro call arrives whole in one method run (~1,000,000 a second in title
1); its parameters were appended to a std::vector first (~2% of the GPU thread). They
are now copied to a stack array. Still a copy: the command list is often guest memory
read in place, which the guest may reuse while the macro runs, and the macro memo
stores the parameters after the call. Accurate GPU mode keeps the vector (it rewrites
parameters in place). EDEN_NX2_MACRO_COPY=1 always uses the vector.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 3 |
2 files changed, 24 insertions, 3 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 60efef9b8e..20a973bb6b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -4,6 +4,8 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <algorithm> +#include <array> #include <cstring> #include <limits> #include <optional> @@ -208,11 +210,29 @@ void Maxwell3D::ProcessMacro(Core::System& system, u32 method, const u32* base_s executing_macro = method; } - macro_params.insert(macro_params.end(), base_start, base_start + amount); macro_segments.emplace_back(current_dma_segment, amount); current_macro_dirty |= current_dirty; current_dirty = false; + // Nearly every call arrives whole in one method run (title 1 makes ~1,000,000 a second): + // copy it to the stack instead of growing the parameter vector. Still a copy: the command + // list is often guest memory read in place, which the guest may reuse while the macro runs + // (and the macro memo stores the parameters after it ran). Only accurate GPU mode rewrites + // the parameters in place (RefreshParameters), so it keeps the vector. + // EDEN_NX2_MACRO_COPY=1: always use the vector (for comparisons). + static const bool always_copy = std::getenv("EDEN_NX2_MACRO_COPY") != nullptr; + if (is_last_call && macro_params.empty() && amount <= 64 && !always_copy && + !Settings::IsGPULevelHigh()) { + std::array<u32, 64> parameters; + std::copy_n(base_start, amount, parameters.begin()); + ConsumeSink(system); + CallMacroMethod(system, executing_macro, std::span<const u32>{parameters.data(), amount}); + macro_segments.clear(); + current_macro_dirty = false; + return; + } + macro_params.insert(macro_params.end(), base_start, base_start + amount); + // Call the macro when there are no more parameters in the command buffer if (is_last_call) { ConsumeSink(system); @@ -379,7 +399,7 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume } } -void Maxwell3D::CallMacroMethod(Core::System& system, u32 method, const std::vector<u32>& parameters) { +void Maxwell3D::CallMacroMethod(Core::System& system, u32 method, std::span<const u32> parameters) { // Reset the current macro. executing_macro = 0; diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 82e716b822..190d5de630 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h @@ -11,6 +11,7 @@ #include <cmath> #include <limits> #include <optional> +#include <span> #include <type_traits> #include <vector> @@ -3247,7 +3248,7 @@ private: * @param method Method to call * @param parameters Arguments to the method call */ - void CallMacroMethod(Core::System& system, u32 method, const std::vector<u32>& parameters); + void CallMacroMethod(Core::System& system, u32 method, std::span<const u32> parameters); /// Handles writes to the macro uploading register. void ProcessMacroUpload(u32 data); |
