use std::{path::PathBuf, sync::OnceLock};
static CACHE_DIR: OnceLock<PathBuf> = OnceLock::new();
pub fn set_pipeline_cache_dir(dir: PathBuf) -> bool {
CACHE_DIR.set(dir).is_ok()
}
#[cfg(not(target_arch = "wasm32"))]
fn cache_file(info: &wgpu::AdapterInfo) -> Option<PathBuf> {
let dir = CACHE_DIR.get()?;
let key = wgpu::util::pipeline_cache_key(info)?;
Some(dir.join(format!("{key}.bin")))
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn load_blob(info: &wgpu::AdapterInfo) -> Option<Vec<u8>> {
let path = cache_file(info)?;
match std::fs::read(&path) {
Ok(bytes) => Some(bytes),
Err(error) => {
tracing::debug!(%error, path = %path.display(), "no pipeline cache blob loaded");
None
}
}
}
#[cfg(target_arch = "wasm32")]
pub(crate) const fn load_blob(_info: &wgpu::AdapterInfo) -> Option<Vec<u8>> {
None
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn persist(cache: &wgpu::PipelineCache, info: &wgpu::AdapterInfo) {
let Some(path) = cache_file(info) else {
return;
};
let Some(data) = cache.get_data() else {
return;
};
let write = || -> std::io::Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let tmp = path.with_extension("tmp");
std::fs::write(&tmp, &data)?;
std::fs::rename(&tmp, &path)
};
if let Err(error) = write() {
tracing::debug!(%error, path = %path.display(), "pipeline cache not persisted");
}
}
#[cfg(target_arch = "wasm32")]
pub(crate) const fn persist(_cache: &wgpu::PipelineCache, _info: &wgpu::AdapterInfo) {}