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 }