diff options
| author | xtam <jj.tobola2@gmail.com> | 2026-10-30 21:49:15 +0100 |
|---|---|---|
| committer | xtam <jj.tobola2@gmail.com> | 2026-10-30 21:49:15 +0100 |
| commit | a4a746b47b1d1ee02ddf1fe528c7db05800eec2c (patch) | |
| tree | 320fd13bf6ceb1e8e88b0164ed0e1c5d9a714a3f /src/tests | |
| parent | 3e950dd677b6d7dca04541855ad5751d057371ea (diff) | |
fix: restore Mario Kart World text by accepting R0 shader returns
Do not treat the reserved destination field of Ampere RET as a write to the return-link register. Keep return linkage validation and rejection of actual link-register writes.
Add three regression tests covering R0 and R55 links, copied links, and overwritten links. Validation: 10 assertions pass; user confirmed the compiled patch restores text in Mario Kart World.
AI-assisted implementation and commit message using OpenAI Codex.
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/tests/video_core/ampere_returns.cpp | 51 |
2 files changed, 52 insertions, 0 deletions
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 875c40604c..dd6f5d97b5 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(tests core/core_timing.cpp core/internal_network/network.cpp video_core/memory_tracker.cpp + video_core/ampere_returns.cpp input_common/calibration_configuration_job.cpp ) diff --git a/src/tests/video_core/ampere_returns.cpp b/src/tests/video_core/ampere_returns.cpp new file mode 100644 index 0000000000..56b8b374da --- /dev/null +++ b/src/tests/video_core/ampere_returns.cpp @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include <array> +#include <catch2/catch_test_macros.hpp> + +#include "shader_recompiler/frontend/ampere/lower_to_maxwell.h" + +namespace { +using Shader::Ampere::Instruction; +using Shader::Ampere::LowerToMaxwell; + +TEST_CASE("Ampere returns do not write the link register", "[video_core][ampere]") { + for (const u32 link : {0U, 55U}) { + const std::array<Instruction, 4> code{{ + {{0x00007802U | (link << 16), 0x20, 0x00000f00, 0}}, + {{0x00007944, 0x10, 0x03c00000, 0}}, + {{0x0000794d, 0, 0x03800000, 0}}, + {{0x00007950U | (link << 24), 0xffffffc0, 0x03c3ffff, 0}}, + }}; + const auto lowered = LowerToMaxwell(code); + REQUIRE(static_cast<bool>(lowered)); + REQUIRE(lowered.source_size == sizeof(code)); + REQUIRE(lowered.instructions.back() == 0xe32000000007000fULL); + } +} + +TEST_CASE("Ampere returns can read a copy of the R0 link", "[video_core][ampere]") { + const std::array<Instruction, 5> code{{ + {{0x00007802, 0x20, 0x00000f00, 0}}, + {{0x00007944, 0x10, 0x03c00000, 0}}, + {{0x0000794d, 0, 0x03800000, 0}}, + {{0x00017202, 0, 0x00000f00, 0}}, + {{0x01007950, 0xffffffb0, 0x03c3ffff, 0}}, + }}; + REQUIRE(static_cast<bool>(LowerToMaxwell(code))); +} + +TEST_CASE("Ampere callees still reject writes to the link", "[video_core][ampere]") { + const std::array<Instruction, 5> code{{ + {{0x00007802, 0x20, 0x00000f00, 0}}, + {{0x00007944, 0x10, 0x03c00000, 0}}, + {{0x0000794d, 0, 0x03800000, 0}}, + {{0x00007802, 0, 0x00000f00, 0}}, + {{0x00007950, 0xffffffb0, 0x03c3ffff, 0}}, + }}; + const auto lowered = LowerToMaxwell(code); + REQUIRE(!static_cast<bool>(lowered)); + REQUIRE(lowered.error == "native callee overwrites link register"); + REQUIRE(lowered.error_offset == 0x30); +} +} // namespace |
