Skip to content

feat(agc): run registered merged hull programs (binary type 3) - #6679

Open
SleglJan wants to merge 1 commit into
boykopovar:mainfrom
SleglJan:pr/merged-hull
Open

SleglJan wants to merge 1 commit into
boykopovar:mainfrom
SleglJan:pr/merged-hull

Conversation

@SleglJan

@SleglJan SleglJan commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What

PPSA11386 (007 First Light) registers its tessellation hull programs as type 3: one binary with the local and the hull part, addressed through SPI_SHADER_PGM_LO_LS (SH 0x148), with no SPI_SHADER_PGM_LO_HS. The local part runs on the lanes below s3[7:0] and writes LDS, an s_barrier follows, and the hull part runs on the lanes below s3[15:8] and may store the registers the local part filled. main skips type 3 at registration (#1893) and its draw decode asks 0x148 for a type-5 local half, so the title stops in its level load:

registered program refers to an incompatible shader binary type

#3444 handles a header fused at runtime that selects a registered back half; a registered type-3 binary has no back half to select.

Changes:

  • Draw decode: a registered type-3 program at 0x148 gets both the local and the hull role, and the tessellation configuration is marked mergedHull. The hull user-data address (SH 0x102/0x103) is optional for it: s[0:1] take it, without the range check, when the draw sets it and are zero otherwise (the separate hull half keeps requiring and checking it). Type 3 is prepared with its stage group like type 5 and takes its float mode from RSRC1_HS.
  • Local stage: only passes gl_VertexIndex and gl_InstanceIndex in a 16-byte record per input control point.
  • Hull stage: runs the whole program, one invocation per output control point. v2 and v5 come from the record of control point min(gl_InvocationID, inputs - 1), v3 is the relative vertex id, and the LDS becomes a per-control-point output array (ControlShared): a control point writes its own record and reads any record of its patch after the barrier, with the stride taken from the code as for the local stride. Registers live across the barrier stay in the invocation.
  • The hull stage of a merged program runs at one lane per invocation on every device (HostSubgroupSize 1, as vertex programs do without vertex subgroups). Its lanes are gl_InvocationID, not host subgroup invocations, and main's hull lowering already turns every lane-dependent value into a per-invocation one (lane id, own-lane bits) and refuses other lane masks. In the test's merged program the s_cbranch_execz around the local part is the only wave-level operation left: with the device's subgroup it took a subgroup ballot (GroupNonUniform, GroupNonUniformBallot), which lavapipe rejects in the tessellation control stage (subgroup capability 61 is unsupported for shader stage 2). With one lane per invocation the branch tests the invocation's own lane and the module declares no subgroup capability, on lavapipe and on hardware alike.
  • The lowering refuses: more input than output control points; LDS writes outside the own record and reads outside the patch's records; an s_barrier that some invocations do not reach or that sits in a loop; reads or writes of another lane's register (v_readlane_b32, v_writelane_b32, DPP, ds_swizzle_b32, ds_permute_b32, ds_bpermute_b32, v_permlane16_b32), which one lane per invocation does not hold; outputs beyond the device's tessellation control limits; fetch subroutines.
  • Both stages refer to one binary, so a draw lists each code and header region once (ProgramMemory, used by the draw and by PrepareGraphicsStages); a request's memory regions must not overlap (RequestMemoryView memory regions overlap otherwise).
  • A CPU-path indirect draw writes its record words (base vertex, start instance, draw index) into every program whose user data holds the register (UserDataWords). The local and hull stages both hold SH 0x10c onwards; main wrote only the first, the local stage, which of a merged program only writes the vertex record. Separate hull halves now get the words in both halves too, as both read the same registers.
  • mergedHull is part of the recompile cache key of the local and hull stages, the draw decode comparison and key, and the request serialization: version 36, a byte at the end of the tessellation configuration.
  • A hull program declares gl_InvocationID when it writes a per-control-point output (ControlOutput, ControlShared), not only when it reads its lane id: those writes are indexed by it.
  • PrepareGraphicsStages takes its memory from ProgramMemory too, so it now leaves out empty regions, as the draw already did.

The Merged hull programs entry in docs/dev/debt/shader.md records where this differs from the console: the same control point of the same patch per hull lane, the register layout taken from the separate halves (not measured on hardware), the one-lane wave-mask branch (an invocation whose own lane fails skips the scalar instructions the console runs for the wave) and v_readfirstlane_b32 (the invocation's own value), runtime buffer loads for the vertex fetches, and the optional user-data address.

Overlap (trial merges with git merge-tree against this branch and against main):

Tested

  • Rebased onto main 676d423. feat(agc): remap a viewport depth range the device cannot express into the vertex shader #4650 took request version 35 there, so this change writes 36 and reads mergedHull only from 36. Git merged the read at 35 without a conflict, and the tests catch that.
    • verifyMergedHullConfiguration finds the flag 50 bytes from the end, because feat(agc): remap a viewport depth range the device cannot express into the vertex shader #4650's depth-remap fields follow with a vertex context. It reads version 30, 31, 32, 34 and 35 requests as not merged.
    • The serializer replay test replays main's version 35 format.
    • Earlier resolutions, still in: milescoviello's rebase onto version 34 (1254a68); with perf(agc): cut per-draw heap allocations #6312, an indirect record's words go into writablePrograms; AppendProgramMemory fills the vector main reserves.
    • On the Linux build node below, request_serializer, agc_shader_memory, agc_driver_tessellation, agc_tessellation_factor_ring, agc_driver_prepared_graphics, agc_driver_prepared_graphics_prebuild_unset, agc_pipeline_journal, agc_driver_pipeline_journal and guest_requested_exit pass.
    • ctest -R 'agc|shader|recompiler|request|tess': this change 753 of 772 pass, and so does main 676d423 built the same way. Both fail the same 19: shader_cache_runtime_sources, plus the 18 listed below for 324e0e4. The container does not permit userfaultfd, and 15 of those 18 report guest memory that is not write-watched or needs to be.
  • On main 324e0e4, the previous head (4e7fa2b, version 35): 744 of 762 pass, the same as main 324e0e4. Both fail the same 18: agc_driver_bc_block_copy, agc_driver_depth_compare_copy, agc_driver_guest_memory_lifetime_converted, agc_driver_image_srgb_sample_copy, agc_driver_image_srgb_sample_copy_forced, agc_driver_image_table_vouched_lookups, agc_driver_image_table_vouch_queued_draws, agc_driver_msaa_dcc_clear_2, agc_driver_msaa_dcc_clear_4, agc_driver_msaa_dcc_clear_8, agc_driver_native_depth_bda_clear, agc_driver_native_depth_clear_refusals, agc_driver_native_depth_clears, agc_driver_native_depth_retirement, agc_driver_native_multisample_depth, agc_driver_staged_clear_sampled_read, agc_driver_storage_write_back_overhang, agc_storage_kept_unit_settle.
  • Linux build node: Arch Linux container on a 16-thread Xeon E5-2640 v3, GCC 16.2.1, Release with BUILD_TESTING=ON, lavapipe (Mesa 26.2.4, LLVM 23.1.1). ctest -R 'agc|shader|recompiler|request' on main 92e5041, with the earlier version-31 head:
    • This change: 591 of 601 pass.
    • main: 591 of 601 pass.
    • Both fail the same ten with the same messages: agc_storage_kept_unit_settle, agc_pending_key_stores, agc_driver_bc_block_copy, agc_driver_depth_compare_copy, agc_driver_native_multisample_depth, agc_driver_staged_clear_sampled_read, agc_driver_storage_write_back_overhang, agc_driver_native_depth_retirement, agc_driver_native_depth_clears, agc_driver_native_depth_clear_refusals (most need write watching, which the container does not have).
  • New and extended tests:
    • agc_driver_tessellation: two merged-hull draws (MergedHullCode, and MergedHullRegisters, whose hull part stores a register its local part filled) checked like the separate-hull draws (RequirePatches); refusals for more input than output control points, an LDS write into another control point's record, an LDS read past the patch's records, a divergent s_barrier and a v_readlane_b32 of lane 0 (which the one-lane emitter would otherwise compile); the merged hull stage compiled with the device target declares no GroupNonUniform capability; registration and graphics ABI resolution of a type-3 stage group (twice, the second from the prepared ABI).
    • agc_driver_prepared_graphics: the decode of a merged hull draw at ABI resolution and at draw time (roles, entry points, user SGPR layout, user-data address set, unset, zero, and set to an unmapped address that the program does not need), its program memory listed once and accepted by RequestMemoryView (and used as the stages' request memory), the user-data words of SH 0x10e in both stages, preparation as two separate stages that the draw reuses, separate halves still decoded as before and still requiring the address; a merged program's vertex tables read from its user-data slots behind the eight hidden words.
    • agc_shader_memory and request_serializer: the mergedHull byte round-trips; version 30, 31 and 32 requests (32 is main's current format; with and without tessellation) read as not merged, keep their fields and re-serialize to the version 33 bytes; the version 33 fixtures; version 34 is rejected. With the field read from version 32 on, as in the previous head, both fail with RequestSerializer: truncated data.
  • Rebased onto main 1b1f848 (after feat(recompiler): run single-wave wave64 compute programs at one lane per invocation on 32-lane hosts #5405 took version 32), the same node: request_serializer, agc_shader_memory, agc_driver_tessellation, agc_tessellation_factor_ring, the four agc_driver_prepared_graphics tests and guest_requested_exit pass (9 of 9). ctest -R 'agc|shader|recompiler|request': this change 617 of 626 pass, main 1b1f848 built the same way 617 of 626; both fail the same nine (agc_driver_bc_block_copy, agc_driver_depth_compare_copy, agc_driver_native_depth_clear_refusals, agc_driver_native_depth_clears, agc_driver_native_depth_retirement, agc_driver_native_multisample_depth, agc_driver_staged_clear_sampled_read, agc_driver_storage_write_back_overhang, agc_storage_kept_unit_settle).
  • On main eb901bc with the previous head 36529f1, the same node: request_serializer, agc_shader_memory, agc_driver_tessellation, agc_tessellation_factor_ring, the four agc_driver_prepared_graphics tests and guest_requested_exit pass (9 of 9).
  • On the same node and base (main 92e5041, earlier head): main with only the tests that compile there (the type-3 registration case in agc_driver_tessellation, the serializer fixtures): agc_driver_tessellation fails with registered program refers to an incompatible shader binary type, agc_shader_memory with new requests did not use serialization version 31 (33 now), and request_serializer aborts on its version fixture. The other new cases use the new field and functions; with the change and one part reverted at a time, the check written for that part fails: the draw decode not detecting type 3 (agc_driver_prepared_graphics and agc_driver_tessellation: registered program refers to an incompatible shader binary type); no mergedHull byte in the serialization (a merged hull configuration was lost in serialization, request_serializer aborts); the lowering not treating the program as merged (unsupported LDS access in a tessellation stage); the hull stage at the device subgroup size (the hull stage of a merged hull program declares subgroup operations ...); no cross-lane refusal (a tessellation program was accepted although another lane's register: a v_readlane_b32 of lane 0 compiles silently); the program memory without the dedupe (a merged hull draw's program memory does not list each code and header region once); UserDataWords stopping at the first program (an indirect draw's user-data register does not reach both stages of a merged hull program); the hull user-data address required (merged shader user-data address is null); the optional address range-checked (guest memory is not readable at 0x10); the read-past-patch check removed (a tessellation program was accepted although reads LDS outside its patch's control point records).
  • On the same node and base, the hull stage of MergedHullCode without the one-lane layout declared capabilities 61 and 64 with one OpGroupNonUniform* instruction; with its s_cbranch_execz replaced by s_nop it declared neither, so the branch is the only source.
  • Not covered by a test: the Draw.cpp indirect record loop (only UserDataWords is), the draw key's mergedHull, and the refusals for outputs beyond the device limits, a barrier in a loop and fetch subroutines.
  • agc_driver_tessellation takes under 1 s on the node.
  • tools/check_conventions.py --base upstream/main and git diff --check pass.
  • With the previous head 36529f1 on main eb901bc: NVIDIA GeForce RTX 3080 (615.78.08), CachyOS (Linux 7.2.10), GCC 16.2.1, Release with BUILD_TESTING=ON, ctest -R 'agc|shader|recompiler|pm4|draw|position|tess|hull|request':
    • This change: 625 of 627 pass; agc_driver_stencil_ref_export skips and agc_driver_store_over_untracked fails.
    • main built the same way: the same 625 pass, the same skip and the same failure, on the same test list.
    • agc_driver_store_over_untracked fails on both with the result did not reach a block the CPU left alone; Windows: StoreOverUntracked fails at "the first result was not stored" #6347 tracks the same test failing on Windows.
  • PPSA11386 v01.018.000, RTX 3080, in a bubblewrap sandbox, on my bring-up stack: main 4186f06 plus open PRs, unpublished local fixes the title needs, local logging and scripted input, and the title's two feedback-wait limits widened in its executable as described in 007 First Light (PPSA11386): the terrain crash after Resume is a stale read of a GPU feedback buffer past the title's own wait limits #6172 (local only). These runs used the earlier version-31 head; the version change does not touch the draw path.
    • With this change the level load passes and the title reaches gameplay's first tutorial prompt.
    • An earlier main-based stack without a merged-hull change stopped in the level load after present 1188 with registered program refers to an incompatible shader binary type.
    • With this change reverted and feat(agc): draw tessellation followed by an NGG geometry stage #6612 (head 89aa76a) merged instead, which brings main up to 5d9dcc4, the title stops in the level load after present 1195 with merged shader user-data address is null: a merged hull draw there leaves the hull user-data address null.

Checklist

  • Based on current main; feat(agc): draw tessellation followed by an NGG geometry stage #6612 builds on this change
  • 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
  • Unblocks: PPSA11386 007 First Light (PPSA11386) #5714
  • GPUs tested: lavapipe (Mesa 26.2.4, LLVM 23.1.1), Arch Linux container; NVIDIA GeForce RTX 3080, 615.78.08, CachyOS
  • AI-assisted: yes (Claude Code)

🤖 Generated with Claude Code

@milescoviello

Copy link
Copy Markdown
Contributor

A note on overlap: #6612 (Crimson Desert, PPSA25286, opened 10-15) also takes a registered type-3 program at 0x148 with nothing at 0x108, in the same lines of DrawDecode.cpp (L96-101) and in TessellationLowering.cpp. Whichever lands second needs a rebase.

The two handle it differently. #6612 compiles the program twice: once as the local role, with no hull threads in s3, and once as the hull role, with no local vertices. The values then go through the existing local-to-hull LDS path. That split can't carry VGPRs from the local part into the hull part across the barrier. Your MergedHullRegisters case covers that, and you say 007 First Light needs it, so your approach looks like the more general one.

Crimson Desert's merged hull draw has VGT_LS_HS_CONFIG 0x1043f (63 patches, 4 input and 4 output control points), so your refusal for more input than output control points wouldn't apply to it. Its halves pass 16-bit values through LDS, and #6612 adds 16-bit LDS writes in local programs and reads in hull programs for that. I haven't run it on your path. The title still needs #6612's tessellation-to-geometry path either way, so I can't check it with this PR alone.

If this lands first, I'll move #6612 onto your merged hull, drop its type-3 split, and check that Crimson Desert gets as far as before.

AI-assisted: yes

@github-actions

github-actions Bot commented Oct 16, 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 6503 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L213-214, L249, L252-253, L274, L397-402, L411, L415-416, L430, L432
PR 6657 core/shader/recompiler/Optimization/src/TessellationLowering.cpp L945-946, L948
PR 6801 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L213-214, L249, L252-253, L274, L397-402, L411, L415-416, L430, L432
PR 6959 docs/dev/debt/shader.md L161
PR 7332 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L4734, L4852, L5086
core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L213-214, L249, L252-253, L274, L397-402, L411, L415-416, L430, L432
docs/dev/debt/shader.md L161
PR 7410 core/shader/recompiler/tests/RequestSerializerTests.cpp L210, L249, L274, L397-400, L411, L430, L432
PR 7446 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp L522-524
PR 7623 docs/dev/debt/shader.md L161
PR 7691 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp L13, L46-47

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 1341 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 3247 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 4072 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Translation/src/InstructionTranslator.cpp
PR 5021 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
docs/dev/debt/shader.md
PR 5115 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
PR 5371 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
docs/dev/debt/shader.md
PR 5404 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 5426 docs/dev/debt/shader.md
PR 5441 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 5500 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/IntermediateRepresentation/include/IntermediateRepresentation/IrMetadata/StageIO.hpp
core/shader/recompiler/Optimization/src/ShaderInfoCollector.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/debt/shader.md
PR 5609 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 5656 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/shader/recompiler/Recompiler.hpp
PR 5941 docs/dev/debt/shader.md
PR 6009 docs/dev/debt/shader.md
PR 6177 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/shader/recompiler/Recompiler.hpp
PR 6235 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Optimization/include/Optimization/ShaderStageInputInfo.hpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/Translation/src/ShaderInputInfoBuilder.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/debt/shader.md
PR 6280 docs/dev/debt/shader.md
PR 6412 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/shader.md
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
docs/dev/debt/shader.md
PR 6535 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
PR 6539 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 6611 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Translation/src/ShaderInputInfoBuilder.cpp
PR 6639 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Optimization/include/Optimization/ShaderStageInputInfo.hpp
core/shader/recompiler/Optimization/src/ShaderInfoCollector.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/Translation/src/ShaderInputInfoBuilder.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6645 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 6683 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Optimization/include/Optimization/ShaderStageInputInfo.hpp
core/shader/recompiler/Optimization/src/ShaderInfoCollector.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/Translation/src/ShaderInputInfoBuilder.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6762 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Optimization/include/Optimization/ShaderStageInputInfo.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/Translation/src/ShaderInputInfoBuilder.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 6867 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
PR 6879 core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 6924 core/shader/recompiler/Recompiler.cpp
docs/dev/debt/shader.md
PR 6931 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 6941 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6946 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 6947 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/IntermediateRepresentation/include/IntermediateRepresentation/IrMetadata/ProgramMetadata.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 6966 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
PR 6970 core/shader/recompiler/Recompiler.hpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawDecode.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawRegisterKey.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/Translation/src/InstructionTranslator.cpp
docs/dev/debt/shader.md
PR 7085 docs/dev/debt/shader.md
PR 7201 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/IntermediateRepresentation/include/IntermediateRepresentation/IrMetadata/ProgramMetadata.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7223 core/shader/recompiler/Recompiler.cpp
docs/dev/debt/shader.md
PR 7369 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
PR 7381 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
docs/dev/debt/shader.md
PR 7388 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
docs/dev/debt/shader.md
PR 7390 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7392 core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
docs/dev/debt/shader.md
PR 7395 core/shader/recompiler/Recompiler.cpp
docs/dev/debt/shader.md
PR 7429 docs/dev/debt/shader.md
PR 7484 core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
docs/dev/debt/shader.md
PR 7622 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Draw/DrawCache.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/Draw.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawLookup.cpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Shaders/ShaderRegistry.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/IntermediateRepresentation/include/IntermediateRepresentation/IrMetadata/ProgramMetadata.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
docs/dev/debt/shader.md
PR 7689 core/shader/recompiler/Recompiler.hpp

milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 16, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added shader core/shader docs agc libSceAgc* labels Oct 16, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 16, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milescoviello

Copy link
Copy Markdown
Contributor

A heads-up on the request version: #5884 merged with version 31 for MeshConfiguration::outputPrimitiveSize, so main now writes 31 without mergedHull. This PR still merges textually, but it reads mergedHull under version >= 31. A version 31 request from main with a tessellation configuration would then have the byte after its tessellation fields read as mergedHull. I hit it while rebasing #6612 on top of this PR. #6639 has moved its point fields to 32, so whichever of the two lands second would take 33.

AI-assisted: yes

milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 16, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SleglJan

Copy link
Copy Markdown
Contributor Author

Thanks @milescoviello, good catch: after #5884 this PR still merged cleanly with main, since both made the same 30 to 31 edits. This PR now writes 32 and reads mergedHull only from 32 on, and a new test checks that main's version 31 requests, with and without tessellation, read as not merged and keep their fields. That test fails with the old >= 31 gate. #6639 and the others that also take 32 are listed under Overlap. #6612's first commit is the old head 8f93aa0, so it needs a restack onto the new one.

AI-assisted: yes (Claude Code)

milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 16, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Scramblrrrr

Copy link
Copy Markdown
Contributor

Fresh Windows11/RTX5070Ti617.42 cross-test on current integrationc6bd8b539047dacb9ddc95b41c45e69b78d39f19 (main d9b696d + shared-table/007 boot stack + canonical #6679 36529f1 and #6364 9fffcea; #4339 excluded):30/30 selected native controls PASS15.94s, no skips. Includes storage_flush_ordering, storage_write_back_overhang, depth_storage_dispatch, tessellation, prepared_graphics and its unset/0/1 prebuild cases, serializer, shader memory/disk cache, shared tables and draw-cache checks.

6364 negative control: retained the new fixture and other integration code, removed only FlushPending's PendingWriterSerial/Reap/Sync/FinishUpTo wait block, rebuilt the unpatched driver and ran the fixture. It FAILS in0.37s with storage flush ordering, writer in flight: the pending image's store put its older texels over a newer address-based store. Restored the exact committed Texture.cpp, rebuilt patched modules, and30/30PASS14.53s. Source/conventions clean. This is a wait-only negative in our integration, not a standalone main red/green.

Public branch https://github.com/Scramblrrrr/AnyPS5/tree/codex/first-light-level-two-lane . Matched driver/Agc/VideoOut now staged together, same2GiBfree/28GiBprivate guard. Starting007; title level/cinematic outcome still pending, so the native pass is not claimed as playable gameplay. AI-assisted: Codex; title data local.

@SleglJan

Copy link
Copy Markdown
Contributor Author

@milescoviello #6679 is rebased onto main 1b1f848. #5405 merged with request version 32 (target.spannedWaves), so mergedHull now reads from version 33. The new head is 01947dd. Against 36529f1 it changes only the request version (the writer, the reader limit and the mergedHull gate) and the serializer tests; the rest of the change, the debt entry included, is the same. #6612's first commit, 734a8f5, is 36529f1 rebased onto main 4524944, so it needs another restack, and its first commit should read mergedHull from 33. #6639 and #6801 also write 33 now; whichever lands first keeps it.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 16, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 17, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 17, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 18, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milescoviello

Copy link
Copy Markdown
Contributor

@SleglJan following up, sorry for the late answer: #6612 now carries this PR's current head unchanged. git range-diff shows 53c0af2 identical to #6612's first commit (52a658c), restacked on main 8625038 today. The tessellation tests pass there 2 runs of 2.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added unblocks title Names a title ID on the Unblocks line needs rebase Conflicts with main, rebase needed labels Oct 18, 2026
@milescoviello

Copy link
Copy Markdown
Contributor

@SleglJan a heads-up: this PR conflicts with main again. main is now at request serialization version 34. The pixel stage's iteratesSamples, positionLocation and sampleLocations read from 34, and there's no use of 33. So mergedHull needs version 35.

I rebased your commit onto main 017f215 for #6612, which stacks on it, and pushed it as offer/6679-main-017f2151 (1254a68, you as author) in case it saves you time. It still merges with main b5be95f. Against your head it changes only:

  • the request version: the writer writes 35, the reader accepts up to 35, and mergedHull reads from 35;
  • the tests' version expectations: NVNQQSMAAAA= for 35, NVNQQSQAAAA= (36) as unsupported, the main34 replay in RequestSerializerTests.cpp, and version 34 added to the old-version loop in verifyMergedHullConfiguration. Main's version 34 fields are pixel-only, so the tessellation-control request there doesn't contain them;
  • "version 33" in the commit message, now 35.

The conflicts were all version numbers: the writer, the reader limit, and the tests' expected bytes. I'm running the serializer and tessellation tests on it now and will post the results here. I'll restack #6612 on whatever head you choose.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor

@SleglJan results for offer/6679-main-017f2151 (1254a68) on Linux, RTX 4070 Ti: request_serializer, agc_shader_memory (with verifyMergedHullConfiguration, now also over version 34), agc_driver_tessellation, agc_tessellation_factor_ring, agc_pipeline_journal and agc_driver_pipeline_journal all pass.

AI-assisted: yes (Claude Code)

@SleglJan

Copy link
Copy Markdown
Contributor Author

@milescoviello thanks, that saved me the work. I took your 1254a68 as is. Since then main moved to 324e0e4, and #6312 made Driver::draw read programs through a const alias, which conflicted in Draw.cpp. The head is now 4e7fa2b:

  • an indirect record's words go into writablePrograms;
  • ProgramMemory became AppendProgramMemory, which fills the vector main reserves, so perf(agc): cut per-draw heap allocations #6312's single allocation for the draw's memory regions stays.

The request version is 35, as in your branch. Tests are in the description: on the Linux node, the serializer, tessellation, prepared-graphics and journal tests pass, and the agc|shader|recompiler|request|tess set fails the same 18 tests as main built the same way. #6612 conflicts today: its first commit is the previous head, so stacking it means swapping that commit for 4e7fa2b and rebasing.

AI-assisted: yes (Claude Code)

@milescoviello

Copy link
Copy Markdown
Contributor

@SleglJan thanks. I've restacked #6612 on 4e7fa2b locally: its three commits now sit on your head instead of the previous one. Two conflicts, both from main:

The result merges cleanly with main 40393b0. I'm building it now and will run the AGC, shader, request and tessellation set on 4e7fa2b and on the restack before I push.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 19, 2026
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from boykopovar#6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@milescoviello

Copy link
Copy Markdown
Contributor

@SleglJan #6612 is pushed on top of 4e7fa2b (head 9825024). On the Linux node (RTX 4070 Ti), the AGC, shader, request, journal and tessellation set passes 609 of 610 with it, against 608 of 609 on 4e7fa2b alone. The one failure on both is agc_driver_bda_device, the fence timeout from #7584. The tessellation, serializer and journal tests pass 3 of 3.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
A registered type-3 hull program holds the local and the hull part of a
tessellation draw in one binary, addressed through SPI_SHADER_PGM_LO_LS
(SH 0x148) with no SPI_SHADER_PGM_LO_HS: the local part runs on the lanes
below s3[7:0] and writes LDS, an s_barrier follows, and the hull part runs
on the lanes below s3[15:8] and may store the registers the local part
filled. The draw decode asked 0x148 for a type-5 local half, and
PPSA11386 (007 First Light) stopped in its level load with "registered
program refers to an incompatible shader binary type".

The draw decode now gives a registered type-3 program both the local and
the hull role and marks the tessellation configuration mergedHull. The
local stage only passes gl_VertexIndex and gl_InstanceIndex in a 16-byte
record. The hull stage runs the whole program, one invocation per output
control point: v2 and v5 come from the record of control point
min(gl_InvocationID, inputs - 1), v3 is the relative vertex id, and the
LDS becomes a per-control-point output array that a control point writes
in its own record and reads in any record of its patch after the barrier.
Registers live across the barrier stay in the invocation.

The hull stage of a merged program runs at one lane per invocation on
every device (HostSubgroupSize 1). Its lanes are gl_InvocationID, not host
subgroup invocations, so the s_cbranch_execz around the local part tests
the invocation's own lane. With the device's subgroup it took a subgroup
ballot, and lavapipe, whose subgroup stages lack the tessellation control
stage, rejected the draw ("subgroup capability 61 is unsupported for
shader stage 2").

The lowering refuses more input than output control points, LDS writes
outside the own record, reads outside the patch's records, barriers that
some invocations do not reach or that sit in a loop, reads or writes of
another lane's register, outputs beyond the device limits, and fetch
subroutines. Type 3 is prepared with its stage group like type 5 and
takes its float mode from RSRC1_HS. The hull user-data address (SH
0x102/0x103) is optional for a merged program: s[0:1] take it, unchecked,
when the draw sets it and are zero otherwise.

Both stages refer to one binary, so a draw lists each code and header
region once (AppendProgramMemory); a request's memory regions must not
overlap. An indirect draw's record words go into every program whose user
data holds the register, so the hull stage of a merged program reads
them too.

mergedHull is part of the recompile cache key, the draw decode comparison
and the request serialization (version 36).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@SleglJan

Copy link
Copy Markdown
Contributor Author

@milescoviello a heads-up for #6612: #4650 merged and took request version 35, so this PR moved again. The head is now d919e63 on main 676d423, and it writes 36 and reads mergedHull only from 36. On the rebase, git merged this PR's version >= 35u read without a conflict. #4650's version 35 requests have no flag, so on those that read takes the next field's first byte as mergedHull and shifts every later read by one. The serializer tests catch it as truncated data. #6612 carries the 35 read from 4e7fa2b, so its restack needs this head.

The test side:

#6801 and #7410 also write 36, so after the first of the three lands, the next one takes 37.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 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* docs shader core/shader unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants