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/video_core/macro.cpp | |
| 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/video_core/macro.cpp')
| -rw-r--r-- | src/video_core/macro.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/src/video_core/macro.cpp b/src/video_core/macro.cpp index a8acd81682..06c649260d 100644 --- a/src/video_core/macro.cpp +++ b/src/video_core/macro.cpp @@ -27,6 +27,7 @@ #include "video_core/engines/maxwell_3d.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/dirty_flags.h" +#include "video_core/memory_manager.h" #include "video_core/rasterizer_interface.h" #include "video_core/macro.h" @@ -1351,11 +1352,43 @@ void MacroEngine::Execute(Core::System& system, Engines::Maxwell3D& maxwell3d, u } LOG_DEBUG(HW_GPU, "Native MME context={:#x}", context); LOG_DEBUG(HW_GPU, "Native MME start={:#x}, parameters={}, data={:08x}", method, parameters.size(), fmt::join(parameters, ",")); - const auto result = native_interpreter.Execute(native_code, method, parameters, + std::vector<u32> fifo(parameters.begin(), parameters.end()); + const auto result = native_interpreter.Execute(native_code, method, fifo, [&](u32 address) { return address < Maxwell3D::Regs::NUM_REGS ? maxwell3d.GetRegisterValue(address) : 0U; }, [&](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); + } maxwell3d.CallMethod(system, address, value, true); + // Turing MME memory reads (methods 0x550 SET_MME_MEM_ADDRESS_A/B, 0x558 data RAM + // address, 0x55c MME_DMA_READ into data RAM, 0x560 MME_DMA_READ_FIFOED into + // the load FIFO, which the macro then reads after a load barrier). + constexpr u32 MemAddressA = 0x154, MemAddressB = 0x155, DataRamAddress = 0x156; + constexpr u32 DmaRead = 0x157, DmaReadFifoed = 0x158; + if (address == DmaRead || address == DmaReadFifoed) { + const GPUVAddr source = (GPUVAddr{maxwell3d.GetRegisterValue(MemAddressA) & 0x1ffffff} << 32) | + maxwell3d.GetRegisterValue(MemAddressB); + auto& memory = maxwell3d.GetMemoryManager(); + const u32 ram = maxwell3d.GetRegisterValue(DataRamAddress); + static u32 dma_logs{}; + if (dma_logs < 400) { + ++dma_logs; + std::array<u32, 8> words{}; + for (u32 i = 0; i < std::min<u32>(value, 8); ++i) words[i] = memory.Read<u32>(source + u64{i} * 4); + LOG_INFO(HW_GPU, "Native MME DMA read{} start={:#x} source={:#x} count={} words={:08x}", + address == DmaReadFifoed ? " fifoed" : "", method, source, value, fmt::join(words, ",")); + } + for (u32 i = 0; i < std::min<u32>(value, 0x1000); ++i) { + const u32 word = memory.Read<u32>(source + u64{i} * 4); + if (address == DmaReadFifoed) { + fifo.push_back(word); + } else if (ram + i < native_interpreter.dram.size()) { + native_interpreter.dram[ram + i] = word; + } + } + } return true; }); if (!result.success) { |
