diff options
| author | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-02 18:00:14 +0000 |
|---|---|---|
| committer | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-02 18:57:54 +0000 |
| commit | 665938d0b157ff1dce056b5c24a57aee9392929b (patch) | |
| tree | 873dac03690bd8558ab95ae5ef3722ce632fea4a /src | |
| parent | 62214094d6c698b70f51016e5c12af415f025be7 (diff) | |
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)
Diffstat (limited to 'src')
| -rw-r--r-- | src/tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/tests/video_core/native_macro_fifo.cpp | 74 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 9 |
3 files changed, 79 insertions, 5 deletions
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index a9be2ec7a8..49fc646dea 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable(tests video_core/memory_tracker.cpp video_core/vertex_repack.cpp video_core/ampere_returns.cpp + video_core/native_macro_fifo.cpp input_common/calibration_configuration_job.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 <array> +#include <vector> +#include <catch2/catch_test_macros.hpp> + +#ifdef ARCHITECTURE_x86_64 +#include "video_core/macro_turing_jit.h" + +namespace { +std::array<u32, 3> FifoInstruction(u32 method, bool end) { + std::array<u32, 3> 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<u32> 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<u32, 0xc00> ram{}; + std::vector<u32> parameters; + std::vector<u32> 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<u32>& input) { + std::vector<std::pair<u32, u32>> 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<u32, u32>{0x200, invocation * 256}); + CHECK(actual[2] == std::pair<u32, u32>{0x201, invocation * 256 + 1}); + parameters.clear(); + } +} +#endif diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 9731f54584..70191ebef0 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -818,7 +818,6 @@ struct Maxwell3D::FrontState { Regs::ShadowRamControl control{}; u32 executing_macro{}; std::vector<u32> parameters; - std::vector<u32> fifo; u64 calls{}; /// A method the draw manager handles was sent since the back last ran DrawDeferred: only /// then can it have a deferred instanced draw to issue at the end of a macro. @@ -1095,9 +1094,9 @@ void Maxwell3D::FrontRunMacro(Core::System& system, VideoCommon::GpuSplit& split engine.native_jit = std::make_shared<TuringMacroJit>(); } engine.native_jit->Prepare(engine.native_code, engine.native_code_generation); - fs.fifo.assign(fs.parameters.begin(), fs.parameters.end()); + const size_t parameter_count = fs.parameters.size(); const auto result = engine.native_jit->Execute( - start, fs.fifo, std::span<u32>{native_data_ram}, + start, fs.parameters, std::span<u32>{native_data_ram}, [&fs](u32 address) { return address < Regs::NUM_REGS ? fs.regs[address] : 0U; }, [&](u32 address, u32 value) { if (address >= MacroRegistersStart) { @@ -1113,7 +1112,7 @@ void Maxwell3D::FrontRunMacro(Core::System& system, VideoCommon::GpuSplit& split if (!result.success) { engine.native_execution_failed = true; LOG_ERROR(HW_GPU, "Native MME (JIT, split front) failed: start={:#x}, consumed={}/{}, error={}", - start, result.consumed, fs.parameters.size(), result.error); + start, result.consumed, parameter_count, result.error); } } fs.parameters.clear(); @@ -1148,7 +1147,7 @@ void Maxwell3D::FrontDmaRead(VideoCommon::GpuSplit& split, FrontState& fs, u32 m for (u32 i = 0; i < words; ++i) { const u32 word = memory_manager.Read<u32>(source + u64{i} * sizeof(u32)); if (method == 0x158) { - fs.fifo.push_back(word); + fs.parameters.push_back(word); } else if (ram + i < native_data_ram.size()) { native_data_ram[ram + i] = word; } |
