diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 20:53:15 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-27 20:53:15 -0400 |
| commit | bf1de8f40130af5d3b490ee40dcc2fb20d460a14 (patch) | |
| tree | f57762bcc67491aa61288bd2eec107348756fb79 /src/video_core/engines/kepler_compute.cpp | |
| parent | 3f5bee600839a7593e98e0cb1231f09c29373ac8 (diff) | |
Switch 2: suspend channels on semaphore acquires; fix pushbuffer desyncs
NVN2 gates command buffers with semaphores the CPU releases after writing
them. Eden read past unmet SEMAPHORED acquires, so it executed stale commands
and desynchronised. Channels now suspend on an unmet acquire and resume from
the same word once it is met (scheduler keeps the waiting channels, the GPU
thread polls them), as in changes.patch.
Also: methods split across GPFIFO entries around a called command buffer are
set aside and resumed; subchannel 2 defaults to inline-to-memory; unbound
subchannels and out-of-range compute/DMA methods are dropped instead of
crashing; 4-byte semaphore releases no longer write 16 bytes; Ampere
SEM_PAYLOAD_HI/SEM_EXECUTE no longer spin as Kepler acquires; unmapped GPU
reads log instead of asserting. Debug aids: EDEN_NX2_PB_CHECK (pushbuffer
changed after submit), EDEN_NX2_QUERY_TRACE, a one-time pushbuffer dump.
Diffstat (limited to 'src/video_core/engines/kepler_compute.cpp')
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 96a12539a2..166bbd6d53 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -35,13 +35,24 @@ void KeplerCompute::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) void KeplerCompute::ConsumeSinkImpl(Core::System& system) { for (auto [method, value] : method_sink) { - regs.reg_array[method] = value; + if (method < Regs::NUM_REGS) { + regs.reg_array[method] = value; + } } method_sink.clear(); } void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argument, bool is_last_call) { - ASSERT_MSG(method < Regs::NUM_REGS, "Invalid KeplerCompute register, increase the size of the Regs structure"); + if (method >= Regs::NUM_REGS) { + // Ampere compute (Switch 2) uses methods past Kepler's register file; writing them would + // run off reg_array, so drop them. + static bool reported = false; + if (!reported) { + reported = true; + LOG_WARNING(HW_GPU, "Ignoring KeplerCompute method {:#x} past the register file", method); + } + return; + } regs.reg_array[method] = method_argument; |
