aboutsummaryrefslogtreecommitdiff
path: root/src/tests/video_core/native_semaphore.cpp
diff options
context:
space:
mode:
authorDjihads <76681596+Djihads80@users.noreply.github.com>2026-10-29 02:25:36 +0100
committerGitHub <noreply@github.com>2026-10-29 02:25:36 +0100
commit0bb5055b6541c74f47603a8dff0569a509cbaf18 (patch)
treeda827ff9c4f2f9a5309ee2804ee689f608c0ac2f /src/tests/video_core/native_semaphore.cpp
parent1af7fe72927af9fc64aa4af117bc9b30043c4dc7 (diff)
parent535b6769709eb22333af26269f1b16f37adce4db (diff)
Merge pull request #1 from Djihads80/yumekiru/ns2-progress-v2
Experimental NS2 support and accumulated GPU fixes
Diffstat (limited to 'src/tests/video_core/native_semaphore.cpp')
-rw-r--r--src/tests/video_core/native_semaphore.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/tests/video_core/native_semaphore.cpp b/src/tests/video_core/native_semaphore.cpp
new file mode 100644
index 0000000000..8dcafd91bc
--- /dev/null
+++ b/src/tests/video_core/native_semaphore.cpp
@@ -0,0 +1,63 @@
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <array>
+#include <optional>
+#include <vector>
+#include <catch2/catch_test_macros.hpp>
+#include "common/common_types.h"
+#include "video_core/native_semaphore.h"
+
+TEST_CASE("Native semaphore predicates require the actual producer value", "[native-gpu]") {
+ const Tegra::NativeSemaphoreWait equal{0x1000, 840, 1};
+ REQUIRE_FALSE(equal.Matches(0));
+ REQUIRE_FALSE(equal.Matches(839));
+ REQUIRE(equal.Matches(840));
+ REQUIRE_FALSE(equal.Matches(841));
+ const Tegra::NativeSemaphoreWait gequal{0x1000, 840, 4};
+ REQUIRE_FALSE(gequal.Matches(0));
+ REQUIRE_FALSE(gequal.Matches(839));
+ REQUIRE(gequal.Matches(840));
+ REQUIRE(gequal.Matches(841));
+ const Tegra::NativeSemaphoreWait mask{0x1000, 0x24, 8};
+ REQUIRE_FALSE(mask.Matches(0));
+ REQUIRE_FALSE(mask.Matches(0x10));
+ REQUIRE(mask.Matches(4));
+ REQUIRE(mask.Matches(0x20));
+ REQUIRE_FALSE(Tegra::NativeSemaphoreWait::Supported(0));
+ REQUIRE_FALSE(Tegra::NativeSemaphoreWait::Supported(2));
+ REQUIRE_FALSE(Tegra::NativeSemaphoreWait{0x1000, 0, 2}.Matches(0));
+}
+
+TEST_CASE("Native channels resume in dependency order without completing blocked work", "[native-gpu]") {
+ const std::array<size_t, 3> channels{0, 1, 2};
+ std::array<std::optional<Tegra::NativeSemaphoreWait>, 3> waits{
+ Tegra::NativeSemaphoreWait{0x1000, 1, 4},
+ Tegra::NativeSemaphoreWait{0x2000, 1, 1},
+ Tegra::NativeSemaphoreWait{0x3000, 1, 4},
+ };
+ std::array<u32, 3> words{};
+ std::array<u32, 3> following_commands{};
+ std::vector<size_t> order;
+ const auto ready = [&](size_t channel) {
+ return waits[channel] && waits[channel]->Matches(words[channel]);
+ };
+ const auto dispatch = [&](size_t channel) {
+ REQUIRE(ready(channel));
+ waits[channel].reset();
+ ++following_commands[channel];
+ order.push_back(channel);
+ if (channel) words[channel - 1] = 1;
+ };
+ REQUIRE(Tegra::ResumeReadyNativeChannels(channels, ready, dispatch) == 0);
+ REQUIRE(order.empty());
+ REQUIRE(following_commands == std::array<u32, 3>{0, 0, 0});
+ // A real independent producer releases the last channel. Its remaining
+ // FIFO commands release the next channel, then the original consumer.
+ words[2] = 1;
+ REQUIRE(Tegra::ResumeReadyNativeChannels(channels, ready, dispatch) == 3);
+ REQUIRE(order == std::vector<size_t>{2, 1, 0});
+ REQUIRE(following_commands == std::array<u32, 3>{1, 1, 1});
+ REQUIRE(Tegra::ResumeReadyNativeChannels(channels, ready, dispatch) == 0);
+ REQUIRE(following_commands == std::array<u32, 3>{1, 1, 1});
+}