Skip to content

fix(agc): keep each descriptor set slot in one of a split pipeline library pair - #7722

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
jotitadev:fix/agc-library-layout-null-sets
Oct 20, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
jotitadev:fix/agc-library-layout-null-sets

Conversation

@jotitadev

Copy link
Copy Markdown
Contributor

What

With graphics pipeline libraries, linking a draw's parts violates VUID-VkGraphicsPipelineCreateInfo-pLibraries-06681. The validation layer reports it on 111 of the 748 ^agc tests on main.

  • SplitsSets splits the layout into two independent sets for every pipeline with a fragment stage when the device has graphicsPipelineLibrary.
  • libraryKeys gives each part a mask of only the sets its own stages bind, and LinkPipelineFromLibraries leaves the other slots VK_NULL_HANDLE in that part's layout.
  • So a fragment shader that binds nothing in set 1, or a draw where no stage binds set 0, leaves that slot null in both the pre-rasterization and the fragment layouts, which the spec does not allow.
vkCreateGraphicsPipelines(): pCreateInfos[0] is linking libraries with pre-raster and fragment shader state. The descriptor set layout at index 1 in pSetLayouts from VkPipelineLayout 0x360000000036 in the fragment shader state is NULL. However, the descriptor set layout at the same index (1) in VkPipelineLayout 0x340000000034 in the pre-raster state is NULL too.

libraryKeys now gives a slot that neither stage binds to the part that owns it: set 0 goes to the pre-rasterization layout and set 1 to the fragment layout. The layout keys include the mask, so the cached parts follow. This path runs for any title on a device with pipeline libraries. #5925, #7334 and #7337 saw this error and put it down to an older layer, but it still shows with layer 1.4.341.

Tested

Intel i7-8700, Ubuntu 26.04, GCC 15.2, Release, on main 43797ca. I ran every ^agc test except display, flip and lds_atomics64 (748 tests), each under VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (layer 1.4.341) with ctest -V, two at a time.

main this change
lavapipe: tests with pLibraries-06681 97 0
RTX 3070: tests with pLibraries-06681 110 0
lavapipe: tests passing 748 / 748 748 / 748
RTX 3070: tests passing 747 / 748 747 / 748

The one failure on the RTX 3070 is agc_driver_bda_device (vkWaitForFences graphics: Vulkan result 2). It fails the same way on main with no layer, so it has nothing to do with this change. Apart from 06681, the layer reports the same messages before and after the change. Repro on main: VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ./build/tests/agc_driver_alpha_to_coverage_tests 2>&1 | grep -c pLibraries-06681 prints 20, and prints 0 with this change.

python3 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: NVIDIA GeForce RTX 3070, driver 595.99.02, Ubuntu 26.04; lavapipe (Mesa 26.0.3, LLVM 21.1.8), Ubuntu 26.04
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

…brary pair

With independent sets, a pipeline linked from a pre-rasterization library and a fragment shader library must not leave the same set slot VK_NULL_HANDLE in both libraries' layouts (VUID-VkGraphicsPipelineCreateInfo-pLibraries-06681). Every pipeline with a fragment stage is split when the device has graphics pipeline libraries, and each part's layout held only the sets its own stages bind, so a fragment shader that binds nothing in set 1, or a draw where no stage binds set 0, left that slot null in both parts. A slot neither stage binds now goes to the part that owns it: set 0 to the pre-rasterization layout, set 1 to the fragment layout.
@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

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 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6612 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6615 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6683 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6947 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7201 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7332 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp
PR 7888 core/libs/prx/libSceAgcDriver/Graphics/src/Pipeline.cpp

@savvaniss

Copy link
Copy Markdown
Contributor

AMD and Intel Windows data: the full CTest suite gives the same results with this PR as on main, on an AMD RX 9070 XT and an Intel UHD 770 with pipeline libraries on. On AMD one intermittent main failure showed up in the PR's run.

Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7, Release, every execution test built, ANYPS5_NO_SHADER_CACHE=1, CTest --parallel 4, one full run per GPU. Intel UHD Graphics 770 (8086:a780), driver 32.0.101.7088. AMD Radeon RX 9070 XT (1002:7550), driver 32.0.31041.1004, with VkCache emptied first. This head 879b9e65c merged into main 85029a00f. On AMD the three tests that turn pipeline libraries off (agc_driver_draw_cache_reuse_off, agc_driver_stencil_replay_no_gpl, agc_driver_layered_volume_vertex_no_gpl) are left out until #7828 merges, because on this driver they can hang the GPU.

Full suite UHD 770 RX 9070 XT
main 85029a00f 1674 of 1676 pass; agc_driver_image_table_vouched_lookups and agc_driver_sample_multisample_target fail 1673 of 1673 pass
This head the same 1674 pass and the same two fail, with the same messages 1672 of 1673 pass; agc_trimmed_import fails

agc_trimmed_import is intermittent on main on this card: after an unmap of 1440 KiB at the start of the import's first 2 MiB run the pages mapped again are served from the import that pinned the old ones. Earlier full runs of main 6b8228b2b failed it with this message. Run alone on this head, it failed 1 of 3 times. It doesn't touch pipeline layouts. The two Intel failures are on main too: #7766 for the vouched lookups test, and #6957 for the multisample target.

The agc_pipeline_library* tests pass on both GPUs. These runs had no validation layer, so they don't check pLibraries-06681. They show that the layout change runs on these two proprietary drivers without a failure that main doesn't have.

AI-assisted: yes (Claude Code)

@adriadam10 adriadam10 self-assigned this Oct 19, 2026
@adriadam10
adriadam10 merged commit 8a76c34 into boykopovar:main Oct 20, 2026
11 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the libraryKeys change: a set slot that neither stage binds now goes to the part that owns it (set 0 to the pre-rasterization layout, set 1 to the fragment layout), so no index is NULL in both layouts of a split pair; used slots are unchanged and the layout keys carry the mask, so the cached parts follow. Windows AMD/Intel data from @savvaniss matches main; merged.

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

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants