From 665938d0b157ff1dce056b5c24a57aee9392929b Mon Sep 17 00:00:00 2001 From: snowstormxd <214507868+snowstormxd@users.noreply.github.com> Date: Mon, 2 Nov 2026 18:00:14 +0000 Subject: macro: execute native parameters without a second FIFO copy Use the owned parameter vector for DMA FIFO appends. Add a native JIT regression covering reallocation and repeated invocations against the copied-input path. Assisted by Codex. (cherry picked from commit 5b6803aaab18e332493903ee49cab026c041d5dc) --- src/tests/video_core/native_macro_fifo.cpp | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/tests/video_core/native_macro_fifo.cpp (limited to 'src/tests/video_core/native_macro_fifo.cpp') diff --git a/src/tests/video_core/native_macro_fifo.cpp b/src/tests/video_core/native_macro_fifo.cpp new file mode 100644 index 0000000000..e19b146192 --- /dev/null +++ b/src/tests/video_core/native_macro_fifo.cpp @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +#include +#include +#include + +#ifdef ARCHITECTURE_x86_64 +#include "video_core/macro_turing_jit.h" + +namespace { +std::array FifoInstruction(u32 method, bool end) { + std::array bits{}; + const auto field = [&](u32 offset, u32 count, u32 value) { + for (u32 bit = 0; bit < count; ++bit) { + bits[(offset + bit) / 32] |= ((value >> bit) & 1) << ((offset + bit) % 32); + } + }; + field(0, 1, end); + for (u32 lane = 0; lane < 2; ++lane) { + field(15 + lane * 36, 5, 24); + field(20 + lane * 36, 5, 24); + field(25 + lane * 36, 5, 24); + } + field(30, 16, method); + field(82, 3, 5); + field(85, 4, 3); + return {bits[2], bits[1], bits[0]}; +} +} // namespace + +TEST_CASE("Owned native macro FIFOs preserve loads across DMA appends and repeated calls", + "[video_core][native_macro]") { + std::vector code; + for (const auto instruction : {FifoInstruction(0x158, false), FifoInstruction(0x200, true), + FifoInstruction(0x201, false)}) { + code.insert(code.end(), instruction.begin(), instruction.end()); + } + Tegra::TuringMacroJit jit; + jit.Prepare(code, 1); + std::array ram{}; + std::vector parameters; + std::vector reference; + for (u32 invocation = 0; invocation < 1000; ++invocation) { + const u32 count = 2 + invocation % 127; + parameters.push_back(count); + reference.assign(parameters.begin(), parameters.end()); + const auto run = [&](std::vector& input) { + std::vector> writes; + const auto result = jit.Execute( + 0, input, ram, [](u32) { return 0U; }, + [&](u32 method, u32 value) { + writes.emplace_back(method, value); + if (method == 0x158) { + for (u32 word = 0; word < value; ++word) { + input.push_back(invocation * 256 + word); + } + } + return true; + }); + CHECK(result.success); + CHECK(result.consumed == 3); + return writes; + }; + const auto expected = run(reference); + const auto actual = run(parameters); + REQUIRE(actual.size() == 3); + CHECK(actual == expected); + CHECK(parameters == reference); + CHECK(actual[1] == std::pair{0x200, invocation * 256}); + CHECK(actual[2] == std::pair{0x201, invocation * 256 + 1}); + parameters.clear(); + } +} +#endif -- cgit v1.2.3