agc: implement branch target patching and packet size queries

This commit is contained in:
nmzik
2026-10-09 03:33:47 +02:00
parent a31e2cd361
commit 3ae5a9b70a
4 changed files with 102 additions and 13 deletions
+44 -13
View File
@@ -830,6 +830,8 @@ enum class RegIndirectPacket : uint32_t {
Uc,
};
static constexpr uint32_t RegIndirectPacketSizeDw = 5;
static uint32_t reg_indirect_native_op(RegIndirectPacket type) {
switch (type) {
case RegIndirectPacket::Cx: return Pm4::IT_SET_CONTEXT_REG_INDIRECT;
@@ -853,7 +855,7 @@ static uint32_t reg_indirect_pm4_r(RegIndirectPacket type) {
static void reg_indirect_write_packet(uint32_t* cmd, uint64_t vaddr, uint32_t num_regs,
RegIndirectPacket type) {
cmd[0] = KYTY_PM4(5, reg_indirect_native_op(type), reg_indirect_pm4_r(type));
cmd[0] = KYTY_PM4(RegIndirectPacketSizeDw, reg_indirect_native_op(type), reg_indirect_pm4_r(type));
cmd[1] = static_cast<uint32_t>(vaddr) & 0xfffffffcu;
cmd[2] = static_cast<uint32_t>(vaddr >> 32u);
cmd[3] = 0x80000000u;
@@ -1789,6 +1791,33 @@ uint32_t KYTY_SYSV_ABI AgcCbDispatchGetSize() {
return 20;
}
static constexpr uint32_t BranchPacketSizeDw = 14;
static void write_branch_target(uint32_t* words, uint64_t address, uint8_t cache_policy,
uint32_t size_in_dwords) {
words[0] = (words[0] & 0x3u) | (static_cast<uint32_t>(address) & ~0x3u);
words[1] = static_cast<uint32_t>(address >> 32u);
words[2] = (words[2] & 0xcff00000u) | (size_in_dwords & 0xfffffu) |
((static_cast<uint32_t>(cache_policy) & 0x3u) << 28u);
}
uint64_t KYTY_SYSV_ABI AgcCbBranchGetSize() {
PRINT_NAME();
return BranchPacketSizeDw * sizeof(uint32_t);
}
int KYTY_SYSV_ABI AgcBranchPatchSetThenTarget(uint32_t* cmd, uint8_t cache_policy,
const volatile uint32_t* target,
uint32_t size_in_dwords) {
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
if (((cmd[0] >> 8u) & 0xffu) != Pm4::IT_INDIRECT_BUFFER) {
return GRAPHICS5_ERROR_INVALID_PACKET;
}
write_branch_target(cmd + 8, reinterpret_cast<uint64_t>(target), cache_policy, size_in_dwords);
return OK;
}
uint32_t* KYTY_SYSV_ABI AgcCbBranch(CommandBuffer* buf, uint8_t mode, uint8_t compare_function,
const volatile uint64_t* compare_addr, uint64_t mask,
uint64_t reference, uint8_t cache_policy1,
@@ -1814,7 +1843,7 @@ uint32_t* KYTY_SYSV_ABI AgcCbBranch(CommandBuffer* buf, uint8_t mode, uint8_t co
EXIT_NOT_IMPLEMENTED(buf == nullptr);
auto* cmd = buf->AllocateDW(14);
auto* cmd = buf->AllocateDW(BranchPacketSizeDw);
if (cmd == nullptr) {
LOGF_COLOR(Log::Color::Red, "\t failed to allocate branch packet\n");
@@ -1825,7 +1854,7 @@ uint32_t* KYTY_SYSV_ABI AgcCbBranch(CommandBuffer* buf, uint8_t mode, uint8_t co
const auto then_vaddr = reinterpret_cast<uint64_t>(buffer1);
const auto else_vaddr = reinterpret_cast<uint64_t>(buffer2);
cmd[0] = KYTY_PM4(14, Pm4::IT_INDIRECT_BUFFER, 0u);
cmd[0] = KYTY_PM4(BranchPacketSizeDw, Pm4::IT_INDIRECT_BUFFER, 0u);
cmd[1] = (mode & 0x3u) | ((static_cast<uint32_t>(compare_function) & 0x7u) << 8u);
cmd[2] = static_cast<uint32_t>(compare_vaddr & 0xfffffff8u);
cmd[3] = static_cast<uint32_t>((compare_vaddr >> 32u) & 0xffffffffu);
@@ -1833,12 +1862,9 @@ uint32_t* KYTY_SYSV_ABI AgcCbBranch(CommandBuffer* buf, uint8_t mode, uint8_t co
cmd[5] = static_cast<uint32_t>((mask >> 32u) & 0xffffffffu);
cmd[6] = static_cast<uint32_t>(reference & 0xffffffffu);
cmd[7] = static_cast<uint32_t>((reference >> 32u) & 0xffffffffu);
cmd[8] = static_cast<uint32_t>(then_vaddr & 0xfffffffcu);
cmd[9] = static_cast<uint32_t>((then_vaddr >> 32u) & 0xffffffffu);
cmd[10] = (size_in_dwords1 & 0xfffffu) | ((static_cast<uint32_t>(cache_policy1) & 0x3u) << 28u);
cmd[11] = static_cast<uint32_t>(else_vaddr & 0xfffffffcu);
cmd[12] = static_cast<uint32_t>((else_vaddr >> 32u) & 0xffffffffu);
cmd[13] = (size_in_dwords2 & 0xfffffu) | ((static_cast<uint32_t>(cache_policy2) & 0x3u) << 28u);
std::fill(cmd + 8, cmd + BranchPacketSizeDw, 0u);
write_branch_target(cmd + 8, then_vaddr, cache_policy1, size_in_dwords1);
write_branch_target(cmd + 11, else_vaddr, cache_policy2, size_in_dwords2);
return cmd;
}
@@ -2353,7 +2379,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetCxRegistersIndirect(CommandBuffer*
buf->DbgDump();
auto* cmd = buf->AllocateDW(5);
auto* cmd = buf->AllocateDW(RegIndirectPacketSizeDw);
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
@@ -2364,6 +2390,11 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetCxRegistersIndirect(CommandBuffer*
return cmd;
}
uint64_t KYTY_SYSV_ABI AgcDcbSetCxRegistersIndirectGetSize() {
PRINT_NAME();
return RegIndirectPacketSizeDw * sizeof(uint32_t);
}
uint32_t* KYTY_SYSV_ABI AgcDcbSetShRegistersIndirect(CommandBuffer* buf,
const volatile ShaderRegister* regs,
uint32_t num_regs) {
@@ -2377,7 +2408,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetShRegistersIndirect(CommandBuffer*
buf->DbgDump();
auto* cmd = buf->AllocateDW(5);
auto* cmd = buf->AllocateDW(RegIndirectPacketSizeDw);
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
@@ -2391,7 +2422,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetShRegistersIndirect(CommandBuffer*
uint64_t KYTY_SYSV_ABI AgcDcbSetShRegistersIndirectGetSize() {
PRINT_NAME();
return 5u * sizeof(uint32_t);
return RegIndirectPacketSizeDw * sizeof(uint32_t);
}
uint32_t* KYTY_SYSV_ABI AgcDcbSetUcRegistersIndirect(CommandBuffer* buf,
@@ -2407,7 +2438,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetUcRegistersIndirect(CommandBuffer*
buf->DbgDump();
auto* cmd = buf->AllocateDW(5);
auto* cmd = buf->AllocateDW(RegIndirectPacketSizeDw);
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
+5
View File
@@ -101,6 +101,10 @@ uint32_t* KYTY_SYSV_ABI AgcCbBranch(CommandBuffer* buf, uint8_t mode, uint8_t co
const volatile uint32_t* buffer1, uint32_t size_in_dwords1,
uint8_t cache_policy2, const volatile uint32_t* buffer2,
uint32_t size_in_dwords2);
uint64_t KYTY_SYSV_ABI AgcCbBranchGetSize();
int KYTY_SYSV_ABI AgcBranchPatchSetThenTarget(uint32_t* cmd, uint8_t cache_policy,
const volatile uint32_t* target,
uint32_t size_in_dwords);
uint32_t* KYTY_SYSV_ABI AgcCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset,
const uint32_t* values, uint32_t num_values);
uint32_t KYTY_SYSV_ABI AgcCbSetShRegisterRangeDirectGetSize(uint32_t num_values);
@@ -134,6 +138,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegi
uint32_t* KYTY_SYSV_ABI AgcDcbSetCxRegistersIndirect(CommandBuffer* buf,
const volatile ShaderRegister* regs,
uint32_t num_regs);
uint64_t KYTY_SYSV_ABI AgcDcbSetCxRegistersIndirectGetSize();
uint32_t* KYTY_SYSV_ABI AgcDcbSetShRegistersIndirect(CommandBuffer* buf,
const volatile ShaderRegister* regs,
uint32_t num_regs);
+3
View File
@@ -59,6 +59,8 @@ LIB_DEFINE(InitAgcDriver_1) {
LIB_FUNC("k3GhuSNmBLU", Gen5::AgcCbDispatch);
LIB_FUNC("Abendgtz+3o", Gen5::AgcCbDispatchGetSize);
LIB_FUNC("w1KFAHVqpaU", Gen5::AgcCbBranch);
LIB_FUNC("uZW-mqsxkrM", Gen5::AgcCbBranchGetSize);
LIB_FUNC("7Wa3aeJgeVU", Gen5::AgcBranchPatchSetThenTarget);
LIB_FUNC("n2fD4A+pb+g", Gen5::AgcCbSetShRegisterRangeDirect);
LIB_FUNC("bxGoVxpdSPQ", Gen5::AgcCbSetShRegisterRangeDirectGetSize);
LIB_FUNC("UZbQjYAwwXM", Gen5::AgcCbSetShRegistersDirect);
@@ -95,6 +97,7 @@ LIB_DEFINE(InitAgcDriver_1) {
LIB_FUNC("1DeUNpRIDDA", Gen5::AgcDcbSetCxRegisterDirectGetSize);
LIB_FUNC("w4-d0n60hdo", Gen5::AgcDcbSetUcRegisterDirect);
LIB_FUNC("ZvwO9euwYzc", Gen5::AgcDcbSetCxRegistersIndirect);
LIB_FUNC("GBCh3zCihoU", Gen5::AgcDcbSetCxRegistersIndirectGetSize);
LIB_FUNC("-HOOCn0JY48", Gen5::AgcDcbSetShRegistersIndirect);
LIB_FUNC("nNlUtdDDvZ0", Gen5::AgcDcbSetShRegistersIndirectGetSize);
LIB_FUNC("hvUfkUIQcOE", Gen5::AgcDcbSetUcRegistersIndirect);