From 1f1e39dccfcb9616ecf22e1545b5036c82c52b03 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:04:50 -0400 Subject: [PATCH 01/10] Update Registers.cpp eight register-write and size-query implementations. --- .../prx/libSceAgc/DcbState/src/Registers.cpp | 42 +++++++------------ 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp b/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp index cf78cf4c8..36acff25b 100644 --- a/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp +++ b/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp @@ -8,16 +8,12 @@ extern "C" { -uint32_t* APS5_VABI sceAgcDcbSetCxRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - (void)buf; - (void)reg; - NotImplemented_nid_no_patch(__func__); - return nullptr; +std::uint32_t* APS5_VABI sceAgcDcbSetCxRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x69u, reg.offset, ®.value, 1, __func__); } -uint32_t APS5_VABI sceAgcDcbSetCxRegisterDirectGetSize(void) { - NotImplemented_nid_no_patch(__func__); - return 0; +std::uint32_t APS5_VABI sceAgcDcbSetCxRegisterDirectGetSize() { + return 12; } std::uint32_t* APS5_VABI sceAgcDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) { @@ -25,21 +21,16 @@ std::uint32_t* APS5_VABI sceAgcDcbSetCxRegistersIndirect(CommandBuffer* buf, con } std::uint32_t APS5_VABI sceAgcDcbSetCxRegistersIndirectGetSize(std::uint32_t numRegs) { - (void)numRegs; - NotImplemented_nid_no_patch(__func__); - return 0; + Agc::Command::CheckBits(numRegs, 0x3fffu, __func__); + return 20; } -uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - (void)buf; - (void)reg; - NotImplemented_nid_no_patch(__func__); - return nullptr; +std::uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x76u, reg.offset, ®.value, 1, __func__); } std::uint32_t APS5_VABI sceAgcDcbSetShRegisterDirectGetSize() { - NotImplemented_nid_no_patch(__func__); - return 0; + return 12; } std::uint32_t* APS5_VABI sceAgcDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) { @@ -51,16 +42,12 @@ std::uint32_t APS5_VABI sceAgcDcbSetShRegistersIndirectGetSize(std::uint32_t num return 20; } -uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - (void)buf; - (void)reg; - NotImplemented_nid_no_patch(__func__); - return nullptr; +std::uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x79u, reg.offset, ®.value, 1, __func__); } std::uint32_t APS5_VABI sceAgcDcbSetUcRegisterDirectGetSize() { - NotImplemented_nid_no_patch(__func__); - return 0; + return 12; } std::uint32_t* APS5_VABI sceAgcDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) { @@ -68,9 +55,8 @@ std::uint32_t* APS5_VABI sceAgcDcbSetUcRegistersIndirect(CommandBuffer* buf, con } std::uint32_t APS5_VABI sceAgcDcbSetUcRegistersIndirectGetSize(std::uint32_t numRegs) { - (void)numRegs; - NotImplemented_nid_no_patch(__func__); - return 0; + Agc::Command::CheckBits(numRegs, 0x3fffu, __func__); + return 20; } } From 01f6311bd369864940d339082b580775678297c9 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:05:27 -0400 Subject: [PATCH 02/10] Update IndirectRegisters.cpp three register-count setters. --- .../libSceAgc/Patch/src/IndirectRegisters.cpp | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/core/libs/prx/libSceAgc/Patch/src/IndirectRegisters.cpp b/core/libs/prx/libSceAgc/Patch/src/IndirectRegisters.cpp index f14d7b320..ff90be0cd 100644 --- a/core/libs/prx/libSceAgc/Patch/src/IndirectRegisters.cpp +++ b/core/libs/prx/libSceAgc/Patch/src/IndirectRegisters.cpp @@ -19,11 +19,9 @@ int APS5_VABI sceAgcSetCxRegIndirectPatchSetAddress(std::uint32_t* cmd, const vo return 0; } -int APS5_VABI sceAgcSetCxRegIndirectPatchSetNumRegisters(uint32_t* cmd, uint32_t num_regs) { - (void)cmd; - (void)num_regs; - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI sceAgcSetCxRegIndirectPatchSetNumRegisters(std::uint32_t* cmd, std::uint32_t numRegs) { + Agc::Command::SetIndirectCount(cmd, 0x9fu, numRegs, __func__); + return 0; } int APS5_VABI sceAgcSetShRegIndirectPatchAddRegisters(std::uint32_t* cmd, std::uint32_t numRegs) { @@ -36,11 +34,9 @@ int APS5_VABI sceAgcSetShRegIndirectPatchSetAddress(std::uint32_t* cmd, const vo return 0; } -int APS5_VABI sceAgcSetShRegIndirectPatchSetNumRegisters(uint32_t* cmd, uint32_t num_regs) { - (void)cmd; - (void)num_regs; - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI sceAgcSetShRegIndirectPatchSetNumRegisters(std::uint32_t* cmd, std::uint32_t numRegs) { + Agc::Command::SetIndirectCount(cmd, 0x63u, numRegs, __func__); + return 0; } int APS5_VABI sceAgcSetUcRegIndirectPatchAddRegisters(std::uint32_t* cmd, std::uint32_t numRegs) { @@ -53,11 +49,9 @@ int APS5_VABI sceAgcSetUcRegIndirectPatchSetAddress(std::uint32_t* cmd, const vo return 0; } -int APS5_VABI sceAgcSetUcRegIndirectPatchSetNumRegisters(uint32_t* cmd, uint32_t num_regs) { - (void)cmd; - (void)num_regs; - NotImplemented_nid_no_patch(__func__); - return 0; +int APS5_VABI sceAgcSetUcRegIndirectPatchSetNumRegisters(std::uint32_t* cmd, std::uint32_t numRegs) { + Agc::Command::SetIndirectCount(cmd, 0x64u, numRegs, __func__); + return 0; } } From 94035e63677627e394b5464d0d79d20006af5d83 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:06:07 -0400 Subject: [PATCH 03/10] Update Packet.hpp declaration for SetIndirectCount. --- core/libs/prx/libSceAgc/Command/include/Packet.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/core/libs/prx/libSceAgc/Command/include/Packet.hpp b/core/libs/prx/libSceAgc/Command/include/Packet.hpp index f95361fd9..7b92007d8 100644 --- a/core/libs/prx/libSceAgc/Command/include/Packet.hpp +++ b/core/libs/prx/libSceAgc/Command/include/Packet.hpp @@ -21,6 +21,7 @@ std::uint32_t* WriteRegisters(CommandBuffer* buffer, std::uint32_t opcode, const std::uint32_t* WriteIndirectRegisters(CommandBuffer* buffer, std::uint32_t opcode, const volatile ShaderRegister* registers, std::uint32_t count, const char* function); void PatchIndirectAddress(std::uint32_t* packet, std::uint32_t opcode, const volatile ShaderRegister* registers, const char* function); void PatchIndirectCount(std::uint32_t* packet, std::uint32_t opcode, std::uint32_t count, const char* function); +void SetIndirectCount(std::uint32_t* packet, std::uint32_t opcode, std::uint32_t count, const char* function); } From 5afbeca23c80490f47c8f478b8cd9fa2e37c38b8 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:06:41 -0400 Subject: [PATCH 04/10] Update Packet.cpp validated count-replacement helper. --- core/libs/prx/libSceAgc/Command/src/Packet.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/libs/prx/libSceAgc/Command/src/Packet.cpp b/core/libs/prx/libSceAgc/Command/src/Packet.cpp index b32303b1c..62a12734b 100644 --- a/core/libs/prx/libSceAgc/Command/src/Packet.cpp +++ b/core/libs/prx/libSceAgc/Command/src/Packet.cpp @@ -159,4 +159,11 @@ void PatchIndirectCount(std::uint32_t* packet, std::uint32_t opcode, std::uint32 packet[4] += count; } +void SetIndirectCount(std::uint32_t* packet, std::uint32_t opcode, std::uint32_t count, const char* function) { + ValidatePacket(packet, opcode, 5, function); + Require(packet[3] == 0x80000000u && packet[4] <= 0x3fffu, function, "invalid indirect register packet"); + CheckBits(count, 0x3fffu, function); + packet[4] = count; +} + } From 6032ba4af999bbf80614c106b1fc73e40177d6a5 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:08:47 -0400 Subject: [PATCH 05/10] Create RegisterCommands.cpp new regression tests. --- .../prx/libSceAgc/tests/RegisterCommands.cpp | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 core/libs/prx/libSceAgc/tests/RegisterCommands.cpp diff --git a/core/libs/prx/libSceAgc/tests/RegisterCommands.cpp b/core/libs/prx/libSceAgc/tests/RegisterCommands.cpp new file mode 100644 index 000000000..e40249ef6 --- /dev/null +++ b/core/libs/prx/libSceAgc/tests/RegisterCommands.cpp @@ -0,0 +1,116 @@ +#include "prx/libSceAgc/Command/include/Packet.hpp" + +#include +#include +#include +#include + +extern "C" { +std::uint32_t* APS5_VABI sceAgcDcbSetCxRegisterDirect(CommandBuffer*, ShaderRegister); +std::uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer*, ShaderRegister); +std::uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer*, ShaderRegister); +std::uint32_t APS5_VABI sceAgcDcbSetCxRegisterDirectGetSize(); +std::uint32_t APS5_VABI sceAgcDcbSetShRegisterDirectGetSize(); +std::uint32_t APS5_VABI sceAgcDcbSetUcRegisterDirectGetSize(); +std::uint32_t* APS5_VABI sceAgcDcbSetCxRegistersIndirect(CommandBuffer*, const volatile ShaderRegister*, std::uint32_t); +std::uint32_t* APS5_VABI sceAgcDcbSetShRegistersIndirect(CommandBuffer*, const volatile ShaderRegister*, std::uint32_t); +std::uint32_t* APS5_VABI sceAgcDcbSetUcRegistersIndirect(CommandBuffer*, const volatile ShaderRegister*, std::uint32_t); +std::uint32_t APS5_VABI sceAgcDcbSetCxRegistersIndirectGetSize(std::uint32_t); +std::uint32_t APS5_VABI sceAgcDcbSetShRegistersIndirectGetSize(std::uint32_t); +std::uint32_t APS5_VABI sceAgcDcbSetUcRegistersIndirectGetSize(std::uint32_t); +int APS5_VABI sceAgcSetCxRegIndirectPatchSetNumRegisters(std::uint32_t*, std::uint32_t); +int APS5_VABI sceAgcSetShRegIndirectPatchSetNumRegisters(std::uint32_t*, std::uint32_t); +int APS5_VABI sceAgcSetUcRegIndirectPatchSetNumRegisters(std::uint32_t*, std::uint32_t); +} + +namespace { + +void check(bool condition, const char* message) { + if (!condition) throw std::runtime_error(message); +} + +template +void expectFailure(TAction action) { + try { + action(); + } catch (const std::runtime_error&) { + return; + } + throw std::runtime_error("expected invalid input to fail"); +} + +struct Storage { + std::array words{}; + CommandBuffer buffer{words.data(), words.data() + words.size(), words.data(), words.data() + words.size(), nullptr, nullptr, 0}; +}; + +void testDirect() { + const std::array writers{sceAgcDcbSetCxRegisterDirect, sceAgcDcbSetShRegisterDirect, sceAgcDcbSetUcRegisterDirect}; + const std::array sizes{sceAgcDcbSetCxRegisterDirectGetSize, sceAgcDcbSetShRegisterDirectGetSize, sceAgcDcbSetUcRegisterDirectGetSize}; + const std::array headers{0xc0016900u, 0xc0017600u, 0xc0017900u}; + for (std::size_t i = 0; i < writers.size(); ++i) { + Storage storage; + storage.words.fill(0xabcdef01u); + auto* packet = writers[i](&storage.buffer, {0xffffu, 0x12345678u}); + const std::array expected{headers[i], 0xffffu, 0x12345678u}; + check(packet == storage.words.data() && std::equal(expected.begin(), expected.end(), packet), "incorrect direct register packet"); + check(storage.buffer.cursor_up == packet + 3 && sizes[i]() == 12, "direct size/cursor mismatch"); + check(packet[3] == 0xabcdef01u, "direct command overwrote following word"); + const auto before = storage.words; + expectFailure([&] { writers[i](&storage.buffer, {0x10000u, 1}); }); + expectFailure([&] { writers[i](nullptr, {0, 1}); }); + storage.buffer.cursor_down = storage.buffer.cursor_up + 2; + expectFailure([&] { writers[i](&storage.buffer, {0, 1}); }); + check(storage.words == before && storage.buffer.cursor_up == packet + 3, "invalid direct write modified buffer"); + } +} + +void testIndirect() { + const std::array writers{sceAgcDcbSetCxRegistersIndirect, sceAgcDcbSetShRegistersIndirect, sceAgcDcbSetUcRegistersIndirect}; + const std::array sizes{sceAgcDcbSetCxRegistersIndirectGetSize, sceAgcDcbSetShRegistersIndirectGetSize, sceAgcDcbSetUcRegistersIndirectGetSize}; + const std::array setters{sceAgcSetCxRegIndirectPatchSetNumRegisters, sceAgcSetShRegIndirectPatchSetNumRegisters, sceAgcSetUcRegIndirectPatchSetNumRegisters}; + const std::array headers{0xc0039f00u, 0xc0036300u, 0xc0036400u}; + ShaderRegister reg{0x10u, 7}; + for (std::size_t i = 0; i < writers.size(); ++i) { + Storage storage; + auto* packet = writers[i](&storage.buffer, ®, 1); + const auto original = storage.words; + check(packet[0] == headers[i] && storage.buffer.cursor_up == packet + 5, "incorrect indirect packet"); + for (const auto count : {0u, 0x3fffu, 2u}) { + check(sizes[i](count) == 20, "indirect size mismatch"); + check(setters[i](packet, count) == 0 && packet[4] == count, "indirect count was not replaced"); + auto expected = original; + expected[4] = count; + check(storage.words == expected, "count setter modified unrelated packet data"); + } + const auto before = storage.words; + for (const auto count : {0x4000u, 0xffffffffu}) { + expectFailure([&] { sizes[i](count); }); + expectFailure([&] { setters[i](packet, count); }); + } + expectFailure([&] { setters[i](nullptr, 0); }); + expectFailure([&] { setters[(i + 1) % setters.size()](packet, 0); }); + check(storage.words == before, "invalid count setter modified packet"); + for (const auto field : {0u, 3u, 4u}) { + storage.words = before; + packet[field] = field == 0 ? headers[i] ^ 0x10000u : 0xffffffffu; + const auto malformed = storage.words; + expectFailure([&] { setters[i](packet, 1); }); + check(storage.words == malformed, "setter modified malformed packet"); + } + } +} + +} + +int main() { + try { + testDirect(); + testIndirect(); + std::puts("AGC register command tests passed"); + return 0; + } catch (const std::exception& error) { + std::fprintf(stderr, "%s\n", error.what()); + return 1; + } +} From 0dcc9f06059b2a826c627a6c0e370d35643287b4 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:09:38 -0400 Subject: [PATCH 06/10] Update CMakeLists.txt test build target and CTest registration. --- CMakeLists.txt | 126 +++++++++++++++++++++++++++++++------------------ 1 file changed, 79 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3751edef8..a477ef338 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,50 +1,82 @@ -cmake_minimum_required(VERSION 3.20) -project(Relinker CXX) +add_library(libSceAgc SHARED EXCLUDE_FROM_ALL + ${CMAKE_CURRENT_SOURCE_DIR}/Unimplemented.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Control.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Dispatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Memory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Sync.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Branch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Dispatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Registers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Sync.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Memory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Control.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Draw.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/RegisterDefaults.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Packet.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/DrawIndexed.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/DrawNonIndexed.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/IndexBuffer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/Instancing.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/Stats.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Control.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Dispatch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Memory.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Sync.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/ContextState.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Display.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Init.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Marker.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Predication.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Registers.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Workload.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/PacketInfo.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/RegisterDefaults.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/ShaderFusion.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/Suspend.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/CondExec.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Dma.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/IndirectRegisters.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Jump.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Nop.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/QueueEndOfPipeAction.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Rewind.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/WaitRegMem.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Branch.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Predication/src/Predication.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/CreateShader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/InterpolantMapping.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/LinkShaders.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/PrimState.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/ShaderUtils.cpp +) -option(BUILD_TESTING "Build and register relinker tests" OFF) +target_include_directories(libSceAgc PRIVATE ${LIBS_INCLUDE_DIR}) +target_link_libraries(libSceAgc PRIVATE libSceAgcDriver libc) + +option(APS5_AGC_CREATE_LOG "Logging sceAgcCreateShader Ok status" ON) + +target_compile_definitions(libSceAgc PRIVATE + APS5_AGC_CREATE_LOG=$ +) + +foreach(runtimeLinkFlag IN ITEMS -static-libgcc -static-libstdc++ -static) + string(REPLACE "${runtimeLinkFlag}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") +endforeach() + +add_executable(agc_command_tests EXCLUDE_FROM_ALL tests/Commands.cpp) +target_include_directories(agc_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) +target_link_libraries(agc_command_tests PRIVATE libSceAgc libc) +configure_windows_unwind(agc_command_tests) +configure_windows_unwind(libSceAgc) + +add_executable(agc_register_command_tests EXCLUDE_FROM_ALL + tests/RegisterCommands.cpp + Command/src/Packet.cpp + DcbState/src/Registers.cpp + Patch/src/IndirectRegisters.cpp +) +target_include_directories(agc_register_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(agc_register_command_tests) if(BUILD_TESTING) - enable_testing() + add_test(NAME agc_register_command_tests COMMAND agc_register_command_tests) endif() - -option(ANYPS5_ENABLE_SPIRV_TOOLS "Enable SPIRV-Tools validation and optimization" OFF) -option(APS5_ENABLE_TIMING_LOG "Enable frame timing logging" OFF) -add_compile_definitions(APS5_ENABLE_TIMING_LOG=$) - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++") - -set(SDL_SHARED OFF CACHE BOOL "" FORCE) -set(SDL_STATIC ON CACHE BOOL "" FORCE) -set(SDL_TEST OFF CACHE BOOL "" FORCE) -set(SDL_VIDEO ON CACHE BOOL "" FORCE) -set(SDL_RENDER OFF CACHE BOOL "" FORCE) -set(SDL_X11 ON CACHE BOOL "" FORCE) -set(SDL_WAYLAND OFF CACHE BOOL "" FORCE) -set(SDL_OPENGL OFF CACHE BOOL "" FORCE) -set(SDL_OPENGLES OFF CACHE BOOL "" FORCE) -set(SDL_VULKAN ON CACHE BOOL "" FORCE) -set(SDL_JOYSTICK ON CACHE BOOL "" FORCE) -set(SDL_HAPTIC OFF CACHE BOOL "" FORCE) -set(SDL_HIDAPI OFF CACHE BOOL "" FORCE) -set(SDL_SENSOR OFF CACHE BOOL "" FORCE) -set(SDL_STATIC_PIC ON CACHE BOOL "" FORCE) -set(ANYPS5_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") -set(CMAKE_EXE_LINKER_FLAGS "") -add_subdirectory(3rdparty/SDL2) -set(CMAKE_EXE_LINKER_FLAGS "${ANYPS5_EXE_LINKER_FLAGS}") - -set(FT_DISABLE_ZLIB ON CACHE BOOL "" FORCE) -set(FT_DISABLE_BZIP2 ON CACHE BOOL "" FORCE) -set(FT_DISABLE_PNG ON CACHE BOOL "" FORCE) -set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE) -set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE) -set(SKIP_INSTALL_ALL ON CACHE BOOL "" FORCE) -add_subdirectory(3rdparty/freetype EXCLUDE_FROM_ALL) -set_target_properties(freetype PROPERTIES POSITION_INDEPENDENT_CODE ON) - -add_subdirectory(core/shader/recompiler) -add_subdirectory(core/Decoder/Jpeg) -add_subdirectory(core/libs) -add_subdirectory(core/relinker) From 883bb7ad13806f8225072f967f43247dadd38f07 Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:22:12 -0400 Subject: [PATCH 07/10] Update CMakeLists.txt Restore to original CMake --- CMakeLists.txt | 126 ++++++++++++++++++------------------------------- 1 file changed, 47 insertions(+), 79 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a477ef338..3751edef8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,82 +1,50 @@ -add_library(libSceAgc SHARED EXCLUDE_FROM_ALL - ${CMAKE_CURRENT_SOURCE_DIR}/Unimplemented.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Control.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Dispatch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Memory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Acb/src/Sync.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Branch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Dispatch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Registers.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Cb/src/Sync.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Memory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Control.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Draw.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/RegisterDefaults.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Command/src/Packet.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/DrawIndexed.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/DrawNonIndexed.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/IndexBuffer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/Instancing.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbDraw/src/Stats.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Control.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Dispatch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Memory.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbFlow/src/Sync.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/ContextState.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Display.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Init.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Marker.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Predication.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Registers.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/DcbState/src/Workload.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/PacketInfo.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/RegisterDefaults.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/ShaderFusion.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Misc/src/Suspend.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/CondExec.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Dma.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/IndirectRegisters.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Jump.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Nop.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/QueueEndOfPipeAction.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Rewind.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/WaitRegMem.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Patch/src/Branch.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Predication/src/Predication.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/CreateShader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/InterpolantMapping.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/LinkShaders.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/PrimState.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/Shader/src/ShaderUtils.cpp -) +cmake_minimum_required(VERSION 3.20) +project(Relinker CXX) -target_include_directories(libSceAgc PRIVATE ${LIBS_INCLUDE_DIR}) -target_link_libraries(libSceAgc PRIVATE libSceAgcDriver libc) - -option(APS5_AGC_CREATE_LOG "Logging sceAgcCreateShader Ok status" ON) - -target_compile_definitions(libSceAgc PRIVATE - APS5_AGC_CREATE_LOG=$ -) - -foreach(runtimeLinkFlag IN ITEMS -static-libgcc -static-libstdc++ -static) - string(REPLACE "${runtimeLinkFlag}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") -endforeach() - -add_executable(agc_command_tests EXCLUDE_FROM_ALL tests/Commands.cpp) -target_include_directories(agc_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) -target_link_libraries(agc_command_tests PRIVATE libSceAgc libc) -configure_windows_unwind(agc_command_tests) -configure_windows_unwind(libSceAgc) - -add_executable(agc_register_command_tests EXCLUDE_FROM_ALL - tests/RegisterCommands.cpp - Command/src/Packet.cpp - DcbState/src/Registers.cpp - Patch/src/IndirectRegisters.cpp -) -target_include_directories(agc_register_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) -configure_windows_unwind(agc_register_command_tests) +option(BUILD_TESTING "Build and register relinker tests" OFF) if(BUILD_TESTING) - add_test(NAME agc_register_command_tests COMMAND agc_register_command_tests) + enable_testing() endif() + +option(ANYPS5_ENABLE_SPIRV_TOOLS "Enable SPIRV-Tools validation and optimization" OFF) +option(APS5_ENABLE_TIMING_LOG "Enable frame timing logging" OFF) +add_compile_definitions(APS5_ENABLE_TIMING_LOG=$) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++") + +set(SDL_SHARED OFF CACHE BOOL "" FORCE) +set(SDL_STATIC ON CACHE BOOL "" FORCE) +set(SDL_TEST OFF CACHE BOOL "" FORCE) +set(SDL_VIDEO ON CACHE BOOL "" FORCE) +set(SDL_RENDER OFF CACHE BOOL "" FORCE) +set(SDL_X11 ON CACHE BOOL "" FORCE) +set(SDL_WAYLAND OFF CACHE BOOL "" FORCE) +set(SDL_OPENGL OFF CACHE BOOL "" FORCE) +set(SDL_OPENGLES OFF CACHE BOOL "" FORCE) +set(SDL_VULKAN ON CACHE BOOL "" FORCE) +set(SDL_JOYSTICK ON CACHE BOOL "" FORCE) +set(SDL_HAPTIC OFF CACHE BOOL "" FORCE) +set(SDL_HIDAPI OFF CACHE BOOL "" FORCE) +set(SDL_SENSOR OFF CACHE BOOL "" FORCE) +set(SDL_STATIC_PIC ON CACHE BOOL "" FORCE) +set(ANYPS5_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "") +add_subdirectory(3rdparty/SDL2) +set(CMAKE_EXE_LINKER_FLAGS "${ANYPS5_EXE_LINKER_FLAGS}") + +set(FT_DISABLE_ZLIB ON CACHE BOOL "" FORCE) +set(FT_DISABLE_BZIP2 ON CACHE BOOL "" FORCE) +set(FT_DISABLE_PNG ON CACHE BOOL "" FORCE) +set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE) +set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE) +set(SKIP_INSTALL_ALL ON CACHE BOOL "" FORCE) +add_subdirectory(3rdparty/freetype EXCLUDE_FROM_ALL) +set_target_properties(freetype PROPERTIES POSITION_INDEPENDENT_CODE ON) + +add_subdirectory(core/shader/recompiler) +add_subdirectory(core/Decoder/Jpeg) +add_subdirectory(core/libs) +add_subdirectory(core/relinker) From bf25ec499e8b0e5d152f86899e87c806ef3487eb Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:23:15 -0400 Subject: [PATCH 08/10] Update CMakeLists.txt test build target and CTest registration. --- core/libs/prx/libSceAgc/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/libs/prx/libSceAgc/CMakeLists.txt b/core/libs/prx/libSceAgc/CMakeLists.txt index dec965a2f..57f8b6e98 100644 --- a/core/libs/prx/libSceAgc/CMakeLists.txt +++ b/core/libs/prx/libSceAgc/CMakeLists.txt @@ -68,3 +68,16 @@ target_include_directories(agc_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) target_link_libraries(agc_command_tests PRIVATE libSceAgc libc) configure_windows_unwind(agc_command_tests) configure_windows_unwind(libSceAgc) + +add_executable(agc_register_command_tests EXCLUDE_FROM_ALL + tests/RegisterCommands.cpp + Command/src/Packet.cpp + DcbState/src/Registers.cpp + Patch/src/IndirectRegisters.cpp +) +target_include_directories(agc_register_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) +configure_windows_unwind(agc_register_command_tests) +if(BUILD_TESTING) + set_target_properties(agc_register_command_tests PROPERTIES EXCLUDE_FROM_ALL FALSE) + add_test(NAME agc_register_command_tests COMMAND agc_register_command_tests) +endif() From a2c639ff2dafe3f72ab839e7b7e0cb898c0a34be Mon Sep 17 00:00:00 2001 From: carman24r Date: Tue, 29 Sep 2026 16:43:10 -0400 Subject: [PATCH 09/10] Update CMakeLists.txt Missing a required Windows runtime dependency, causing a __gxx_personality_v0 linker error with windows build. --- core/libs/prx/libSceAgc/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/libs/prx/libSceAgc/CMakeLists.txt b/core/libs/prx/libSceAgc/CMakeLists.txt index 57f8b6e98..1db3169a0 100644 --- a/core/libs/prx/libSceAgc/CMakeLists.txt +++ b/core/libs/prx/libSceAgc/CMakeLists.txt @@ -76,8 +76,13 @@ add_executable(agc_register_command_tests EXCLUDE_FROM_ALL Patch/src/IndirectRegisters.cpp ) target_include_directories(agc_register_command_tests PRIVATE ${LIBS_INCLUDE_DIR}) +target_link_libraries(agc_register_command_tests PRIVATE libc) configure_windows_unwind(agc_register_command_tests) if(BUILD_TESTING) set_target_properties(agc_register_command_tests PROPERTIES EXCLUDE_FROM_ALL FALSE) add_test(NAME agc_register_command_tests COMMAND agc_register_command_tests) + if(WIN32) + set_tests_properties(agc_register_command_tests PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() endif() From b9955d8e531a186ed1a05355df6c8eb654c03ea7 Mon Sep 17 00:00:00 2001 From: carman24r Date: Wed, 30 Sep 2026 04:55:24 -0400 Subject: [PATCH 10/10] Update Registers.cpp fix conflict I think --- core/libs/prx/libSceAgc/DcbState/src/Registers.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp b/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp index 36acff25b..11d3ce528 100644 --- a/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp +++ b/core/libs/prx/libSceAgc/DcbState/src/Registers.cpp @@ -8,11 +8,11 @@ extern "C" { -std::uint32_t* APS5_VABI sceAgcDcbSetCxRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - return Agc::Command::WriteRegisterRange(buf, 0x69u, reg.offset, ®.value, 1, __func__); +uint32_t* APS5_VABI sceAgcDcbSetCxRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x69u, reg.offset, ®.value, 1u, __func__); } -std::uint32_t APS5_VABI sceAgcDcbSetCxRegisterDirectGetSize() { +uint32_t APS5_VABI sceAgcDcbSetCxRegisterDirectGetSize(void) { return 12; } @@ -25,8 +25,8 @@ std::uint32_t APS5_VABI sceAgcDcbSetCxRegistersIndirectGetSize(std::uint32_t num return 20; } -std::uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - return Agc::Command::WriteRegisterRange(buf, 0x76u, reg.offset, ®.value, 1, __func__); +uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x76u, reg.offset, ®.value, 1u, __func__); } std::uint32_t APS5_VABI sceAgcDcbSetShRegisterDirectGetSize() { @@ -42,8 +42,8 @@ std::uint32_t APS5_VABI sceAgcDcbSetShRegistersIndirectGetSize(std::uint32_t num return 20; } -std::uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { - return Agc::Command::WriteRegisterRange(buf, 0x79u, reg.offset, ®.value, 1, __func__); +uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegister reg) { + return Agc::Command::WriteRegisterRange(buf, 0x79u, reg.offset, ®.value, 1u, __func__); } std::uint32_t APS5_VABI sceAgcDcbSetUcRegisterDirectGetSize() {