From ea625698369f4ebdedf9db6f1566bb345f30195d Mon Sep 17 00:00:00 2001 From: Dean Galvin Date: Sat, 10 Oct 2026 20:57:01 +1300 Subject: [PATCH] revert(agc): undo #1629's sceAgcDcbResetQueue packet sequence #1629 makes sceAgcDcbResetQueue throw 'unsupported op bit 0x40' (and for 0x200/0x400). Dreaming Sarah and Astro Bot call it with op bit 0x40 at start-up, so both abort before the first frame. Main with only #1629 reverted runs Dreaming Sarah normally again (59.9/59.9 fps, no skipped draws, no flashes). --- .../prx/libSceAgc/DcbFlow/src/Control.cpp | 65 +------------------ core/libs/prx/libSceAgc/tests/Commands.cpp | 40 ++---------- 2 files changed, 5 insertions(+), 100 deletions(-) diff --git a/core/libs/prx/libSceAgc/DcbFlow/src/Control.cpp b/core/libs/prx/libSceAgc/DcbFlow/src/Control.cpp index 2a6a89c88..bb68d80d8 100644 --- a/core/libs/prx/libSceAgc/DcbFlow/src/Control.cpp +++ b/core/libs/prx/libSceAgc/DcbFlow/src/Control.cpp @@ -6,45 +6,9 @@ #include "prx/libSceAgcDriver/Execution/include/VideoOutput.hpp" #include #include -#include -#include -#include -#include -#include -#include #include "SceTypes.hpp" #include "prx/libc/include/General.hpp" -namespace { - -std::vector resetQueueGroup(std::uint32_t bit, std::uint32_t state) { - const std::uint32_t stateThree = state == 3u ? 0x00840f80u : 0x00000000u; - switch (bit) { - case 0x001u: - return {0xc0039f00u, 0x00000000u, 0x00000000u, 0x80000000u, 0x00000000u}; - case 0x002u: - return {0xc0036300u, 0x00000000u, 0x00000000u, 0x80000000u, 0x00000000u}; - case 0x004u: - return {0xc0036400u, 0x00000000u, stateThree, 0x80000000u, 0x00000000u}; - case 0x008u: - return {0xc0002f00u, 0x00000001u}; - case 0x010u: - return {0xc0017a00u, 0x20000243u, 0x00000480u, 0xc0012600u, 0x00000000u, 0x00000000u, 0xc0001300u, 0xffffffffu}; - case 0x020u: - return {0xc0021102u, 0x00000001u, 0x00000000u, 0x00000000u, 0xc0021100u, 0x00000001u, 0x00000000u, 0x00000000u}; - case 0x080u: - return {0xc0004600u, 0x00000407u}; - case 0x100u: - return {0xc0004600u, 0x00000410u}; - case 0x800u: - return {0xc0036400u, 0x00000000u, stateThree, 0x80000000u, 0x00000000u}; - default: - throw std::runtime_error(std::string("sceAgcDcbResetQueue: unsupported op bit ") + std::to_string(bit)); - } -} - -} - extern "C" { @@ -67,34 +31,7 @@ std::uint32_t APS5_VABI sceAgcDcbJumpGetSize() { std::uint32_t* APS5_VABI sceAgcDcbResetQueue(CommandBuffer* buf, std::uint32_t op, std::uint32_t state) { Agc::Command::CheckBits(op, 0xfffu, __func__); Agc::Command::CheckBits(state, 0xfu, __func__); - - constexpr std::array unsupported{0x040u, 0x200u, 0x400u}; - for (const auto bit : unsupported) { - if ((op & bit) != 0u) { - char message[64]; - std::snprintf(message, sizeof(message), "unsupported op bit 0x%x", bit); - Agc::Command::Require(false, __func__, message); - } - } - - const std::uint32_t envelopeFlag = state == 2u ? 0x00000008u : 0x00000000u; - std::vector words{ - 0xffff1000u, - 0xc0027904u, 0x00000342u, 0xce200000u | (op & 0xffffu), envelopeFlag}; - - constexpr std::array order{0x001u, 0x002u, 0x004u, 0x008u, 0x010u, 0x020u, 0x080u, 0x100u, 0x800u}; - for (const auto bit : order) { - if ((op & bit) != 0u) { - const auto group = resetQueueGroup(bit, state); - words.insert(words.end(), group.begin(), group.end()); - } - } - - words.insert(words.end(), {0xc0017904u, 0x00000342u, 0xcea00000u}); - - auto* packet = Agc::Command::Allocate(buf, static_cast(words.size()), __func__); - std::copy(words.begin(), words.end(), packet); - return packet; + return Agc::Command::Emit(buf, 0x12u, {state}, __func__); } std::uint32_t* APS5_VABI sceAgcDcbClearState(CommandBuffer* buf, std::uint32_t command) { diff --git a/core/libs/prx/libSceAgc/tests/Commands.cpp b/core/libs/prx/libSceAgc/tests/Commands.cpp index bd953a62d..58b9f1026 100644 --- a/core/libs/prx/libSceAgc/tests/Commands.cpp +++ b/core/libs/prx/libSceAgc/tests/Commands.cpp @@ -81,46 +81,14 @@ bool APS5_VABI growReserved(CommandBuffer* buffer, std::uint32_t count, void* us void testPackets() { Storage storage; - auto* reset = sceAgcDcbResetQueue(&storage.buffer, 0, 3); + sceAgcDcbResetQueue(&storage.buffer, 0, 3); sceAgcDcbDrawIndexAuto(&storage.buffer, 17, 0); - const std::array expected{0xffff1000u, 0xc0027904u, 0x00000342u, 0xce200000u, 0x00000000u, 0xc0017904u, 0x00000342u, 0xcea00000u, 0xc0012d00u, 17, 2}; - check(reset == storage.words.data() && std::equal(expected.begin(), expected.end(), storage.words.begin()), "reset or draw packet mismatch"); + const std::array expected{0xc0001200u, 3, 0xc0012d00u, 17, 2}; + check(std::equal(expected.begin(), expected.end(), storage.words.begin()), "reset or draw packet mismatch"); check(storage.buffer.cursor_up == storage.words.data() + expected.size(), "incorrect packet cursor advance"); - - Storage base; - const auto* baseReset = sceAgcDcbResetQueue(&base.buffer, 0, 0); - const std::array baseEnvelope{0xffff1000u, 0xc0027904u, 0x00000342u, 0xce200000u, 0x00000000u, 0xc0017904u, 0x00000342u, 0xcea00000u}; - check(baseReset == base.words.data() && std::equal(baseEnvelope.begin(), baseEnvelope.end(), baseReset), "op=0 state=0 envelope mismatch"); - check(base.buffer.cursor_up == base.words.data() + baseEnvelope.size(), "op=0 state=0 cursor advance mismatch"); - - Storage single; - sceAgcDcbResetQueue(&single.buffer, 0x001u, 0); - const std::array singleExpected{0xffff1000u, 0xc0027904u, 0x00000342u, 0xce200001u, 0x00000000u, 0xc0039f00u, 0x00000000u, 0x00000000u, 0x80000000u, 0x00000000u, 0xc0017904u, 0x00000342u, 0xcea00000u}; - check(std::equal(singleExpected.begin(), singleExpected.end(), single.words.begin()), "op=0x001 group mismatch"); - check(single.buffer.cursor_up == single.words.data() + singleExpected.size(), "op=0x001 cursor advance mismatch"); - - Storage flagged; - sceAgcDcbResetQueue(&flagged.buffer, 0, 2); - check(flagged.words[4] == 0x00000008u, "state=2 did not set the envelope flag dword"); - - Storage stated; - sceAgcDcbResetQueue(&stated.buffer, 0x004u, 3); - const std::array statedExpected{0xffff1000u, 0xc0027904u, 0x00000342u, 0xce200004u, 0x00000000u, 0xc0036400u, 0x00000000u, 0x00840f80u, 0x80000000u, 0x00000000u, 0xc0017904u, 0x00000342u, 0xcea00000u}; - check(std::equal(statedExpected.begin(), statedExpected.end(), stated.words.begin()), "state=3 did not set the 0x004 group payload dword"); - - Storage upper; - sceAgcDcbResetQueue(&upper.buffer, 0x800u, 0); - const std::array upperExpected{0xffff1000u, 0xc0027904u, 0x00000342u, 0xce200800u, 0x00000000u, 0xc0036400u, 0x00000000u, 0x00000000u, 0x80000000u, 0x00000000u, 0xc0017904u, 0x00000342u, 0xcea00000u}; - check(std::equal(upperExpected.begin(), upperExpected.end(), upper.words.begin()), "op=0x800 group mismatch"); - check(upper.buffer.cursor_up == upper.words.data() + upperExpected.size(), "op=0x800 cursor advance mismatch"); - const auto before = storage.words; expectFailure([&] { sceAgcDcbResetQueue(&storage.buffer, 0, 16); }); - expectFailure([&] { sceAgcDcbResetQueue(&storage.buffer, 0x040u, 0); }); - expectFailure([&] { sceAgcDcbResetQueue(&storage.buffer, 0x200u, 0); }); - expectFailure([&] { sceAgcDcbResetQueue(&storage.buffer, 0x400u, 0); }); - expectFailure([&] { sceAgcDcbResetQueue(&storage.buffer, 0x1000u, 0); }); - check(storage.words == before && storage.buffer.cursor_up == storage.words.data() + expected.size(), "invalid reset modified packet memory"); + check(storage.words == before, "invalid reset modified packet memory"); Storage destination; CommandBuffer empty{nullptr, nullptr, nullptr, nullptr, grow, &destination, 0}; Agc::Command::Emit(&empty, 0x15u, {1, 1, 1, 0x41u}, __func__);