From 630a850d4d5a0509b16e96aaccc81e9384e1fba8 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 24 Aug 2015 01:48:15 -0300 Subject: Shaders: Fix multiplications between 0.0 and inf The PICA200 semantics for multiplication are so that when multiplying inf by exactly 0.0, the result is 0.0, instead of NaN, as defined by IEEE. This is relied upon by games. Fixes #1024 (missing OoT interface items) --- src/video_core/pica.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 58b924f9e..cf148de50 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -1021,12 +1021,20 @@ struct float24 { return ret; } + static float24 Zero() { + return FromFloat32(0.f); + } + // Not recommended for anything but logging float ToFloat32() const { return value; } float24 operator * (const float24& flt) const { + if ((this->value == 0.f && flt.value == flt.value) || + (flt.value == 0.f && this->value == this->value)) + // PICA gives 0 instead of NaN when multiplying by inf + return Zero(); return float24::FromFloat32(ToFloat32() * flt.ToFloat32()); } @@ -1043,7 +1051,11 @@ struct float24 { } float24& operator *= (const float24& flt) { - value *= flt.ToFloat32(); + if ((this->value == 0.f && flt.value == flt.value) || + (flt.value == 0.f && this->value == this->value)) + // PICA gives 0 instead of NaN when multiplying by inf + *this = Zero(); + else value *= flt.ToFloat32(); return *this; } -- cgit v1.2.3 From eff10959de41027da7a09298941fcb403f610192 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 24 Aug 2015 02:10:11 -0300 Subject: fixup! Shaders: Fix multiplications between 0.0 and inf --- src/video_core/pica.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/video_core/pica.h') diff --git a/src/video_core/pica.h b/src/video_core/pica.h index cf148de50..bb689f2a9 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -1031,8 +1031,8 @@ struct float24 { } float24 operator * (const float24& flt) const { - if ((this->value == 0.f && flt.value == flt.value) || - (flt.value == 0.f && this->value == this->value)) + if ((this->value == 0.f && !std::isnan(flt.value)) || + (flt.value == 0.f && !std::isnan(this->value))) // PICA gives 0 instead of NaN when multiplying by inf return Zero(); return float24::FromFloat32(ToFloat32() * flt.ToFloat32()); @@ -1051,8 +1051,8 @@ struct float24 { } float24& operator *= (const float24& flt) { - if ((this->value == 0.f && flt.value == flt.value) || - (flt.value == 0.f && this->value == this->value)) + if ((this->value == 0.f && !std::isnan(flt.value)) || + (flt.value == 0.f && !std::isnan(this->value))) // PICA gives 0 instead of NaN when multiplying by inf *this = Zero(); else value *= flt.ToFloat32(); -- cgit v1.2.3