mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-19 06:31:29 +00:00
[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 <lizzie@eden-emu.dev> Co-authored-by: maufeat <sahyno1996@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
@@ -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<EngineID>(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<GpuSemaphoreOperation>(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<u32>(regs.semaphore_address.SemaphoreAddress())};
|
||||
const u32 word = dma_pusher.memory_manager.Read<u32>(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<u32>(regs.semaphore_address.SemaphoreAddress());
|
||||
void Puller::ProcessSemaphoreAcquire(DmaPusher& dma_pusher) {
|
||||
u32 word = dma_pusher.memory_manager.Read<u32>(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<u32>(regs.semaphore_address.SemaphoreAddress());
|
||||
dma_pusher.rasterizer->ReleaseFences();
|
||||
word = dma_pusher.memory_manager.Read<u32>(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<BufferMethods>(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<BufferMethods>(method);
|
||||
[[nodiscard]] bool Puller::ExecuteMethodOnEngine(DmaPusher& dma_pusher, u32 method) {
|
||||
const auto buffer_method = BufferMethods(method);
|
||||
return buffer_method >= BufferMethods::NonPullerMethods;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user