diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 00:24:14 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 00:24:14 -0400 |
| commit | a5e528e2d0bc784ebf24850e5913cece912c685e (patch) | |
| tree | 8a0323e46528f768dc9fd0b0843419be2892de95 /src/core | |
| parent | f8c8b809e64c57d34837b09cce3b6a7fd8e5295a (diff) | |
nx2: get title 4 past the difficulty confirm
- MME: implement MME_DMA_READ / MME_DMA_READ_FIFOED (Turing macros read query
results into their load FIFO; the conditional-render macro at 0x142 needs it).
- vi2 present waits up to 4 s for the frame fence (was 250 ms) so shader
compile stalls don't let the game lap its equal-value gate semaphores.
- Native QMD: fire the third release slot at word 52, which NVN2 patches for
queue-to-queue syncs (compute queue releasing a gate the 3D queue waits on).
- Compute class SET_REPORT_SEMAPHORE (0x6c0-0x6c3) releases.
- Ampere lowering: AOFFI, any LOP3 truth table, STG RZ, LDG 0x981, IABS,
I2FP rounding, IMAD negated addend, SHFL 0x989 (all 77 title-4 shaders lower).
- Debug: EDEN_NX2_SEM_WATCH=<addr> traces acquires, releases, method
arguments and compute macro emits for one semaphore block;
EDEN_NX2_KEY_SCRIPT scripted key presses; per-submit logs moved to TRACE.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nx2_gsv.h | 10 |
2 files changed, 11 insertions, 3 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index cf3948c321..2a144cc7ab 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -421,7 +421,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandL if (g_nx2_driver) { for (const auto& entry : entries.command_lists) { - LOG_DEBUG(Service_NVDRV, "nx2 GPFIFO entry raw={:#018x} addr={:#x} size={:#x}", entry.raw, + LOG_TRACE(Service_NVDRV, "nx2 GPFIFO entry raw={:#018x} addr={:#x} size={:#x}", entry.raw, entry.addr.Value(), entry.size.Value()); } static const bool check = std::getenv("EDEN_NX2_PB_CHECK") != nullptr; @@ -471,7 +471,7 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandL } if (g_nx2_driver) { - LOG_DEBUG(Service_NVDRV, + LOG_TRACE(Service_NVDRV, "nx2 SubmitGPFIFO entries={} flags={:#x} fence_out=({}, {}) guest_value={}", params.num_entries, flags.raw, params.fence.id, params.fence.value, system.Host1x().GetSyncpointManager().GetGuestSyncpointValue(params.fence.id)); diff --git a/src/core/hle/service/nx2_gsv.h b/src/core/hle/service/nx2_gsv.h index 8073e0bd96..89f3a9fd50 100644 --- a/src/core/hle/service/nx2_gsv.h +++ b/src/core/hle/service/nx2_gsv.h @@ -580,17 +580,25 @@ private: // free, so pace the game here instead: wait (bounded, in case the GPU waits on the CPU) until // Eden's GPU thread has processed the frame. Otherwise the game laps the GPU thread and // rewrites command memory it hasn't read yet. + u32 m_wait_timeouts{}; + void WaitForFrame(u32 fence_id, u32 fence_value) { if (fence_id >= 192) { return; } auto& syncpoints = system.Host1x().GetSyncpointManager(); const auto start = std::chrono::steady_clock::now(); - const auto deadline = start + std::chrono::milliseconds{250}; + // Long enough to cover shader/pipeline compile stalls: a game that gets more than a few + // command buffers ahead misses the equal-value gates its other channels acquire. + const auto deadline = start + std::chrono::milliseconds{4000}; while (!syncpoints.IsReadyGuest(fence_id, fence_value) && std::chrono::steady_clock::now() < deadline && system.IsPoweredOn()) { std::this_thread::sleep_for(std::chrono::microseconds{200}); } + if (!syncpoints.IsReadyGuest(fence_id, fence_value) && m_wait_timeouts++ < 64) { + LOG_WARNING(Service, "nx2:vi2 present #{} fence ({}, {}) not reached in 4 s (now {})", + m_presents, fence_id, fence_value, syncpoints.GetGuestSyncpointValue(fence_id)); + } if (m_presents <= 8 || (m_presents % 600) == 0) { LOG_INFO(Service, "nx2:vi2 present #{} fence ({}, {}) now {}, waited {} us", m_presents, fence_id, fence_value, syncpoints.GetGuestSyncpointValue(fence_id), |
