use std::path::Path;
use concinnity_host::store::cache::{CACHE_BUDGET_BYTES, Segment};
use concinnity_host::store::paths;
use crate::shader_cache::Ensured;
#[derive(Debug, Default)]
pub struct Report {
pub reused: usize,
pub compiled: usize,
pub failed: Vec<String>,
}
impl Report {
pub(crate) fn record(&mut self, label: &str, result: Result<Ensured, String>) {
match result {
Ok(Ensured::Present) | Ok(Ensured::Copied) => self.reused += 1,
Ok(Ensured::Compiled) => self.compiled += 1,
Err(e) => self.failed.push(format!("{label}: {e}")),
}
}
pub fn cached(&self) -> usize {
self.reused + self.compiled
}
}
pub fn precompile_builtin_shaders(state_dir: &Path) -> Report {
let path = paths::runtime_cache_in(state_dir);
let mut bundle = Segment::read_from(&path);
let mut report = Report::default();
#[cfg(backend_dx)]
{
crate::directx::builtins::precompile(&mut bundle, &mut report);
crate::directx::slang_builtins::precompile(&mut bundle, &mut report);
}
#[cfg(backend_vk)]
crate::vulkan::builtins::precompile(&mut bundle, &mut report);
bundle.write_to(&path, CACHE_BUDGET_BYTES);
crate::runtime_cache::checkpoint();
report
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn report_tallies_reuse_compile_and_failure() {
let mut r = Report::default();
r.record("a", Ok(Ensured::Present));
r.record("b", Ok(Ensured::Copied));
r.record("c", Ok(Ensured::Compiled));
r.record("d ps_5_1", Err("boom".to_string()));
assert_eq!(r.reused, 2);
assert_eq!(r.compiled, 1);
assert_eq!(r.cached(), 3);
assert_eq!(r.failed, vec!["d ps_5_1: boom".to_string()]);
}
}