aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/gpu.cpp
diff options
context:
space:
mode:
authorxbzk <xbzk@eden-emu.dev>2026-09-30 22:13:37 +0200
committercrueter <crueter@eden-emu.dev>2026-09-30 22:13:37 +0200
commit8e2d26c272681d6cafe6d5e703dafdc8200c7b65 (patch)
tree6273515e99af89cf33de15fba8205ee7ab676941 /src/video_core/gpu.cpp
parentf8b76511041bb54070c52d1d09ea07d8108c592a (diff)
[video_core] buffer cache readback for nce invalidations (#4490)
- [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. ------------------- This is a follow up of 4473, a fix for the next Ender Magnolia known crash, the shackled beast's vaper crash, but specific for NCE. Imma try to be short: NCE invalidation was dooming whole guest pages when it shouldn't. If the GPU buffer cache owns some bytes on a page, invalidating first discards their ownership, and the retrying CPU can then observe stale data. On Android, this was corrupting some indirect draw packets and causing huge invalid index count reach staging memory allocation. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4490 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/video_core/gpu.cpp')
-rw-r--r--src/video_core/gpu.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 9901cf4262..6aa7f9abd8 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -226,7 +226,17 @@ struct GPU::Impl {
}
/// Notify rasterizer that any caches of the specified region should be invalidated
- void InvalidateRegion(DAddr addr, u64 size) {
+ void InvalidateRegion(DAddr addr, u64 size, bool preserve_gpu_writes) {
+ VideoCore::RasterizerInterface* rasterizer = renderer->ReadRasterizer();
+ if (preserve_gpu_writes && rasterizer->MustFlushRegion(addr, size, VideoCommon::CacheType::BufferCache)) {
+ const u64 fence = RequestSyncOperation([rasterizer, addr, size] {
+ rasterizer->FlushRegion(addr, size, VideoCommon::CacheType::BufferCache);
+ rasterizer->OnCacheInvalidation(addr, size);
+ });
+ gpu_thread.TickGPU(is_async);
+ WaitForSyncOperation(fence);
+ return;
+ }
gpu_thread.InvalidateRegion(addr, size);
}
@@ -518,8 +528,8 @@ void GPU::FlushRegion(DAddr addr, u64 size) {
impl->FlushRegion(addr, size);
}
-void GPU::InvalidateRegion(DAddr addr, u64 size) {
- impl->InvalidateRegion(addr, size);
+void GPU::InvalidateRegion(DAddr addr, u64 size, bool preserve_gpu_writes) {
+ impl->InvalidateRegion(addr, size, preserve_gpu_writes);
}
bool GPU::OnCPUWrite(DAddr addr, u64 size) {