From 1fe85339f25210d1e8f01402e225ffb3b4434c8d Mon Sep 17 00:00:00 2001 From: James Dansereau <106631954+jkdansereau@users.noreply.github.com> Date: Fri, 28 Aug 2026 22:02:25 -0400 Subject: [PATCH] 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. --- port/fast3d/gfx_pc.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 00cdb291..3a783ba8 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -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) {