aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/cdma_pusher.cpp
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-04-29 19:23:20 +0200
committercrueter <crueter@eden-emu.dev>2026-04-29 19:23:20 +0200
commit8765b4951201a94673d5b561f6ba5094b2af0fa5 (patch)
treeeda339e386199eec0761307bfa14a0c9ed162e7c /src/video_core/cdma_pusher.cpp
parenta587b7dc3ae5eb475ca63c747afe8866a590d499 (diff)
[video_core] fix H264 and jthread() causing spurious errors (#3907)
fixes regression by #3878 Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3907 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Diffstat (limited to 'src/video_core/cdma_pusher.cpp')
-rw-r--r--src/video_core/cdma_pusher.cpp149
1 files changed, 70 insertions, 79 deletions
diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp
index 7c342dbefa..1f0f8b5a38 100644
--- a/src/video_core/cdma_pusher.cpp
+++ b/src/video_core/cdma_pusher.cpp
@@ -20,110 +20,101 @@
namespace Tegra {
CDmaPusher::CDmaPusher(Host1x::Host1x& host1x_, s32 id)
- : host_processor{std::make_unique<Host1x::Control>(host1x_)}
+ : host_processor(host1x_)
, host1x{host1x_}
, current_class{ChClassId(id)}
{
- thread = std::jthread([this](std::stop_token stop_token) { ProcessEntries(stop_token); });
-}
-
-CDmaPusher::~CDmaPusher() = default;
-
-void CDmaPusher::ProcessEntries(std::stop_token stop_token) {
- Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
- ChCommandHeaderList command_list{host1x.System().ApplicationMemory(), 0, 0};
- u32 count{};
- u32 method_offset{};
- u32 mask{};
- bool incrementing{};
+ thread = std::jthread([this](std::stop_token stop_token) {
+ Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
+ ChCommandHeaderList command_list{host1x.System().ApplicationMemory(), 0, 0};
+ u32 count{};
+ u32 method_offset{};
+ u32 mask{};
+ bool incrementing{};
+ while (!stop_token.stop_requested()) {
+ {
+ std::unique_lock l{command_mutex};
+ command_cv.wait(l, stop_token, [this]() { return command_lists.size() > 0; });
+ if (stop_token.stop_requested()) {
+ return;
+ }
- while (!stop_token.stop_requested()) {
- {
- std::unique_lock l{command_mutex};
- command_cv.wait(l, stop_token,
- [this]() { return command_lists.size() > 0; });
- if (stop_token.stop_requested()) {
- return;
+ command_list = std::move(command_lists.front());
+ command_lists.pop_front();
}
- command_list = std::move(command_lists.front());
- command_lists.pop_front();
- }
-
- size_t i = 0;
- for (const auto value : command_list) {
- i++;
- if (mask != 0) {
- const auto lbs = static_cast<u32>(std::countr_zero(mask));
- mask &= ~(1U << lbs);
- ExecuteCommand(method_offset + lbs, value.raw);
- continue;
- } else if (count != 0) {
- --count;
- ExecuteCommand(method_offset, value.raw);
- if (incrementing) {
- ++method_offset;
+ size_t i = 0;
+ for (const auto value : command_list) {
+ i++;
+ if (mask != 0) {
+ const auto lbs = static_cast<u32>(std::countr_zero(mask));
+ mask &= ~(1U << lbs);
+ ExecuteCommand(method_offset + lbs, value.raw);
+ continue;
+ } else if (count != 0) {
+ --count;
+ ExecuteCommand(method_offset, value.raw);
+ if (incrementing) {
+ ++method_offset;
+ }
+ continue;
+ }
+ const auto mode = value.submission_mode.Value();
+ switch (mode) {
+ case ChSubmissionMode::SetClass: {
+ mask = value.value & 0x3f;
+ method_offset = value.method_offset;
+ current_class = ChClassId((value.value >> 6) & 0x3ff);
+ break;
+ }
+ case ChSubmissionMode::Incrementing:
+ case ChSubmissionMode::NonIncrementing:
+ count = value.value;
+ method_offset = value.method_offset;
+ incrementing = mode == ChSubmissionMode::Incrementing;
+ break;
+ case ChSubmissionMode::Mask:
+ mask = value.value;
+ method_offset = value.method_offset;
+ break;
+ case ChSubmissionMode::Immediate: {
+ const u32 data = value.value & 0xfff;
+ method_offset = value.method_offset;
+ ExecuteCommand(method_offset, data);
+ break;
+ }
+ default:
+ LOG_ERROR(HW_GPU, "Bad command at index {} (bytes {:#X}), buffer size {}", i - 1, (i - 1) * sizeof(u32), command_list.size());
+ UNIMPLEMENTED_MSG("ChSubmission mode {} is not implemented!", u32(mode));
+ break;
}
- continue;
- }
- const auto mode = value.submission_mode.Value();
- switch (mode) {
- case ChSubmissionMode::SetClass: {
- mask = value.value & 0x3f;
- method_offset = value.method_offset;
- current_class = static_cast<ChClassId>((value.value >> 6) & 0x3ff);
- break;
- }
- case ChSubmissionMode::Incrementing:
- case ChSubmissionMode::NonIncrementing:
- count = value.value;
- method_offset = value.method_offset;
- incrementing = mode == ChSubmissionMode::Incrementing;
- break;
- case ChSubmissionMode::Mask:
- mask = value.value;
- method_offset = value.method_offset;
- break;
- case ChSubmissionMode::Immediate: {
- const u32 data = value.value & 0xfff;
- method_offset = value.method_offset;
- ExecuteCommand(method_offset, data);
- break;
- }
- default:
- LOG_ERROR(HW_GPU, "Bad command at index {} (bytes {:#X}), buffer size {}", i - 1,
- (i - 1) * sizeof(u32), command_list.size());
- UNIMPLEMENTED_MSG("ChSubmission mode {} is not implemented!",
- static_cast<u32>(mode));
- break;
}
}
- }
+ });
}
+CDmaPusher::~CDmaPusher() = default;
+
void CDmaPusher::ExecuteCommand(u32 method, u32 arg) {
switch (current_class) {
case ChClassId::Control:
- LOG_TRACE(Service_NVDRV, "Class {} method {:#X} arg 0x{:X}",
- static_cast<u32>(current_class), method, arg);
- host_processor->ProcessMethod(static_cast<Host1x::Control::Method>(method), arg);
+ LOG_TRACE(Service_NVDRV, "Class {} method {:#X} arg 0x{:X}", u32(current_class), method, arg);
+ host_processor.ProcessMethod(Host1x::Control::Method(method), arg);
break;
default:
thi_regs.reg_array[method] = arg;
switch (static_cast<ThiMethod>(method)) {
case ThiMethod::IncSyncpt: {
- const auto syncpoint_id = static_cast<u32>(arg & 0xFF);
- [[maybe_unused]] const auto cond = static_cast<u32>((arg >> 8) & 0xFF);
- LOG_TRACE(Service_NVDRV, "Class {} IncSyncpt Method, syncpt {} cond {}",
- static_cast<u32>(current_class), syncpoint_id, cond);
+ const auto syncpoint_id = u32(arg & 0xFF);
+ [[maybe_unused]] const auto cond = u32((arg >> 8) & 0xFF);
+ LOG_TRACE(Service_NVDRV, "Class {} IncSyncpt Method, syncpt {} cond {}", u32(current_class), syncpoint_id, cond);
auto& syncpoint_manager = host1x.GetSyncpointManager();
syncpoint_manager.IncrementGuest(syncpoint_id);
syncpoint_manager.IncrementHost(syncpoint_id);
break;
}
case ThiMethod::SetMethod1:
- LOG_TRACE(Service_NVDRV, "Class {} method {:#X} arg 0x{:X}",
- static_cast<u32>(current_class), static_cast<u32>(thi_regs.method_0), arg);
+ LOG_TRACE(Service_NVDRV, "Class {} method {:#X} arg 0x{:X}", u32(current_class), u32(thi_regs.method_0), arg);
ProcessMethod(thi_regs.method_0, arg);
break;
default: