From 5a9bb045d72998c3d1a76e2afbae60119fb033da Mon Sep 17 00:00:00 2001 From: Vitor Kiguchi Date: Tue, 23 Jan 2024 00:56:57 -0300 Subject: [PATCH] tests: fix shader_jit_compiler and add pica_float The Uniform Read and Address Register Offset ran into precision differences between f32 and f24, which can be easily fixed and are not the point of the tests. As for the LG2 and EX2 tests that were failing, they were wrong. While it is true that 2^79.7 ~= 1e24, the value is bigger than the biggest representable value in f24, therefore both EX2 and LG2(?) should result in Inf. --- src/tests/CMakeLists.txt | 1 + src/tests/video_core/pica_float.cpp | 30 +++++++++++++++++++ .../video_core/shader/shader_jit_compiler.cpp | 10 ++++--- 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/tests/video_core/pica_float.cpp 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};