WIP: feat(vk): log the indexed descriptor arrays a program declares #475

Draft
mooki wants to merge 1 commit from mooki/Longshot:feat/descriptor-array-census into main
Member

Why

The translator is given no device limits (host_info() in vk_shader.cpp fills none), so a texture array a shader indexes
is sized with the defaults, up to 1024 elements, on every GPU. Apple's M1 and M2 reach 996 samplers a stage through an
argument buffer, and other drivers have per-stage limits of their own. Nobody has counted whether the game declares arrays
that long, or image, image-buffer and texture-buffer arrays at all, so whether to give the translator real limits is a guess.
This logs them.

What changed

  • vk: gpu/vk/descriptor_array_census.h (new): ArrayCensus.
    • note() takes a program's stage and counts its arrays (descriptors with a count above 1) by stage, kind (texture,
      texture buffer, storage image, image buffer) and size: 2-16, 17-64, 65-256, 257-995, 996-1023, 1024 and more. A program
      stage is counted once, whatever its variants.
    • It names the first 30 arrays near a limit:
      • 1024 elements or more, the translator's cap (HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT, DESCRIPTOR_MAX_COUNT);
      • 996 or more, near it;
      • the texture arrays of a stage with more than 996 samplers, the M1's and M2's;
      • the arrays of a stage past this GPU's maxPerStageDescriptorSamplers, ...SampledImages or ...StorageImages.
    • summary(): the counts, then a line for each stage with arrays, by kind and size, with its longest array.
  • vk: gpu/vk/vk_programs.cpp, beside the programs' census: descriptor_arrays_note() (with the device's per-stage limits)
    and descriptor_arrays_log(), declared in vk_programs.h.
  • vk: gpu/vk/vk_progcache.cpp: every program the program cache sees is noted: translated (program_cache_save, before
    it returns for a cache that is off) or read (program_cache_read, program_cache_read_light). So a start that reads its
    programs from the cache is counted as well as one that translates them.
  • vk: prepare_run (gpu/vk/vk_draw.cpp) logs the summary after the preparation, and mkwvk_close_asked (vk_main.cpp)
    when the window closes.
  • Nothing in the translator's stamp changes (nx2/build.py: eden/, sirit/, compat/, vk_shader.cpp, vk_bank.cpp,
    vk_state.h, vk_api.h), so no player's programs are translated again, and the program cache's format is the same.
  • tests: tests/test_descriptor_array_census.py (new).
    • It runs the census against stand-in stages: an array at the cap, a 64-element handle table, F1's three kinds, a variant
      of a stage already counted, a mesh fallback's stages, a 1000-sampler mesh stage, a stage it does not know, and 40 more
      past the 30 named. It does so once with no device limits and once with MoltenVK's (16 samplers, 256 sampled and 256
      storage images a stage).
    • It holds the cap, the four lists and the stages to the translator's and Vulkan's (a static_assert in vk_programs.cpp
      holds the stage bits), checks each call site, and checks that nothing of the census is in the translator's stamp.
    • It fails on main.
  • tests: tests/program_cache_cleanup_test.cpp, tests/program_cache_one_variant_test.cpp: a stand-in for
    descriptor_arrays_note beside their module_id_learned one, for the cache functions they cut out and compile.

Flags and settings

None.

Measurements

