Commit Graph
624 Commits
Author SHA1 Message Date
Adrià beb20cfcdf Merge pull request #11719 from milescoviello/perf/srt-evaluator-requirements
perf(shader): reuse the evaluator's requirement list across values
2026-10-28 17:35:37 +01:00
Adrià a444a18d93 Merge pull request #11507 from hugodearaujo/fix/agc-short-cube-sampling
fix(agc): sample cube descriptors with fewer than six slices as six faces
2026-10-28 10:14:50 +01:00
Dean 00e85fea39 Merge pull request #10348 from oneandonlydean/perf-D2-v47
fix(agc): clamp an exported pixel depth to the viewport depth range
2026-10-28 18:25:05 +13:00
Adrià e5c952d51f Merge pull request #9806 from frankea/fix/hull-masked-control-point
fix(shader): evaluate a control point masked out of the packed hull register
2026-10-28 05:35:24 +01:00
Adrià ed94f8443f Merge pull request #11699 from Filip722/perf/shader-pixel-entry-mask
perf(shader): reuse starting pixel lane predicates
2026-10-28 04:59:08 +01:00
Dean Galvin c116f4f2f0 Merge branch 'main' into perf-D2-v47
# Conflicts:
#	docs/dev/debt/libSceAgcDriver.md
2026-10-28 13:52:37 +13:00
Dean c96d9fff00 Merge pull request #11440 from hamb3r/fix/agc-shader-memory-descriptor-epoch
fix(agc,shader): unify descriptor pendingWrite policy and enforce invalidation epochs
2026-10-28 13:51:32 +13:00
Dean b0bed62fa5 Merge pull request #10228 from mrfelek/claude/project-thread-f9yg74
fix(shader): plan an image table for a T# read at a first-lane offset
2026-10-28 12:56:15 +13:00
Dean Galvin d4a296d863 Merge main into perf-D2-v47: depth export tail moves to request version 49
Main took request serialization version 48 for the fragment barycentric
built-ins flag (#9193). The depth export clamp bounds are now written at
version 49 and read only for versions from 49, so a version 48 request as main
writes it still decodes, with default bounds. Tests: version 49 is the
emitted prefix, 50 the first unsupported one, a depth exporting request
without its bounds decodes at 48, 47 and 46 (the last two without main's
barycentric byte), and a version 48 two-sample dithered request decodes as
written.
2026-10-28 08:24:34 +13:00
Adrià 6f7cb75291 Merge pull request #9193 from imellag/feat/shader-barycentric-builtins-moltenvk
feat(recompiler): read I/J from barycentric built-ins on MoltenVK
2026-10-27 16:21:05 +01:00
frankea 724cabcffd fix(shader): evaluate a control point masked out of the packed hull register 2026-10-27 12:03:47 +01:00
Adrià 768e92f8b6 Merge pull request #9743 from frankea/fix/hull-reads-control-point-outputs
fix(shader): read other control points' off-chip outputs in hull programs
2026-10-27 12:00:31 +01:00
Dean Galvin 1bf274a817 Merge main into perf-D2-v47: depth export tail moves to request version 48
Main took request serialization version 47 for the two-sample dithered
alpha-to-coverage value. The depth export clamp bounds are now written at
version 48 and read only for versions from 48, so a version 47 request as main
writes it still decodes, with default bounds. Tests: version 48 is the
emitted prefix, 49 the first unsupported one, and a version 47 two-sample
dithered request (with and without depth export) decodes as written.
2026-10-27 22:37:31 +13:00
Adrià 76dec1794b Merge pull request #8998 from MarcZX10/codex/f32-image-store-rtz-8282
fix(agc): round 16-bit float image stores toward zero
2026-10-27 07:59:23 +01:00
hugodearaujo 5a5e54a455 Merge main into fix/agc-short-cube-sampling 2026-10-27 03:46:24 -03:00
Emanuele 03f7c1134f fix(shader): keep the position read of barycentric built-ins on MoltenVK
The I/J reads take the BaryCoordSmooth input, but gl_FragCoord was declared
only for the offset kinds, so its w was read as the constant 0 and the
fragment function never read [[position]]; Apple GPUs then return the
weights unnormalized. Declare it with the built-in, and select on
gl_FragCoord.w > 0, which a compiler cannot fold as it can
min(b, b + |w|).
2026-10-27 07:25:48 +01:00
Emanueleandyripper a95ced504c feat(recompiler): read I/J from barycentric built-ins on MoltenVK
MoltenVK exposes VK_KHR_fragment_shader_barycentric but its MSL step
rejects PerVertexKHR, so the extension is disabled there and a pixel
shader whose I/J VGPRs outlive their v_interp_p1/p2 pairs takes the
generated barycentric stages, which accept only triangle lists without
primitive restart on a device without geometry shaders.

A new target flag, fragmentBarycentricBuiltins, enables the extension
for its built-ins only. The host interpolation check then keeps the
leftover I/J reads (all perspective or all linear, at the fragment's
default position) and reads them from BaryCoordKHR or
BaryCoordNoPerspKHR, while the interpolated attributes stay hardware
varyings. Raw vertex parameters and I/J at an offset or a sample
position still take the generated stages. Apple GPUs return
unnormalized perspective weights unless the fragment function reads
[[position]], so each perspective read keeps a neutral use of
gl_FragCoord.w, loaded as a float. Devices with the full extension are
unaffected; the request serialization moves to version 45.

Co-authored-by: yripper <[email protected]>
2026-10-27 07:25:48 +01:00
milescovielloandClaude Opus 5.5 bf97894bc8 perf(shader): reuse the evaluator's requirement list across values
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 05:15:23 +00:00
Adrià 4c486ca322 Merge pull request #10515 from JJenkx/fix/agc-two-sample-dithered-a2c
fix(agc): emulate two-sample DB_ALPHA_TO_MASK 0xe701 dithered alpha-to-coverage
2026-10-27 04:52:02 +01:00
Filip Michalski 9c5397dc27 perf(shader): reuse starting pixel lane predicates 2026-10-27 04:31:07 +01:00
frankea 909a2f1f3b fix(shader): read other control points' off-chip outputs in hull programs 2026-10-27 03:47:24 +01:00
Dean 37c6b4bc25 Merge pull request #8077 from 0xcrstn/ufc6/descriptor-web-fold
fix(shader): split descriptor webs whose paths fold or hold invalid arms
2026-10-27 14:56:47 +13:00
Dean 630211a866 Merge pull request #6612 from milescoviello/feat/tess-geometry
feat(agc): draw tessellation followed by an NGG geometry stage
2026-10-27 14:56:18 +13:00
Dean 7d1ed9bb1e Merge pull request #8879 from MarcZX10/codex/masked-select-single-pass
perf(shader): stop masked-select elimination after one analysis pass
2026-10-27 14:26:37 +13:00
MarcZX10 9d6b917388 fix(agc): round 16-bit float image stores toward zero 2026-10-26 23:51:54 +00:00
hamb3r 6a3542dd9f fix(shader): rebuild materialized resource tables on descriptor invalidation
Symptom / Log:
- 26102026_05_33_48.log:L3022-L3034: [gpu] driver failure: compute shader 0x248a05b00: runtime image descriptor is invalid

Root Cause:
- core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp:ReadRuns/ReadColumn/Select/TableSnapshotter::Run/Materialize:L882-L1220 — table materialization did not propagate descriptorScope across table entries and did not rebuild earlier runs or records when a later run or indirect record waited on the GPU and invalidated cached Raw words.

Change:
- Set descriptorScope to the record/descriptor size during ReadRuns, ReadColumn, Select, and TableSnapshotter::Run, rebuild the full table or snapshot across up to 3 attempts when rawInvalidations changes mid-pass, force PendingWrite::Sync on the final attempt via SrtDescriptorForceSync, and refuse if the epoch still fails to stabilize.

Metric / Verification:
- Materialize and SnapshotResourceTables rebuild earlier runs/records when a late wait invalidates Raw words and refuse unstable snapshots.
2026-10-27 01:37:42 +03:00
hamb3r f38b6bc288 fix(agc): unify descriptor pendingWrite policy and enforce invalidation epochs
Symptom / Log:
- 26102026_05_33_48.log:L3022-L3034: [gpu] driver failure: compute shader 0x248a05b00: runtime image descriptor is invalid

Root Cause:
- core/libs/prx/libSceAgcDriver/Execution/src/ShaderMemory.cpp:ShaderMemory::read:L302-L361 and ShaderMemory::readWords:L441-L463 — per-dword PendingWrite decisions on wordwise pages allowed leading dwords of a 32-byte T# to be cached with PendingWrite::Raw before a later dword waited on the GPU, and page->valid.All() in readWords() copied wordwise pages without re-checking descriptorSpanBytes or pendingWrite policy.

Change:
- Propagate the remaining descriptor span size through SrtRuntime::descriptorScope during SRT tape and evaluator reads, restrict the page->valid.All() fast-path in readWords() to non-wordwise pages, re-evaluate cached wordwise words against checkSpanBytes, invalidate cached Raw words when a read waits on the GPU, and require a stable rawInvalidations epoch across up to 3 attempts (forcing PendingWrite::Sync on the final attempt and throwing if the epoch fails to stabilize).

Metric / Verification:
- ShaderMemory and SrtWalker reads never mix pre-wait Raw words with post-wait words across a descriptor span and refuse unstable snapshots.
2026-10-27 01:37:42 +03:00
hugodearaujo 787b6a6720 fix(agc): sample cube descriptors with fewer than six slices as six faces 2026-10-26 15:11:35 -03:00
0xcrstnandClaude Opus 5.5 ac0c125999 Merge upstream main into ufc6/descriptor-web-fold
Resolve the overlap with main's WindowLaneGuard and image-resource changes
by keeping both sides: DescriptorFault sits next to WindowLaneGuard in the
opcode list, metadata and side-effect switch, and its emitter next to
EmitWindowLaneGuard; optionalDescriptor is serialized after
remappedDepth1D; undefinedImageWords follows the new image helpers; the
descriptor web debt entry follows main's new entries.

The ImageResource field-count assertion is derived from the merged
structure (44 fields: main's 43 plus optionalDescriptor). sizeof
(ImageResource) stays 96 and sizeof(MemoryInfo) stays 80, so those
assertions are unchanged. The undefined-format test keeps its captured
regions in a variable, as MemoryRegionView no longer binds a temporary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 14:10:30 +02:00
Dean 9bbb7f37c6 Merge pull request #8898 from camezaro-intc/format11-11-10-float-stores
fix(shader_recompiler): pack format 11_11_10 float image stores in shader
2026-10-27 01:03:40 +13:00
Dean d9f5bf4d91 Merge pull request #11120 from shahulmubeen-a/fix/shader-1d-store-through-2d-array
fix(shader): write 1D storage images through 2D-array stores at slice 0
2026-10-26 21:58:24 +13:00
Dean 943ea8acb2 Merge pull request #9957 from mrfelek/fix/shader-runtime-buffer-presence
fix(shader): read a buffer V#'s presence at run time instead of specializing it
2026-10-26 16:54:34 +13:00
Shahul Mubeen AandClaude Opus 5.5 b9d00c5d80 fix(shader): write 1D storage images through 2D-array stores at slice 0
An image_store with DIM 2D_ARRAY through a 1D T# had no runtime image
mode, so the dispatch stopped with "image descriptor is incompatible
with the static runtime image interface". #2348 added a 1D mode for
DIM 2D stores only.

Write-only 2D-array storage images now get the same 1D mode as the 2D
case. On RDNA2 (gfx1036, hardware oracle) such a store writes texel x
and ignores y when the slice is 0, and writes nothing for any other
slice, with DEPTH 0 or 3, so the store is skipped unless the slice is 0.

New execution test agc_driver_image_store_line_through_plane_array.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-26 00:10:03 +05:30
Adrià e317f41d59 Merge pull request #10440 from SuarezPM/ai/atomic64-keyed-tables
feat(shader): support 64-bit image atomics through keyed image tables
2026-10-25 11:58:35 +01:00
milescovielloandClaude Opus 5.5 b6da343d20 fix(agc): keep the negated-predicate proof when a negated condition isn't implied
ImpliesNot returned at a negated condition, so a predicate !!a against
the condition !a, or !!a in either order of a conjunction, never reached
the negated-predicate and conjunction cases, which prove it. Lane-bit
lowering makes such a predicate from a complemented own-lane ballot of
!a, and the address evaluator then read both arms of a select on !a
instead of the one the predicate implies. Each case now falls through
when it does not prove the negation. Three hull reads under that
complemented ballot bit, alone and conjoined on either side, check it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 08:32:48 +00:00
milescovielloandClaude Opus 5.5 cd5fc9e838 feat(agc): draw tessellation followed by an NGG geometry stage
Crimson Desert (PPSA25286) draws with VGT_SHADER_STAGES_EN 0x60212d:
local, hull, domain and NGG geometry stages, the hull halves merged in one
registered type-3 program, the domain and geometry halves in one type-2
program. The domain half runs as the tessellation evaluation stage and
captures each vertex's ESGS item, and a mesh shader runs the geometry half
on the captured items.

Registered type-3 merged hulls come from #6679; this adds 16-bit LDS
reads and writes in tessellation stages, which Crimson Desert's merged
hull uses.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-25 08:32:37 +00:00
camezaro-intc e3f644040c fix(shader_recompiler): pack format 11_11_10 float image stores in shader 2026-10-24 21:32:14 -06:00
JJenkxandClaude Opus 5.5 2ff14f34e3 fix(agc): emulate two-sample DB_ALPHA_TO_MASK 0xe701 dithered alpha-to-coverage
Bugsnax (PPSA01503) draws with DB_ALPHA_TO_MASK 0xe701 (quad offsets
3, 1, 2, 3 without OFFSET_ROUND) on a two-sample target and stopped on
the refusal of every dither but the eight-sample 0x18701. The pixel
shader now applies an eight-level per-quad table for it, measured
natively on gfx1032, and the request's dither byte selects that table
(serialization version 47). It is accepted only for two matched raster
and DB_EQAA samples, the two measured location pairs and FP16_ABGR or
32_ABGR exports.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 16:40:02 -04:00
Dean Galvin c8f6a33164 Merge main into perf-D2-v47 fix (request serializer version 47 on top of main's 46) 2026-10-25 08:55:48 +13:00
Adrià 66de8e7a12 Merge pull request #9177 from milescoviello/perf/draw-allocations
perf(agc): drop three per-draw allocations on the draw and materialize paths
2026-10-24 18:29:19 +02:00
Adrià c9b2660d56 Merge pull request #9567 from Izamaru/fix/rve-descriptor-references
fix(shader): refresh descriptor sources after redundant value elimination
2026-10-24 15:46:56 +02:00
Adrià 522e32e3b6 Merge pull request #7550 from gjonn/fix/shader-resinfo-any-descriptor-dimension
fix(shader): answer image_get_resinfo on any T# dimension
2026-10-24 15:30:15 +02:00
mrfelek 20311903c3 fix(shader): read a buffer V#'s presence at run time instead of specializing it
A buffer V#'s presence came from the dispatch's V# snapshot as the
specialization constant BufferBase + 2, which buildSpecializedModule
turns into a literal. One guest program then compiled to two SPIR-V
modules, one with the buffer bound and one with it still null, each a
separate pipeline. descriptor() now reads presence from the V# words at
run time, as registration modules already do, and the formatted-buffer
helper takes it from its valid parameter.

AI-assisted. Tested by me on my own machine.
2026-10-24 12:59:47 +00:00
Adrià 924b5628b3 Merge pull request #8632 from JJenkx/fix/srt-unsigned-bound-compare
fix(shader): decide an unsigned bound compare from its extreme operand
2026-10-24 11:56:35 +02:00
Adrià FranchandClaude Sonnet 5.5 424b8f90b1 fix(shader): a negated predicate excludes only conditions that imply its operand
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-24 08:40:33 +02:00
xQuakes 418db9d2f8 fix(shader): accept a local tessellation index that nothing observes
A local program that keeps the relative patch index only on inactive
lanes, or in a vector-window slot nothing reloads, was refused as a
data use. Follow the index through the values that carry it, and
refuse only when a side effect still observes it.
2026-10-24 08:40:33 +02:00
Adrià a5a2c946a3 Merge pull request #10396 from CrimsonMac/fix/lds-misaligned-atomic64-fault
fix(shader): fault on misaligned 64-bit LDS atomics under the workgroup lock
2026-10-24 07:33:30 +02:00
JJenkxandClaude Opus 5.5 9ed24c8b41 fix(shader): decide an unsigned bound compare from its extreme operand
A resource block behind v_cmpx_gt_u32 exec, s, v0 and s_cbranch_execz keeps
its condition only if the compare can decide it, but UGreaterThan32 and
ULessThan32 needed both operands and v0 is a lane value. When the uniform
operand is 0 (or 0xffffffff on the other side) no lane can pass the compare,
so the walk can skip the block without the lane value.

UGreaterThan32 now yields false when its first operand is 0 or its second is
0xffffffff, and ULessThan32 when its first is 0xffffffff or its second is 0,
in the SRT interpreter and in the SRT tape alike; MayDecide keeps such a
condition when either operand is evaluable. Fully evaluable compares are
unchanged.

Destruction AllStars (PPSA02630) dispatches compute shader 0x200a220000 with
a thread count of 0 and leaves the V# in the skipped block stale (one
dispatch holds 00000000 00000000 00000000 ffffffff), which stopped it at
about 40 s with "buffer descriptor uses an unsupported type".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-23 23:59:32 -04:00
Adrià FranchandClaude Opus 5.5 7b4b9d9814 fix(shader): zero the resinfo layer count for DIMs without layers
image_get_resinfo returns 0 in its third component when the instruction's
DIM has no layers (1D, 2D, 2D MSAA) and the T# is not 3D, as measured on
RDNA 2 in #7550. Keep 1D-array T#s on their first layer and MSAA T#s
refused, and record the unmeasured forms in the shader debt file.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-24 04:21:06 +02:00
Gjon Gojcevic 3ba1d39db6 fix(shader): answer image_get_resinfo on any T# dimension
image_get_resinfo with DIM 1D on a cube, 3D or 2D-array T# was refused
with "image address has too few coordinate components": the tracker made
a 1D image that only the query uses, and no 1D mode matches such a T#.
The returned size, layer count and levels come from the T#; DIM only sets
the number of address registers. A 1D image used only by dimension
queries now decodes the T#'s own dimension and accepts 2D, 1D array,
2D array, 3D and cube views.
The flag is stored in the shader disk cache, so FormatVersion moves to 38.

PPSA01317 queries a 64x64 cube with DIM 1D in a pixel shader.

AI-assisted: yes
2026-10-24 04:07:24 +02:00