mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 13:37:37 -06:00
gpu: upload cache drops textures of freed buffers on every insert
Entries whose layer buffer was freed were pruned only once the cache went over its budget (1.5 GiB), so an animated layer, which makes a new buffer every frame, left a dead 4K texture per frame allocated until the cache filled up.
This commit is contained in:
@@ -919,6 +919,12 @@ impl GpuContext {
|
||||
|
||||
/// Upload a (layer cache) buffer, reusing the texture while the same `Arc` is alive: static
|
||||
/// layers upload once, not every frame.
|
||||
/// Entries in the layer upload cache.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn upload_entries(&self) -> usize {
|
||||
self.uploads.lock().map(|u| u.map.len()).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn upload_buf(&self, buf: &Arc<Buf>) -> Option<GpuImage> {
|
||||
let key = Arc::as_ptr(buf) as usize;
|
||||
if let Ok(mut u) = self.uploads.lock() {
|
||||
@@ -939,14 +945,14 @@ impl GpuContext {
|
||||
u.bytes -= old.bytes;
|
||||
}
|
||||
u.bytes += bytes;
|
||||
// Drop textures of freed buffers, then the least recently used over budget.
|
||||
// Drop textures of freed buffers at once (a layer whose buffer changes every frame
|
||||
// makes a new one each time, and nothing can hit the old one again), then the least
|
||||
// recently used over budget.
|
||||
let budget = self.upload_budget();
|
||||
if u.bytes > budget {
|
||||
let dead: Vec<usize> = u.map.iter().filter(|(_, e)| e.buf.strong_count() == 0).map(|(k, _)| *k).collect();
|
||||
for k in dead {
|
||||
if let Some(e) = u.map.remove(&k) {
|
||||
u.bytes -= e.bytes;
|
||||
}
|
||||
let dead: Vec<usize> = u.map.iter().filter(|(_, e)| e.buf.strong_count() == 0).map(|(k, _)| *k).collect();
|
||||
for k in dead {
|
||||
if let Some(e) = u.map.remove(&k) {
|
||||
u.bytes -= e.bytes;
|
||||
}
|
||||
}
|
||||
if u.bytes > budget && !self.upload_full_warned.swap(true, std::sync::atomic::Ordering::Relaxed) {
|
||||
|
||||
Reference in New Issue
Block a user