Skip to content

fix(agc): load the Vulkan loader and list MoltenVK on macOS - #11554

Open
maximilianfv wants to merge 1 commit into
boykopovar:mainfrom
maximilianfv:fix/agc-moltenvk-loader-portability
Open

maximilianfv wants to merge 1 commit into
boykopovar:mainfrom
maximilianfv:fix/agc-moltenvk-loader-portability

Conversation

@maximilianfv

Copy link
Copy Markdown
Contributor

What

On macOS the AGC driver cannot create a Vulkan device. VulkanDevice loads libvulkan.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 with VK_KHR_portability_enumeration and VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR.

This PR changes Execution/src/VulkanDevice.cpp, plus one line in core/libs/prx/libSceAgcDriver/CMakeLists.txt that defines VK_ENABLE_BETA_EXTENSIONS for that file only. VkPhysicalDevicePortabilitySubsetFeaturesKHR and its VkStructureType value are only declared under that define, the same way #10920 enables it for its test files:

  • On macOS it loads libvulkan.1.dylib. Windows and Linux keep vulkan-1.dll and libvulkan.so.1.
  • On macOS every instance requests VK_KHR_portability_enumeration and sets VK_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 (nullptr when it is empty).
  • A device that advertises VK_KHR_portability_subset must enable it. When the device advertises it, the driver enables it, queries VkPhysicalDevicePortabilitySubsetFeaturesKHR with vkGetPhysicalDeviceFeatures2 and chains the reported values into VkDeviceCreateInfo. 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 main needs a local VulkanDevice.cpp patch that loads libvulkan.1.dylib and enables portability enumeration, and that no open PR covers it: #10540 (comment) . This PR is that patch on its own.

Prior work and credit:

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. main alone does not build on macOS, so the tree is mugurc's macOS series (ci/macos-series-2, 27e9689) merged with main at 2742004, plus local build fixes for that merge (the FrameRecorder.cpp and ResidentHeapMirror.cpp changes from #10540, the StandardExceptions.cpp cast from #10419, the __tls_get_addr test excluded as in #10885) and #10898, all identical in the three variants. The PR is based on main 7cf8602; 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 in VulkanDevice.cpp (and the VK_ENABLE_BETA_EXTENSIONS line for the third):

  • without: mugurc's three hunks removed, i.e. main's code;
  • series: mugurc's version (loader, enumeration, subset extension without its features);
  • with: this PR.

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 has was not found but was requested by env var VK_INSTANCE_LAYERS.

without series with
agc_driver_image* (64 tests, 1 run) 1 pass, 63 fail 55 pass, 2 skip, 7 fail 55 pass, 2 skip, 7 fail
Validation Error lines in that run 0 114 22
focused (image_cache_bits, lazy_resolved_abi, native_multisample_depth), 3 runs 0/3 each 1/3 each 1/3 each

Known gap, not changed here: MoltenVK reports pointPolygons as false, and State.cpp can still request VK_POLYGON_MODE_POINT (Pipeline.cpp checks only fillModeNonSolid and maintenance5). Before this PR the driver could not create a device on macOS at all; a check on pointPolygons or 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_subset gets no new extension or struct.

uv run tools/check_conventions.py --base origin/main passes.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: Apple M1 Pro, MoltenVK 1.4.2 (LunarG Vulkan SDK 1.4.363), macOS 27.0.1
  • AI-assisted: yes

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

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 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

github-actions Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 11638 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L1177-1178

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.

Pull request Shared files not compared
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 1896 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4449 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6804 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6960 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7449 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7922 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8004 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8542 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8874 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8939 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9248 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9356 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9387 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9431 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9432 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9489 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9533 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9633 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9672 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9673 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9674 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9675 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9676 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9700 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9717 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9742 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9748 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9749 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9790 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9842 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9852 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9891 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9892 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9893 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9895 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9897 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9898 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9969 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10000 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10043 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10064 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10069 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10193 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10233 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10333 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10435 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10442 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10489 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10498 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10678 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10757 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 10846 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10867 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11351 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11557 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11920 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp

@iamthehimansh

Copy link
Copy Markdown
Contributor

Tested on an Apple M2 Pro (macOS, x86_64 under Rosetta 2, Vulkan SDK 1.4.363.0 with MoltenVK 1.4.2), running agc_driver_image_table_reuse because it goes through VulkanDevice. The validation layer was on (VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, ANYPS5_REQUIRE_VULKAN=1).

VulkanDevice.cpp Runs Loader error Device ready GPU VUID lines
main 1 1 (libvulkan.so.1) 0 none 0
this PR (both VulkanDevice.cpp hunks, plus the VK_ENABLE_BETA_EXTENSIONS line) 3 0 3 Apple M2 Pro 0

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 VK_KHR_portability_subset produced no validation messages.

Test base: main at b27cc8416 with the other open macOS build PRs applied locally (#10552, #10898, #8311, #9738, plus local scaffolding so the AGC driver compiles on macOS). It is not pushed anywhere.

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)

@iamthehimansh

iamthehimansh commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

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 Validation Error lines:

VulkanDevice.cpp Runs Device ready Validation Error per run
main 1 0 (libvulkan.so.1 fails to load, so no instance) n/a
this PR 3 3 of 3, Apple M2 Pro 1: VUID-vkCreateDescriptorSetLayout-support-09582
my loader-only version (no VK_KHR_portability_subset) 2 2 of 2 2: the same 09582, plus VUID-VkDeviceCreateInfo-pProperties-04451

So enabling VK_KHR_portability_subset here removes the 04451 error rather than adding one. The remaining 09582 ("262341 total descriptors which is more than maxPerSetDescriptors (1212)") comes from the image-table test's own descriptor layout on MoltenVK, not from this PR.

AI-assisted: yes (Cana)

@Gonic0

Gonic0 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

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 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation.

Base: main 1be850b6e1 with the macOS PRs imellag listed in #7804, plus #10676 (Texture.cpp needs it with Apple's libc++) and a local list-restart change. The title is relinked with --macos --to-rosetta --macos-fixed-base 0x400000. Only VulkanDevice.cpp changes between the three variants. For this PR I applied the diff of 9138260572 alone, so its newer base doesn't come in.

VulkanDevice.cpp runs where it stops Validation Error lines
main 1 at start: Failed loading libvulkan.so.1 0 (no instance)
mugurc's 20ee39de9a 2 "device does not support mesh shaders" 26 in each
this PR 2 "device does not support mesh shaders" 0 in each
  • With mugurc's version, each run has the same 26: 10 imageViewFormatSwizzle-04465, 10 imageViewFormatReinterpretation-04466, 5 imageView2DOn3DImage-04459 and 1 samplerMipLodBias-04467. All four are portability-subset checks, and none appears with this PR.
  • With this PR the device opens on the Apple M5 Pro and the title runs until it needs mesh shaders, the same place as with mugurc's version. That stop is a separate gap that this PR doesn't touch.
  • VK_LOADER_DEBUG=layer on a run with this PR shows Insert instance layer "VK_LAYER_KHRONOS_validation", so the 0 isn't a missing layer.

AI-assisted: yes

@github-actions github-actions Bot added build agc libSceAgc* labels Oct 27, 2026
This was referenced Oct 27, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 27, 2026
This was referenced Oct 27, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants