Posterize on the GPU: divide by the levels exactly, as the CPU does (#3179)

Native division isn't correctly rounded on real GPUs, so
posterize_matches_the_cpu_on_every_8bpc_pair failed on NVIDIA and Apple
GPUs while passing on the software renderer hosted CI uses.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
FredAppsandClaude Opus 5.5 authored and GitHub committed 2026-11-06 20:04:21 +01:00
1 parent ca1ff9cfc2
commit 5047d8b5e7
1 file changed
+3 -1
+3 -1
View File
@@ -127,7 +127,9 @@ fn fxs_point(@builtin(global_invocation_id) gid: vec3<u32>) {
case 1u: {
let lv = P.f[0].x;
let c = vec3<f32>(unit_div(px.x, a), unit_div(px.y, a), unit_div(px.z, a));
let o = vec3<f32>(fxs_posterize_bin(c.x, u32(lv)), fxs_posterize_bin(c.y, u32(lv)), fxs_posterize_bin(c.z, u32(lv))) / lv;
// (`unit_div`: a native division by the levels is off by an ulp on real GPUs)
let bins = vec3<f32>(fxs_posterize_bin(c.x, u32(lv)), fxs_posterize_bin(c.y, u32(lv)), fxs_posterize_bin(c.z, u32(lv)));
let o = vec3<f32>(unit_div(bins.x, lv), unit_div(bins.y, lv), unit_div(bins.z, lv));
textureStore(out, p, vec4<f32>(o * a, a));
}
case 2u: {