diff options
| author | xbzk <xbzk@eden-emu.dev> | 2026-09-24 18:44:14 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-09-24 18:44:14 +0200 |
| commit | dbeb73ee011416cffc6c203945f5ccc6b90621f6 (patch) | |
| tree | 43d3674029e1756dfbab6554c853d8a371570240 /src/video_core/dma_pusher.cpp | |
| parent | cb73a4dcc7710a7fea1643797b17e39858f4ae6a (diff) | |
[video_core] cpu buffer fix + kepler uploads / maxwell macro dirty tracking fixes (#4473)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.
-------------------
Aimed to fix two known UE5 crashes: Kepler uploads and Maxwell macros, both caused by CPU/GPU races due dirty tracking issues.
Kepler ComputeInline: preserved dirty tracking across dma continuations and async readback.
Maxwell macros: preserved gpu owned subranges during page granular cpu uploads.
DiscardWrite: stopped clearing neighboring macro arguments by rounding up ranges.
DMA Step: improved continuation aware dirty sampling.
To the Ender Magnolia crew (maybe 1 or 2 persons): This will fix the dash crash, and the random / shackled beast vaper crashes.
There are some more UE5 issues to go next.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4473
Reviewed-by: lizzie <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'src/video_core/dma_pusher.cpp')
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index 2417659f09..2c0ba007ef 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -16,7 +16,7 @@ namespace Tegra { constexpr u32 MacroRegistersStart = 0xE00; -[[maybe_unused]] constexpr u32 ComputeInline = 0x6D; +constexpr u32 ComputeInline = 0x6D; DmaPusher::DmaPusher(Core::System& system_, MemoryManager& memory_manager_, Control::ChannelState& channel_state_) : system{system_} @@ -73,11 +73,16 @@ bool DmaPusher::Step() { synced = false; } - if (header.size > 0 && dma_state.method >= MacroRegistersStart && subchannels[dma_state.subchannel]) { - subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, header.size * sizeof(u32)); - } - if (header.size > 0) { + if (subchannels[dma_state.subchannel] && dma_state.method_count) { + const auto engine = subchannel_type[dma_state.subchannel]; + const bool kepler_payload = engine == Engines::EngineTypes::KeplerCompute && dma_state.method == ComputeInline && dma_state.non_incrementing; + const bool macro_payload = engine == Engines::EngineTypes::Maxwell3D && dma_state.method >= MacroRegistersStart; + if (kepler_payload || macro_payload) { + const size_t words = std::min<size_t>(dma_state.method_count, header.size); + subchannels[dma_state.subchannel]->current_dirty = memory_manager.IsMemoryDirty(dma_state.dma_get, words * sizeof(u32)); + } + } const bool use_safe = Settings::IsDMALevelDefault() ? Settings::IsGPULevelHigh() : Settings::IsDMALevelSafe(); if (use_safe) { Tegra::Memory::GpuGuestMemory<Tegra::CommandHeader, Tegra::Memory::GuestMemoryFlags::SafeRead>headers(memory_manager, dma_state.dma_get, header.size, &command_headers); |
