From 3aa0d462598beb2021308eee1d757d74fe33b312 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 23 Jun 2026 06:31:25 +0200 Subject: [video_core, hle] remove redundant parent references in system structs (#3908) reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads Signed-off-by: lizzie Co-authored-by: maufeat Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908 Reviewed-by: Maufeat Reviewed-by: crueter --- src/video_core/engines/puller.cpp | 139 ++++++++++++++++---------------------- 1 file changed, 58 insertions(+), 81 deletions(-) (limited to 'src/video_core/engines/puller.cpp') diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 4030f93d49..5816b5901a 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp @@ -22,37 +22,29 @@ namespace Tegra::Engines { -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{ - channel_state_} {} - -Puller::~Puller() = default; - -void Puller::ProcessBindMethod(const MethodCall& method_call) { +void Puller::ProcessBindMethod(DmaPusher& dma_pusher, const MethodCall& method_call) { // Bind the current subchannel to the desired engine id. - LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, - method_call.argument); + LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, method_call.argument); const auto engine_id = static_cast(method_call.argument); bound_engines[method_call.subchannel] = engine_id; switch (engine_id) { case EngineID::FERMI_TWOD_A: - dma_pusher.BindSubchannel(&*channel_state.fermi_2d, method_call.subchannel, EngineTypes::Fermi2D); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->fermi_2d, method_call.subchannel, EngineTypes::Fermi2D); break; case EngineID::MAXWELL_B: - dma_pusher.BindSubchannel(&*channel_state.maxwell_3d, method_call.subchannel, EngineTypes::Maxwell3D); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->maxwell_3d, method_call.subchannel, EngineTypes::Maxwell3D); break; case EngineID::KEPLER_COMPUTE_B: - dma_pusher.BindSubchannel(&*channel_state.kepler_compute, method_call.subchannel, EngineTypes::KeplerCompute); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->kepler_compute, method_call.subchannel, EngineTypes::KeplerCompute); break; case EngineID::MAXWELL_DMA_COPY_A: - dma_pusher.BindSubchannel(&*channel_state.maxwell_dma, method_call.subchannel, EngineTypes::MaxwellDMA); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->maxwell_dma, method_call.subchannel, EngineTypes::MaxwellDMA); break; case EngineID::KEPLER_INLINE_TO_MEMORY_B: - dma_pusher.BindSubchannel(&*channel_state.kepler_memory, method_call.subchannel, EngineTypes::KeplerMemory); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->kepler_memory, method_call.subchannel, EngineTypes::KeplerMemory); break; case EngineID::NV01_TIMER: - dma_pusher.BindSubchannel(&*channel_state.nv01_timer, method_call.subchannel, EngineTypes::Nv01Timer); + dma_pusher.BindSubchannel(&dma_pusher.channel_state.payload->nv01_timer, method_call.subchannel, EngineTypes::Nv01Timer); break; default: UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id); @@ -60,15 +52,15 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) { } } -void Puller::ProcessFenceActionMethod() { +void Puller::ProcessFenceActionMethod(DmaPusher& dma_pusher) { switch (regs.fence_action.op) { case Puller::FenceOperation::Acquire: // UNIMPLEMENTED_MSG("Channel Scheduling pending."); // WaitFence(regs.fence_action.syncpoint_id, regs.fence_value); - rasterizer->ReleaseFences(); + dma_pusher.rasterizer->ReleaseFences(); break; case Puller::FenceOperation::Increment: - rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id); + dma_pusher.rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id); break; default: UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value()); @@ -76,37 +68,35 @@ void Puller::ProcessFenceActionMethod() { } } -void Puller::ProcessSemaphoreTriggerMethod() { +void Puller::ProcessSemaphoreTriggerMethod(DmaPusher& dma_pusher) { const auto semaphoreOperationMask = 0xF; - const auto op = - static_cast(regs.semaphore_trigger & semaphoreOperationMask); + const auto op = GpuSemaphoreOperation(regs.semaphore_trigger & semaphoreOperationMask); if (op == GpuSemaphoreOperation::WriteLong) { const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()}; const u32 payload = regs.semaphore_sequence; - rasterizer->Query(sequence_address, VideoCommon::QueryType::Payload, - VideoCommon::QueryPropertiesFlags::HasTimeout, payload, 0); + dma_pusher.rasterizer->Query(sequence_address, VideoCommon::QueryType::Payload, VideoCommon::QueryPropertiesFlags::HasTimeout, payload, 0); } else { do { - const u32 word{memory_manager.Read(regs.semaphore_address.SemaphoreAddress())}; + const u32 word = dma_pusher.memory_manager.Read(regs.semaphore_address.SemaphoreAddress()); regs.acquire_source = true; regs.acquire_value = regs.semaphore_sequence; if (op == GpuSemaphoreOperation::AcquireEqual) { regs.acquire_active = true; regs.acquire_mode = false; if (word != regs.acquire_value) { - rasterizer->ReleaseFences(); + dma_pusher.rasterizer->ReleaseFences(); continue; } } else if (op == GpuSemaphoreOperation::AcquireGequal) { regs.acquire_active = true; regs.acquire_mode = true; if (word < regs.acquire_value) { - rasterizer->ReleaseFences(); + dma_pusher.rasterizer->ReleaseFences(); continue; } } else if (op == GpuSemaphoreOperation::AcquireMask) { if (word && regs.semaphore_sequence == 0) { - rasterizer->ReleaseFences(); + dma_pusher.rasterizer->ReleaseFences(); continue; } } else { @@ -116,21 +106,20 @@ void Puller::ProcessSemaphoreTriggerMethod() { } } -void Puller::ProcessSemaphoreRelease() { +void Puller::ProcessSemaphoreRelease(DmaPusher& dma_pusher) { const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()}; const u32 payload = regs.semaphore_release; - rasterizer->Query(sequence_address, VideoCommon::QueryType::Payload, - VideoCommon::QueryPropertiesFlags::IsAFence, payload, 0); + dma_pusher.rasterizer->Query(sequence_address, VideoCommon::QueryType::Payload, VideoCommon::QueryPropertiesFlags::IsAFence, payload, 0); } -void Puller::ProcessSemaphoreAcquire() { - u32 word = memory_manager.Read(regs.semaphore_address.SemaphoreAddress()); +void Puller::ProcessSemaphoreAcquire(DmaPusher& dma_pusher) { + u32 word = dma_pusher.memory_manager.Read(regs.semaphore_address.SemaphoreAddress()); const auto value = regs.semaphore_acquire; while (word != value) { regs.acquire_active = true; regs.acquire_value = value; - rasterizer->ReleaseFences(); - word = memory_manager.Read(regs.semaphore_address.SemaphoreAddress()); + dma_pusher.rasterizer->ReleaseFences(); + word = dma_pusher.memory_manager.Read(regs.semaphore_address.SemaphoreAddress()); // TODO(kemathe73) figure out how to do the acquire_timeout regs.acquire_mode = false; regs.acquire_source = false; @@ -138,13 +127,13 @@ void Puller::ProcessSemaphoreAcquire() { } /// Calls a GPU puller method. -void Puller::CallPullerMethod(const MethodCall& method_call) { +void Puller::CallPullerMethod(DmaPusher& dma_pusher, const MethodCall& method_call) { regs.reg_array[method_call.method] = method_call.argument; const auto method = static_cast(method_call.method); switch (method) { case BufferMethods::BindObject: { - ProcessBindMethod(method_call); + ProcessBindMethod(dma_pusher, method_call); break; } case BufferMethods::Nop: @@ -155,16 +144,16 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { case BufferMethods::WrcacheFlush: break; case BufferMethods::RefCnt: - rasterizer->SignalReference(); + dma_pusher.rasterizer->SignalReference(); break; case BufferMethods::SyncpointOperation: - ProcessFenceActionMethod(); + ProcessFenceActionMethod(dma_pusher); break; case BufferMethods::WaitForIdle: - rasterizer->WaitForIdle(); + dma_pusher.rasterizer->WaitForIdle(); break; case BufferMethods::SemaphoreOperation: { - ProcessSemaphoreTriggerMethod(); + ProcessSemaphoreTriggerMethod(dma_pusher); break; } case BufferMethods::NonStallInterrupt: { @@ -177,7 +166,7 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { } case BufferMethods::MemOpB: { // Implement this better. - rasterizer->InvalidateGPUCache(); + dma_pusher.rasterizer->InvalidateGPUCache(); break; } case BufferMethods::MemOpC: @@ -186,11 +175,11 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { break; } case BufferMethods::SemaphoreAcquire: { - ProcessSemaphoreAcquire(); + ProcessSemaphoreAcquire(dma_pusher); break; } case BufferMethods::SemaphoreRelease: { - ProcessSemaphoreRelease(); + ProcessSemaphoreRelease(dma_pusher); break; } case BufferMethods::Yield: { @@ -205,27 +194,26 @@ void Puller::CallPullerMethod(const MethodCall& method_call) { } /// Calls a GPU engine method. -void Puller::CallEngineMethod(const MethodCall& method_call) { +void Puller::CallEngineMethod(DmaPusher& dma_pusher, const MethodCall& method_call) { const EngineID engine = bound_engines[method_call.subchannel]; - switch (engine) { case EngineID::FERMI_TWOD_A: - channel_state.fermi_2d->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->fermi_2d.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; case EngineID::MAXWELL_B: - channel_state.maxwell_3d->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->maxwell_3d.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; case EngineID::KEPLER_COMPUTE_B: - channel_state.kepler_compute->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->kepler_compute.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; case EngineID::MAXWELL_DMA_COPY_A: - channel_state.maxwell_dma->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->maxwell_dma.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; case EngineID::KEPLER_INLINE_TO_MEMORY_B: - channel_state.kepler_memory->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->kepler_memory.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; case EngineID::NV01_TIMER: - channel_state.nv01_timer->CallMethod(method_call.method, method_call.argument, method_call.IsLastCall()); + dma_pusher.channel_state.payload->nv01_timer.CallMethod(dma_pusher.system, method_call.method, method_call.argument, method_call.IsLastCall()); break; default: UNIMPLEMENTED_MSG("Unimplemented engine"); @@ -234,28 +222,26 @@ void Puller::CallEngineMethod(const MethodCall& method_call) { } /// Calls a GPU engine multivalue method. -void Puller::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, - u32 methods_pending) { +void Puller::CallEngineMultiMethod(DmaPusher& dma_pusher, u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { const EngineID engine = bound_engines[subchannel]; - switch (engine) { case EngineID::FERMI_TWOD_A: - channel_state.fermi_2d->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->fermi_2d.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; case EngineID::MAXWELL_B: - channel_state.maxwell_3d->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->maxwell_3d.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; case EngineID::KEPLER_COMPUTE_B: - channel_state.kepler_compute->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->kepler_compute.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; case EngineID::MAXWELL_DMA_COPY_A: - channel_state.maxwell_dma->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->maxwell_dma.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; case EngineID::KEPLER_INLINE_TO_MEMORY_B: - channel_state.kepler_memory->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->kepler_memory.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; case EngineID::NV01_TIMER: - channel_state.nv01_timer->CallMultiMethod(method, base_start, amount, methods_pending); + dma_pusher.channel_state.payload->nv01_timer.CallMultiMethod(dma_pusher.system, method, base_start, amount, methods_pending); break; default: UNIMPLEMENTED_MSG("Unimplemented engine"); @@ -264,31 +250,26 @@ void Puller::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_s } /// Calls a GPU method. -void Puller::CallMethod(const MethodCall& method_call) { - LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method_call.method, - method_call.subchannel); - +void Puller::CallMethod(DmaPusher& dma_pusher, const MethodCall& method_call) { + LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method_call.method, method_call.subchannel); ASSERT(method_call.subchannel < bound_engines.size()); - if (ExecuteMethodOnEngine(method_call.method)) { - CallEngineMethod(method_call); + if (ExecuteMethodOnEngine(dma_pusher, method_call.method)) { + CallEngineMethod(dma_pusher, method_call); } else { - CallPullerMethod(method_call); + CallPullerMethod(dma_pusher, method_call); } } /// Calls a GPU multivalue method. -void Puller::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount, - u32 methods_pending) { +void Puller::CallMultiMethod(DmaPusher& dma_pusher, u32 method, u32 subchannel, const u32* base_start, u32 amount, u32 methods_pending) { LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, subchannel); - ASSERT(subchannel < bound_engines.size()); - - if (ExecuteMethodOnEngine(method)) { - CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending); + if (ExecuteMethodOnEngine(dma_pusher, method)) { + CallEngineMultiMethod(dma_pusher, method, subchannel, base_start, amount, methods_pending); } else { for (u32 i = 0; i < amount; i++) { - CallPullerMethod(MethodCall{ + CallPullerMethod(dma_pusher, MethodCall{ method, base_start[i], subchannel, @@ -298,13 +279,9 @@ void Puller::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, } } -void Puller::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) { - rasterizer = rasterizer_; -} - /// Determines where the method should be executed. -[[nodiscard]] bool Puller::ExecuteMethodOnEngine(u32 method) { - const auto buffer_method = static_cast(method); +[[nodiscard]] bool Puller::ExecuteMethodOnEngine(DmaPusher& dma_pusher, u32 method) { + const auto buffer_method = BufferMethods(method); return buffer_method >= BufferMethods::NonPullerMethods; } -- cgit v1.2.3