perf(assets): cache graph material validation
Docs Deploy / Build and Deploy MkDocs (push) Successful in 35s
Test / Lint (push) Failing after 2m9s
Test / Test (push) Skipped
Test / Render parity (push) Skipped

This commit is contained in:
2026-07-18 11:24:31 +04:00
parent 421c9d7aa3
commit ceb7ea1fab
2 changed files with 40 additions and 1 deletions
+32 -1
View File
@@ -1124,6 +1124,7 @@ pub fn extend_graph_report_with_visual_dependencies<R: ResourceRepository>(
.map_or(0, |value| value.saturating_add(1)); .map_or(0, |value| value.saturating_add(1));
let mut diffuse_texture_validation = HashMap::new(); let mut diffuse_texture_validation = HashMap::new();
let mut lightmap_texture_validation = HashMap::new(); let mut lightmap_texture_validation = HashMap::new();
let mut material_validation = HashMap::new();
for (prototype_index, prototype) in prototypes.iter().enumerate() { for (prototype_index, prototype) in prototypes.iter().enumerate() {
let PrototypeGeometry::Mesh(mesh) = &prototype.geometry else { let PrototypeGeometry::Mesh(mesh) = &prototype.geometry else {
@@ -1190,7 +1191,12 @@ pub fn extend_graph_report_with_visual_dependencies<R: ResourceRepository>(
); );
continue; continue;
}; };
match resolve_material(repository, &table, material_index) { match resolve_material_validation_cached(
repository,
&table,
material_index,
&mut material_validation,
) {
Ok(material) => { Ok(material) => {
report.material_resolved_count += 1; report.material_resolved_count += 1;
let material_key = ResourceKey { let material_key = ResourceKey {
@@ -1900,6 +1906,31 @@ fn resolve_texm_validation_cached<R: ResourceRepository>(
result result
} }
fn resolve_material_validation_cached<R: ResourceRepository>(
repository: &R,
table: &WearTable,
index: u16,
cache: &mut HashMap<Vec<u8>, Result<ResolvedMaterial, String>>,
) -> Result<ResolvedMaterial, String> {
let request = table
.entries
.get(usize::from(index))
.ok_or(MaterialError::WearIndexOutOfBounds {
index,
count: table.entries.len(),
})
.map_err(|error| error.to_string())?
.material
.0
.clone();
if let Some(result) = cache.get(&request) {
return result.clone();
}
let result = resolve_material(repository, table, index).map_err(|error| error.to_string());
cache.insert(request, result.clone());
result
}
#[cfg(test)] #[cfg(test)]
fn resolve_texture<R: ResourceRepository>( fn resolve_texture<R: ResourceRepository>(
repository: &R, repository: &R,
+8
View File
@@ -1063,6 +1063,14 @@ provenance while avoiding repeat format work for repeated components. The same
demonstrate an additional checkpoint advance from this cache; it must not be demonstrate an additional checkpoint advance from this cache; it must not be
reported as a measured startup improvement. reported as a measured startup improvement.
Visual-graph material resolution now also caches the complete success or failure
of each WEAR material request. Every material edge and failure remains in the
graph; the cache only avoids reopening and decoding an already resolved MAT0.
Under the controlled 60-second GOG first-root probe, the phase sequence advanced
from `GraphVisuals` to `AssetModelMeshes`, `AssetWearTables`, then
`AssetTextures` before termination. This is a bounded timing observation, not a
claim that a frame completed or that every run has identical timing.
`Assets` now has four ordered diagnostic sub-checkpoints: `AssetModelMeshes` `Assets` now has four ordered diagnostic sub-checkpoints: `AssetModelMeshes`
(MSH), `AssetWearTables` (WEAR), `AssetMaterials` (MAT0) and `AssetTextures` (MSH), `AssetWearTables` (WEAR), `AssetMaterials` (MAT0) and `AssetTextures`
(diffuse TEXM and lightmaps). The callback is observational: it neither changes (diffuse TEXM and lightmaps). The callback is observational: it neither changes