From a2fef127326799dfbc3232d388273bc201610ebc Mon Sep 17 00:00:00 2001 From: frankea Date: Sun, 25 Oct 2026 20:06:59 -0400 Subject: [PATCH] fix(agc): bracket sceAgcDcbDrawIndexIndirectMulti with the console's tag markers On a PS5 (firmware 13.40) the builder writes SET_UCONFIG_REG 0x342 = 0xc6000005 before its DRAW_INDEX_INDIRECT_MULTI packet and 0xc6000000 after it, 64 bytes in all, and sceAgcDcbDrawIndexIndirectMultiGetSize returns 64. --- .../prx/libSceAgc/DcbDraw/src/DrawIndexed.cpp | 22 +++++++++++++++++-- core/libs/prx/libSceAgc/tests/Commands.cpp | 3 ++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/core/libs/prx/libSceAgc/DcbDraw/src/DrawIndexed.cpp b/core/libs/prx/libSceAgc/DcbDraw/src/DrawIndexed.cpp index 88f8636615..d766762edc 100644 --- a/core/libs/prx/libSceAgc/DcbDraw/src/DrawIndexed.cpp +++ b/core/libs/prx/libSceAgc/DcbDraw/src/DrawIndexed.cpp @@ -57,11 +57,29 @@ uint32_t* APS5_VABI sceAgcDcbDrawIndexIndirectMulti(CommandBuffer* buf, uint32_t const auto offsets = Agc::Command::DrawPatchOffsets(modifier, __func__); const auto low = static_cast(modifier); const auto control = Agc::Command::DrawIndexLocation(modifier) | ((low & 0x10u) << 23u) | (count_indirect << 30u) | ((low & 8u) << 28u); - return Agc::Command::Emit(buf, 0x38u, {data_offset_in_bytes, static_cast(offsets), static_cast(offsets >> 32u), control, max_count_or_count, static_cast(address), static_cast(address >> 32u), stride_in_bytes, Agc::Command::DrawInitiator(modifier, true, __func__)}, __func__); + const auto initiator = Agc::Command::DrawInitiator(modifier, true, __func__); + auto* packet = Agc::Command::Allocate(buf, 16, __func__); + packet[0] = Agc::Command::Header(0x79u, 3, 4); + packet[1] = 0x342u; + packet[2] = 0xc6000005u; + packet[3] = Agc::Command::Header(0x38u, 10); + packet[4] = data_offset_in_bytes; + packet[5] = static_cast(offsets); + packet[6] = static_cast(offsets >> 32u); + packet[7] = control; + packet[8] = max_count_or_count; + packet[9] = static_cast(address); + packet[10] = static_cast(address >> 32u); + packet[11] = stride_in_bytes; + packet[12] = initiator; + packet[13] = Agc::Command::Header(0x79u, 3, 4); + packet[14] = 0x342u; + packet[15] = 0xc6000000u; + return packet; } std::uint32_t APS5_VABI sceAgcDcbDrawIndexIndirectMultiGetSize() { - return 40; + return 64; } uint32_t* APS5_VABI sceAgcDcbDrawIndexMultiInstanced(CommandBuffer* buf, uint32_t index_count, const volatile void* index_addr, const volatile void* object_ids, uint32_t instance_count, uint64_t modifier) { diff --git a/core/libs/prx/libSceAgc/tests/Commands.cpp b/core/libs/prx/libSceAgc/tests/Commands.cpp index a9ec29ed76..224dfca6ac 100644 --- a/core/libs/prx/libSceAgc/tests/Commands.cpp +++ b/core/libs/prx/libSceAgc/tests/Commands.cpp @@ -167,9 +167,10 @@ void testIndexedIndirectDraws() { alignas(4) std::uint32_t count = 0; const auto* multi = sceAgcDcbDrawIndexIndirectMulti(&storage.buffer, 0x80, 1, 8, &count, 20, 0); const auto address = reinterpret_cast(&count); - const std::array expectedMulti{0xc0083800u, 0x80, 0x280, 0x280, 0x40000280u, 8, static_cast(address), static_cast(address >> 32u), 20, 0}; + const std::array expectedMulti{0xc0017904u, 0x342, 0xc6000005u, 0xc0083800u, 0x80, 0x280, 0x280, 0x40000280u, 8, static_cast(address), static_cast(address >> 32u), 20, 0, 0xc0017904u, 0x342, 0xc6000000u}; check(multi == storage.words.data() + expectedSingle.size() && std::equal(expectedMulti.begin(), expectedMulti.end(), multi), "indexed indirect multi draw packet mismatch"); check(storage.buffer.cursor_up == storage.words.data() + expectedSingle.size() + expectedMulti.size(), "incorrect indexed indirect cursor advance"); + check(sceAgcDcbDrawIndexIndirectMultiGetSize() == expectedMulti.size() * sizeof(std::uint32_t), "indexed indirect multi draw size differs from its packets"); const auto before = storage.words; expectFailure([&] { sceAgcDcbDrawIndexIndirect(&storage.buffer, 2, 0); }); expectFailure([&] { sceAgcDcbDrawIndexIndirectMulti(&storage.buffer, 0, 1, 8, &count, 16, 0); });