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.
This commit is contained in:
frankea committed 2026-10-25 20:06:59 -04:00
1 parent acb900c194
commit a2fef12732
2 files changed
+22 -3

No files matched your search

@@ -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<std::uint32_t>(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<std::uint32_t>(offsets), static_cast<std::uint32_t>(offsets >> 32u), control, max_count_or_count, static_cast<std::uint32_t>(address), static_cast<std::uint32_t>(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<std::uint32_t>(offsets);
packet[6] = static_cast<std::uint32_t>(offsets >> 32u);
packet[7] = control;
packet[8] = max_count_or_count;
packet[9] = static_cast<std::uint32_t>(address);
packet[10] = static_cast<std::uint32_t>(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) {
+2 -1
View File
@@ -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<std::uintptr_t>(&count);
const std::array<std::uint32_t, 10> expectedMulti{0xc0083800u, 0x80, 0x280, 0x280, 0x40000280u, 8, static_cast<std::uint32_t>(address), static_cast<std::uint32_t>(address >> 32u), 20, 0};
const std::array<std::uint32_t, 16> expectedMulti{0xc0017904u, 0x342, 0xc6000005u, 0xc0083800u, 0x80, 0x280, 0x280, 0x40000280u, 8, static_cast<std::uint32_t>(address), static_cast<std::uint32_t>(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); });