> are there subtle differences between GPUs and their software rendering that, statistically, can be recovered from the somewhat noisy print?
I'm not sure these days when most GPUs are IEEE-754-compliant. But back in the mid to late 2000's I worked on a GPU renderer for video editing and we had a few filters that gave noticeably different results on different GPUs. One filter did a hard black and white threshold, then blurred the result, did another hard threshold, etc., in a loop. Because of differences in precision of the floating point values (24-bit on AMD at the time, if I recall correctly), the thresholds could produce minor differences that got magnified by the blurring, and then created new thresholds with minor differences, etc.
Even if all the GPUs are using IEEE-754 floats, there are driver differences that can cause the results to be slightly different, too. Like a simple GLSL mix() function could be implemented as result = x * a + y * (1 - a) (where x and y are 2 input pixels and a is the alpha of x). Or it could be implemented more efficiently as result = a * (x - y) + y. Doing the same math in a slightly different way can sometimes lead to slight differences in intermediate results which compound in the final result. So yeah, it may be possible to tease out some of these things by examining something like font rendering.
I'm not sure these days when most GPUs are IEEE-754-compliant. But back in the mid to late 2000's I worked on a GPU renderer for video editing and we had a few filters that gave noticeably different results on different GPUs. One filter did a hard black and white threshold, then blurred the result, did another hard threshold, etc., in a loop. Because of differences in precision of the floating point values (24-bit on AMD at the time, if I recall correctly), the thresholds could produce minor differences that got magnified by the blurring, and then created new thresholds with minor differences, etc.
Even if all the GPUs are using IEEE-754 floats, there are driver differences that can cause the results to be slightly different, too. Like a simple GLSL mix() function could be implemented as result = x * a + y * (1 - a) (where x and y are 2 input pixels and a is the alpha of x). Or it could be implemented more efficiently as result = a * (x - y) + y. Doing the same math in a slightly different way can sometimes lead to slight differences in intermediate results which compound in the final result. So yeah, it may be possible to tease out some of these things by examining something like font rendering.