diff --git a/src/video_core/control/channel_state.cpp b/src/video_core/control/channel_state.cpp index d07c7e2a83..c3e54b2fbf 100644 --- a/src/video_core/control/channel_state.cpp +++ b/src/video_core/control/channel_state.cpp @@ -16,6 +16,24 @@ #include "video_core/memory_manager.h" namespace Tegra::Control { +namespace { + +// Match NVK/Nouveau's initial pushbuffer subchannel layout. +constexpr u32 Nvk3DSubchannel = 0; +constexpr u32 NvkComputeSubchannel = 1; +constexpr u32 Nvk2DSubchannel = 3; +constexpr u32 NvkCopySubchannel = 4; + +void BindNvkDefaultSubchannels(ChannelState& channel_state) { + auto& dma_pusher = *channel_state.dma_pusher; + dma_pusher.BindSubchannel(&*channel_state.maxwell_3d, Nvk3DSubchannel, Engines::EngineTypes::Maxwell3D); + dma_pusher.BindSubchannel(&*channel_state.kepler_compute, NvkComputeSubchannel, Engines::EngineTypes::KeplerCompute); + // Subchannel 2 is M2MF there; Eden does not expose a 0x9039 engine yet. + dma_pusher.BindSubchannel(&*channel_state.fermi_2d, Nvk2DSubchannel, Engines::EngineTypes::Fermi2D); + dma_pusher.BindSubchannel(&*channel_state.maxwell_dma, NvkCopySubchannel, Engines::EngineTypes::MaxwellDMA); +} + +} // Anonymous namespace ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {} @@ -28,6 +46,7 @@ void ChannelState::Init(Core::System& system, GPU& gpu, u64 program_id_) { kepler_compute.emplace(system, *memory_manager); maxwell_dma.emplace(system, *memory_manager); kepler_memory.emplace(system, *memory_manager); + BindNvkDefaultSubchannels(*this); initialized = true; } diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 4030f93d49..a5a6138cbe 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp @@ -22,6 +22,13 @@ namespace Tegra::Engines { +namespace { + +constexpr u32 Gf100BindClassMask = 0xffff; +constexpr u32 Gf100BindValidMask = 0x1f0000 | Gf100BindClassMask; + +} // Anonymous namespace + Puller::Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher_, Control::ChannelState& channel_state_) : gpu{gpu_}, memory_manager{memory_manager_}, dma_pusher{dma_pusher_}, channel_state{ @@ -30,10 +37,14 @@ Puller::Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher_ Puller::~Puller() = default; void Puller::ProcessBindMethod(const MethodCall& method_call) { - // Bind the current subchannel to the desired engine id. - LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, + LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {:#x}", method_call.subchannel, method_call.argument); - const auto engine_id = static_cast(method_call.argument); + u32 engine = method_call.argument; + if ((engine & ~Gf100BindClassMask) != 0 && (engine & ~Gf100BindValidMask) == 0) { + engine &= Gf100BindClassMask; + } + + const auto engine_id = static_cast(engine); bound_engines[method_call.subchannel] = engine_id; switch (engine_id) { case EngineID::FERMI_TWOD_A: