fix: D430 -- stale per-texture anisotropy on recycled GL ids made watch text layout-dependent

gfx_opengl_set_sampler_parameters set GL_TEXTURE_MAX_ANISOTROPY only for
mipmapped samplers and never reset it. GL ids freed by
gfx_texture_cache_delete_range are recycled in unordered_map order (keyed by
texture address), so a non-mipmapped glyph could inherit a world texture's
4x anisotropy depending on the binary's data layout -> +-1-2 per channel on
the MP pause-menu text in couch 2P (frame 2400). Now always written (level
when mipmapped, 1 otherwise). #ifdef PORT, render-only.

Verified: couch 2P frames 2300-2500 fix vs fix+3KB array 0/21 differ
(before: 13/21); base vs fix: couch 2P 0/21, solo -level_09 f1800 and couch
4P f2400 byte-identical; netplay 2P SH identical (2 671 ticks).
Findings D430 + index row, porting note.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit ec5057f026259f35d4075833e89bf6fd0b6c467f)
This commit is contained in:
dolent committed 2026-09-29 13:26:20 -07:00
1 parent 0e8c2ce213
commit 4705b0e4e8
3 files changed
+55

No files matched your search

+12
View File
@@ -787,9 +787,21 @@ static void gfx_opengl_set_sampler_parameters(int tile, bool linear_filter, uint
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_filter);
#ifdef PORT
/* D430: anisotropy is per-texture-object state. It was only ever SET
* (when mipmapped), never reset, so a GL texture id freed by
* gfx_texture_cache_delete_range and reused for a non-mipmapped texture
* (HUD / watch text glyphs) kept the previous owner's 4x -- llvmpipe then
* filters that glyph differently (+-1..2 per channel). Which id a texture
* inherits follows the unordered_map iteration order, i.e. the texture
* ADDRESSES, so the frame changed with the binary's data layout. Always
* write it: the level when mipmapped, 1 (off) otherwise. */
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, mipmaps ? (float)current_anisotropy_level : 1.0f);
#else
if (mipmaps) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, current_anisotropy_level);
}
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gfx_cm_to_opengl(cms));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gfx_cm_to_opengl(cmt));