Repository navigation
Conversation
…time CPU (#482) * perf(shader): rewrite high-fan-out IR uses in linear time Ported from upstream PR boykopovar#4035 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(shader): index specialization tables by SPIR-V id Ported from upstream PR boykopovar#4772 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(shader): honor disabled optimization during specialization Ported from upstream PR boykopovar#4827 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(shader): discard helper functions unreachable after specialization Ported from upstream PR boykopovar#5064 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(shader): drop module constants nothing references after specialization Ported from upstream PR boykopovar#5315 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(shader): cap SPIR-V scalar replacement Ported from upstream PR boykopovar#4288 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(recompiler): iterate structurizer fixpoints in post-order and bound shared merge splitting growth Includes the stacked upstream commit that structurizes refused control flow with reach flags, which this change builds on. Ported from upstream PR boykopovar#5028 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(shader): emit image_bvh_intersect_ray as one shared function per variant Ported from upstream PR boykopovar#5455 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * perf(shader): avoid redundancy traversal map copies Patches the bundled SPIRV-Tools redundancy elimination (only built with ANYPS5_ENABLE_SPIRV_TOOLS=ON). Ported from upstream PR boykopovar#5511 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(metal): accept a specialized BDA module that dropped one of its two BDA descriptors Specialization removes descriptor variables the final module no longer references. With helper functions now discarded after specialization, a compute module can drop its page-table variable while keeping the fault buffer, and the bridge then rejected the dispatch ("BDA ABI requires page-table and fault-buffer descriptor metadata"). Require at least one of the two roles instead of both; the module's own descriptors are still checked against the prepared plan. Not a port; needed by the port of upstream PR boykopovar#5064. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
|
Conflicts with main in |
# Conflicts: # core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
|
Still needs the rebase for |
|
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.
|
…ation A specialized pipeline variant materializes its specialization values as OpConstant, and SpecializeSpirv folds them into the code. The folding left the materialized constants in the module with no use. Image channel selectors are such values (RuntimeImageSwizzle). Two variants of one program that differed only in an image's channel order therefore had identical code but different SPIR-V, and the second one was created and compiled again instead of coming from the pipeline cache. removeUnusedConstants now also removes module constants (OpConstant, OpConstantTrue/False, OpConstantComposite, OpConstantNull) that no instruction references any more, repeating until nothing changes. Run already drops the names and decorations of removed ids. Test: agc_shader_disk_cache verifySpecializationDropsDeadConstants. Two modules that differ only in a constant the folding consumes specialize to the same words, that constant and its name are gone, a constant still in use (an array length) stays, the store still reads the selected value, and the result is stable. agc_formatted_buffer_once bounds its vertex registration module by 1.5x the specialized one. Both modules lose dead constants, the specialized one more (Linux with SPIRV-Tools: 1348 -> 1126 words, registration 1917 -> 1739), so their ratio moves from 1.42 to 1.54. The bound moves to 1.6x; a module that kept the format table for every format would be about 14,000 words, like the GPU-selected compute module (13,897).
76bb7da to
1ea471b
Compare
|
@oneandonlydean rebased onto Conflict. Tests (fork, Linux, lavapipe, SPIRV-Tools on, all 605
Sizes in
The 1.6x bound is still needed: 1.5x of 1126 is 1689 words and the registration module has 1739; 1.6x gives 1801. The Cold load. The Sword of the Sea dump the description was written against is gone, so the before/after runs on Minecraft Dungeons II (PPSA16064) at its title screen, one machine (RTX 5070 Laptop 8 GB, NVIDIA 617.42, Windows 11), |
|
The rebase is right, both tests kept. The |
|
Cold-load numbers from Minecraft Dungeons II (PPSA16064) on Windows 11, NVIDIA GeForce RTX 5070 Laptop GPU (617.42): two rows per arm,
So the change does what it says: the two specializations that differed only in constants nothing references now share one module, and the modules are 10 % smaller. The 15.7 s in the PR's first row is the NVIDIA driver compiling the new modules once: the driver keeps its own cache outside the row's AI-assisted: yes (Claude Code) |
What
Two pipeline variants of one program that differ only in a folded specialization value now produce the same SPIR-V. The second variant is then served by the pipeline cache instead of a cold compile.
buildSpecializedModulematerializes a variant's specialization values asOpConstant, andSpecializeSpirvfolds them into the code. The folding left the materialized constants in the module with no use.Image channel selectors (
RuntimeImageSwizzle) are such values. So two variants of a program whose only difference was an image's channel order, 4,5,6,7 vs 6,5,4,7, had identical code but different SPIR-V, and the second one was created and compiled again.removeUnusedConstantsnow also removes scalar and null module constants (OpConstant,OpConstantTrue/False,OpConstantNull) that no instruction references any more.OpConstantCompositeis not removed:VisitIdOperandscounts a composite's own result id as a reference, so a composite and its members always stay.Runalready drops the names and decorations of removed ids.Evidence from Sword of the Sea (PPSA25344), loading on a cold cache, compute programs of 100k+ SPIR-V words. Every pipeline's SPIR-V was dumped (
APS5_DUMP_COMPUTE_PIPELINES) and diffed withspirv-dis --raw-id:OpConstantvalues that nothing in the module uses: each id occurs once, at its definition. The values are 4/5/6/7 in another order. The 15th pair is a real variant (10,738 differing lines).Test change: agc_formatted_buffer_once
@adriadam10, this touches the bound from 56d5a49. That bound checks that a formatted load from a descriptor with a known format does not carry every format's decoder in registration form, measured against the specialized module.
This change shrinks both modules, the specialized one more, so the ratio between them moves. Sizes in words, from this PR's fork CI and from
main0214069 on the same runners:mainmainThe bound moves from 1.5x to 1.6x of the specialized module. A registration module that kept every decoder would be about as large as the GPU-selected compute module, about 14,000 words on current
main(13,897; it was 85,945 when this PR was opened, before #3656), so 1.6x still catches it.I first tried bounding the registration module against a vertex module with a GPU-selected descriptor instead, which would have measured the property directly. The recompiler rejects that request in both forms ("buffer specialization has an unsupported format"), so the test keeps its original comparison.
Tested
agc_shader_disk_cache, newverifySpecializationDropsDeadConstants:OpNameare gone;Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)