Skip to content

feat(agc): add opt-in bounded submission progress - #7307

Open
Zenodeon wants to merge 2 commits into
boykopovar:mainfrom
Zenodeon:agc-submit-progress-pr
Open

Zenodeon wants to merge 2 commits into
boykopovar:mainfrom
Zenodeon:agc-submit-progress-pr

Conversation

@Zenodeon

@Zenodeon Zenodeon commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

What

Add experimental, off-by-default APS5_SUBMIT_PROGRESS=1 pacing for eligible graphics-queue submissions. A guest that immediately polls a terminal GPU release can otherwise return from submit before its small batch is recorded, miss the release, and enter another sleep/poll cycle.

An internal per-submission ticket acknowledges the recorded prefix and its actual recorder timeline. The submitting call shares a nominal two-millisecond budget between waiting for that acknowledgement and waiting for that specific timeline value. Expiry or an unavailable timeline retains asynchronous acceptance; neither reports GPU completion nor retires work. OS scheduling can overshoot the requested timeout. No whole-device wait, guest sleep change, exported API/NID change, or shader change is added.

Eligibility excludes flips, conditional ranges and unproven CP waits. A preceding nonpredicated literal memory write may prove a 32/64-bit wait's compared bytes using the existing PM4 comparison; the real wait still executes. Unknown writes and intervening GPU draw/dispatch work discard that proof. A final REWIND acknowledges only its finite prefix: its continuation and logical completion remain blocked until the guest releases them. Current-main queue-zero completion wakeups are retained.

This is a standalone extraction of the local SuperTuxKart PPSA69421 experiment. No resource-ownership, residency, selected-image-import, write-watch, game configuration or shader experiment is included. No dependency on our earlier PRs is needed.

Overlap review: the refreshed bot report identified a textual conflict with #6507 at the include/helper insertion points in Submission.cpp. Follow-up 544d5ae8b relocates the unchanged progress helper and its include. Before the change, combining both PRs over main 9caecfd2d conflicted in that file; afterward, the combined merge tree is clean and retains both implementations (#6507 head db091f5fb). No #6507 code is included and no dependency is introduced. #6867 waits for referenced shader preparations, #6507 changes CPU flip scheduling, #5925/#6188 compile ahead, and #6946/#6947 change draw/descriptor preparation; those mechanisms remain separate.

Tested

Source base b4f05ab32, original validated candidate 8582ce0e69deb768bf3ce8b5ba3aa73ea9b34e2a, current head 544d5ae8b58d04614d800c67f71b80cfc7bf5081 (still merges cleanly with fetched main 9caecfd2d). GCC 15.2, Ninja, Release (-O3 -DNDEBUG), BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON, bundled dependencies.

  • Windows 11 Pro 10.0.26200, Core i7-13700, 32 GiB, NVIDIA RTX 4070 12 GiB, driver 591.86: complete libs rebuild; 21/21 focused tests pass with the surrounding suite configured off, and 21/21 on, zero skips. Coverage includes resource uploads/write-back/retirement, arrays/aliases/clears, graphics, pixel ancillary/fixed-point semantics, REWIND watchdog, nanosleep and trace handling.
  • Ubuntu 26.04.1 under WSL2, GCC 15.2, Mesa 26.0.8 llvmpipe/lavapipe (LLVM 21.1.8): rebuilt driver and relevant binaries; 7/7 focused tests pass in each surrounding-suite mode, zero skips. This is software Vulkan coverage, not native Linux NVIDIA validation.
  • The new progress tests explicitly enable the feature in CTest in both suite modes. A separate direct run with the feature absent passes the asynchronous correctness checks on each platform. The no-timeline variant covers unsupported-timeline fallback.
  • The synthetic workload checks real dispatch/release stores, interrupt/no-interrupt releases, byte-proven 32/64-bit waits, preserved neighboring bytes and CPU-written high words, prefix acknowledgement without early logical completion, a genuine CPU-dependent wait, and a slow GPU batch that remains valid after the pacing budget expires. All individual tests have a 30-second timeout. Readiness-count assertions exercise the intended pacing policy and are sensitive to host scheduling.
  • Follow-up relocation validation: Windows 8/8 focused submission/PM4/REWIND/nanosleep tests and Linux/lavapipe 7/7, each surrounding-suite mode, zero skips; explicit feature-disabled workloads also pass. The helper body and all remaining source tokens are unchanged after removing the moved helper/include for comparison. These are source-validation results, not fresh game measurements.
  • Conventions against canonical origin/main and git diff --check pass. No full-suite, fresh cross-title, completed-race or 15-minute stability acceptance is claimed.

