D107: fast3d sampled unloaded mip tile for GE's LOD textures (blurry ceilings)

GE's room GDLs emit G_TL_LOD + G_TD_DETAIL for mip-mapped textures, but
gfx_detail_textures_enabled is false for this port. gfx_lod_tile_offset's
'rdp.tex_lod ? rdp.tex_detail : i' then returned tex_detail (1) for every
texel, so fast3d sampled GE's first mip (render tile 1). GE loads the
whole mip chain with one G_LOADBLOCK to TMEM 0 and just points tiles 1..5
at offsets inside it; fast3d keys loaded_texture[] by TMEM addr and has
no entry for tile 1's offset, so import_texture fabricated a 16x16 from
the top-left 256 bytes of the base image and magnified it across the
polygon -- the blurry brown/grey ceilings and wall panels in BUNKER1.

Fix: when detail textures are disabled, gfx_lod_tile_offset always
returns 0 (the base render tile, the only correctly-loaded level). Sharp
near surfaces, matching what the N64 shows at close range.

Verified -level_09: BUNKER1 ventilation room ceilings/walls/light panels
now render crisp instead of brown mush. Single-level textures (racks,
room 1) were already fine and are unaffected.
This commit is contained in:
James Dansereau committed 2026-08-28 22:02:25 -04:00
1 parent 5f6741a432
commit 1fe85339f2
1 file changed
+9 -1
+9 -1
View File
@@ -1258,7 +1258,15 @@ static void gfx_sp_modify_vertex(uint16_t vtx_idx, uint8_t where, uint32_t val)
static inline int gfx_lod_tile_offset(const int i) {
if (gfx_detail_textures_enabled)
return ((rdp.tex_lod && !rdp.tex_detail) ? 0 : i);
return (rdp.tex_lod ? rdp.tex_detail : i);
// D107: GE has no true detail textures (gfx_detail_textures_enabled is
// false), but its room GDLs still emit G_TL_LOD + G_TD_DETAIL for
// mip-mapped textures. The old `rdp.tex_lod ? rdp.tex_detail : i` then
// returned tex_detail (1) for every texel -> fast3d sampled GE's first
// mip (tile 1), whose single-LOADBLOCK TMEM slot fast3d never registers
// -> a magnified crop of the base image (the "blurry blob" ceilings /
// wall panels in BUNKER1). GE loads the whole mip chain at TMEM 0, so
// the base render tile is the only correctly-loaded level: always use it.
return 0;
}
static void gfx_sp_tri1(uint8_t vtx1_idx, uint8_t vtx2_idx, uint8_t vtx3_idx, bool is_rect) {