Repository navigation
fix(libSceVideoOut): report the output resolution from the host display as measured on a PS5 - #7814
Conversation
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
@ionut27001 thanks, reporting the resolution from the host display like a console on Automatic is the right default, and we'd like to keep it. One addition before merge: on PC this means anyone with a 4K monitor always gets a title's 4K mode, even on a GPU that can't sustain it, and there's no way back. Could you add an override for the reported output resolution, for example Once that's in, we'll review the delta and run our title test with the override set to the previous resolution, so it measures this change rather than the jump to 4K. |
ae0907b to
eaadab6
Compare
|
Added |
eaadab6 to
f65e06b
Compare
f65e06b to
4e7d372
Compare
…ay as measured on a PS5 sceVideoOutGetOutputStatus derived resolution from the size of the registered buffers, so a title that reads it right after sceVideoOutOpen got 1 (1080p) whatever the display. In a payload process on a PS5 (firmware 12.70), with no buffer registered, the field changed with the console's resolution setting: 2 with it on Automatic on a 4K display, 1 with it set to 1080p. Read it from the display mode SDL reports for the window's display, next to the refresh rate, and keep it independent of the registered buffers.
…ted output resolution
4e7d372 to
983a81d
Compare
|
Re-checked after main changed docs/dev/ENVIRONMENT.md again. The code is unchanged since the last review. We rebased onto current main: the |
What
sceVideoOutGetOutputStatusfilledresolutionfrom the size of the registered buffers (cfg.widthandcfg.height, 1920x1080 until the first buffer registration), so a title that reads it right aftersceVideoOutOpengot 1 on every host. By #7635's reading of its disassembly and crash, NHL 27 (PPSA34063) builds its hardware profile from that call before it registers a buffer and then reads a null entry for the 1080p profile its data has no entry for.Measured in a payload process on a PS5 (firmware 12.70; payload SDK v0.44, clang 18.1.8), with
libSceVideoOut.sprxloaded into the process throughsceKernelLoadStartModule, right aftersceVideoOutOpen(0xff, 0, 0, NULL)and with no buffer registered. The console is connected to a 4K HDR display with HDR on; the first run has its resolution setting on Automatic, the second the same display with the setting changed to 1080p. Probep76_libvideoout, source and both logs attached: p76-videoout-output-status.zip; the lines below are quoted unchanged with ap76:prefix, except that the 160-byteaapoison pattern of the last line in the first block is shortened toaaaa…:So with no buffer registered,
resolutionwas 2 with the console's resolution setting on Automatic on the 4K display and 1 with it set to 1080p: it changed with the console's resolution setting.dynamicRangewas 2,refreshRate3 andflags0 both times;sceVideoOutGetResolutionStatusreported 3840x2160 for the full and pane sizes both times,refreshRate3,screenSizeInInch60 andflags0 (theresolution_status_wordsline in the logs splits those bytes as if they were the output status; read the hex);sceVideoOutGetOutputStatusWithVrrreturned0x8029001c, the global-flag check its debt entry describes.The change:
VideoOutDriverkeeps the display's resolution class next to the refresh rate, from the sameSDL_GetCurrentDisplayModecall for the display the window is on (2 when the mode is at least 3840 pixels wide or 2160 high, 1 below, the threshold the buffer rule used), andoutputStatusreports it, so it no longer depends on the registered buffers.sceVideoOutGetOutputStatusWithVrrsharesoutputStatus, so its first 48 bytes change the same way. The present loop reads the mode every iteration, as it does for the refresh rate, so a window moved to another display changes the next status. On Wayland SDL's current mode is the output's logical size (from SDL's Wayland source, not run), so a scaled 4K output reports 1 (recorded in debt).resolution(video_out_flip_resolution): a freshly opened port reports the class of display 0, and registering and flipping a linear buffer of the other class (3840x2160 on a display below 4K, 1920x1080 on a 4K display) leaves it unchanged, while the port records the buffer's size. Like the othervideo_out_flip_*tests that open a window, it is skipped where the SDL driver has no Vulkan surface, which includes the defaultoffscreendriver CI uses.sceVideoOutGetOutputStatusentry records what was not measured, the measurement, that the payload process reporteddynamicRange2 withflags0 while this code sets flag bit 0 whenever it reports dynamic range 2, and the Wayland case; thesceVideoOutGetResolutionStatusentry records the 48 bytes the payload process wrote and that this code reports the registered buffers' size where the payload process reported 3840x2160 at both settings. Neither of those two is changed here.Not measured: the status after a buffer is registered or flipped, a 1440p output, and a console on a display below 4K with the resolution on Automatic (the 1080p row is the setting on the 4K display). On a host whose display is below 3840x2160 this PR still reports 1, so NHL 27's missing 1080p profile entry (#7635) stays the title's data on such hosts, which is why this PR does not close the issue; the title was not run here.
Overlaps: #6879 changes the same lines of
updateDisplayRefreshRateinVideoOutDriver.cpp. #4040 (Output.cpp, the debt file), #7008 (VideoOutDriver.cpp), #674 and #6044 (CMakeLists.txt; #6044 also editstests/Flip.cppwithout conflict) touch the same files but already conflict withmainwithout this PR (git merge-tree --write-treeagainst eachrefs/pull/N/head, with and without this branch). #7259 addssceVideoOutGetCurrentOutputMode_with a resolution code derived fromcfg->widthandcfg->heightwhose top tier is the rule this PR removes fromoutputStatus; no textual conflict.APS5_OUTPUT_RESOLUTION=<width>x<height>(for example1920x1080) overrides the size the host display contributes to the reported output resolution.sceVideoOutGetOutputStatusandsceVideoOutGetOutputStatusWithVrrthen report resolution 2 when the override is at least 3840 wide or 2160 high and 1 otherwise, instead of reading the display. Unset or empty keeps the follow-the-display behaviour above. A value that is not two positive decimal integers separated byxmakes the call throw, naming the variable and the value. The variable is documented indocs/dev/ENVIRONMENT.mdand noted in thesceVideoOutGetOutputStatusdebt entry.sceVideoOutGetResolutionStatusstill reports the registered buffers' size and is not affected.Tested
Windows 11 Pro 10.0.26300, WinLibs MinGW-w64 GCC 15.2.0 r7 (posix, UCRT), Ninja, Release,
-DBUILD_TESTING=ON, branch built and tested onmain6030b31 and then rebased on 3fdd1f5, whose 42 changed files since then touch no VideoOut, SDL or test file (core/libs/SceTypes.hppgained five lines away from the VideoOut structs); NVIDIA GeForce RTX 4080 SUPER (driver 617.42), host display 3440x1440 at 164 Hz, so the host class is 1 and the new test registers and flips a 3840x2160 linear buffer.ANYPS5_VIDEO_OUT_TEST_DRIVER=offscreenthe flip tests that open a window are skipped on this host (resolution,lifetimeandps4checked: "DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform";decode, which opens no window, passes), so the VideoOut tests ran with-DANYPS5_VIDEO_OUT_TEST_DRIVER=windows, a real window:ctest -R "video_out_|guest_video_out", 27 tests: 25 passed,guest_video_out_wqhd_detection_no_vulkanskipped,video_out_hdr_probefailed with "FAIL: a window without a Windows HDR monitor report reads as HDR although only the surface offers HDR10 (driver windows)"; this host's monitor is HDR, and withOutput.cpp,VideoOutDriver.cppandVideoOutDriver.hppfrommainit fails with the same message.mainand the new test kept,video_out_flip_resolutionfails with "the flipped buffer's size changed the reported resolution" (run before and after the rebase); with the branch's files it passed in every run.SDL_GetCurrentDisplayModeis imported fromlibSceAgcDriver.prx, the SDL copy the driver uses (objdump -pon the test executable and onlibSceVideoOut.prx).python tools/check_conventions.py --base origin/mainpasses.p76_libvideooutbuilt with the payload SDK v0.44 and clang 18.1.8 (-target x86_64-sie-ps5), launched twice through the payload manager; both logs are in the attachment.Not tested: Linux (CI's offscreen driver skips the window tests, so the new test does not run there; where SDL binds on Linux was not checked), a 4K host display (the 1920x1080 branch of the test), NHL 27.
Override commit, rebased onto main e25333e, Windows 11, WinLibs GCC 15.2.0 r7, NVIDIA-less laptop (AMD Radeon 8060S):
ANYPS5_VIDEO_OUT_TEST_DRIVER=windows ctest -R "video_out|videoout|flip"twice: 31 of 31 pass both times. The new testvideo_out_flip_resolution_overrideis skipped by ctest here (the offscreen SDL driver has no Vulkan device on this machine), so it was run directly with the windows driver, twice: with the variable unset the status equals the display's;1920x1080and1280x720give 1 and3840x2160,2560x2160and3840X1give 2 from both status calls; twelve malformed values throw a message namingAPS5_OUTPUT_RESOLUTION; clearing the variable returns to the display's value. Revert check: withVideoOutDriver.cpprestored from the previous commit the test fails on the 3840x2160 case. Not run: Linux and macOS.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)