Historical investigation only, not a clean-main performance result: a single short Abyss/Tux/easy/four-kart, 1920x1080 pair on the same frozen integration binary 2f26d7b4051f, feature absent/present, gave:

Mode Presents / window FPS Frame p50 / p90 / p99
Off 126 / 12.042317 s 10.46 95.104 / 99.181 / 101.847 ms
On 166 / 12.000923 s 13.83 71.888 / 74.700 / 85.184 ms

tools/trace_digest.py summaries of that historical integration pair:

off: seconds 30:12, present 207, 126 presents; p50 95.1 / p90 99.2 / p99 101.8 / max 118.3 ms; GPU busy 13.9 ms/present; dropped: no
on:  seconds 30:12, present 256, 166 presents; p50 71.9 / p90 74.7 / p99 85.2 / max 105.7 ms; GPU busy 12.7 ms/present; dropped: no

Both arms held the legacy #6759/#1191/#6820 integration, local ownership and TheAggie's shader revision 45944fbbe0dc constant. These changes are outside this PR, and their effects are not credited here. The preserved complete runtime and trace hashes were verified locally.

One 12-second pair does not establish repeatability; the user also observed later drops toward 10 FPS. These are not current-main versus PR measurements, nor a claim that this standalone branch delivers the same FPS. Required acceptance-length comparisons, cross-title coverage and public trace evidence remain unavailable; traces/evidence bundles are intentionally not uploaded. This PR requests review of the mechanism and trade-offs, not performance acceptance or default enablement. Pacing may reduce useful CPU/GPU overlap in other workloads.

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; investigation workload SuperTuxKart PPSA69421
  • GPUs tested: NVIDIA RTX 4070, driver 591.86, Windows 11 Pro 10.0.26200; Mesa 26.0.8 llvmpipe/lavapipe, LLVM 21.1.8, Ubuntu 26.04.1 / WSL2
  • AI-assisted: yes (OpenAI Codex)

@Zenodeon
Zenodeon marked this pull request as ready for review October 17, 2026 22:42
@github-actions

github-actions Bot commented Oct 17, 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 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4072 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4448 core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4472 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5115 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5404 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5441 core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5609 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 5656 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6177 core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6202 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6252 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6290 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6292 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
PR 6539 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6588 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6611 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6615 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 6636 docs/dev/debt/libSceAgcDriver.md
PR 6642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6683 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6727 docs/dev/debt/libSceAgcDriver.md
PR 6741 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6867 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Queues/Submission.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6887 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6937 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6960 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6965 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7233 core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7254 docs/dev/debt/libSceAgcDriver.md
PR 7256 docs/dev/debt/libSceAgcDriver.md
PR 7258 docs/dev/debt/libSceAgcDriver.md
PR 7292 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7390 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7426 docs/dev/debt/libSceAgcDriver.md
PR 7432 docs/dev/debt/libSceAgcDriver.md
PR 7446 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
docs/dev/debt/libSceAgcDriver.md
PR 7449 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7484 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7622 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Queues/Submission.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/include/Driver/Driver.hpp
core/libs/prx/libSceAgcDriver/Execution/include/VulkanDevice.hpp
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Recorder.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7659 docs/dev/debt/libSceAgcDriver.md
PR 7683 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketExecution.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 7827 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp

@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 18, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for splitting this out. The mechanism reads as bounded and safe (timeout, prefix-only REWIND ack, flips/conditionals excluded), but a few things need fixing before it can merge:

  • No measurement on current main. The PR body says the numbers come from a frozen integration binary with other PRs and local changes, and are "not current-main versus PR measurements". A performance change needs the main vs PR summary lines from the same machine and scene, with traces, as the PR template asks. Please add that (ideally with APS5_SUBMIT_PROGRESS on and off on the same build), or say what the feature gives without the other patches.
  • Scheduler-dependent assertions in tests/execution/SubmitProgress.cpp:89 (ready >= 48 of 64) and :122 (prefixesReady >= 12 of 16). The PR body notes they are sensitive to host scheduling; on shared CI runners and lavapipe they will flake. Keep the invariants that hold regardless of timing (no lost completion store, no early REWIND continuation, bounded return) and drop or loosen the readiness counts.
  • Technical debt placement. docs/dev/debt/libSceAgcDriver.md gets a new ### Experimental submission progress section at the top, which isn't one of the file's headings, and the text describes the feature rather than a gap. Keep only what is actually unverified or deviating (e.g. the 2 ms budget is a guess, no hardware validation across titles) as short lines under the existing headings.

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 docs unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants