Skip to content

fix(shader): ignore unused descriptor fields for scalar buffer loads - #5049

Merged
oneandonlydean merged 2 commits into
boykopovar:mainfrom
eljackjoestar-cmd:codex/scalar-buffer-descriptor-fields
Oct 14, 2026
Merged

oneandonlydean merged 2 commits into
boykopovar:mainfrom
eljackjoestar-cmd:codex/scalar-buffer-descriptor-fields

Conversation

@eljackjoestar-cmd

@eljackjoestar-cmd eljackjoestar-cmd commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What

A scalar-only s_buffer_load_* resource can carry non-buffer fields in its descriptor. The recompiler previously rejected word 3's TYPE; this PR normalizes word 3 only for scalar-only resources. Review also found that Kena reached ShaderResources::addGuestBuffer and stopped on reserved bit 30 of word 1. The same scalar-only normalization now clears that bit before building the driver-visible descriptor, preserving base address, stride and record count.

Vector, mixed scalar/vector, formatted, writable, atomic and image-alias resources retain their validation. No driver-wide acceptance of reserved bits is added.

Semantics source: AMD RDNA2 ISA §7.2.1, printed page 52 (PDF page 60), describes the scalar buffer fields as base address, stride and record count, with other fields ignored: https://gpuopen.com/download/rdna2-shader-instruction-set-architecture.pdf . Native console/ISA comparison of the ignored reserved bit is not claimed.

Lost Soul Aside (PPSA26358), captured shader 0x12c2298400, previously stopped on unsupported descriptor TYPE. A Kena run reported in review exposed the later reserved-bit rejection. This addresses those validation rules; no new Kena game run or completed gameplay is claimed.

Tested

Rebased onto current main f87799aa3, Windows 11 Pro, GCC 15.2, Release, SPIRV-Tools OFF. Full Windows build passed.

The new native regression failed before the reserved-bit normalization with AGC graphics: buffer descriptor has reserved bits set. With the fix, every lane receives the expected scalar value across both reserved-bit states and four word-3 patterns (including image-shaped TYPE and all bits set). Vector-only and mixed scalar/vector resources still reject non-buffer TYPE during recompilation and reserved word-1 bits during driver dispatch.

  • NVIDIA RTX 5070, driver 617.14: four focused tests passed without skips in 1.93 s: agc_driver_buffer_descriptor_runtime, agc_shader_memory, agc_driver_buffer_load_store, agc_driver_scalar_wide_loads.
  • AMD Radeon integrated gfx1036, driver 32.0.21036.18: the three Vulkan buffer/scalar tests passed without skips in 1.25 s.
  • Conventions and whitespace checks passed. Linux/full-suite/CI and complete game playability are not claimed. These checks use this branch alone on the stated main, not the combined title integration.

Checklist

  • Based on current main; no equivalent open PR found
  • One topic per PR
  • No comments in code added
  • Unimplemented paths throw; no silent stubs
  • No investigation files, requests, logs or screenshots added to the repository
  • No third-party code added
  • Generic scalar-load behaviour; vector/mixed validation retained
  • Depends on: none
  • Unblocks: PPSA26358 Lost Soul Aside (PPSA26358): bring-up and remaining blockers #4401 (one descriptor-validation blocker; later blockers remain)
  • GPUs tested: NVIDIA RTX 5070 / 617.14 and AMD Radeon integrated gfx1036 / 32.0.21036.18, Windows 11 Pro 10.0.26300
  • AI-assisted: yes, OpenAI Codex

@alfalfa-star

Copy link
Copy Markdown
Contributor

Tested on Kena: Bridge of Spirits (PPSA01802), Linux/RADV (RX 9070 XT), on main 0214069 with this PR merged.

Kena has the same pattern: a pixel shader binds a T# in buffer slot 1 and reads it only with scalar loads. The read extent is 108 to 112 bytes, first used at pc 0x94. One example of the words is 20f56700 caa00000 03ffc3ff 909c0fac.

  • Without this PR, those draws stop at buffer descriptor uses an unsupported type (about 7.1k skips in a 5 minute run).
  • With this PR the recompiler accepts them, and the type refusal is gone. The same draws now stop in the driver instead: ShaderResources::addGuestBuffer checks word 1 bit 30 before anything else and refuses with buffer descriptor has reserved bits set (1,353 skips in the same window). The T#'s word 1 (0xcaa00000) has that bit set, and this PR only normalizes word 3.
  • Read as a V#, the base is 0x20f56700 (T# word 0 plus the low 16 bits of word 1). That address isn't registered guest memory here (RegisteredReadableEnd returns 0). Stride × NUM_RECORDS from the T# words also comes out at several GB, over maxStorageBufferRange.

So for this title the scalar-only case also needs the driver path to stop validating fields that s_buffer_load doesn't use, and to decide what an unmapped base reads. As a local test only, I bound it as an empty buffer, and Kena then reaches its combat tutorial with the arena lit. I'm not claiming that is the right upstream behaviour.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 13, 2026
RINNECODER added a commit to RINNECODER/AnyPS5 that referenced this pull request Oct 14, 2026
…474)

* fix(shader): verify materialized snapshot identity before memo reuse

Ported from upstream PR boykopovar#4757.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(shader): emit both registration layouts of a pixel shader from one program

Ported from upstream PR boykopovar#4884. The libSceAgcDriver test hunks are not
ported: those tests are not built by any macOS configuration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(recompiler): keep the front-end resource plan in the shader disk cache

