diff options
| author | lizzie <lizzie@eden-emu.dev> | 2026-04-29 19:23:20 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-04-29 19:23:20 +0200 |
| commit | 8765b4951201a94673d5b561f6ba5094b2af0fa5 (patch) | |
| tree | eda339e386199eec0761307bfa14a0c9ed162e7c /src/video_core/cdma_pusher.cpp | |
| parent | a587b7dc3ae5eb475ca63c747afe8866a590d499 (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.cpp | 149 |
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: |