main: 5e072fc8c2 (2026-11-14)
this PR: feat/descriptor-array-census @ 45d2bbaa8e
Hardware: Apple M4 Max (16 CPUs), macOS 26.7.1, Apple clang 21. Game-free: no GPU, no game
Scene: none. The census's proof is the test; its cost is a micro-benchmark of the census alone
Method: tests/test_descriptor_array_census.py against a copy of main's tree (git archive 5e072fc8) and against this
PR; the full game-free suite on both; the census's note timed for 20,000 two-stage programs, new and then seen again (-O2)
How to reproduce: python -I -B tests/test_descriptor_array_census.py --cxx clang++ (add --source <a tree of main> for
main's side)

main @ 5e072fc8 this PR @ 45d2bbaa
tests/test_descriptor_array_census.py FAIL: no census PASS
full game-free suite on macOS (tests/run_all.py --jobs 6) 525 passed, 19 failed, 17 skipped 526 passed, 19 failed, 17 skipped
the census's work for each program the program cache sees (20,000 programs, new / seen again) none 0.10 µs / 0.06 µs a program
main @ 5e072fc8:
FAIL: gpu/vk/descriptor_array_census.h: no census of the indexed descriptor arrays the programs declare

this PR @ 45d2bbaa:
PASS: the programs' indexed descriptor arrays are counted by stage, kind and size, translated or read, and the ones near a limit are named

Some of the lines the test expects, with MoltenVK's limits:

vk: indexed descriptor array, program 000000000000000a's fragment stage: texture[1024]: at the translator's cap of 1024 elements, its default limit (the game's may be longer); the stage's 1089 samplers pass the 996 that an Apple M1 or M2 stage reaches through an argument buffer; the stage's 1089 samplers pass this GPU's maxPerStageDescriptorSamplers (16); the stage's 1091 sampled images pass this GPU's maxPerStageDescriptorSampledImages (256)
vk: indexed descriptor array, program 000000000000000c's fragment stage: texture[17]: the stage's 17 samplers pass this GPU's maxPerStageDescriptorSamplers (16)
...
vk: indexed descriptor arrays (close): 52 in 47 of 49 program stages, 47 of them near a limit (the first 30 named above)
vk: indexed descriptor arrays (close), fragment stages: 43 texture (17-64: 2, 996-1023: 40, 1024 and more: 1), 1 texture buffer (2-16: 1), 1 storage image (2-16: 1), 1 image buffer (2-16: 1); the longest 1024
vk: indexed descriptor arrays (close), compute stages: 2 texture (2-16: 1, 996-1023: 1), 1 image buffer (2-16: 1); the longest 996
vk: indexed descriptor arrays (close), task stages: 1 texture (2-16: 1); the longest 2
vk: indexed descriptor arrays (close), mesh stages: 2 texture (257-995: 2); the longest 700

With no array: vk: indexed descriptor arrays (the preparation): none in 2 program stages.

Testing

Tested:

  • On an Apple M4 Max with macOS 26.7.1, game-free only.
  • tests/test_descriptor_array_census.py fails on main and passes here.
  • The full suite on both sides, compared by test name.
    • Only one status changed: tests/test_descriptor_array_census.py, absent on main, passes here.
    • The same 19 checks fail on both, each with the same first error (in test_program_cache_one_variant three lines further
      down its cut-out functions). They fail on main on a Mac whatever this PR does: most need the macOS port's fixes, and
      test_module_ids looks for a complete_from signature main no longer has:
      test_appimage_package_retry, test_collect_wide, test_control, test_framegen_resources, test_game_layout,
      test_low_memory_notice, test_mem_gate, test_mem_gate_children, test_mirror_trim, test_module_ids,
      test_oot_state_tap, test_pad_layout, test_pcache_header_read, test_pipeline_cache_file,
      test_pipeline_cache_save, test_pipeline_play_cache, test_prof_symbols, test_program_cache_cleanup,
      test_program_cache_one_variant.
  • Two of those 19 compile the cache functions this PR calls the census from: test_program_cache_cleanup and
    test_program_cache_one_variant. On a Mac they stop at posix_fadvise, which Darwin lacks. With a compiler wrapper
    that gives them a no-op posix_fadvise, both pass on main and here. Without this PR's stand-in for
    descriptor_arrays_note, test_program_cache_one_variant stops at it.
  • The other checks that read the changed functions pass on both: test_program_cache_format, test_program_cache_index,
    test_load_default, test_program_life, test_program_load_wait.
  • Object compiles of gpu/vk/vk_programs.cpp, vk_progcache.cpp, vk_draw.cpp and vk_main.cpp with the renderer's
    flags (nx2/build.py), Apple clang 21: arm64 and x86_64, on main and here, all 16 build.
    • Main's renderer does not build on macOS as it is. Three of these four stop on both sides at the same Linux names:
      RUSAGE_THREAD (vk_programs.cpp), posix_fadvise and POSIX_FADV_WILLNEED (vk_progcache.cpp), and
      posix_fallocate (pipeline_cache_file.h). The compiles used a compile-only prelude that declares them, with environ.
    • The static_assert that holds the census's stage bits to VK_SHADER_STAGE_* is part of vk_programs.cpp's compile.
    • Not built on Windows or Linux: the change uses only the standard library, logf and dev.props.limits, as the code
      around it does.
  • The census's cost, timed alone on this Mac: 0.10 µs for each new program, 0.06 µs for one seen again, plus a mutex.

Not tested:

  • An in-game run on any platform (none on this Mac's lane: no GPU or game runs). No translation, no program, no cache record
    and no draw changes.
  • A program that fails translation is not counted: the census counts what the program cache sees. A texture-buffer array is
    one (it throws "Array of texture buffers" in the SPIR-V back end), and those programs are already named by the
    "not translated" lines. Image and image-buffer arrays translate today and are counted.

Needs other testers:

  • Windows or Linux, any GPU: start the game (a first start after this PR translates nothing new: the census counts the
    programs read as well), play a few minutes and close the window, then read longshot_log.txt. Expect vk: indexed descriptor arrays (close): ... near the end, and a line for each stage with arrays. The numbers decide whether real
    limits should reach the translator, on M1 and M2 especially (request to open).

Screenshots

Nothing on screen.

Risk and rollback

  • Low. The output added is at most 30 lines in a run, plus the summary after the preparation and at close.
  • Each program the program cache sees takes one more mutex for a short count, on the threads that read or translate it.
  • Reverting the commit is enough.

Reviewer notes

  • Read ArrayCensus::note and summary in descriptor_array_census.h, then descriptor_arrays_note in vk_programs.cpp
    and the three calls in vk_progcache.cpp.
  • A stage is the Vulkan stage the GPU runs: a mesh fallback's task and mesh stages are counted as compute, which is the
    stage their limits are checked against.
  • The counts are by program stage, so a fragment program shared by several programs is counted in each.
  • Why not in the translator: a census in vk_shader.cpp or eden/ would change the translator's stamp and translate
    every player's programs again, and it would miss every start that reads them from the cache.

Issues

None.

Checklist

For everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description).
  • Rebased on current main. Branched from 5e072fc8; main has moved since, and it is rebased in one sweep before ready.
  • python -I -B tests/run_all.py run and passing (any failure that also fails on main is named above). (Run on macOS: the 19 failures also fail on main, named under Testing.)
  • Tested in the game, or what wasn't is named under Testing.
  • Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). The test request is still to open.
  • Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (Not in the game: the test fails on main and passes here, and the census's own cost is timed alone. An in-game start is the test request above.)
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

If applicable

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • A game-free test added for the fix, failing on main and passing here.
  • A check under tests/ that reads changed source updated in this PR, not weakened.
## Why The translator is given no device limits (`host_info()` in `vk_shader.cpp` fills none), so a texture array a shader indexes is sized with the defaults, up to 1024 elements, on every GPU. Apple's M1 and M2 reach 996 samplers a stage through an argument buffer, and other drivers have per-stage limits of their own. Nobody has counted whether the game declares arrays that long, or image, image-buffer and texture-buffer arrays at all, so whether to give the translator real limits is a guess. This logs them. ## What changed - vk: `gpu/vk/descriptor_array_census.h` (new): `ArrayCensus`. - `note()` takes a program's stage and counts its arrays (descriptors with a count above 1) by stage, kind (texture, texture buffer, storage image, image buffer) and size: 2-16, 17-64, 65-256, 257-995, 996-1023, 1024 and more. A program stage is counted once, whatever its variants. - It names the first 30 arrays near a limit: - 1024 elements or more, the translator's cap (`HostTranslateInfo::DEFAULT_DESCRIPTOR_LIMIT`, `DESCRIPTOR_MAX_COUNT`); - 996 or more, near it; - the texture arrays of a stage with more than 996 samplers, the M1's and M2's; - the arrays of a stage past this GPU's `maxPerStageDescriptorSamplers`, `...SampledImages` or `...StorageImages`. - `summary()`: the counts, then a line for each stage with arrays, by kind and size, with its longest array. - vk: `gpu/vk/vk_programs.cpp`, beside the programs' census: `descriptor_arrays_note()` (with the device's per-stage limits) and `descriptor_arrays_log()`, declared in `vk_programs.h`. - vk: `gpu/vk/vk_progcache.cpp`: every program the program cache sees is noted: translated (`program_cache_save`, before it returns for a cache that is off) or read (`program_cache_read`, `program_cache_read_light`). So a start that reads its programs from the cache is counted as well as one that translates them. - vk: `prepare_run` (`gpu/vk/vk_draw.cpp`) logs the summary after the preparation, and `mkwvk_close_asked` (`vk_main.cpp`) when the window closes. - Nothing in the translator's stamp changes (`nx2/build.py`: `eden/`, `sirit/`, `compat/`, `vk_shader.cpp`, `vk_bank.cpp`, `vk_state.h`, `vk_api.h`), so no player's programs are translated again, and the program cache's format is the same. - tests: `tests/test_descriptor_array_census.py` (new). - It runs the census against stand-in stages: an array at the cap, a 64-element handle table, F1's three kinds, a variant of a stage already counted, a mesh fallback's stages, a 1000-sampler mesh stage, a stage it does not know, and 40 more past the 30 named. It does so once with no device limits and once with MoltenVK's (16 samplers, 256 sampled and 256 storage images a stage). - It holds the cap, the four lists and the stages to the translator's and Vulkan's (a `static_assert` in `vk_programs.cpp` holds the stage bits), checks each call site, and checks that nothing of the census is in the translator's stamp. - It fails on main. - tests: `tests/program_cache_cleanup_test.cpp`, `tests/program_cache_one_variant_test.cpp`: a stand-in for `descriptor_arrays_note` beside their `module_id_learned` one, for the cache functions they cut out and compile. ## Flags and settings None. ## Measurements main: 5e072fc8c2adadba5ea610148be1c47800ba0cca (2026-11-14) this PR: feat/descriptor-array-census @ 45d2bbaa8e12c2bc33b6e9336d1b80594bd54e9b Hardware: Apple M4 Max (16 CPUs), macOS 26.7.1, Apple clang 21. Game-free: no GPU, no game Scene: none. The census's proof is the test; its cost is a micro-benchmark of the census alone Method: `tests/test_descriptor_array_census.py` against a copy of main's tree (`git archive 5e072fc8`) and against this PR; the full game-free suite on both; the census's `note` timed for 20,000 two-stage programs, new and then seen again (`-O2`) How to reproduce: `python -I -B tests/test_descriptor_array_census.py --cxx clang++` (add `--source <a tree of main>` for main's side) | | main @ 5e072fc8 | this PR @ 45d2bbaa | |---|---|---| | `tests/test_descriptor_array_census.py` | FAIL: no census | PASS | | full game-free suite on macOS (`tests/run_all.py --jobs 6`) | 525 passed, 19 failed, 17 skipped | 526 passed, 19 failed, 17 skipped | | the census's work for each program the program cache sees (20,000 programs, new / seen again) | none | 0.10 µs / 0.06 µs a program | ``` main @ 5e072fc8: FAIL: gpu/vk/descriptor_array_census.h: no census of the indexed descriptor arrays the programs declare this PR @ 45d2bbaa: PASS: the programs' indexed descriptor arrays are counted by stage, kind and size, translated or read, and the ones near a limit are named ``` Some of the lines the test expects, with MoltenVK's limits: ``` vk: indexed descriptor array, program 000000000000000a's fragment stage: texture[1024]: at the translator's cap of 1024 elements, its default limit (the game's may be longer); the stage's 1089 samplers pass the 996 that an Apple M1 or M2 stage reaches through an argument buffer; the stage's 1089 samplers pass this GPU's maxPerStageDescriptorSamplers (16); the stage's 1091 sampled images pass this GPU's maxPerStageDescriptorSampledImages (256) vk: indexed descriptor array, program 000000000000000c's fragment stage: texture[17]: the stage's 17 samplers pass this GPU's maxPerStageDescriptorSamplers (16) ... vk: indexed descriptor arrays (close): 52 in 47 of 49 program stages, 47 of them near a limit (the first 30 named above) vk: indexed descriptor arrays (close), fragment stages: 43 texture (17-64: 2, 996-1023: 40, 1024 and more: 1), 1 texture buffer (2-16: 1), 1 storage image (2-16: 1), 1 image buffer (2-16: 1); the longest 1024 vk: indexed descriptor arrays (close), compute stages: 2 texture (2-16: 1, 996-1023: 1), 1 image buffer (2-16: 1); the longest 996 vk: indexed descriptor arrays (close), task stages: 1 texture (2-16: 1); the longest 2 vk: indexed descriptor arrays (close), mesh stages: 2 texture (257-995: 2); the longest 700 ``` With no array: `vk: indexed descriptor arrays (the preparation): none in 2 program stages`. ## Testing **Tested:** - On an Apple M4 Max with macOS 26.7.1, game-free only. - `tests/test_descriptor_array_census.py` fails on main and passes here. - The full suite on both sides, compared by test name. - Only one status changed: `tests/test_descriptor_array_census.py`, absent on main, passes here. - The same 19 checks fail on both, each with the same first error (in `test_program_cache_one_variant` three lines further down its cut-out functions). They fail on main on a Mac whatever this PR does: most need the macOS port's fixes, and `test_module_ids` looks for a `complete_from` signature main no longer has: `test_appimage_package_retry`, `test_collect_wide`, `test_control`, `test_framegen_resources`, `test_game_layout`, `test_low_memory_notice`, `test_mem_gate`, `test_mem_gate_children`, `test_mirror_trim`, `test_module_ids`, `test_oot_state_tap`, `test_pad_layout`, `test_pcache_header_read`, `test_pipeline_cache_file`, `test_pipeline_cache_save`, `test_pipeline_play_cache`, `test_prof_symbols`, `test_program_cache_cleanup`, `test_program_cache_one_variant`. - Two of those 19 compile the cache functions this PR calls the census from: `test_program_cache_cleanup` and `test_program_cache_one_variant`. On a Mac they stop at `posix_fadvise`, which Darwin lacks. With a compiler wrapper that gives them a no-op `posix_fadvise`, both pass on main and here. Without this PR's stand-in for `descriptor_arrays_note`, `test_program_cache_one_variant` stops at it. - The other checks that read the changed functions pass on both: `test_program_cache_format`, `test_program_cache_index`, `test_load_default`, `test_program_life`, `test_program_load_wait`. - Object compiles of `gpu/vk/vk_programs.cpp`, `vk_progcache.cpp`, `vk_draw.cpp` and `vk_main.cpp` with the renderer's flags (`nx2/build.py`), Apple clang 21: arm64 and x86_64, on main and here, all 16 build. - Main's renderer does not build on macOS as it is. Three of these four stop on both sides at the same Linux names: `RUSAGE_THREAD` (`vk_programs.cpp`), `posix_fadvise` and `POSIX_FADV_WILLNEED` (`vk_progcache.cpp`), and `posix_fallocate` (`pipeline_cache_file.h`). The compiles used a compile-only prelude that declares them, with `environ`. - The `static_assert` that holds the census's stage bits to `VK_SHADER_STAGE_*` is part of `vk_programs.cpp`'s compile. - Not built on Windows or Linux: the change uses only the standard library, `logf` and `dev.props.limits`, as the code around it does. - The census's cost, timed alone on this Mac: 0.10 µs for each new program, 0.06 µs for one seen again, plus a mutex. **Not tested:** - An in-game run on any platform (none on this Mac's lane: no GPU or game runs). No translation, no program, no cache record and no draw changes. - A program that fails translation is not counted: the census counts what the program cache sees. A texture-buffer array is one (it throws "Array of texture buffers" in the SPIR-V back end), and those programs are already named by the "not translated" lines. Image and image-buffer arrays translate today and are counted. **Needs other testers:** - Windows or Linux, any GPU: start the game (a first start after this PR translates nothing new: the census counts the programs read as well), play a few minutes and close the window, then read `longshot_log.txt`. Expect `vk: indexed descriptor arrays (close): ...` near the end, and a line for each stage with arrays. The numbers decide whether real limits should reach the translator, on M1 and M2 especially (request to open). ## Screenshots Nothing on screen. ## Risk and rollback - Low. The output added is at most 30 lines in a run, plus the summary after the preparation and at close. - Each program the program cache sees takes one more mutex for a short count, on the threads that read or translate it. - Reverting the commit is enough. ## Reviewer notes - Read `ArrayCensus::note` and `summary` in `descriptor_array_census.h`, then `descriptor_arrays_note` in `vk_programs.cpp` and the three calls in `vk_progcache.cpp`. - A stage is the Vulkan stage the GPU runs: a mesh fallback's task and mesh stages are counted as compute, which is the stage their limits are checked against. - The counts are by program stage, so a fragment program shared by several programs is counted in each. - Why not in the translator: a census in `vk_shader.cpp` or `eden/` would change the translator's stamp and translate every player's programs again, and it would miss every start that reads them from the cache. ## Issues None. ## Checklist ### For everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`). - [ ] Rebased on current `main`. Branched from 5e072fc8; main has moved since, and it is rebased in one sweep before ready. - [x] `python -I -B tests/run_all.py` run and passing (any failure that also fails on `main` is named above). (Run on macOS: the 19 failures also fail on main, named under Testing.) - [x] Tested in the game, or what wasn't is named under Testing. - [ ] Testing filled in: what was tested, what wasn't, and what needs other testers (with test requests). The test request is still to open. - [ ] Measured: main and this PR at named commits, on the same PC, scene and settings, at least 2 interleaved runs each, the median reported. (Not in the game: the test fails on main and passes here, and the census's own cost is timed alone. An in-game start is the test request above.) - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### If applicable - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] A check under `tests/` that reads changed source updated in this PR, not weakened.
feat(vk): log the indexed descriptor arrays a program declares
All checks were successful
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 6s
CI / Conventional Commit title (pull_request) Successful in 7s
CI / Workflow lint (actionlint) (pull_request) Successful in 8s
Third-party parts / As their notes say (pull_request) Successful in 16s
Website / Website on Cloudflare (pull_request_target) Has been skipped
45d2bbaa8e
host_info() gives the translator no device limits, so a dynamically indexed texture array is sized with its defaults, up to
1024 elements, on every GPU, and Apple's M1 and M2 reach 996 samplers a stage through an argument buffer. Whether the game
declares such arrays, or image, image-buffer and texture-buffer arrays at all, was never counted.

- gpu/vk/descriptor_array_census.h (new): the census. A program stage's arrays (count above 1) are counted by stage, kind
  and size, once a program stage whatever its variants; the first 30 near a limit are named: 996 elements or more (the
  translator's cap is 1024), a stage with more than 996 samplers, or a stage past this GPU's per-stage samplers, sampled
  images or storage images. The summary has the counts and a line for each stage with arrays.
- vk_programs.cpp: descriptor_arrays_note (with the device's limits) and descriptor_arrays_log.
- vk_progcache.cpp: every program the program cache sees is noted, translated (program_cache_save, before it returns for a
  cache that is off) or read (program_cache_read, program_cache_read_light). Nothing in the translator's stamp changes:
  no player's programs are translated again.
- vk_draw.cpp prepare_run and vk_main.cpp mkwvk_close_asked log the summary.
- tests/test_descriptor_array_census.py (new): the census against stand-in stages, its cap, lists and stages against the
  translator's and Vulkan's, and the call sites. It fails on main.
- tests/program_cache_cleanup_test.cpp, program_cache_one_variant_test.cpp: a stand-in for descriptor_arrays_note beside
  module_id_learned's, for the cache functions they cut out.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <[email protected]>
All checks were successful
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 6s
CI / Conventional Commit title (pull_request) Successful in 7s
CI / Workflow lint (actionlint) (pull_request) Successful in 8s
Third-party parts / As their notes say (pull_request) Successful in 16s
Website / Website on Cloudflare (pull_request_target) Has been skipped
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'feat/descriptor-array-census:mooki-feat/descriptor-array-census'
git switch 'mooki-feat/descriptor-array-census'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!475
No description provided.