diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 16:44:24 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 16:44:24 -0400 |
| commit | cc3d73762a41dba370aadd3468cb510dcbc2b74d (patch) | |
| tree | 32629e503c2cd1d64ce2353c76fb02585ce1d1cb /src/video_core/macro.cpp | |
| parent | 82a5b520bc6dc4a77acca9b3ddd0bc577ada5676 (diff) | |
Performance diagnostics and small wins for title 1
- eden-cli: SDL called SDL_AppIterate back to back, keeping a host core at
100% polling input; run the main callbacks at 240 Hz.
- EDEN_NX2_IDLE_SPIN_US: optional spin before an idle core blocks (measured:
no gain on title 1, so off by default).
- EDEN_NX2_SVC_TRACE=<first>:<last>: trace SVCs (with thread ids) for a range
of presents only.
- MME DMA reads flush GPU-written memory first (never triggered on title 1,
kept for correctness); render-enable override histogram instead of the
first-400 log.
Measured on title 1's title screen (RTX 4070 Laptop): GPU ~20% busy, the six
emulated cores ~0.9 host cores in total, Eden's GPU thread 45-70% busy and
largely waiting: on host fences for semaphore acquires (GPU accuracy High
delays every release to host completion), on ASTC upload Finish(), and in a
1 ms poll sleep. gpu_accuracy=Low: ~12.5 -> ~16 fps.
Diffstat (limited to 'src/video_core/macro.cpp')
| -rw-r--r-- | src/video_core/macro.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/video_core/macro.cpp b/src/video_core/macro.cpp index 59396cb58b..d70cfefd2f 100644 --- a/src/video_core/macro.cpp +++ b/src/video_core/macro.cpp @@ -4,6 +4,7 @@ // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <array> #include <cstdlib> #include <unordered_set> #include <cstring> @@ -1360,8 +1361,15 @@ void MacroEngine::Execute(Core::System& system, Engines::Maxwell3D& maxwell3d, u [&](u32 address, u32 value) { if (address >= 0xe00) return false; if (address == 0x556) { - static u32 enable_logs{}; - if (enable_logs++ < 400) LOG_INFO(HW_GPU, "Native MME start={:#x} render enable mode={}", method, value); + // SET_RENDER_ENABLE_OVERRIDE: 0 use the render-enable condition, 1 always, + // 2 never. Log a histogram every 20000 macro writes (pop-in diagnostics). + static std::array<u64, 4> modes{}; + static u64 enable_writes{}; + ++modes[value & 3]; + if (++enable_writes % 20000 == 0) { + LOG_INFO(HW_GPU, "Native MME render enable modes: use {} always {} never {} other {}", + modes[0], modes[1], modes[2], modes[3]); + } } maxwell3d.CallMethod(system, address, value, true); // Turing MME memory reads (methods 0x550 SET_MME_MEM_ADDRESS_A/B, 0x558 data RAM @@ -1374,6 +1382,17 @@ void MacroEngine::Execute(Core::System& system, Engines::Maxwell3D& maxwell3d, u maxwell3d.GetRegisterValue(MemAddressB); auto& memory = maxwell3d.GetMemoryManager(); const u32 ram = maxwell3d.GetRegisterValue(DataRamAddress); + // The words may have just been written by the GPU (e.g. indirect draw arguments + // from a culling dispatch) and still be only in host buffers: flush them first, + // or the macro draws with an older frame's arguments (objects pop in and out). + const size_t read_bytes = size_t{std::min<u32>(value, 0x1000)} * 4; + if (memory.IsMemoryDirty(source, read_bytes, VideoCommon::CacheType::BufferCache)) { + memory.FlushRegion(source, read_bytes, VideoCommon::CacheType::BufferCache); + static u64 flushes{}; + if (++flushes % 2000 == 1) { + LOG_INFO(HW_GPU, "Native MME DMA read flushed GPU-written memory ({} times)", flushes); + } + } static u32 dma_logs{}; if (dma_logs < 400) { ++dma_logs; |
