perf(assets): cache visual wear validation
This commit is contained in:
@@ -50,6 +50,9 @@ const TEXTURES_ARCHIVE: &str = "textures.lib";
|
|||||||
const LIGHTMAP_ARCHIVE: &str = "lightmap.lib";
|
const LIGHTMAP_ARCHIVE: &str = "lightmap.lib";
|
||||||
const VISUAL_DEPENDENCY_PROGRESS_INTERVAL: usize = 64;
|
const VISUAL_DEPENDENCY_PROGRESS_INTERVAL: usize = 64;
|
||||||
|
|
||||||
|
type WearValidationCache =
|
||||||
|
HashMap<(NormalizedPath, Vec<u8>), Result<fparkan_material::WearTable, String>>;
|
||||||
|
|
||||||
/// Canonical terrain archive paths derived from a mission land reference.
|
/// Canonical terrain archive paths derived from a mission land reference.
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub struct MissionTerrainPaths {
|
pub struct MissionTerrainPaths {
|
||||||
@@ -1202,6 +1205,7 @@ pub fn extend_graph_report_with_visual_dependencies_with_progress<R: ResourceRep
|
|||||||
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();
|
let mut material_validation = HashMap::new();
|
||||||
|
let mut wear_validation = HashMap::new();
|
||||||
let mut wear_requests = 0usize;
|
let mut wear_requests = 0usize;
|
||||||
let mut material_requests = 0usize;
|
let mut material_requests = 0usize;
|
||||||
let mut texture_requests = 0usize;
|
let mut texture_requests = 0usize;
|
||||||
@@ -1236,7 +1240,7 @@ pub fn extend_graph_report_with_visual_dependencies_with_progress<R: ResourceRep
|
|||||||
VisualDependencyPhase::Wear,
|
VisualDependencyPhase::Wear,
|
||||||
wear_requests,
|
wear_requests,
|
||||||
);
|
);
|
||||||
match resolve_wear_table(repository, mesh) {
|
match resolve_wear_table_cached(repository, mesh, &mut wear_validation) {
|
||||||
Ok(table) => {
|
Ok(table) => {
|
||||||
report.wear_resolved_count += 1;
|
report.wear_resolved_count += 1;
|
||||||
let wear_key = match wear_resource_key(mesh) {
|
let wear_key = match wear_resource_key(mesh) {
|
||||||
@@ -1457,7 +1461,7 @@ pub fn extend_graph_report_with_visual_dependencies_with_progress<R: ResourceRep
|
|||||||
mesh.name.0.clone(),
|
mesh.name.0.clone(),
|
||||||
PrototypeGraphEdge::MeshToWear,
|
PrototypeGraphEdge::MeshToWear,
|
||||||
PrototypeGraphRequiredness::Required,
|
PrototypeGraphRequiredness::Required,
|
||||||
&message.to_string(),
|
&message,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1899,6 +1903,21 @@ fn resolve_wear_table<R: ResourceRepository>(
|
|||||||
decode_wear(&bytes).map_err(AssetError::Material)
|
decode_wear(&bytes).map_err(AssetError::Material)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolve_wear_table_cached<R: ResourceRepository>(
|
||||||
|
repository: &R,
|
||||||
|
mesh: &ResourceKey,
|
||||||
|
cache: &mut WearValidationCache,
|
||||||
|
) -> Result<fparkan_material::WearTable, String> {
|
||||||
|
let wear_key = wear_resource_key(mesh).map_err(|error| error.to_string())?;
|
||||||
|
let cache_key = (wear_key.archive.clone(), wear_key.name.0.clone());
|
||||||
|
if let Some(result) = cache.get(&cache_key) {
|
||||||
|
return result.clone();
|
||||||
|
}
|
||||||
|
let result = resolve_wear_table(repository, mesh).map_err(|error| error.to_string());
|
||||||
|
cache.insert(cache_key, result.clone());
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
fn push_visual_failure(
|
fn push_visual_failure(
|
||||||
report: &mut PrototypeGraphReport,
|
report: &mut PrototypeGraphReport,
|
||||||
graph: &PrototypeGraph,
|
graph: &PrototypeGraph,
|
||||||
@@ -2323,6 +2342,26 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn wear_validation_cache_replays_archive_qualified_failure() {
|
||||||
|
let repository = repository_with_archives(&[]);
|
||||||
|
let mesh = ResourceKey {
|
||||||
|
archive: parse_path("static.rlb").expect("archive"),
|
||||||
|
name: resource_name(b"tree.msh"),
|
||||||
|
type_id: Some(0x4853_454D),
|
||||||
|
};
|
||||||
|
let mut cache = WearValidationCache::new();
|
||||||
|
cache.insert(
|
||||||
|
(mesh.archive.clone(), b"tree.wea".to_vec()),
|
||||||
|
Err("cached WEAR failure".to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_wear_table_cached(&repository, &mesh, &mut cache),
|
||||||
|
Err("cached WEAR failure".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn count_only_plan_uses_graph_requests() {
|
fn count_only_plan_uses_graph_requests() {
|
||||||
let graph = PrototypeGraph::default();
|
let graph = PrototypeGraph::default();
|
||||||
|
|||||||
@@ -1151,6 +1151,17 @@ the measured unfinished interval for this run. It still does not allocate that
|
|||||||
time among MAT0 decode, graph allocation, archive I/O, OS cache state, or the
|
time among MAT0 decode, graph allocation, archive I/O, OS cache state, or the
|
||||||
interleaved TEXM requests.
|
interleaved TEXM requests.
|
||||||
|
|
||||||
|
Visual expansion now also caches WEAR validation by the complete derived WEAR
|
||||||
|
archive/name key and replays both successes and failures. It still creates each
|
||||||
|
per-prototype WEAR edge, increments the same request counters, and reports the
|
||||||
|
same failure provenance. A unit test verifies an archive-qualified cached
|
||||||
|
failure is replayed without consulting the repository. In a matched bounded
|
||||||
|
Part 2 probe the first TEXM-64 marker occurred at 135,520 ms, versus 134,793
|
||||||
|
ms in the preceding sample, and neither run reached `Assets`; therefore this
|
||||||
|
corpus does not evidence a startup advance from WEAR caching. The path is kept
|
||||||
|
as a correctness-preserving duplicate-resolve optimization, not a causal
|
||||||
|
performance claim.
|
||||||
|
|
||||||
A rebuilt executable then ran a controlled 180-second Part 2 `Autodemo.00`
|
A rebuilt executable then ran a controlled 180-second Part 2 `Autodemo.00`
|
||||||
probe with the append-only trace. Before exact-child termination it recorded
|
probe with the append-only trace. Before exact-child termination it recorded
|
||||||
`GraphVisualTextureRequests(64)`, `GraphVisualMaterialRequests(100)`, and every
|
`GraphVisualTextureRequests(64)`, `GraphVisualMaterialRequests(100)`, and every
|
||||||
|
|||||||
Reference in New Issue
Block a user