aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 00:24:14 -0400
committerTakoroka <137927095+Takoroka@users.noreply.github.com>2026-10-28 00:24:14 -0400
commita5e528e2d0bc784ebf24850e5913cece912c685e (patch)
tree8a0323e46528f768dc9fd0b0843419be2892de95 /src/core
parentf8c8b809e64c57d34837b09cce3b6a7fd8e5295a (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.cpp4
-rw-r--r--src/core/hle/service/nx2_gsv.h10
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),