diff --git a/crates/xenia-gpu/src/gpu_system.rs b/crates/xenia-gpu/src/gpu_system.rs index 86a7f2c..03952b3 100644 --- a/crates/xenia-gpu/src/gpu_system.rs +++ b/crates/xenia-gpu/src/gpu_system.rs @@ -1385,9 +1385,24 @@ impl GpuSystem { .register_file .read(CONST_BASE_FETCH + slot as u32 * 6 + k as u32); } - let Some(key) = crate::texture_cache::decode_fetch_constant(fetch6) else { + let Some(mut key) = crate::texture_cache::decode_fetch_constant(fetch6) else { continue; }; + // The Xenos texture fetch constant carries a guest + // *physical* base address (`base >> 12`). On the Xbox + // 360 the GPU reads the unified physical memory; the + // CPU writes the (decompressed) texels through its + // cached-physical aperture, which ours backs at the + // committed `0x4000_0000` window. Map the physical + // base onto that backing window so the GPU samples the + // bytes the guest actually wrote — exactly as the + // vertex-fetch path does (`draw_capture.rs`) and as + // canary reads textures through its GPU shared memory + // (= physical). Without this the decode reads the + // low VA `0x0dbee000` (always zero) instead of the + // filled `0x4dbee000`, flattening every disk-asset + // texture (e.g. the publisher logo `E59B2B3D`). + key.base_address = physical_to_backing(key.base_address); let bi = key.format.block_info(); let span_bytes = (key.pitch_texels as u32) * (key.height as u32)