From 42f6ab7670f1fe0a9ef22043c3bbd371a045f8e1 Mon Sep 17 00:00:00 2001 From: psucien Date: Fri, 21 Jun 2024 20:40:16 +0200 Subject: [PATCH] amdgpu: added ASC commands processor --- src/video_core/amdgpu/liverpool.cpp | 69 ++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 956e65a1..38d27410 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -12,7 +12,7 @@ namespace AmdGpu { static const char* dcb_task_name{"DCB_TASK"}; static const char* ccb_task_name{"CCB_TASK"}; -static const char* asc_task_name{"ACB_TASK"}; +static const char* acb_task_name{"ACB_TASK"}; std::array Liverpool::ConstantEngine::constants_heap; @@ -381,6 +381,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span acb) { + TracyFiberEnter(acb_task_name); + while (!acb.empty()) { const auto* header = reinterpret_cast(acb.data()); const u32 type = header->type; @@ -393,6 +395,69 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb) { const PM4ItOpcode opcode = header->type3.opcode; const auto* it_body = reinterpret_cast(header) + 1; switch (opcode) { + case PM4ItOpcode::Nop: { + const auto* nop = reinterpret_cast(header); + break; + } + case PM4ItOpcode::IndirectBuffer: { + const auto* indirect_buffer = reinterpret_cast(header); + auto task = + ProcessCompute({indirect_buffer->Address(), indirect_buffer->ib_size}); + while (!task.handle.done()) { + task.handle.resume(); + + TracyFiberLeave; + co_yield {}; + TracyFiberEnter(acb_task_name); + }; + break; + } + case PM4ItOpcode::AcquireMem: { + break; + } + case PM4ItOpcode::SetShReg: { + const auto* set_data = reinterpret_cast(header); + std::memcpy(®s.reg_array[ShRegWordOffset + set_data->reg_offset], header + 2, + (count - 1) * sizeof(u32)); + break; + } + case PM4ItOpcode::DispatchDirect: { + const auto* dispatch_direct = reinterpret_cast(header); + regs.cs_program.dim_x = dispatch_direct->dim_x; + regs.cs_program.dim_y = dispatch_direct->dim_y; + regs.cs_program.dim_z = dispatch_direct->dim_z; + regs.cs_program.dispatch_initiator = dispatch_direct->dispatch_initiator; + if (rasterizer && (regs.cs_program.dispatch_initiator & 1)) { + rasterizer->DispatchDirect(); + } + break; + } + case PM4ItOpcode::WriteData: { + const auto* write_data = reinterpret_cast(header); + ASSERT(write_data->dst_sel.Value() == 2 || write_data->dst_sel.Value() == 5); + const u32 data_size = (header->type3.count.Value() - 2) * 4; + if (!write_data->wr_one_addr.Value()) { + std::memcpy(write_data->Address(), write_data->data, data_size); + } else { + UNREACHABLE(); + } + break; + } + case PM4ItOpcode::WaitRegMem: { + const auto* wait_reg_mem = reinterpret_cast(header); + ASSERT(wait_reg_mem->engine.Value() == PM4CmdWaitRegMem::Engine::Me); + while (!wait_reg_mem->Test()) { + TracyFiberLeave; + co_yield {}; + TracyFiberEnter(acb_task_name); + } + break; + } + case PM4ItOpcode::ReleaseMem: { + const auto* release_mem = reinterpret_cast(header); + release_mem->SignalFence(Platform::InterruptId::Compute0RelMem); // <--- + break; + } default: UNREACHABLE_MSG("Unknown PM4 type 3 opcode {:#x} with count {}", static_cast(opcode), count); @@ -401,7 +466,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb) { acb = acb.subspan(header->type3.NumWords() + 1); } - return {}; // Not a coroutine yet + TracyFiberLeave; } void Liverpool::SubmitGfx(std::span dcb, std::span ccb) {