Repository navigation
Upload only the shader constants a draw reads - #221
Merged
Merged
Conversation
Every draw byte-swapped both stages' whole 4 KiB constant files into the upload ring (8 KiB a draw, ~3% of an AYN Thor race's main thread). The translated shaders read a float4 constant only through the name their constant table gives it, so each native shader now records those registers (shader_constant_use.cpp, from the container's table) and a draw swaps only them; the rest of each 4 KiB block keeps what an earlier draw left, which the shader never reads. A shader that addresses constants relatively (a0/aL, 33 of the game's vertex shaders) still gets all 256. The skinning palette is swapped from guest memory straight into the ring instead of a copy, a swap and a second copy. SFR_CONSTANT_RUNS=0 (also a Test options choice) restores the full upload; SFR_TEST_CONSTANT_POISON=1 fills the unwritten registers with NaNs to show a missed read; SFR_CONSTANT_TIMING=1 prints the constant writes' time and bytes per draw and what each shader uploads. The microcode walk vertex_palette.cpp used is shared in xenos_microcode.h. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #215: the per-draw shader constant cost on the main thread.
What changed
src/shader_constant_use.cpp, from the guest container's table) and a draw swaps only them. The rest of each 4 KiB block keeps what an earlier draw left; the shader never reads it.vertex_palette.cppalready had moved tosrc/xenos_microcode.hso both use it.SFR_CONSTANT_RUNS=0(also on the Test options page, and kept in the Android diagnostic ZIP) restores the full upload and the old palette copy.SFR_TEST_CONSTANT_POISON=1fills the registers a draw does not write with NaNs.SFR_CONSTANT_TIMING=1prints the constant writes' ns and bytes per draw, plus what each shader uploads.Dirty tracking at write time was not needed after this: the writes left are ~620 bytes a draw.
A/B on the AYN Thor
One APK (versionCode 61),
SFR_CONSTANT_RUNS=0for the baseline. Moving Dolphin Resort race, HOST_THREADS over frames 13000-21000, frame metrics off, runs interleaved. drawn_ms stays near 16 ms because of the 60 fps pacing.Mean change: draw_ms -0.33, record_ms -0.29, cpu_ms -0.54 ms a frame. Race speed was 0.9994 in every run.
Per-draw timing of the constant writes (
SFR_CONSTANT_TIMING=1, one run each, two clock reads of ~0.13 us included):A frame has about 820 draws. The Windows machine had other load on it, so its frame-level numbers are not reported.
Pixel check
Screenshots from two runs can't be compared pixel for pixel in this harness. The menus animate in real time and the fixed-step race diverges: two runs of the same build differ in about 520,000 pixels at present 5000. Behaviour was checked three other ways instead:
OpAccessChaininto the stage's constant block uses a constant row inside the uploaded registers.cbufferLoadLegacyon the stage's cbuffer does the same.SHADER_CONSTANT_RUNS) matches.SFR_TEST_CONSTANT_POISON=1races on Windows Vulkan and D3D12 render normally (characters, skinning, effects, HUD). Any read of an unwritten register would show up as NaN garbage.Tests
New unit test:
tests/shader_constant_use_test.cpp.Risks
SFR_CONSTANT_RUNS=0turns the change off.SFR_CONSTANT_UPLOAD_REUSEandSFR_CONSTANT_REUSE_TRACEstill compare and upload whole arrays, as before.🤖 Generated with Claude Code