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/engines/kepler_compute.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/engines/kepler_compute.cpp')
| -rw-r--r-- | src/video_core/engines/kepler_compute.cpp | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp index 1ef6e0fc0d..96a12539a2 100644 --- a/src/video_core/engines/kepler_compute.cpp +++ b/src/video_core/engines/kepler_compute.cpp @@ -49,13 +49,16 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu case KEPLER_COMPUTE_REG_INDEX(exec_upload): { UploadInfo info{.upload_address = upload_address, .exec_address = upload_state.ExecTargetAddress(), - .copy_size = upload_state.GetUploadSize()}; + .copy_size = upload_state.GetUploadSize(), + .was_dirty = upload_dirty}; uploads.push_back(info); upload_state.ProcessExec(regs.exec_upload.linear != 0); break; } case KEPLER_COMPUTE_REG_INDEX(data_upload): { upload_address = current_dma_segment; + upload_dirty = current_dirty; + current_dirty = false; upload_state.ProcessData(method_argument, is_last_call); break; } @@ -64,9 +67,11 @@ void KeplerCompute::CallMethod(Core::System& system, u32 method, u32 method_argu for (auto& data : uploads) { const GPUVAddr offset = data.exec_address - launch_desc_loc; - if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x) && - memory_manager.IsMemoryDirty(data.upload_address, data.copy_size)) { - indirect_compute = {data.upload_address}; + if (offset / sizeof(u32) == LAUNCH_REG_INDEX(grid_dim_x)) { + const bool source_dirty = memory_manager.IsMemoryDirty(data.upload_address, data.copy_size); + if (data.was_dirty || source_dirty) { + indirect_compute = {data.upload_address}; + } } } uploads.clear(); @@ -83,6 +88,8 @@ void KeplerCompute::CallMultiMethod(Core::System& system, u32 method, const u32* switch (method) { case KEPLER_COMPUTE_REG_INDEX(data_upload): upload_address = current_dma_segment; + upload_dirty = current_dirty; + current_dirty = false; upload_state.ProcessData(base_start, amount); return; default: |
