feat(libs): add new sceAgc functions def

This commit is contained in:
boykopovar 2026-09-24 07:54:15 +03:00
parent 9f2b41b9a1
commit f5bc2d7649
22 changed files with 327 additions and 10 deletions

View File

@ -30,6 +30,36 @@ uint32_t* APS5_VABI sceAgcAcbResetQueue(CommandBuffer* buf, uint32_t op) {
return nullptr;
}
std::uint32_t* APS5_VABI sceAgcAcbRewind(CommandBuffer* buf, std::uint32_t initialState) {
(void)buf;
(void)initialState;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t APS5_VABI sceAgcAcbRewindGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcAcbWaitUntilSafeForRendering(CommandBuffer* buf, std::uint32_t videoOutHandle, std::uint32_t displayBufferIndex) {
(void)buf;
(void)videoOutHandle;
(void)displayBufferIndex;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t* APS5_VABI sceAgcAcbSetFlip(CommandBuffer* buf, std::uint32_t videoOutHandle, std::int32_t displayBufferIndex, std::uint32_t flipMode, std::int64_t flipArg) {
(void)buf;
(void)videoOutHandle;
(void)displayBufferIndex;
(void)flipMode;
(void)flipArg;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
uint32_t* APS5_VABI sceAgcAcbPushMarker(CommandBuffer* buf, const char* str, uint32_t color) {
(void)buf;
(void)str;

View File

@ -17,4 +17,9 @@ uint32_t* APS5_VABI sceAgcAcbDispatchIndirect(CommandBuffer* buf, const volatile
return nullptr;
}
std::uint32_t APS5_VABI sceAgcAcbDispatchIndirectGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -42,6 +42,47 @@ std::uint32_t* APS5_VABI sceAgcAcbDmaData(CommandBuffer* buf, std::uint8_t dst,
return Agc::Command::WriteDma(buf, true, 0, dst, dstCachePolicy, dstAddress, src, srcCachePolicy, srcAddress, numBytes, waitForPrevious, writeConfirm, 0, __func__);
}
std::uint32_t APS5_VABI sceAgcAcbDmaDataGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcAcbAtomicMem(CommandBuffer* buf, std::uint8_t atomicOp, std::uint8_t command, std::uint8_t cachePolicy, const volatile void* address, std::uint64_t srcData, std::uint64_t compareData, std::uint16_t loopInterval) {
(void)buf;
(void)atomicOp;
(void)command;
(void)cachePolicy;
(void)address;
(void)srcData;
(void)compareData;
(void)loopInterval;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t APS5_VABI sceAgcAcbAtomicMemGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcAcbAtomicGdsGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcAcbPrimeUtcl2(CommandBuffer* buf, const volatile void* address, std::uint32_t sizeInBytes) {
(void)buf;
(void)address;
(void)sizeInBytes;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t APS5_VABI sceAgcAcbPrimeUtcl2GetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcAcbWriteData(CommandBuffer* buf, std::uint8_t dst, std::uint8_t cachePolicy, std::uint64_t address, const void* data, std::uint32_t numDwords, std::uint8_t increment, std::uint8_t writeConfirm) {
return Agc::Command::WriteData(buf, true, dst, cachePolicy, address, data, numDwords, increment, writeConfirm, __func__);
}

View File

@ -38,4 +38,24 @@ std::uint32_t* APS5_VABI sceAgcAcbEventWrite(CommandBuffer* buf, std::uint8_t ev
return Agc::Command::Emit(buf, 0x46u, {eventType | (eventType == 7 ? 0x400u : 0u)}, __func__);
}
std::uint64_t APS5_VABI sceAgcAcbEventWriteGetSize(std::uint8_t eventType) {
(void)eventType;
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcAcbQueueEndOfShaderActionGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcAcbMemSemaphore(CommandBuffer* buf, std::uint8_t action, std::uint8_t clientCode, const volatile void* address) {
(void)buf;
(void)action;
(void)clientCode;
(void)address;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
}

View File

@ -39,6 +39,7 @@ add_library(libSceAgc SHARED EXCLUDE_FROM_ALL
${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

View File

@ -38,4 +38,9 @@ uint32_t* APS5_VABI sceAgcCbCondWrite(CommandBuffer* buf, uint32_t cond, uint32_
return nullptr;
}
std::uint32_t APS5_VABI sceAgcCbCondWriteGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -22,12 +22,30 @@ uint32_t APS5_VABI sceAgcCbSetShRegisterRangeDirectGetSize(uint32_t num_values)
return 0;
}
std::uint32_t APS5_VABI sceAgcCbSetUcRegisterRangeDirectGetSize(std::uint32_t numValues) {
(void)numValues;
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcCbSetShRegistersDirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) {
return Agc::Command::WriteRegisters(buf, 0x76u, regs, numRegs, true, __func__);
}
std::uint32_t APS5_VABI sceAgcCbSetShRegistersDirectGetSize(std::uint32_t numRegs) {
(void)numRegs;
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcCbSetUcRegistersDirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) {
return Agc::Command::WriteRegisters(buf, 0x79u, regs, numRegs, false, __func__);
}
std::uint32_t APS5_VABI sceAgcCbSetUcRegistersDirectGetSize(std::uint32_t numRegs) {
(void)numRegs;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -13,6 +13,11 @@ std::uint32_t* APS5_VABI sceAgcDcbSetIndexBuffer(CommandBuffer* buf, std::uint64
return Agc::Command::Emit(buf, 0x26u, {static_cast<std::uint32_t>(indexAddress), static_cast<std::uint32_t>(indexAddress >> 32u)}, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbSetIndexBufferGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
uint32_t* APS5_VABI sceAgcDcbSetIndexCount(CommandBuffer* buf, uint32_t index_count) {
(void)buf;
(void)index_count;
@ -20,10 +25,32 @@ uint32_t* APS5_VABI sceAgcDcbSetIndexCount(CommandBuffer* buf, uint32_t index_co
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbSetIndexCountGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbSetIndexSize(CommandBuffer* buf, std::uint8_t indexSize, std::uint8_t cachePolicy) {
Agc::Command::Require(indexSize <= 2, __func__, "invalid index element size");
Agc::Command::CheckBits(cachePolicy, 3, __func__);
return Agc::Command::Emit(buf, 0x7au, {0x20000243u, 0x400u | indexSize | (static_cast<std::uint32_t>(cachePolicy) << 6u)}, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbSetIndexSizeGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbSetIndexIndirectArgs(CommandBuffer* buf, std::uint32_t dataOffsetInBytes) {
(void)buf;
(void)dataOffsetInBytes;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbSetIndexIndirectArgsGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -20,4 +20,14 @@ std::uint32_t* APS5_VABI sceAgcDcbGetLodStats(CommandBuffer* buf, std::uint8_t c
return Agc::Command::Emit(buf, 0x8eu, {bufferSizeInBytes, static_cast<std::uint32_t>(address), static_cast<std::uint32_t>(address >> 32u), control}, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbBeginOcclusionQueryGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcDcbEndOcclusionQueryGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -49,6 +49,34 @@ std::uint32_t* APS5_VABI sceAgcDcbDmaData(CommandBuffer* buf, std::uint8_t engin
return Agc::Command::WriteDma(buf, false, engine, dst, dstCachePolicy, dstAddress, src, srcCachePolicy, srcAddress, numBytes, waitForPrevious, writeConfirm, blockEngine, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbDmaDataGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbAtomicMem(CommandBuffer* buf, std::uint8_t atomicOp, std::uint8_t command, std::uint8_t cachePolicy, const volatile void* address, std::uint64_t srcData, std::uint64_t compareData, std::uint16_t loopInterval) {
(void)buf;
(void)atomicOp;
(void)command;
(void)cachePolicy;
(void)address;
(void)srcData;
(void)compareData;
(void)loopInterval;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbAtomicMemGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcDcbAtomicGdsGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbWriteData(CommandBuffer* buf, std::uint8_t dst, std::uint8_t cachePolicy, std::uint64_t address, const void* data, std::uint32_t numDwords, std::uint8_t increment, std::uint8_t writeConfirm) {
return Agc::Command::WriteData(buf, false, dst, cachePolicy, address, data, numDwords, increment, writeConfirm, __func__);
}

View File

@ -54,4 +54,18 @@ std::uint32_t* APS5_VABI sceAgcDcbStallCommandBufferParser(CommandBuffer* buf) {
return Agc::Command::Emit(buf, 0x42u, {0}, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbStallCommandBufferParserGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbMemSemaphore(CommandBuffer* buf, std::uint8_t action, std::uint8_t clientCode, const volatile void* address) {
(void)buf;
(void)action;
(void)clientCode;
(void)address;
NotImplemented_nid_no_patch(__func__);
return nullptr;
}
}

View File

@ -28,4 +28,9 @@ uint32_t* APS5_VABI sceAgcDcbPrimeUtcl2(CommandBuffer* buf, const volatile void*
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbPrimeUtcl2GetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -19,4 +19,19 @@ uint32_t* APS5_VABI sceAgcDcbSetPredication(CommandBuffer* buf, uint8_t conditio
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbSetZPassPredicationEnableGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcDcbSetPredicationDisableGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t APS5_VABI sceAgcDcbSetBoolPredicationEnableGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -24,6 +24,12 @@ std::uint32_t* APS5_VABI sceAgcDcbSetCxRegistersIndirect(CommandBuffer* buf, con
return Agc::Command::WriteIndirectRegisters(buf, 0x9fu, regs, numRegs, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbSetCxRegistersIndirectGetSize(std::uint32_t numRegs) {
(void)numRegs;
NotImplemented_nid_no_patch(__func__);
return 0;
}
uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegister reg) {
(void)buf;
(void)reg;
@ -31,6 +37,11 @@ uint32_t* APS5_VABI sceAgcDcbSetShRegisterDirect(CommandBuffer* buf, ShaderRegis
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbSetShRegisterDirectGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) {
return Agc::Command::WriteIndirectRegisters(buf, 0x63u, regs, numRegs, __func__);
}
@ -47,8 +58,19 @@ uint32_t* APS5_VABI sceAgcDcbSetUcRegisterDirect(CommandBuffer* buf, ShaderRegis
return nullptr;
}
std::uint32_t APS5_VABI sceAgcDcbSetUcRegisterDirectGetSize() {
NotImplemented_nid_no_patch(__func__);
return 0;
}
std::uint32_t* APS5_VABI sceAgcDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, std::uint32_t numRegs) {
return Agc::Command::WriteIndirectRegisters(buf, 0x64u, regs, numRegs, __func__);
}
std::uint32_t APS5_VABI sceAgcDcbSetUcRegistersIndirectGetSize(std::uint32_t numRegs) {
(void)numRegs;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -0,0 +1,4 @@
#ifndef CORE_LIBS_PRX_LIBSCEAGC_PATCH_INCLUDE_BRANCH_HPP
#define CORE_LIBS_PRX_LIBSCEAGC_PATCH_INCLUDE_BRANCH_HPP
#endif

View File

@ -0,0 +1,35 @@
#include "prx/libSceAgc/Patch/include/Branch.hpp"
#include "prx/libSceAgc/Command/include/Memory.hpp"
#include "prx/libSceAgc/Command/include/Packet.hpp"
#include <cstdint>
#include <cstddef>
#include "SceTypes.hpp"
#include "prx/libc/include/General.hpp"
extern "C" {
int APS5_VABI sceAgcBranchPatchSetCompareAddress(std::uint32_t* cmd, const volatile std::uint64_t* compareAddress) {
(void)cmd;
(void)compareAddress;
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceAgcBranchPatchSetThenTarget(std::uint32_t* cmd, const volatile std::uint32_t* target, std::uint32_t sizeInDwords) {
(void)cmd;
(void)target;
(void)sizeInDwords;
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceAgcBranchPatchSetElseTarget(std::uint32_t* cmd, const volatile std::uint32_t* target, std::uint32_t sizeInDwords) {
(void)cmd;
(void)target;
(void)sizeInDwords;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -39,4 +39,18 @@ int APS5_VABI sceAgcQueueEndOfPipeActionPatchData(uint32_t* cmd, uint32_t contex
return 0;
}
int APS5_VABI sceAgcQueueEndOfPipeActionPatchGcrCntl(std::uint32_t* cmd, std::uint16_t gcrControl) {
(void)cmd;
(void)gcrControl;
NotImplemented_nid_no_patch(__func__);
return 0;
}
int APS5_VABI sceAgcQueueEndOfPipeActionPatchType(std::uint32_t* cmd, std::uint8_t action) {
(void)cmd;
(void)action;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -16,4 +16,11 @@ int APS5_VABI sceAgcRewindPatchSetRewindState(uint32_t* cmd, uint8_t state) {
return 0;
}
int APS5_VABI sceAgcAsyncRewindPatchSetRewindState(std::uint32_t* cmd, std::uint8_t state) {
(void)cmd;
(void)state;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -29,4 +29,11 @@ int APS5_VABI sceAgcWaitRegMemPatchReference(std::uint32_t* cmd, std::uint64_t r
return 0;
}
int APS5_VABI sceAgcWaitRegMemPatchCompareFunction(std::uint32_t* cmd, std::uint8_t compareFunction) {
(void)cmd;
(void)compareFunction;
NotImplemented_nid_no_patch(__func__);
return 0;
}
}

View File

@ -12,7 +12,7 @@ struct Args {
bool lazyBinding = false;
bool autorun = false;
bool windowsDiagnostics = false;
std::uint32_t unusedFilterLevel = 2;
std::uint32_t unusedFilterLevel = 1;
std::string inputPath;
std::string outputPath;
std::string runPath = "$ORIGIN/libs";

View File

@ -178,17 +178,9 @@ public:
const StrictImage image(elfBytes);
const auto input = image.Build(nidRefs, textSection, textVAddr);
const auto analysis = UnusedNidFilter::AnalyzeStrictReachability(input);
std::vector<NidReference> nonPlt;
for (const auto& reference : nidRefs)
if (reference.RelocationTypeValue != 7) nonPlt.push_back(reference);
const auto originalNonPltCount = nonPlt.size();
if (!nonPlt.empty()) nonPlt = MakeUnusedNidFilter()->Filter(nonPlt, elfBytes, textSection, textVAddr);
std::set<VirtualAddress> nonPltSlots;
for (const auto& reference : nonPlt) nonPltSlots.insert(reference.RelocationAddress);
std::cout << "CFG/GOT filtering: " << originalNonPltCount << " -> " << nonPlt.size() << "; filtered=" << originalNonPltCount - nonPlt.size() << "\n";
std::vector<NidReference> result;
for (const auto& reference : nidRefs) {
if (reference.RelocationTypeValue == 7 ? analysis.ImportSlots.contains(reference.RelocationAddress) : nonPltSlots.contains(reference.RelocationAddress)) result.push_back(reference);
if (analysis.ImportSlots.contains(reference.RelocationAddress)) result.push_back(reference);
}
std::cout << "Strict reachability: " << analysis.Instructions.size() << " instructions; conservative indirect transfers=" << analysis.IndirectTransfers << "\n";
std::cout << "Function graph: " << analysis.LiveRegions << "/" << analysis.TotalRegions << " live regions; address-taken roots=" << analysis.AddressTakenRoots << "; unwind functions=" << input.Functions.size() << "\n";

View File

@ -222,6 +222,22 @@ std::vector<std::uint8_t> elfFixture(const StrictReachabilityInput& input) {
return bytes;
}
void filterCallbackDataImports() {
auto input = fixture();
ripOperand(input, 0, {0x48, 0x8D, 0x3D}, 0x1020);
emit(input, 7, {0xC3});
ripOperand(input, 32, {0x48, 0x8B, 0x05}, 0x2000);
emit(input, 39, {0xC3});
ripOperand(input, 48, {0x48, 0x8B, 0x05}, 0x2008);
emit(input, 55, {0xC3});
const auto bytes = elfFixture(input);
for (const std::uint32_t relocationType : {1, 6}) {
const std::vector<Relinker::NidReference> references = {{"callbackData", {}, relocationType, 0x300, 0x2000, 0}, {"deadData", {}, relocationType, 0x318, 0x2008, 0}};
const auto filtered = Relinker::MakeStrictUnusedNidFilter()->Filter(references, bytes, input.Text, input.TextVaddr);
require(filtered.size() == 1 && filtered[0].Nid == references[0].Nid, "Strict ELF filter lost callback data or retained unreachable data");
}
}
void filterAndPltCompaction() {
auto input = fixture();
importThunk(input, 0, 0x2000);
@ -274,6 +290,7 @@ int main() {
relativeTableAndWholeFunction();
vectorInstructionLengths();
exceptionLandingPads();
filterCallbackDataImports();
filterAndPltCompaction();
std::cout << "Strict NID filter tests passed\n";
} catch (const std::exception& error) {