From bc5709e1bd295c81dd236b53a4a97a0d83d25128 Mon Sep 17 00:00:00 2001 From: nmzik Date: Thu, 20 Aug 2026 21:36:15 +0200 Subject: [PATCH] agc: new ABIs --- src/libs/agc.cpp | 76 +++++++++++++++++++++++++++++++++++++++ src/libs/agc.h | 4 +++ src/libs/libAgcDriver.cpp | 2 ++ 3 files changed, 82 insertions(+) diff --git a/src/libs/agc.cpp b/src/libs/agc.cpp index 92d60478e..87230aae3 100644 --- a/src/libs/agc.cpp +++ b/src/libs/agc.cpp @@ -1930,6 +1930,76 @@ uint32_t* KYTY_SYSV_ABI AgcCbSetShRegistersDirect(CommandBuffer* return first_cmd; } +uint32_t* KYTY_SYSV_ABI AgcCbSetUcRegistersDirect(CommandBuffer* buf, + const volatile ShaderRegister* regs, + uint32_t num_regs) { + PRINT_NAME(); + + LOGF("\t regs = 0x%016" PRIx64 "\n" + "\t num_regs = %" PRIu32 "\n", + reinterpret_cast(regs), num_regs); + + if (num_regs == 0) { + return nullptr; + } + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(regs == nullptr); + + buf->DbgDump(); + + // Original implementation stages register values in a temporary DWORD array. It reads each new run only + // after the preceding run has been allocated, so preserve that ordering around grow callbacks. + std::vector values(num_regs); + values[0] = regs[0].value; + + uint32_t* first_cmd = nullptr; + uint32_t run_start_index = 0; + uint32_t run_start_offset = regs[0].offset; + uint32_t prev_offset = run_start_offset; + uint32_t i = 1; + + for (;;) { + if (i < num_regs) { + const auto offset = regs[i].offset; + if (offset == prev_offset + 1u) { + values[i] = regs[i].value; + prev_offset = offset; + i++; + continue; + } + } + + const auto run_count = i - run_start_index; + auto* cmd = buf->AllocateDW(run_count + 2u); + + if (cmd != nullptr) { + if (first_cmd == nullptr) { + first_cmd = cmd; + } + + cmd[0] = KYTY_PM4(run_count + 2u, Pm4::IT_SET_UCONFIG_REG, 0u); + cmd[1] = run_start_offset & 0xffffu; + memcpy(cmd + 2, values.data() + run_start_index, + static_cast(run_count) * sizeof(uint32_t)); + } else { + LOGF_COLOR(Log::Color::Red, + "\t failed to allocate set-uc-registers-direct command\n"); + } + + if (i == num_regs) { + return first_cmd; + } + + // Original implementation skips an intermediate run whose grow callback fails, then keeps scanning. + run_start_index = i; + run_start_offset = regs[i].offset; + prev_offset = run_start_offset; + values[i] = regs[i].value; + i++; + } +} + int KYTY_SYSV_ABI AgcDebugRaiseException(uint32_t exception_id) { PRINT_NAME(); @@ -2833,6 +2903,12 @@ uint32_t* KYTY_SYSV_ABI AgcDcbEventWrite(CommandBuffer* buf, uint8_t event_type, return cmd; } +uint64_t KYTY_SYSV_ABI AgcDcbEventWriteGetSize(uint8_t event_type) { + PRINT_NAME(); + + return (event_type & 0xfeu) == 0x38u ? 16u : 8u; +} + uint32_t* KYTY_SYSV_ABI AgcAcbEventWrite(CommandBuffer* buf, uint8_t event_type, const volatile void* /*address*/) { if (buf == nullptr) { diff --git a/src/libs/agc.h b/src/libs/agc.h index 617f925fe..592204c52 100644 --- a/src/libs/agc.h +++ b/src/libs/agc.h @@ -107,6 +107,9 @@ uint32_t KYTY_SYSV_ABI AgcCbSetShRegisterRangeDirectGetSize(uint32_t num_values uint32_t* KYTY_SYSV_ABI AgcCbSetShRegistersDirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); +uint32_t* KYTY_SYSV_ABI AgcCbSetUcRegistersDirect(CommandBuffer* buf, + const volatile ShaderRegister* regs, + uint32_t num_regs); uint32_t* KYTY_SYSV_ABI AgcCbReleaseMem(CommandBuffer* buf, uint8_t action, uint16_t gcr_cntl, uint8_t dst, uint8_t cache_policy, const volatile Label* address, uint8_t data_sel, @@ -179,6 +182,7 @@ uint32_t* KYTY_SYSV_ABI AgcDcbDispatchIndirect(CommandBuffer* buf, uint32_t data uint32_t KYTY_SYSV_ABI AgcDcbDispatchIndirectGetSize(); uint32_t* KYTY_SYSV_ABI AgcDcbEventWrite(CommandBuffer* buf, uint8_t event_type, const volatile void* address); +uint64_t KYTY_SYSV_ABI AgcDcbEventWriteGetSize(uint8_t event_type); uint32_t* KYTY_SYSV_ABI AgcDcbAcquireMem(CommandBuffer* buf, uint8_t engine, uint32_t cb_db_op, uint32_t gcr_cntl, const volatile void* base, uint64_t size_bytes, uint32_t poll_cycles); diff --git a/src/libs/libAgcDriver.cpp b/src/libs/libAgcDriver.cpp index f6fbca6a6..1a09e3684 100644 --- a/src/libs/libAgcDriver.cpp +++ b/src/libs/libAgcDriver.cpp @@ -202,6 +202,7 @@ LIB_DEFINE(InitAgcDriver_1) { LIB_FUNC("n2fD4A+pb+g", Gen5::AgcCbSetShRegisterRangeDirect); LIB_FUNC("bxGoVxpdSPQ", Gen5::AgcCbSetShRegisterRangeDirectGetSize); LIB_FUNC("UZbQjYAwwXM", Gen5::AgcCbSetShRegistersDirect); + LIB_FUNC("03RZmELWWzw", Gen5::AgcCbSetUcRegistersDirect); LIB_FUNC("wr23dPKyWc0", Gen5::AgcCbReleaseMem); LIB_FUNC("hL7C0IRpWZI", Gen5::AgcCbQueueEndOfPipeActionGetSize); LIB_FUNC("T6xuVw0KUJo", Gen5::AgcDebugRaiseException); @@ -254,6 +255,7 @@ LIB_DEFINE(InitAgcDriver_1) { LIB_FUNC("CtB+A9-VxO0", Gen5::AgcDcbDispatchIndirect); LIB_FUNC("w8HVkEeXPv8", Gen5::AgcDcbDispatchIndirectGetSize); LIB_FUNC("aJf+j5yntiU", Gen5::AgcDcbEventWrite); + LIB_FUNC("C4l9fB17t8w", Gen5::AgcDcbEventWriteGetSize); LIB_FUNC("57labkp+rSQ", Gen5::AgcDcbAcquireMem); LIB_FUNC("-vnlTPPXPrw", Gen5::AgcDcbAcquireMemGetSize); LIB_FUNC("1rZSWUv1IRc", Gen5::AgcDcbCopyData);