Ported from upstream PR boykopovar#4883. A warm launch loads the stored resource
plan and skips the shader front end. ShaderDiskCache FormatVersion
32 -> 33. The libSceAgcDriver test hunks are not ported: those tests
are not built by any macOS configuration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(shader): compile reusable SRT expression plans

Ported from upstream PR boykopovar#1341. The disk-cache plan decoder from boykopovar#4883
rebuilds the execution plan after a stored plan is decoded, since it is
derived from the value graph and not stored. The libSceAgcDriver test
hunks are not ported: those tests are not built by any macOS configuration.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(shader): keep only evaluable branch conditions in resource plans

Ported from upstream PR boykopovar#5181. The plan values now live in an
IrValueArena, so the disk-cache plan codec from boykopovar#4883 walks and fills
the arena instead of a vector of owned values. The libSceAgcDriver test
hunks and the docs hunk are not ported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(shader): ignore unused descriptor fields for scalar buffer loads

Ported from upstream PR boykopovar#5049. The test and docs hunks are not ported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(agc): cheaper shader-memory captures per draw (ShaderMemory half)

Ported from upstream PR boykopovar#1193, ShaderMemory.hpp/.cpp of its last commit
only: word-mask page marks, pooled pages with a last-page shortcut, and
lazily copied 64-byte blocks for pages no recorded GPU work writes.
Adapted for native guest memory: a lazy block is read through
GuestMemory::Read instead of the guest address as a host pointer, and
NativeGuestMemory gains a no-op FlushGpuWrites (it keeps no deferred
GPU writes). The SRT evaluator half is superseded by boykopovar#1341; the draw
cache commits are stacked on upstream #494/boykopovar#1191 and not ported. The
capture profile line keeps its current fields.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(graphics): retain vertex descriptor decode plans (ShaderInputState half)

Ported from upstream PR boykopovar#1313, Graphics/ShaderInputState only. The
Metal draw path calls DecodeVertexStageInfo per draw, which now builds
a VertexStagePlan and reads only the referenced, coalesced table words.
The Vulkan DrawDecode/DrawCache hooks that keep the plan across draws
are not ported (that driver is not built on macOS).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(graphics): retain vertex input layouts (Metal draw)

Ported from upstream PR boykopovar#1316 and adapted to Metal. VertexInputCache
(LRU per shader variant, shape-checked on every hit, a variant seen with
two shapes is bypassed) now takes a layout builder, so MetalDraw.mm
keeps the layout it built with the Metal format predicate instead of
calling BuildVertexInputLayout on every draw. Vertex buffer addresses
are still validated per draw. The Vulkan Context/VulkanDevice/Draw.cpp
hooks and the libSceAgcDriver test are not ported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(shader): build and run the shader disk cache codec tests on macOS

Registers anyps5_metal_shader_disk_cache with ctest in the Metal guest-replay
configuration and adds a plan round trip: value arena, rebuilt SRT execution
plan (evaluated against the original), phi blocks, indirect image tables, and
the 9-field SamplerResource / 5-field SampledResourcePair encodings.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@eljackjoestar-cmd
eljackjoestar-cmd force-pushed the codex/scalar-buffer-descriptor-fields branch from 8e47bd6 to 23a4d91 Compare October 14, 2026 01:29
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 14, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 14, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

The conventions check fails because the body lost the template sections (What, Tested, Checklist); please put them back.
alfalfa-star's Kena run shows the same scalar-only T# now stops in the driver instead: ShaderResources::addGuestBuffer refuses word 1 with buffer descriptor has reserved bits set. If s_buffer_load ignores those fields, the driver check needs the same rule for scalar-only buffers, otherwise the titles still stop. Can you cover that here?

@eljackjoestar-cmd
eljackjoestar-cmd force-pushed the codex/scalar-buffer-descriptor-fields branch 2 times, most recently from 000ccf6 to afd9b92 Compare October 14, 2026 07:50
@eljackjoestar-cmd

Copy link
Copy Markdown
Contributor Author

Restored the What, Tested and Checklist sections and rebased onto f87799aa3. The scalar-only snapshot normalization now also clears reserved bit 30 of word 1 before the driver-visible binding is built, while preserving the base, stride and record count. The general driver check remains strict for vector/mixed and other non-scalar-only uses.

The new native case failed before the change with AGC graphics: buffer descriptor has reserved bits set. With afd9b92b0, all scalar readbacks pass across both word-1 states and four word-3 patterns; vector-only and mixed uses still reject reserved bits during dispatch and non-buffer TYPE during recompilation. Full Windows Release build, four focused NVIDIA checks and three AMD Vulkan checks pass without skips; conventions pass. I have not rerun Kena itself, so this is an end-to-end driver regression result, not a new Kena gameplay claim.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 14, 2026
@oneandonlydean
oneandonlydean force-pushed the codex/scalar-buffer-descriptor-fields branch from afd9b92 to bfab566 Compare October 14, 2026 09:43
@oneandonlydean

Copy link
Copy Markdown
Collaborator

Rebased onto main: kept both debt entries in docs/dev/debt/shader.md; build and shader tests pass.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 14, 2026
@oneandonlydean
oneandonlydean merged commit c654b19 into boykopovar:main Oct 14, 2026
8 checks passed
@p3n1cillin

Copy link
Copy Markdown

Heads-up @eljackjoestar-cmd: a first-parent bisect points at this merge for a regression in Surround Sound Studio (PPSA99051). It exits about 3 s in with [ps5-agc] submission retirement failed on Windows/NVIDIA, and is fine on eecf90953. Details and the bisect table are in #5876.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants