fix(agc): return error for unsupported init versions

This commit is contained in:
MarcZX100 2026-10-12 23:15:39 +00:00
parent 43e3a70f81
commit cbd615bb42
3 changed files with 10 additions and 2 deletions

View File

@ -7,6 +7,8 @@
#include "SceTypes.hpp"
#include "prx/libc/include/General.hpp"
static constexpr int SCE_AGC_ERROR_INVALID_ARGUMENT = static_cast<int>(0x80890001);
extern "C" {
int APS5_VABI sceAgcInit_0090(std::uint32_t* state, std::uint32_t version) {
@ -16,6 +18,7 @@ int APS5_VABI sceAgcInit_0090(std::uint32_t* state, std::uint32_t version) {
}
int APS5_VABI sceAgcInit(std::uint32_t version) {
if (version >= 14) return SCE_AGC_ERROR_INVALID_ARGUMENT;
Agc::Command::GetRegisterDefaults(version, false, __func__);
Agc::Command::GetRegisterDefaults(version, true, __func__);
return 0;

View File

@ -50,6 +50,8 @@ extern "C" std::uint32_t* APS5_VABI sceAgcAcbAtomicGds_0900(CommandBuffer* buf,
namespace {
constexpr int SCE_AGC_ERROR_INVALID_ARGUMENT = static_cast<int>(0x80890001);
void check(bool condition, const char* message) {
if (!condition) {
throw std::runtime_error(message);
@ -622,8 +624,10 @@ void testDefaults() {
expectFailure([] { sceAgcInit_0090(nullptr, 8); });
expectFailure([&] { sceAgcInit_0090(&state, 14); });
check(sceAgcInit(8) == 0, "AGC version initialization failed");
expectFailure([] { sceAgcInit(14); });
expectFailure([] { sceAgcInit(0xffffffffu); });
check(sceAgcInit(13) == 0, "AGC version 13 initialization failed");
check(sceAgcInit(14) == SCE_AGC_ERROR_INVALID_ARGUMENT, "unsupported AGC version did not return invalid argument");
check(sceAgcInit(0xffffffffu) == SCE_AGC_ERROR_INVALID_ARGUMENT, "maximum AGC version did not return invalid argument");
check(sceAgcInit(0xffffc278u) == SCE_AGC_ERROR_INVALID_ARGUMENT, "pointer-valued AGC argument did not return invalid argument");
for (std::uint32_t version = 0; version < 14; ++version) {
for (const bool internal : {false, true}) {
auto* first = Agc::Command::GetRegisterDefaults(version, internal, __func__);

View File

@ -7,6 +7,7 @@
- [sceAgcDcbSetCfRegisterDirect, sceAgcDcbSetCfRegisterRangeDirect](../../../core/libs/prx/libSceAgc/DcbState/src/Registers.cpp) (libSceAgc) - signatures follow [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c) and [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Agc/SceAgc.cs), which agree; the SET_CONFIG_REG (0x68) packet is OpenAGC's. The driver does not execute SET_CONFIG_REG, so a submitted packet throws
- [Command buffer cursors](../../../core/libs/prx/libSceAgc/Command/src/Packet.cpp) (libSceAgc) - a null `cursor_down` is taken as a buffer without downward allocations, whose limit is `top`. PPSA16064 builds one-packet buffers of 8 dwords that way; the console's handling is unconfirmed
- [sceAgcGetRegisterDefaultsInternal](../../../core/libs/prx/libSceAgc/Misc/src/RegisterDefaults.cpp) (libSceAgc) - returns the version 0 internal table, as `sceAgcGetRegisterDefaults` returns the version 0 public one; [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c) returns the table of the version passed to `sceAgcInit` instead, and null before it
- [sceAgcInit](../../../core/libs/prx/libSceAgc/DcbState/src/Init.cpp) (libSceAgc) - unsupported register-default versions return `0x80890001` following [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c); AnyPS5 keeps version 13 support because its register-default tables include it, while that reference accepts only versions 0–12. The upper version accepted by PS5 firmware is unverified
- [sceAgcSetSubmitMode](../../../core/libs/prx/libSceAgc/Misc/src/Suspend.cpp) (libSceAgc) - mode values unknown; only 0 is accepted
- [sceAgcGetGsOversubscription](../../../core/libs/prx/libSceAgc/Shader/src/GsOversubscription.cpp) (libSceAgc) - signature and occupancy formula (base and expanded vertex/export capacities, budget shift, `GE_PC_ALLOC` / `SPI_SHADER_PGM_RSRC4_GS` encoding) follow KytyPS5 only, not confirmed on hardware or a title; a negative or NaN factor that gives a negative target, a missing GS context register or a zero `GE_MAX_OUTPUT_PER_SUBGROUP` throws
- [sceAgcCbCondWrite](../../../core/libs/prx/libSceAgc/Cb/src/Branch.cpp) (libSceAgc) - argument order and the 9-dword COND_WRITE layout follow the clean-room [OpenAGC](https://github.com/OpenAGC/OpenAGC/blob/main/src/game_compat.c) and [sharpemu](https://github.com/sharpemu/sharpemu/blob/main/src/SharpEmu.Libs/Agc/AgcExports.CommandPackets.cs), which agree on them; SharpProspero lists another order. The write space is accepted only as 1 (memory), the one value both encode the same way, and other values throw.