Skip to content

perf(agc): data-only draw hits compare only the user words a stage reads - #5656

Merged
oneandonlydean merged 4 commits into
boykopovar:mainfrom
Raghav314:perf/agc-data-hit-user-word-mask
Oct 20, 2026
Merged

oneandonlydean merged 4 commits into
boykopovar:mainfrom
Raghav314:perf/agc-data-hit-user-word-mask

Conversation

@Raghav314

@Raghav314 Raghav314 commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

What

A data-only draw hit (#494) reuses a cached stage only when every user data word of the stage is unchanged. A title that changes a user word per draw that a stage never reads (a per-draw counter, a pointer only another stage follows) gets no reuse for that stage, though its compiled result and captured memory would be the same.

  • When a stage is captured, it records the user words it depends on, as a 64-bit mask over its user data:
    • the words its SRT walk reads, as values or as bases (SrtUserDataUse::asValue | asBase);
    • the words its binding layout forwards into shader data (userDataRegisterReads), which covers words a stage reads straight from its SGPRs;
    • the two words of each vertex fetch table register in its vertex stage info.
  • A capture whose walk reads no user word gets the full mask, and a word at index 64 or above always counts as read.
  • On a data-only hit, a cached stage is a candidate when the words that changed are all outside its mask. Its captured memory is then validated as before; every other check is unchanged.
  • The mask is stored with the stage's result in the pipeline journal, so the journal file format goes from 4 to 5. Disk cache entries recompute it from the variant when they are loaded, so the disk cache format is unchanged.

PPSA36082

In Hades II most draws change user words between draws (a per-draw counter and ring pointers). In the level UI/menu, the stage preparation in the draw path (Shader.DrawStage) goes from 6.5 to 5.1 ms per frame and the frame time p50 from 18.5 to 17.6 ms (530 to 560 presents in 10 s). The picture is unchanged.

Level UI/menu standing still, APS5_HOST_IMPORT_MIB=6784, no APS5_PROFILE_* switch, APS5_TRACE_EVENTS=1048576 so the traces are whole, shader cache warmed for each build, one run each (measured on main 93e54ce):

  • main:
    {"commit":"93e54cedd3dd","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6784","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"70:10"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 615.78.08","os":"Linux 7.2.10-1-cachyos","resolution":"1920x1080","window":{"spec":"seconds 70:10","first_present":4314,"ms":10016.434},"presents":530,"frame_ms":{"p50":18.546,"p90":21.041,"p99":23.527,"max":42.509},"gpu_busy_ms_per_present":2.046,"worker_busy_pct":{"queue worker 0x0":94.100},"top_phases_ms_per_frame":{"Driver.Packet":17.778,"Driver.Packet.draw":15.493,"Driver.Draw":15.323,"Driver.Draw.shader_compile_and_link":10.913,"Shader.DrawStage":6.526,"Shader.DrawStage.capture_resources":4.228,"Driver.Draw.draw_enqueued":2.180,"Shader.DrawStage.materialize":1.505},"trace_dropped":false,"trace":"aps5-trace-93e54cedd3dd-723638.json.gz"}
    
  • this PR:
    {"commit":"bd7a16e291bc","dirty":false,"env":{"APS5_HOST_IMPORT_MIB":"6784","APS5_TRACE_DIR":"<path>","APS5_TRACE_EVENTS":"1048576","APS5_TRACE_SECONDS":"70:10"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 615.78.08","os":"Linux 7.2.10-1-cachyos","resolution":"1920x1080","window":{"spec":"seconds 70:10","first_present":4301,"ms":10010.943},"presents":560,"frame_ms":{"p50":17.623,"p90":19.970,"p99":24.124,"max":29.993},"gpu_busy_ms_per_present":2.047,"worker_busy_pct":{"queue worker 0x0":93.836},"top_phases_ms_per_frame":{"Driver.Packet":16.769,"Driver.Packet.draw":14.312,"Driver.Draw":14.152,"Driver.Draw.shader_compile_and_link":9.588,"Shader.DrawStage":5.116,"Shader.DrawStage.capture_resources":3.273,"Driver.Draw.draw_enqueued":2.273,"Shader.DrawStage.materialize":1.212},"trace_dropped":false,"trace":"aps5-trace-bd7a16e291bc-723937.json.gz"}
    

The frame time moves with the window position (an earlier pair at 150:10 gave 466 to 574 presents), so the stage time is the steadier number.

Tested

Linux (CachyOS), x86-64, GCC, 7800X3D / RTX 4090, NVIDIA 615.78.08, on main 0d8c51a.

  • agc_driver_draw_data_hit_user_words: the pixel stage loads a buffer descriptor through user words 0 and 1 and never reads word 2. A draw that changes only word 2 is a data-only hit that reuses both stages; a draw that points words 0 and 1 at another descriptor compiles the pixel stage again and reuses the vertex stage. _verify runs the same draws with APS5_VERIFY_DRAW_DATA_HITS=1.
  • A pixel stage that adds user word 2, read straight from its SGPR, to its output: a draw that changes only word 2 writes 191 instead of 128. With userDataRegisterReads left out of the mask the draw reuses the old stage, writes 127, and verify mode aborts.
  • JJenkx's round trip of a full 64-bit mask through the disk cache, and his commit that admits the serial key twice first, as main's second-sight admission needs.
  • The linux job of current build.yml run locally on perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE) #6946's branch, which is this PR with perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE) #6946 on top: configure with SPIRV tools on, test registration check, build, libs, the whole ctest and conventions. 1693/1693 pass, 16 expected skips, conventions OK.
  • Hades II with APS5_VERIFY_DRAW_DATA_HITS=1 APS5_VERIFY_DRAW_ENTRIES=1 APS5_VERIFY_REGISTER_KEYS=1 on the earlier perf(agc): draws that differ only in user data reuse their shape's decode and stages #494-based version of this change: 0 stages differed, picture fine.

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
  • Unblocks: perf(agc): draw finisher pipeline (APS5_DRAW_PIPELINE) #6946
  • GPUs tested: NVIDIA GeForce RTX 4090, 615.78.08, Linux 7.2.10 (CachyOS)
  • AI-assisted: yes

@CnRJay CnRJay left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comparing only the user words a stage depends on is a natural refinement of #494. Running Hades II with APS5_VERIFY_DRAW_DATA_HITS=1 and 0 differing stages is the right correctness check.

On the evidence: both summary lines were captured with APS5_PROFILE_DRAW=1 set (it is in their env). The Performance report form asks for runs with no APS5_PROFILE_* switch, because the draw profiler times every draw and changes the cost being measured, here on the draw path itself. Please capture the two lines again with only APS5_HOST_IMPORT_MIB and APS5_TRACE_SECONDS. If the p50 gain (34.0 → 26.9 ms) holds without the profiler, that settles it. Both lines also show trace_dropped: true, so the attached traces are incomplete; a shorter window keeps them whole.

One question on the mask: are user words a stage uses as plain values, read straight from user SGPRs into ALU work rather than through the SRT walk or forwarded shader data, always covered by userDataRegisterReads? If a stage can consume a user word that neither source records, a change to that word would leave it outside the mask and reuse a stage compiled for the old value. Either a sentence saying which path covers it, or a test with a pixel stage that does arithmetic on a user word (and nothing else), would close that.

@Gashrod1

Copy link
Copy Markdown
Contributor

Measured on DAVE THE DIVER (PPSA19115), as announced in #5436. Short version: data-only hits trigger on almost every keyless draw, but the frame time barely moves, because the user words that change in this title are pointers the stages read.

Setup. Windows 11, RTX 5060 (596.36), Ryzen 7 5800X; build with -fno-omit-frame-pointer -g1, Release otherwise. Same underwater scene each time, APS5_PROFILE_DRAW=1 APS5_TRACE_SUMMARY_EVERY=10. Base: main 956269a plus the MSAA stack this title needs (#4820, #5496, #5445, #5892, #5558, local changes listed in #5963). The test build merges 8267abd (this PR with #494) into that base.

Median over the 10 s intervals after the first 50 s:

Build frame p50 Driver.Draw Graphics.Draw
base 43.6 ms 39.2 ms 27.6 ms
base, APS5_DRAW_CACHE_ENTRIES=65536 41.8 ms 37.1 ms 27.0 ms
base + #494 + #5656 42.1 ms 37.3 ms 26.8 ms

The gain is within run-to-run noise (the #5656 run had 9 intervals in the scene, the base 28). From the [draw-cache] register key lines (10 s windows):

So the shape lookup works and the decode is skipped nearly everywhere, but the stages are still captured and compiled. A churn trace on the base (exact key vs shape, logged per user word) showed 288 shapes against ~456k exact keys in a few minutes, every new key differing only in user words, about 95% of the changed words increasing: ring-buffer pointers that the SRT walk reads, so userDataMask rightly keeps them. A stage that could be reused here would need its captured addresses relocated rather than compared as-is.

Port notes, in case they are useful for a rebase:

  • main now reads the vertex user-data tail continuation from the user words (DrawProgram::tailContinuation). I moved that read into ReadUserWords so a data-only refresh recomputes it, and skip the candidates of a stage whose continuation changed.
  • main's 0adbdcf caches a draw key only at its second sight, so the first draw of a shape never gets an entry and agc_driver_draw_data_hit_user_words fails. I admitted the first key of a shape that has no entry yet (at most one key per shape skips the second sight), and ran agc_driver_draw_cache_reuse with APS5_NO_DRAW_DATA_HITS=1, since it checks the second-sight rule. With that, the five agc_driver_draw* tests pass on Linux. The lower full-hit rate above may come from this admission rule or from the scene; I have not separated the two.
  • ShaderDiskCache sizes on current main: ShaderInvocation 120, RecompileResult 360, format version bumped past 32.

Most of the frame in this title is on the resource side (Graphics.Draw, ~27 ms), which neither variant touches; I will look there next.

AI-assisted: yes

@fma-rc

fma-rc commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Stacked this on #6188 (0eb0d89) over d92a8da in Astro's Playroom on Linux (RTX 5080, heavy in-game scene, one 20 s run each, APS5_PROFILE_DRAW=1). The frames match.

FPS register-key hits per 10 s capture / recompile / decode, us per draw
d92a8da 7.57 9k of 227k 7.8 / 4.3 / 1.4
6188 8.37 83k of 242k 5.4 / 1.3 / 3.0
6188 + 5656 12.77 372k of 373k 0.1 / 0.0 / 0.4

So with 6188 compiling ahead, 5656's data-only hits cover almost every draw in this scene. In the merge I applied the user-word mask in 6188's compileDrawAhead too.

@EdouardSence

EdouardSence commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

A small positive result on ASTRO BOT now that #7844 removes the import-budget regression that hid it in my earlier A/B.

Builds: the merge parent 2185dbf92^1 and the merge 2185dbf92, both + #7844 (pre / post). Linux, RX 9070 XT / RADV Mesa 26.2.4, PPSA21567 01.019.000, Sky Garden (-lvl underwater_aerial_garden), headless, level start, APS5_TRACE_SECONDS=90:50, warm caches, order pre → post → post → pre.

Run Frame p50 ms p90 ms p99 ms
pre 1 258.9 275.8 319.9
post 1 253.9 273.3 280.4
post 2 253.2 272.8 280.0
pre 2 257.8 278.9 401.4

Both post medians are below both pre medians: about 2 % lower frame time, with a tighter p99. GPU busy time per present is unchanged (~136 ms), so the gain is on the CPU side.

Edit: where the remaining data-only misses come from on this level (corrected). A local counter in lookupDraw's data-candidate loop (post build, Sky Garden, not pushed) shows that about 87 % of the stage variants it checks are rejected because a user data word the stage uses changed. The changing words come in steps of four (w0, w4 … w28), which first made me think of inline buffer descriptors. A prototype that reuses the stage when only inline V# words (or user words the shader only reads at run time through push constants) change, and patches the bindings and push constants, passes APS5_VERIFY_DRAW_DATA_HITS but gives no measurable gain (255–258 ms against 256–259 ms). Classifying what still blocks the candidates explains why:

Rejected candidates, by the first blocking word Share
a word the SRT walk reads memory through (asBase, a per-draw table pointer) ~70 %
a vertex fetch table register ~25 %
a value word that is not a plain V# copy ~4 %

So on this title the per-draw cost comes from per-object descriptor tables in memory, at a new address and with new contents for each draw. The existing relocation (relocateDrawEntry) only covers moved tables with the same contents. Reusing a stage here would need the captured table to be re-read and its descriptors patched without recompiling, like the flattened-SRT data positions, but for tables reached through a user pointer. I haven't tried that.

Tested and written by Claude (AI assistant) on a contributor's machine.
AI-assisted: yes

milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 20, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 6 (main took 5 for the recipe codec change of boykopovar#5656).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 20, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 6 (main took 5
for the recipe codec change of boykopovar#5656). A pipeline drawn with a
tessellation capture validates against that draw's capture buffers,
which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 6 (main took 5 for the recipe codec change of boykopovar#5656).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 6 (main took 5 for the recipe codec change of boykopovar#5656).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 7 (main took 5 for the recipe codec change of boykopovar#5656
and 6 for the polygon modes of boykopovar#7869).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 7 (main took 5
for the recipe codec change of boykopovar#5656 and 6 for the polygon modes of
boykopovar#7869). A pipeline drawn with a
tessellation capture validates against that draw's capture buffers,
which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
Module records are SPIR-V and take almost all of a journal's bytes, so
APS5_PIPELINE_JOURNAL_MAX_MIB fills with modules and later pipelines
are not recorded (boykopovar#8309). A module record now keeps its identity, stage
and encoded size, followed by a zstd frame (level 1) of the encoded
result; loading and replay expand it before decoding. The journal format
becomes 7 (main took 5 for the recipe codec change of boykopovar#5656 and 6 for
the polygon modes of boykopovar#7869).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
JJenkx pushed a commit to JJenkx/AnyPS5 that referenced this pull request Oct 21, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 6 (main took 5 for the recipe codec change of boykopovar#5656).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 7 (main took 5
for the recipe codec change of boykopovar#5656 and 6 for the polygon modes of
boykopovar#7869). A pipeline drawn with a
tessellation capture validates against that draw's capture buffers,
which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 21, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 7 (main took 5 for the recipe codec change of boykopovar#5656
and 6 for the polygon modes of boykopovar#7869).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 22, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 7 (main took 5
for the recipe codec change of boykopovar#5656 and 6 for the polygon modes of
boykopovar#7869). A pipeline drawn with a
tessellation capture validates against that draw's capture buffers,
which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 22, 2026
Module records are SPIR-V and take almost all of a journal's bytes, so
APS5_PIPELINE_JOURNAL_MAX_MIB fills with modules and later pipelines
are not recorded (boykopovar#8309). A module record now keeps its identity, stage
and encoded size, followed by a zstd frame (level 1) of the encoded
result; loading and replay expand it before decoding. The journal format
becomes 7 (main took 5 for the recipe codec change of boykopovar#5656 and 6 for
the polygon modes of boykopovar#7869).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 22, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 7 (main took 5
for the recipe codec change of boykopovar#5656 and 6 for the polygon modes of
tessellation capture validates against that draw's capture buffers,
which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 22, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 8 (main took 5 for the recipe codec change of
boykopovar#5656, 6 for the polygon modes of boykopovar#7869 and 7 for the truncated coverage
of boykopovar#8115).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
oneandonlydean pushed a commit that referenced this pull request Oct 23, 2026
Pipeline creation and SPIR-V validation read State::vertexPoints and the
three point sizes, so the pipeline journal's recipe codec and canonical
state now carry them, the State layout guard names its new size and the
journal format becomes 6 (main took 5 for the recipe codec change of #5656).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 23, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 9 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115 and 8 for the point lists of
boykopovar#6801). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 23, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 9 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115 and 8 for the point lists of
boykopovar#6801). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 23, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 9 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115 and 8 for the point lists of
boykopovar#6801). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 23, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 9 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115 and 8 for the point lists of
boykopovar#6801). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 24, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 10 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115, 8 for the point lists of boykopovar#6801
and 9 for the 4_4_4_4 UNORM target merges of boykopovar#8564). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 24, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 12 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115, 8 for the point lists of boykopovar#6801
and 9 for the 4_4_4_4 UNORM target merges of boykopovar#8564; open pull requests
use 10 and 11). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 24, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 12 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115, 8 for the point lists of boykopovar#6801
9 for the 4_4_4_4 UNORM target merges of boykopovar#8564 and 10 for the colour
logic operation of boykopovar#9348; boykopovar#8365 uses 11, and the number is set to main+1
when this lands). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 24, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 12 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115, 8 for the point lists of boykopovar#6801
9 for the 4_4_4_4 UNORM target merges of boykopovar#8564 and 10 for the colour
logic operation of boykopovar#9348; boykopovar#8365 uses 11, and the number is set to main+1
when this lands). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
milescoviello added a commit to milescoviello/AnyPS5 that referenced this pull request Oct 25, 2026
The pipeline journal guards State and ShaderStages, which this branch
extends. The recipe codec and canonical state now carry the hull wave
size, the geometry stage after tessellation, the merged hull flag
(TessellationConfiguration keeps its size, so its guard can't see it)
and rasterizer discard, and the journal format becomes 12 (main took 5
for the recipe codec change of boykopovar#5656, 6 for the polygon modes of boykopovar#7869,
7 for the truncated coverage of boykopovar#8115, 8 for the point lists of boykopovar#6801
9 for the 4_4_4_4 UNORM target merges of boykopovar#8564 and 10 for the colour
logic operation of boykopovar#9348; boykopovar#8365 uses 11, and the number is set to main+1
when this lands). A draw's tessellation capture validates against that draw's
capture buffers, which a replay doesn't have, so it isn't journaled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build perf Performance change shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants