tgsi_exec: Fix NaN behavior of saturate

Modern shader APIs, like DX10 and GLSL 1.30, want saturate or
clamp(..., 0.0, 1.0) to "cleanse" NaN.  If the source is NaN, the
result should be zero.

There are many cases where TGSI is generate from NIR, and many
optimizations in NIR expect this behavior.  Not meeting these
expectations can lead to unexpected results.

Reviewed-by: Eric Anholt <eric@anholt.net>
Fixes: 56c30bf17b ("tgsi: Saturate modifier obeys ExecMask. Implement NVIDIA [-1;+1] saturate mode.")
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10419>
(cherry picked from commit d1c0f62b42)
This commit is contained in:
Ian Romanick 2021-04-22 17:41:57 -07:00 committed by Eric Engestrom
parent 975ab701d7
commit 3521f76806
2 changed files with 3 additions and 3 deletions

View file

@ -76,7 +76,7 @@
"description": "tgsi_exec: Fix NaN behavior of saturate",
"nominated": true,
"nomination_type": 1,
"resolution": 0,
"resolution": 1,
"master_sha": null,
"because_sha": "56c30bf17b9f57efdb93ae5d1b801677535a9651"
},

View file

@ -1938,7 +1938,7 @@ store_dest(struct tgsi_exec_machine *mach,
else {
for (i = 0; i < TGSI_QUAD_SIZE; i++)
if (execmask & (1 << i)) {
if (chan->f[i] < 0.0f)
if (chan->f[i] < 0.0f || isnan(chan->f[i]))
dst->f[i] = 0.0f;
else if (chan->f[i] > 1.0f)
dst->f[i] = 1.0f;
@ -3621,7 +3621,7 @@ store_double_channel(struct tgsi_exec_machine *mach,
else {
for (i = 0; i < TGSI_QUAD_SIZE; i++)
if (execmask & (1 << i)) {
if (chan->d[i] < 0.0)
if (chan->d[i] < 0.0 || isnan(chan->d[i]))
temp.d[i] = 0.0;
else if (chan->d[i] > 1.0)
temp.d[i] = 1.0;