diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 1aac0daa2..488cbc554 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -13,11 +13,17 @@ set(HEADERS core/arm/arm_test_common.h ) +if (ARCHITECTURE_x86_64) + set(SRCS ${SRCS} + video_core/shader/shader_jit_x64_compiler.cpp + ) +endif() + create_directory_groups(${SRCS} ${HEADERS}) add_executable(tests ${SRCS} ${HEADERS}) -target_link_libraries(tests PRIVATE common core) +target_link_libraries(tests PRIVATE common core video_core) target_link_libraries(tests PRIVATE glad) # To support linker work-around -target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) +target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include nihstro-headers Threads::Threads) add_test(NAME tests COMMAND tests) diff --git a/src/tests/video_core/shader/shader_jit_x64_compiler.cpp b/src/tests/video_core/shader/shader_jit_x64_compiler.cpp new file mode 100644 index 000000000..7008670f5 --- /dev/null +++ b/src/tests/video_core/shader/shader_jit_x64_compiler.cpp @@ -0,0 +1,91 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include +#include +#include "video_core/shader/shader_jit_x64_compiler.h" + +using float24 = Pica::float24; +using JitShader = Pica::Shader::JitShader; + +using DestRegister = nihstro::DestRegister; +using OpCode = nihstro::OpCode; +using SourceRegister = nihstro::SourceRegister; + +static std::unique_ptr CompileShader(std::initializer_list code) { + const auto shbin = nihstro::InlineAsm::CompileToRawBinary(code); + + std::array program_code{}; + std::array swizzle_data{}; + + std::transform(shbin.program.begin(), shbin.program.end(), program_code.begin(), + [](const auto& x) { return x.hex; }); + std::transform(shbin.swizzle_table.begin(), shbin.swizzle_table.end(), swizzle_data.begin(), + [](const auto& x) { return x.hex; }); + + auto shader = std::make_unique(); + shader->Compile(&program_code, &swizzle_data); + + return shader; +} + +class ShaderTest { +public: + explicit ShaderTest(std::initializer_list code) + : shader(CompileShader(code)) {} + + float Run(float input) { + Pica::Shader::ShaderSetup shader_setup; + Pica::Shader::UnitState shader_unit; + + shader_unit.registers.input[0].x = float24::FromFloat32(input); + shader->Run(shader_setup, shader_unit, 0); + return shader_unit.registers.output[0].x.ToFloat32(); + } + +public: + std::unique_ptr shader; +}; + +TEST_CASE("LG2", "[video_core][shader][shader_jit]") { + const auto sh_input = SourceRegister::MakeInput(0); + const auto sh_output = DestRegister::MakeOutput(0); + + auto shader = ShaderTest({ + // clang-format off + {OpCode::Id::LG2, sh_output, sh_input}, + {OpCode::Id::END}, + // clang-format on + }); + + REQUIRE(std::isnan(shader.Run(NAN))); + REQUIRE(std::isnan(shader.Run(-1.f))); + REQUIRE(std::isinf(shader.Run(0.f))); + REQUIRE(shader.Run(4.f) == Approx(2.f)); + REQUIRE(shader.Run(64.f) == Approx(6.f)); + REQUIRE(shader.Run(1.e24f) == Approx(79.7262742773f)); +} + +TEST_CASE("EX2", "[video_core][shader][shader_jit]") { + const auto sh_input = SourceRegister::MakeInput(0); + const auto sh_output = DestRegister::MakeOutput(0); + + auto shader = ShaderTest({ + // clang-format off + {OpCode::Id::EX2, sh_output, sh_input}, + {OpCode::Id::END}, + // clang-format on + }); + + REQUIRE(std::isnan(shader.Run(NAN))); + REQUIRE(shader.Run(-800.f) == Approx(0.f)); + REQUIRE(shader.Run(0.f) == Approx(1.f)); + REQUIRE(shader.Run(2.f) == Approx(4.f)); + REQUIRE(shader.Run(6.f) == Approx(64.f)); + REQUIRE(shader.Run(79.7262742773f) == Approx(1.e24f)); + REQUIRE(std::isinf(shader.Run(800.f))); +} diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 82f47d8a9..d492e5188 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -87,7 +87,7 @@ target_link_libraries(video_core PUBLIC common core) target_link_libraries(video_core PRIVATE glad nihstro-headers) if (ARCHITECTURE_x86_64) - target_link_libraries(video_core PRIVATE xbyak) + target_link_libraries(video_core PUBLIC xbyak) endif() if (PNG_FOUND)