diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 590f07e78..741ba7ec0 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(tests audio_core/audio_fixures.h audio_core/decoder_tests.cpp video_core/shader/shader_jit_compiler.cpp + video_core/pica_float.cpp audio_core/merryhime_3ds_audio/merry_audio/merry_audio.cpp audio_core/merryhime_3ds_audio/merry_audio/merry_audio.h audio_core/merryhime_3ds_audio/merry_audio/service_fixture.cpp diff --git a/src/tests/video_core/pica_float.cpp b/src/tests/video_core/pica_float.cpp new file mode 100644 index 000000000..394420c99 --- /dev/null +++ b/src/tests/video_core/pica_float.cpp @@ -0,0 +1,30 @@ +// Copyright 2024 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include "video_core/pica_types.h" + +using Pica::f24; + +TEST_CASE("Infinities", "[video_core][pica_float]") { + REQUIRE(std::isinf(f24::FromFloat32(INFINITY).ToFloat32())); + REQUIRE(std::isinf(f24::FromFloat32(1.e20f).ToFloat32())); + REQUIRE(std::isinf(f24::FromFloat32(-1.e20f).ToFloat32())); +} + +TEST_CASE("Subnormals", "[video_core][pica_float]") { + REQUIRE(f24::FromFloat32(1e-20f).ToFloat32() == 0.f); +} + +TEST_CASE("NaN", "[video_core][pica_float]") { + const auto inf = f24::FromFloat32(INFINITY); + const auto nan = f24::FromFloat32(NAN); + + REQUIRE(std::isnan(nan.ToFloat32())); + REQUIRE(std::isnan((nan * f24::Zero()).ToFloat32())); + REQUIRE(std::isnan((inf - inf).ToFloat32())); + REQUIRE((inf * f24::Zero()).ToFloat32() == 0.f); +} diff --git a/src/tests/video_core/shader/shader_jit_compiler.cpp b/src/tests/video_core/shader/shader_jit_compiler.cpp index 01698a2e1..579bf7e99 100644 --- a/src/tests/video_core/shader/shader_jit_compiler.cpp +++ b/src/tests/video_core/shader/shader_jit_compiler.cpp @@ -260,7 +260,7 @@ TEST_CASE("LG2", "[video_core][shader][shader_jit]") { REQUIRE(std::isinf(shader.Run(0.f).x)); REQUIRE(shader.Run(4.f).x == Catch::Approx(2.f)); REQUIRE(shader.Run(64.f).x == Catch::Approx(6.f)); - REQUIRE(shader.Run(1.e24f).x == Catch::Approx(79.7262742773f)); + // REQUIRE(std::isinf(shader.Run(INFINITY).x)); } TEST_CASE("EX2", "[video_core][shader][shader_jit]") { @@ -277,8 +277,9 @@ TEST_CASE("EX2", "[video_core][shader][shader_jit]") { REQUIRE(shader.Run(0.f).x == Catch::Approx(1.f)); REQUIRE(shader.Run(2.f).x == Catch::Approx(4.f)); REQUIRE(shader.Run(6.f).x == Catch::Approx(64.f)); - REQUIRE(shader.Run(79.7262742773f).x == Catch::Approx(1.e24f)); REQUIRE(std::isinf(shader.Run(800.f).x)); + // If we respect f24 precision, 2^79 = inf, as 79 > 63 + // REQUIRE(std::isinf(shader.Run(79.7262742773f).x)); } TEST_CASE("MUL", "[video_core][shader][shader_jit]") { @@ -469,7 +470,7 @@ TEST_CASE("Uniform Read", "[video_core][shader][shader_jit]") { const float color = (i * 2.0f) / 255.0f; const auto color_f24 = Pica::f24::FromFloat32(color); shader.shader_setup->uniforms.f[i] = {color_f24, color_f24, color_f24, Pica::f24::One()}; - f_uniforms[i] = {color, color, color, 1.0f}; + f_uniforms[i] = {color_f24.ToFloat32(), color_f24.ToFloat32(), color_f24.ToFloat32(), 1.0f}; } for (u32 i = 0; i < 96; ++i) { @@ -506,7 +507,8 @@ TEST_CASE("Address Register Offset", "[video_core][shader][shader_jit]") { const auto color_f24 = Pica::f24::FromFloat32(color); shader.shader_setup->uniforms.f[i] = {color_f24, color_f24, color_f24, Pica::f24::One()}; - f_uniforms[i] = {color, color, color, 1.f}; + f_uniforms[i] = {color_f24.ToFloat32(), color_f24.ToFloat32(), color_f24.ToFloat32(), + 1.f}; } else if (i >= 0x60 && i < 0x64) { const u8 color = static_cast((i - 0x60) * 0x10); shader.shader_setup->uniforms.i[i - 0x60] = {color, color, color, 255};