diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index f93b3dbf0..fdc3a1acd 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -383,9 +383,16 @@ s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset, return -1; } -int PS4_SYSV_ABI sceGnmDispatchIndirectOnMec() { - LOG_ERROR(Lib_GnmDriver, "(STUBBED) called"); - return ORBIS_OK; +s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier) { + if (cmdbuf != nullptr && size == 8 && args != 0 && ((args & 3u) == 0)) { + cmdbuf[0] = 0xc0021602 | (modifier & 1u); + *(VAddr*)(&cmdbuf[1]) = args; + cmdbuf[3] = (modifier & 0x18) | 1u; + cmdbuf[4] = 0xc0021000; + cmdbuf[5] = 0; + return ORBIS_OK; + } + return ORBIS_FAIL; } u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size) { diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index d15483323..609e26c0d 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -39,7 +39,7 @@ int PS4_SYSV_ABI sceGnmDisableMipStatsReport(); s32 PS4_SYSV_ABI sceGnmDispatchDirect(u32* cmdbuf, u32 size, u32 threads_x, u32 threads_y, u32 threads_z, u32 flags); s32 PS4_SYSV_ABI sceGnmDispatchIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 flags); -int PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(); +s32 PS4_SYSV_ABI sceGnmDispatchIndirectOnMec(u32* cmdbuf, u32 size, VAddr args, u32 modifier); u32 PS4_SYSV_ABI sceGnmDispatchInitDefaultHardwareState(u32* cmdbuf, u32 size); s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr_t index_addr, u32 flags, u32 type); diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 985f3c652..a59d4a64d 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -823,10 +823,10 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb, u32 vqid) { break; } case PM4ItOpcode::DispatchIndirect: { - const auto* dispatch_indirect = reinterpret_cast(header); + const auto* dispatch_indirect = + reinterpret_cast(header); auto& cs_program = GetCsRegs(); - const auto offset = dispatch_indirect->data_offset; - const auto ib_address = mapped_queues[vqid].indirect_args_addr; + const auto ib_address = dispatch_indirect->Address(); const auto size = sizeof(PM4CmdDispatchIndirect::GroupDimensions); if (DebugState.DumpingCurrentReg()) { DebugState.PushRegsDumpCompute(base_addr, reinterpret_cast(header), @@ -835,7 +835,7 @@ Liverpool::Task Liverpool::ProcessCompute(std::span acb, u32 vqid) { if (rasterizer && (cs_program.dispatch_initiator & 1)) { const auto cmd_address = reinterpret_cast(header); rasterizer->ScopeMarkerBegin(fmt::format("acb[{}]:{}:Dispatch", vqid, cmd_address)); - rasterizer->DispatchIndirect(ib_address, offset, size); + rasterizer->DispatchIndirect(ib_address, 0, size); rasterizer->ScopeMarkerEnd(); } break; diff --git a/src/video_core/amdgpu/pm4_cmds.h b/src/video_core/amdgpu/pm4_cmds.h index e7d6b29e5..135415458 100644 --- a/src/video_core/amdgpu/pm4_cmds.h +++ b/src/video_core/amdgpu/pm4_cmds.h @@ -796,6 +796,18 @@ struct PM4CmdDispatchIndirect { u32 dispatch_initiator; ///< Dispatch Initiator Register }; +struct PM4CmdDispatchIndirectMec { + PM4Type3Header header; + u32 address0; + u32 address1; + u32 dispatch_initiator; ///< Dispatch Initiator Register + + template + T Address() const { + return reinterpret_cast(address0 | (u64(address1 & 0xffff) << 32u)); + } +}; + struct DrawIndirectArgs { u32 vertex_count_per_instance; u32 instance_count;