Repository navigation
fix(agc): load the Vulkan loader and list MoltenVK on macOS - #11554
maximilianfv wants to merge 1 commit into
Conversation
The driver loaded libvulkan.so.1, which does not exist on macOS, so it could not create a Vulkan device there. Load libvulkan.1.dylib on macOS. MoltenVK is a portability driver: the loader lists it only for an instance created with VK_KHR_portability_enumeration and VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, so request both on macOS, with or without a window. A device that advertises VK_KHR_portability_subset must enable it; enable it with the portability features the device reports. Co-authored-by: mugurc <20699965+mugurc@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MarcZX10
left a comment
There was a problem hiding this comment.
Two repository requirements still need attention before this is ready:\n\n1. Resolve and declare the overlap. VulkanDevice.cpp changes overlap the still-open #5021 and #7201 branches (the PR description also identifies the conflicts). CONTRIBUTING.md requires the authors to agree which change goes first and to declare that order with Depends on; the checklist currently says Depends on: none. Please coordinate the order and update the field, or resolve the overlapping hunks so the overlap no longer applies.\n\n2. Record the acknowledged MoltenVK gap. The PR description says MoltenVK reports pointPolygons false and that Pipeline.cpp can still request VK_POLYGON_MODE_POINT after checking only fillModeNonSolid and maintenance5. I confirmed the current pipeline guard does not check pointPolygons, and I could not find this gap in docs/dev/debt/libSceAgcDriver.md. AGENTS.md and CONTRIBUTING.md require known gaps to be recorded there. Please add the concise debt entry (or include a general guard that throws when the unsupported mode is requested).\n\nThe portability-subset feature query and device-create chain are present, and the current eligibility, conventions, intake, label, and report checks pass. The Linux/Windows product and relinker jobs are skipped by path policy; the detailed macOS/MoltenVK validation results in the PR description are therefore the available platform evidence.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
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.
|
|
Tested on an Apple M2 Pro (macOS, x86_64 under Rosetta 2, Vulkan SDK 1.4.363.0 with MoltenVK 1.4.2), running
The test still fails with this PR for an unrelated reason: image-table descriptor reuse counters stay at 0. Device creation itself is clean, and enabling Test base: main at I had a local branch with the same loader name and portability enumeration change but not the portability subset. I won't open it, since this PR covers it. AI-assisted: yes (Cana) |
|
Correction to my test above: the "0 VUID lines" was wrong. My Rosetta wrapper never pointed the loader at the SDK's layer folder, so the validation layer didn't load and nothing was counted. I fixed the wrapper and re-ran with the layer loaded (no "was not found but was requested" line, and the layer reported errors), counting
So enabling AI-assisted: yes (Cana) |
|
A game run for this PR: ASTRO BOT (PPSA21564, US), Apple M5 Pro, macOS 27.2, x86-64 Release under Rosetta 2, MoltenVK 1.4.2 from the LunarG SDK 1.4.363, with Base:
AI-assisted: yes |
What
On macOS the AGC driver cannot create a Vulkan device.
VulkanDeviceloadslibvulkan.so.1, which does not exist there. Even with a loader, MoltenVK is a portability driver, and the loader lists it only for an instance created withVK_KHR_portability_enumerationandVK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR.This PR changes
Execution/src/VulkanDevice.cpp, plus one line incore/libs/prx/libSceAgcDriver/CMakeLists.txtthat definesVK_ENABLE_BETA_EXTENSIONSfor that file only.VkPhysicalDevicePortabilitySubsetFeaturesKHRand itsVkStructureTypevalue are only declared under that define, the same way #10920 enables it for its test files:libvulkan.1.dylib. Windows and Linux keepvulkan-1.dllandlibvulkan.so.1.VK_KHR_portability_enumerationand setsVK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, with or without a window. The extension count and names are now set after the window block, so a windowless instance passes its list too (nullptrwhen it is empty).VK_KHR_portability_subsetmust enable it. When the device advertises it, the driver enables it, queriesVkPhysicalDevicePortabilitySubsetFeaturesKHRwithvkGetPhysicalDeviceFeatures2and chains the reported values intoVkDeviceCreateInfo. Without the chained struct, every subset feature counts as off, even the ones MoltenVK supports. Devices that do not advertise the subset, including every Linux and Windows driver I know of, take the same path as before.imellag reported on #10540 that booting titles on macOS from
mainneeds a localVulkanDevice.cpppatch that loadslibvulkan.1.dyliband enables portability enumeration, and that no open PR covers it: #10540 (comment) . This PR is that patch on its own.Prior work and credit:
62917206d9("feat(macos): relink and run titles on macOS (x86-64 under Rosetta)", 2026-10-05), and then in20ee39de9a("feat(agc): create the Vulkan device on MoltenVK", 2026-10-12) in the macOS series (ci/macos-series-2). Both also enable the subset extension, but without chaining its features. The loader and enumeration hunks here are ported from20ee39de9aand credited with aCo-authored-by:trailer. mugurc has not opened a PR for that commit. Both commits are carried in the closed feat: macOS on Apple Silicon host support (Rosetta 2 and MoltenVK) #7332.VkPhysicalDevicePortabilitySubsetFeaturesKHRchained intoVkDeviceCreateInfo. Without it, the validation layer reportsVUID-VkSamplerCreateInfo-samplerMipLodBias-04467. He offered mugurc a follow-up that does this: fix(agc): build the frame recorder and the resident heap mirror test on macOS #10540 (comment) . The features part here follows that explanation. His follow-up was never published, so no code was taken from it.b949b38295("feat(aot): run source-built graphics on native Apple ARM64", 2026-10-12), with the subset enabled without its features, inside a 100-commit AOT PR. It conflicts with this branch at these lines.840b4e7b50("feat(macos): render through MoltenVK", 2026-10-16). On macOS it tries several loader names and anANYPS5_VULKAN_LIBRARYoverride, and it requests enumeration only when the instance lists it. It enables the subset without its features.libvulkan.1.dyliband requests enumeration in8d9b031ccb("feat(agc): find MoltenVK through the macOS Vulkan loader", 2026-10-17). It does not enable the subset. None of the PRs it was split into (build: compile the shared libc headers, thread priority and three tests on macOS #10362, build: compile FileStream, error categories, thread priority and two tests on macOS #10419, build(agc): compile Lifecycle, GuestMemory and GuestBufferMemory on macOS #11447 and the othersplit/macos-*branches) touchesVulkanDevice.cpp.245f177de7(2026-10-18).Tested
Apple M1 Pro, macOS 27.0.1, x86_64 Release build under Rosetta 2, MoltenVK 1.4.2 from the LunarG Vulkan SDK 1.4.363.
mainalone does not build on macOS, so the tree is mugurc's macOS series (ci/macos-series-2, 27e9689) merged withmainat 2742004, plus local build fixes for that merge (theFrameRecorder.cppandResidentHeapMirror.cppchanges from #10540, theStandardExceptions.cppcast from #10419, the__tls_get_addrtest excluded as in #10885) and #10898, all identical in the three variants. The PR is based onmain7cf8602; its hunks are identical in both trees. That tree already carries mugurc's version of this change, so it was built three times, differing only inVulkanDevice.cpp(and theVK_ENABLE_BETA_EXTENSIONSline for the third):main's code;All runs:
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation,ctest -E 'audio_in|voice' -V. No log haswas not found but was requested by env var VK_INSTANCE_LAYERS.agc_driver_image*(64 tests, 1 run)Validation Errorlines in that runimage_cache_bits,lazy_resolved_abi,native_multisample_depth), 3 runsVulkan loader: Failed loading libvulkan.so.1: dlopen(libvulkan.so.1, ...) (no such file).seriesandwithfail the same 7agc_driver_image*tests, all failures this change does not touch and other open PRs address:image_cache_bitsandimage_texel_status(fix(shader): order an image store before a later image atomic on MoltenVK #10652),image_srgb_sample_copyand..._forced(fix(agc): keep sRGB storage images in their UNORM twin on every driver #10859),image_table_reuseand..._draw_pipeline(test(agc): expect no kept image table writes for a set from the shared pool chain #10651), andimage_plane_bias_on_single_level_volume. In the focused set,lazy_resolved_abifails in both because its child process losesDYLD_FALLBACK_LIBRARY_PATH(fixed by test(agc): spawn the lazy resolved ABI reference child without a shell #10650), andimage_cache_bitsis the fix(shader): order an image store before a later image atomic on MoltenVK #10652 failure.series→with:VUID-VkImageViewCreateInfo-imageViewFormatReinterpretation-0446650 → 0,VUID-VkImageViewCreateInfo-imageViewFormatSwizzle-0446541 → 0,VUID-VkImageCreateInfo-imageView2DOn3DImage-044591 → 0. The remaining 22 are the same in both: 13VUID-vkCreateDescriptorSetLayout-support-09582and 9VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251. With the features chained, the validation layer checks against what MoltenVK reports instead of treating every subset feature as off. No VUID appears inwiththat is not inseries. Againstmain's code (without, 0Validation Errorlines) the 22 are new only because those tests now reach a device at all:withoutstops before any Vulkan call. The two skips areagc_driver_image_atomics64andagc_driver_image_sample_reduction, in bothseriesandwith.Known gap, not changed here: MoltenVK reports
pointPolygonsas false, andState.cppcan still requestVK_POLYGON_MODE_POINT(Pipeline.cppchecks onlyfillModeNonSolidandmaintenance5). Before this PR the driver could not create a device on macOS at all; a check onpointPolygonsor a debt entry belongs in a follow-up.Not tested on Linux or Windows; there the loader name and instance flags are unchanged, and a device that does not advertise
VK_KHR_portability_subsetgets no new extension or struct.uv run tools/check_conventions.py --base origin/mainpasses.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)The first box: #5021 and #7201 also change these lines, but as parts of an AOT compiler and a whole macOS port. No open PR makes this change on its own.
🤖 Generated with Claude Code