Merge pull request #2152 from MathiasDevelopes/feat/videoout-pre-vblank-start-events

feat(libSceVideoOut): deliver pre-vblank start events
This commit is contained in:
Dean 2026-10-10 17:44:23 +13:00 committed by GitHub
commit b57e66fa60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 13 additions and 4 deletions

View File

@ -121,10 +121,7 @@ int APS5_VABI sceVideoOutAddVblankEvent(KernelEqueue eq, int handle, void* udata
}
int APS5_VABI sceVideoOutAddPreVblankStartEvent(KernelEqueue eq, int handle, void* udata) try {
static_cast<void>(eq);
static_cast<void>(udata);
VideoOutDriver::Get().GetConfig(handle);
throw std::runtime_error("VideoOut: physical pre-vblank timing is not implemented");
return registerVideoOutEvent(handle, eq, VIDEO_OUT_EVENT_PRE_VBLANK_START, udata);
} catch (const ProcessShutdown&) {
LibcAwaitExit_nid_postfix();
}

View File

@ -419,6 +419,10 @@ void VideoOutDriver::vblankEnd() {
std::lock_guard cfgLock(cfg->mutex);
if (!cfg->opened || cfg->failure) continue;
require(cfg->vblankStatus.count != std::numeric_limits<uint64_t>::max(), "vblank counter overflow");
++cfg->preVblankStatus.count;
cfg->preVblankStatus.processTime = sceKernelGetProcessTime();
cfg->preVblankStatus.processTimeCounter = sceKernelGetProcessTimeCounter();
triggerEvents(*cfg, VIDEO_OUT_EVENT_PRE_VBLANK_START, reinterpret_cast<void*>(cfg->preVblankStatus.count));
++cfg->vblankStatus.count;
cfg->vblankStatus.processTime = sceKernelGetProcessTime();
cfg->vblankStatus.processTimeCounter = sceKernelGetProcessTimeCounter();

View File

@ -266,6 +266,13 @@ void testControls() {
}
check(sceVideoOutWaitVblank(handle) == 0, "vblank wait failed");
check(owner->GetTriggeredEvents(&event, 1) == 1 && event.udata == &settings && sceVideoOutGetEventId(&event) == VIDEO_OUT_EVENT_VBLANK, "vblank event or updated user data missing");
check(sceVideoOutAddPreVblankStartEvent(queue, handle, &mode) == 0, "pre-vblank subscription failed");
check(sceVideoOutWaitVblank(handle) == 0, "vblank wait failed");
KernelEvent events[2]{};
check(owner->GetTriggeredEvents(events, 2) == 2, "pre-vblank or vblank event missing");
const auto& preVblank = sceVideoOutGetEventId(&events[0]) == VIDEO_OUT_EVENT_PRE_VBLANK_START ? events[0] : events[1];
check(sceVideoOutGetEventId(&preVblank) == VIDEO_OUT_EVENT_PRE_VBLANK_START && preVblank.udata == &mode, "pre-vblank event missing");
check(sceVideoOutDeletePreVblankStartEvent(queue, handle) == 0, "pre-vblank unsubscription failed");
std::vector<std::byte> allocation(65536 + 65535);
const auto storage = alignedBuffer(allocation);
VideoOutBuffers buffer{storage.data(), nullptr, {allocation.data(), storage.data()}};

View File

@ -248,6 +248,7 @@ Throughout the project, every function at every stage either **does exactly what
- [sceAjmBatchJobSetResampleParameters, sceAjmBatchJobGetResampleInfo](../../core/libs/prx/libSceAjm.native/src/Ajm.cpp) (libSceAjm) - the ratio is taken as decoded samples per output sample and num_samples as the decoded samples the resampler holds, both inferred from FMOD (Hades II); the console's interpolation is unknown, a 4-point Catmull-Rom is used. The flags argument is ignored, as in shadPS4 and Kyty
- [scePlayerReviewDialogOpen, scePlayerReviewDialogGetResult](../../core/libs/prx/libSceCdlgPlayerReview/Export.cpp) (libSceCdlgPlayerReview) - the PS5-only dialog has no public reference: the parameter is not read and the result is assumed to start with the 32-bit common dialog result, as `sceWebBrowserDialogGetResult` assumes
- [sceHttpWaitRequest](../../core/libs/prx/libSceHttp/Export.cpp) (libSceHttp) - the timeout is assumed to be in microseconds and a negative timeout to wait without limit; the invalid-value error for a null handle or event array or a non-positive event count is assumed, not measured. No request is ever pending, so the call waits for the timeout and returns 0 events, and a wait without limit throws
- [sceVideoOutAddPreVblankStartEvent](../../core/libs/prx/libSceVideoOut/src/Event.cpp) (libSceVideoOut) - how long before the vblank the console signals pre-vblank start is unknown. The event is triggered on each emulated vblank tick immediately before the vblank event, with its own count as the event data
- [gethostbyname](../../core/libs/prx/libScePosixForWebKit/Resolver.cpp) (libScePosixForWebKit) - numeric IPv4 forms, trailing whitespace and 64-bit accumulation follow FreeBSD 11.4 [inet_aton](https://github.com/freebsd/freebsd-src/blob/releng/11.4/lib/libc/inet/inet_addr.c); clearing the resolver error on numeric success follows [fakeaddr](https://github.com/freebsd/freebsd-src/blob/releng/11.4/lib/libc/net/gethostnamadr.c). Exact PS5 behavior is unverified; hostname lookup still uses the host resolver