mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 03:29:43 -10:00
gfx/drivers_shader/shader_gl_cg: mask IN.frame_count when no modulo declared
The Cg shader 'IN.frame_count' input is bound via cg_gl_set_param_1f, which forces a (float) cast of an unsigned monotonic counter. fp32 integer precision dies at 2^24 = 16,777,216, so at 60 fps any Cg shader that uses IN.frame_count for time-based animation freezes its counter after roughly 77 hours of continuous play. The frame_count_mod field on each shader pass is the documented defense, but it is opt-in and most presets do not set it. Add a default 24-bit mask when no modulo is declared, so the cast stays bit-exact in perpetuity and existing Cg shaders that key animation off IN.frame_count keep working in long sessions. Presets that do declare frame_count_mod are unaffected.
This commit is contained in:
1 parent
aebd062503
commit
9e5bd445a1
1 file changed
+7
@@ -455,6 +455,13 @@ static void gl_cg_set_params(void *dat, void *shader_data)
|
||||
unsigned modulo = cg->shader->pass[cg->active_idx - 1].frame_count_mod;
|
||||
if (modulo)
|
||||
frame_count %= modulo;
|
||||
else
|
||||
/* fp32 mantissa is 23 bits; integers above 2^24 cannot be
|
||||
* represented exactly. Mask to 24 bits when the shader pass
|
||||
* has not declared its own modulo, so (float)frame_count stays
|
||||
* bit-exact and time-based Cg shaders keep animating beyond
|
||||
* ~77 h of continuous play. */
|
||||
frame_count &= 0xFFFFFFu;
|
||||
|
||||
cg_gl_set_param_1f(cg->prg[cg->active_idx].frame_cnt_f, (float)frame_count);
|
||||
cg_gl_set_param_1f(cg->prg[cg->active_idx].frame_cnt_v, (float)frame_count);
|
||||
|
||||
Reference in new issue
Block a user