Repository navigation
fix(videoout): create the window and the device when VideoOut starts - #1367
Merged
oneandonlydean merged 1 commit intoOct 9, 2026
Merged
Conversation
The driver created a windowless Vulkan device at the first dispatch and replaced it with a windowed one at the first flip. The replacement built a second device and re-imported every host import, and the first flip paid for it. VideoOut now creates its window when it starts (the first VideoOut call), at the default 1920x1080 output, and attaches it to the driver (AgcDriverAttachWindow) before the call returns. The driver creates its device with that window, so GPU work and presentation use one device. Present no longer creates or replaces a device. A device created by GPU work before VideoOut started is still replaced, now in AttachWindow. A failure to create the window or the device is thrown from that first VideoOut call instead of terminating the presentation thread. Tests: - video_out_flip_tests onedevice: GPU work, then a flip, leaves one device. - pacing makes its first presentation span vblanks with GPU work queued ahead of the flip; it relied on the device being created at the flip. - unavailable expects the failure from sceVideoOutOpen. - guest_video_out_wqhd_detection writes a param.json for the window title and is skipped without a display or Vulkan device unless ANYPS5_REQUIRE_DISPLAY is set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 tasks done
This was referenced Oct 8, 2026
9 tasks done
9 tasks done
This was referenced Oct 9, 2026
9 tasks done
9 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The driver created a windowless Vulkan device at the first dispatch and replaced it with a windowed one at the first flip. The replacement built a second device and re-imported the host imports (#284), and the first flip waited for both. #59, #110, #284 and #373 fix problems caused by the replacement.
shadPS4, KytyPS5 and SharpEmu create the window first and build one device with its surface:
emulator.cppcreates the window at startup;gnmdriver.cppRegisterLibcreatesVulkan::Presenter(*g_window).agc.cppInitializecallsWindowInit, which creates the window and the Vulkan device, beforeVideoOutInit.VulkanVideoPresenter.Initializecreates the instance, the surface, the device, then the swapchain.This change does the same at the first VideoOut call. AnyPS5 has no hook before the guest's entry point, and the libraries' static initializers can't create a window (loader lock on Windows).
AgcDriverAttachWindowbefore the call returns. The driver creates its device with that window.Presentno longer creates or replaces a device. A device created by GPU work submitted before VideoOut started is still replaced, now inAttachWindow.Tests that open VideoOut now need a display and a Vulkan device.
guest_video_out_wqhd_detectionwrites aparam.jsonfor the window title and is skipped without a display or Vulkan device unlessANYPS5_REQUIRE_DISPLAYis set.ANYPS5_REQUIRE_VULKANcan't be used: the Linux job sets it, but its SDL is built without X11 and Wayland, so neither CI job can create a Vulkan window and the test is skipped in both.Hades II (PPSA36082) also needs this to load: its 512 MiB upload pool is freed only after a GPU fence, and creating the device at the first dispatch was one of the delays in front of that fence. With this change and some local changes, it gets past loading; without this change it overflows the pool and crashes (2/2 runs).
Tested
Linux (CachyOS), x86-64, GCC, 7800X3D / RTX 4090.
video_out_flip_tests onedevice(new): GPU work, then a flip, leaves one device. Fails on main (two devices); dropping the attach at start fails it.pacingrelied on the first flip creating the device to span several vblanks. It now queues GPU work ahead of the flip and checks thatlastFlipVblankis at least 3 vblanks behind the vblank the presentation finished at, so it doesn't depend on which vblank the flip reaches the presenter at. Moving thelastFlipVblankstore back after the present fails it.unavailablenow expects the failure fromsceVideoOutOpen, and the same failure from a second open (run without a Vulkan driver).onedevice,pacing,aftergpu,present,backtoback,dcc,controls,decode,unavailablepass.unavailablewith Vulkan disabled.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)