mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-20 09:09:19 +02:00
Add EU7 PACK v11 UTEX, section unload, and LRU streaming caches
Bake deduplicated section texture lists (UTEX) and read them at runtime so texture warm/prefetch no longer scans every instance. Evict PACK sections outside a 16 km keep ring and cap mesh/nodedata/texture warm caches to stop RAM and apply cost from growing without bound during long fast camera flight. - Bake v11 (format=4): UMES + UTEX + CHNK; mesh/texture ordering by frequency - Runtime: incremental UTEX warm, adaptive apply slices, preempt/catchup tuning - Unload: track instances per section, Region erase, pack pool release - LRU: mesh/nodedata (2000, ref-counted), warmed textures (2048) - Bench/diagnostics: unload and cache eviction counters - Fix pack instance erase in Region; resolve duplicate helper symbols
This commit is contained in:
@@ -505,6 +505,48 @@ parse_pack_section_header(
|
||||
const std::uint8_t first_byte {
|
||||
peek == EOF ? std::uint8_t { 0 } : static_cast<std::uint8_t>( peek ) };
|
||||
|
||||
bool use_v11_header { false };
|
||||
if( first_byte == kPackSectionFormatV11 ) {
|
||||
cursor.section_format = sn_utils::d_uint8( input );
|
||||
const std::uint32_t solo_total { sn_utils::ld_uint32( input ) };
|
||||
const std::uint32_t inst_total { sn_utils::ld_uint32( input ) };
|
||||
const std::uint32_t unique_mesh_count { sn_utils::ld_uint32( input ) };
|
||||
if( solo_total + inst_total == entry.model_count ) {
|
||||
use_v11_header = true;
|
||||
cursor.model_total = solo_total + inst_total;
|
||||
cursor.solo_remaining = 0;
|
||||
cursor.inst_remaining = 0;
|
||||
|
||||
StringTable const strings { module.strings };
|
||||
cursor.unique_meshes.reserve( unique_mesh_count );
|
||||
for( std::uint32_t mesh_idx { 0 }; mesh_idx < unique_mesh_count; ++mesh_idx ) {
|
||||
cursor.unique_meshes.push_back(
|
||||
strings.resolve( sn_utils::ld_uint32( input ) ) );
|
||||
}
|
||||
|
||||
const std::uint32_t unique_texture_count { sn_utils::ld_uint32( input ) };
|
||||
cursor.unique_textures.reserve( unique_texture_count );
|
||||
for( std::uint32_t tex_idx { 0 }; tex_idx < unique_texture_count; ++tex_idx ) {
|
||||
cursor.unique_textures.push_back(
|
||||
strings.resolve( sn_utils::ld_uint32( input ) ) );
|
||||
}
|
||||
|
||||
cursor.chunk_count = sn_utils::ld_uint32( input );
|
||||
cursor.chunk_model_counts.resize( cursor.chunk_count );
|
||||
cursor.chunk_byte_offsets.resize( cursor.chunk_count );
|
||||
for( std::uint32_t chunk_idx { 0 }; chunk_idx < cursor.chunk_count; ++chunk_idx ) {
|
||||
cursor.chunk_model_counts[ chunk_idx ] = sn_utils::ld_uint32( input );
|
||||
cursor.chunk_byte_offsets[ chunk_idx ] = sn_utils::ld_uint32( input );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( use_v11_header ) {
|
||||
cursor.models_read = 0;
|
||||
cursor.header_parsed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
bool use_v10_header { false };
|
||||
if( first_byte == kPackSectionFormatV10 ) {
|
||||
cursor.section_format = sn_utils::d_uint8( input );
|
||||
@@ -1168,11 +1210,13 @@ read_pack_section_chunk_load_impl(
|
||||
result.chunk_index = chunk_index;
|
||||
if( chunk_index == 0 ) {
|
||||
result.unique_meshes = header.unique_meshes;
|
||||
result.unique_textures = header.unique_textures;
|
||||
}
|
||||
|
||||
Eu7PackSectionCursor chunk_cursor { header };
|
||||
if(
|
||||
header.section_format == kPackSectionFormatV10 &&
|
||||
( header.section_format == kPackSectionFormatV10 ||
|
||||
header.section_format == kPackSectionFormatV11 ) &&
|
||||
false == header.chunk_byte_offsets.empty() ) {
|
||||
auto const section_start {
|
||||
static_cast<std::streamoff>( module.pack_payload_offset + entry->pack_offset ) };
|
||||
@@ -1218,9 +1262,11 @@ read_pack_section_load_impl( Eu7Module const &module, int const row, int const c
|
||||
parse_pack_section_header( module, input, *entry, header );
|
||||
|
||||
result.unique_meshes = header.unique_meshes;
|
||||
result.unique_textures = header.unique_textures;
|
||||
|
||||
if(
|
||||
header.section_format == kPackSectionFormatV10 &&
|
||||
( header.section_format == kPackSectionFormatV10 ||
|
||||
header.section_format == kPackSectionFormatV11 ) &&
|
||||
header.chunk_count > 0 ) {
|
||||
result.models.reserve( entry->model_count );
|
||||
for( std::uint32_t chunk_idx { 0 }; chunk_idx < header.chunk_count; ++chunk_idx ) {
|
||||
|
||||
Reference in New Issue
Block a user