From 35c7abb7cc377a9f5d87a3a07a22765e2ac9801b Mon Sep 17 00:00:00 2001 From: Antonio Sokic <5701985+finaler1x@users.noreply.github.com> Date: Sat, 31 Oct 2026 02:01:05 +0100 Subject: [PATCH] Issue #1764: keep a failed upload out of the shared source Record the out-of-memory failure when the staging buffer can't be allocated, and don't publish the zeroed buffer to SHARED_SOURCE when the render has failed, so a concurrent render can't reuse it. --- crates/gpu/src/ctx.rs | 4 ++++ crates/gpu/src/render.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/crates/gpu/src/ctx.rs b/crates/gpu/src/ctx.rs index c235b93ae..c15aa51d7 100644 --- a/crates/gpu/src/ctx.rs +++ b/crates/gpu/src/ctx.rs @@ -518,6 +518,10 @@ impl Gpu { } // (dropping the view schedules the copy) drop(view); + } else { + // recorded now, not only when the error scope pops: the zeroed buffer must not be + // shared before then (`render::shared_source`) + fail(FailKind::OutOfMemory, "out of device memory: the upload's staging buffer couldn't be allocated".into()); } // no view: the buffer couldn't be allocated (out of device memory). The error scope has recorded why and // the render fails over to the CPU; allocating it again would only fail again (issue #1764) diff --git a/crates/gpu/src/render.rs b/crates/gpu/src/render.rs index 90aed7974..26634d437 100644 --- a/crates/gpu/src/render.rs +++ b/crates/gpu/src/render.rs @@ -466,6 +466,10 @@ fn shared_source(src: &Arc, upload: impl FnOnce() -> Buf) -> Arc { *g = None; SOURCE_UPLOADS.fetch_add(1, std::sync::atomic::Ordering::Relaxed); let buf = Arc::new(upload()); + // a failed upload's buffer holds zeros: this render falls back, and no other may reuse it + if crate::ctx::failed() { + return buf; + } *g = Some((Arc::downgrade(src), buf.clone())); buf }