mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 19:36:55 +02:00
agc: implement branch target patching and packet size queries
This commit is contained in:
+44
-13
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user