Properly implement sceVideoOutGetBufferLabelAddress (#2642)

* Export sceVideoOutGetBufferLabelAddress

It's an exported function, used by red_prig's BLACKSQUAR2 homebrew sample.
This also fixes the function's return type accordingly.

* More sceVideoOutGetBufferLabelAddress fixups

Library decomp shows a hardcoded return 16 on success. Not sure why it does that, but it never hurts to be accurate.
Also needs to have an openOrbis-specific export to get it to work with the homebrew sample I'm testing.

* Final fixups

Removed the port assert and added asserts in libSceGnmDriver for when sceVideoOutGetBufferLabelAddress calls fail.
This commit is contained in:
Stephen Miller 2025-03-12 13:36:01 -05:00 committed by GitHub
parent f663176a5d
commit 4d0c03fd4a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 17 additions and 5 deletions

View file

@ -1087,7 +1087,8 @@ s32 PS4_SYSV_ABI sceGnmInsertWaitFlipDone(u32* cmdbuf, u32 size, s32 vo_handle,
}
uintptr_t label_addr{};
VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr);
ASSERT_MSG(VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr) == 16,
"sceVideoOutGetBufferLabelAddress call failed");
auto* wait_reg_mem = reinterpret_cast<PM4CmdWaitRegMem*>(cmdbuf);
wait_reg_mem->header = PM4Type3Header{PM4ItOpcode::WaitRegMem, 5};
@ -2041,7 +2042,8 @@ static inline s32 PatchFlipRequest(u32* cmdbuf, u32 size, u32 vo_handle, u32 buf
}
uintptr_t label_addr{};
VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr);
ASSERT_MSG(VideoOut::sceVideoOutGetBufferLabelAddress(vo_handle, &label_addr) == 16,
"sceVideoOutGetBufferLabelAddress call failed");
// Write event to lock the VO surface
auto* write_lock = reinterpret_cast<PM4CmdWriteData*>(cmdbuf);

View file

@ -295,10 +295,16 @@ s32 PS4_SYSV_ABI sceVideoOutUnregisterBuffers(s32 handle, s32 attributeIndex) {
return driver->UnregisterBuffers(port, attributeIndex);
}
void sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr) {
s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr) {
if (label_addr == nullptr) {
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
}
auto* port = driver->GetPort(handle);
ASSERT(port);
if (!port) {
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
}
*label_addr = reinterpret_cast<uintptr_t>(port->buffer_labels.data());
return 16;
}
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, u32 arg, void** unk) {
@ -430,6 +436,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
sceVideoOutIsFlipPending);
LIB_FUNCTION("N5KDtkIjjJ4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
sceVideoOutUnregisterBuffers);
LIB_FUNCTION("OcQybQejHEY", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
sceVideoOutGetBufferLabelAddress);
LIB_FUNCTION("uquVH4-Du78", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutClose);
LIB_FUNCTION("1FZBKy8HeNU", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
sceVideoOutGetVblankStatus);
@ -460,6 +468,8 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
sceVideoOutSetBufferAttribute);
LIB_FUNCTION("w3BY+tAEiQY", "libSceVideoOut", 1, "libSceVideoOut", 1, 1,
sceVideoOutRegisterBuffers);
LIB_FUNCTION("OcQybQejHEY", "libSceVideoOut", 1, "libSceVideoOut", 1, 1,
sceVideoOutGetBufferLabelAddress);
LIB_FUNCTION("U46NwOiJpys", "libSceVideoOut", 1, "libSceVideoOut", 1, 1, sceVideoOutSubmitFlip);
LIB_FUNCTION("SbU3dwp80lQ", "libSceVideoOut", 1, "libSceVideoOut", 1, 1,
sceVideoOutGetFlipStatus);

View file

@ -118,6 +118,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::SceKernelEqueue eq, s32 handle,
s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handle, void* udata);
s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses,
s32 bufferNum, const BufferAttribute* attribute);
s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr);
s32 PS4_SYSV_ABI sceVideoOutSetFlipRate(s32 handle, s32 rate);
s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle);
s32 PS4_SYSV_ABI sceVideoOutWaitVblank(s32 handle);
@ -133,7 +134,6 @@ s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* sett
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings);
// Internal system functions
void sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_addr);
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, u32 arg, void** unk);
void RegisterLib(Core::Loader::SymbolsResolver* sym);