aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/macro.cpp
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 16:44:24 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 16:44:24 -0400
commitcc3d73762a41dba370aadd3468cb510dcbc2b74d (patch)
tree32629e503c2cd1d64ce2353c76fb02585ce1d1cb /src/video_core/macro.cpp
parent82a5b520bc6dc4a77acca9b3ddd0bc577ada5676 (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.cpp23
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;