Commit Graph
53 Commits
Author SHA1 Message Date
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
JAB-devandClaude Sonnet 5.5 8d54357e79 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 21:18:00 +02:00
Adrià 1e1ab77684 Merge pull request #8495 from yabanana/fix/borrowed-memory-regions
fix(shader): reject temporary owners for borrowed memory regions
2026-10-23 20:47:29 +02:00
Maz 913e458369 fix(shader): deserialize pixel function storage dwords at version 45
The SM-budget threshold writes the storage size after the LDS flag; read it back and keep the fixtures on the fused+pointList trailer.
2026-10-23 20:53:29 +04:00
Maz 40c7ff888c fix(shader): scale pixel LDS Function threshold by SM budget
Max measured a 4 GiB private-memory ceiling on a 4090; use
VK_NV_shader_sm_builtins so denser cards take the buffer path below 4096.
2026-10-23 20:53:24 +04:00
mazen dba7f5466c fix(shader): keep a pixel LDS overflow until the GPU is idle
The slot counter is reset only after earlier fragment writes, and the overflow flag stays until WaitIdle. The storage buffer is limited to NVIDIA's proprietary driver, which is where the large function array does not finish.
2026-10-23 20:53:21 +04:00
Daniele Giovane 13b1892fdd Merge main and address review for PR 8495 2026-10-23 12:45:54 +02:00
EmanueleandYcaro Gabriel 7410c37b6c perf(shader): emit exact f32 add, subtract and multiply as fma on MoltenVK
The recompiler marks every guest f32 add, subtract and multiply
NoContraction, because the guest rounds each one separately.
SPIRV-Cross turns each of them into a call to a helper that Metal
compiles without optimization, which dominates fragment time on
MoltenVK, and its multiply helper, fma(a, b, +0.0), turns a -0.0
product into +0.0.

On MoltenVK they are now GLSL Fma whose second step is exact, which
gives the separately rounded result: a * b is fma(a, b, -0.0), a + b
is fma(1.0, a, b) and a - b is fma(-1.0, b, a). The sin, cos and log2
series and the offset image coordinates and gather texel scale use the
same forms. The choice is a SpirvTarget flag set for
VK_DRIVER_ID_MOLTENVK, part of the shader cache key and of the request
serialization (version 44); other drivers are unchanged.

agc_driver_f32_separate_rounding checks a multiply feeding an add or a
subtract on rows where fusing them changes the result. It,
agc_driver_f32_arithmetic_nan and agc_driver_f32_denormal_flush also
run the fused forms on devices that do not use them, so lavapipe checks
them against the same rows.

Co-authored-by: Ycaro Gabriel <[email protected]>
2026-10-23 12:13:18 +02:00
JAB-devandClaude Sonnet 5.5 d201de3f32 Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-23 04:09:40 +02:00
JAB-devandClaude Sonnet 5.5 8ed185a51c Merge branch 'main' of https://github.com/boykopovar/AnyPS5 into feat/agc-4-4-4-4-partial-writes
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 20:13:17 +02:00
JJenkx b779c90159 test(shader): retain sample order through legacy point replay 2026-10-21 09:13:32 -04:00
JJenkx 19be2835f2 test(shader): preserve legacy point requests after denorm serialization 2026-10-21 09:13:32 -04:00
JJenkx ee9b1c8249 test(shader): upgrade legacy point requests to version 40 2026-10-21 09:13:32 -04:00
JJenkx 70c8476c7c test(shader): align request version guards after float flush merge 2026-10-21 09:13:32 -04:00
JJenkx c750708c8d test(shader): preserve depth remap requests through point replay 2026-10-21 09:13:32 -04:00
JJenkx 8409360d40 test(shader): retain request versions through 34 for point replay 2026-10-21 09:13:32 -04:00
JJenkx 95a2a45fe3 test(shader): preserve version 32 requests with spanned waves 2026-10-21 09:13:32 -04:00
milescovielloandClaude Opus 5.5 89be76cb4c test(shader): check version 39, 41, 42 and 43 requests with merged hull and point state
A tessellated vertex request with the merged hull flag and a point list
serializes as version 43 with both. Without its point tail it reads as
main's version 42, without the pixel sample order as version 41, and
without the f32 denormal preserve flag as version 39, each keeping the
merged hull flag and taking the default point state.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 09:13:32 -04:00
milescovielloandClaude Opus 5.5 11bc7b1686 fix(shader): move the vertex point fields to request version 43
main took request versions 33 to 42 for other fields, the last of them
the pixel sample order, so requests of those versions from main have no
point-list tail. The point fields now come with version 43, after them,
and the tests expect 43 and reject 44.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 09:13:32 -04:00
milescovielloandClaude Opus 5.5 e7ea490325 feat(agc): draw point lists on the vertex path with their point size
A point list routed through the vertex path was refused, and so was
PA_CL_VS_OUT_CNTL.USE_VTX_POINT_SIZE on it. OliSe Player (PPSA01153)
stops on the latter with two of its MilkDrop presets.

The vertex path now draws point lists as Vulkan points. The vertex stage
writes PointSize: the misc export's X clamped to PA_SU_POINT_MINMAX when
USE_VTX_POINT_SIZE is set, and the PA_SU_POINT_SIZE height otherwise.
The point state travels in the recompile request (version 31) and the
cache and draw keys. Non-square register sizes, inverted clamps, point
sprite texture coordinates and, without largePoints, sizes other than
one pixel throw.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 09:13:09 -04:00
Yunus Shaikh 6d09797d6b Merge main into fix/agc-sample-location-grid-exact 2026-10-21 05:39:42 +00:00
Dean Galvin a07ad30578 feat(shader): request DenormPreserve 32 where the device preserves f32 denormals
The recompiler asked for DenormPreserve only for 16-bit and 64-bit floats,
so a device that flushes 32-bit denormals by default (RADV, MoltenVK) flushed
them whatever the guest's float mode said. target.float32DenormPreserve is set
from shaderDenormPreserveFloat32 when denormBehaviorIndependence allows a 32-bit
mode, is part of the cache key and of the request serialization (version 41),
and makes the module declare DenormPreserve 32 unless the 32-bit flush is
already taken in hardware. APS5_NO_HW_F32_PRESERVE=1 turns it off.
2026-10-21 10:45:24 +13:00
JAB-devandClaude Sonnet 5.5 6ccb8c052e fix(agc): refuse memory-writing 4_4_4_4 merges only where tests can reject pixels
The refusal of a merging shader that writes guest memory under late
tests fired in two cases where the early tests change nothing.

The first was a draw with no depth, stencil or depth-bounds test. Early
tests reject no pixel there, so every write the console makes still
happens. The target merge now carries whether the draw has such a
test, and the refusal applies only then. This adds one byte to the
version 40 merge fields of the recompile request.

The second was any GDS binding, including a shader that only reads GDS.
The refusal now looks for GDS writes, atomics, appends and consumes.

Tests: the depth and stencil decode checks the new flag, and the
static shader key depends on it. A counter-adding shader under late
tests compiles without a test and throws with one. A late-test merge
that reads GDS compiles, and one that adds to GDS throws.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 19:09:49 +02:00
JAB-devandClaude Sonnet 5.5 27c0004991 fix(agc): merge kill shaders under late tests when the draw writes no depth or stencil
A packed 4_4_4_4 partial write merges inside the pixel shader after early
depth and stencil tests. Moving the tests ahead of a pixel kill only changes
the result when the draw writes depth or stencil, so the target merge now
carries whether the draw does (depth write, or stencil with a write mask and
a non-keep operation), and the late-test kill refusal applies only then.
The flag is part of the static shader key, the serialized request (now
version 40) and the pixel input info.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 19:09:48 +02:00
JAB-devandClaude Sonnet 5.5 48a7efcbec feat(agc): merge partial writes into 4_4_4_4 UNORM color targets
A CB_TARGET_MASK that writes fewer than four components of a 4_4_4_4
target leaves the other nibbles of each packed word as they were, which
an R16_UINT attachment cannot do. Such draws now close the attachment's
color write mask, and the pixel shader merges the written nibbles into
the target through a storage image: inside a pixel interlock it reads
the word, keeps the bits the mask leaves alone and stores it back.

The merge (export index, word mask, sample count) is part of the static
shader key, request version 40 and shader disk cache format 42; the
storage image is appended to the shader's images with a single runtime
mode, and its T# is encoded from the target's surface at draw time, so
the draw resolves it to the target's resident image, which Draw
requires. Merging shaders declare early fragment tests; shaders that
kill under late tests, export depth, stencil or coverage, use
alpha-to-coverage or a quad sample mask are refused, as are
multisampled, mipmapped, volume and array targets and more than one
merged target per draw.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-20 19:09:48 +02:00
Jan ŠléglandClaude Opus 5.5 8b8219dcef feat(agc): run registered merged hull programs (binary type 3)
A registered type-3 hull program holds the local and the hull part of a
tessellation draw in one binary, addressed through SPI_SHADER_PGM_LO_LS
(SH 0x148) with no SPI_SHADER_PGM_LO_HS: the local part runs on the lanes
below s3[7:0] and writes LDS, an s_barrier follows, and the hull part runs
on the lanes below s3[15:8] and may store the registers the local part
filled. The draw decode asked 0x148 for a type-5 local half, and
PPSA11386 (007 First Light) stopped in its level load with "registered
program refers to an incompatible shader binary type".

The draw decode now gives a registered type-3 program both the local and
the hull role and marks the tessellation configuration mergedHull. The
local stage only passes gl_VertexIndex and gl_InstanceIndex in a 16-byte
record. The hull stage runs the whole program, one invocation per output
control point: v2 and v5 come from the record of control point
min(gl_InvocationID, inputs - 1), v3 is the relative vertex id, and the
LDS becomes a per-control-point output array that a control point writes
in its own record and reads in any record of its patch after the barrier.
Registers live across the barrier stay in the invocation.

The hull stage of a merged program runs at one lane per invocation on
every device (HostSubgroupSize 1). Its lanes are gl_InvocationID, not host
subgroup invocations, so the s_cbranch_execz around the local part tests
the invocation's own lane. With the device's subgroup it took a subgroup
ballot, and lavapipe, whose subgroup stages lack the tessellation control
stage, rejected the draw ("subgroup capability 61 is unsupported for
shader stage 2").

The lowering refuses more input than output control points, LDS writes
outside the own record, reads outside the patch's records, barriers that
some invocations do not reach or that sit in a loop, reads or writes of
another lane's register, outputs beyond the device limits, and fetch
subroutines. Type 3 is prepared with its stage group like type 5 and
takes its float mode from RSRC1_HS. The hull user-data address (SH
0x102/0x103) is optional for a merged program: s[0:1] take it, unchecked,
when the draw sets it and are zero otherwise.

Both stages refer to one binary, so a draw lists each code and header
region once (AppendProgramMemory); a request's memory regions must not
overlap. An indirect draw's record words go into every program whose user
data holds the register, so the hull stage of a merged program reads
them too.

mergedHull is part of the recompile cache key, the draw decode comparison
and the request serialization (version 39).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-20 15:55:50 +02:00
Daniele Giovane f923961c66 fix(shader): reject temporary owners for borrowed memory regions 2026-10-20 15:47:24 +02:00
sussyandClaude Sonnet 5.5 dd41527ce2 feat(shader): emulate smooth barycentrics on the mesh path
A pixel shader that reads barycentrics on a device without
VK_KHR_fragment_shader_barycentric used to need a vertex shader so a
generated geometry stage could follow it, which a mesh pipeline cannot
have. The mesh program is now compiled a second time with the layout
its pixel shader needs: it writes its clip position as a varying and the
three corner positions of each primitive as per-primitive outputs, and
the pixel shader solves for the weights, for both smooth and linear
interpolation.

The layout is part of the mesh cache key, the stored artifact and the
captured request. Without VK_EXT_mesh_shader the draw still throws, now
saying so. Per-vertex parameters on the mesh path still throw.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-19 17:26:37 +02:00
Adrià FranchandClaude Sonnet 5.5 02c5470080 test(shader): drop the stencil operation value byte from the version 35 request
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-19 12:53:13 +02:00
simonbronkandClaude Opus 5.5 7563b4a480 fix(agc): replace with a stencil operation value the pixel shader exports
With DB_SHADER_CONTROL.STENCIL_OP_VAL_EXPORT_ENABLE the pixel shader
supplies the value that REPLACE_OP and the add and subtract operations
use in place of DB_STENCILREFMASK.STENCILOPVAL. The bit was refused as a
whole, which stopped Onimusha: Way of the Sword (PPSA27836) at a
DB_SHADER_CONTROL 0x45 draw with DB_STENCIL_CONTROL 0x40040 (REPLACE_OP
on depth pass, both faces), write mask 0xff and compare ALWAYS.

The export is accepted with the 32_GR and 32_ABGR Z formats. When no
reachable operation through a non-zero write mask reads the value, it
cannot change the result and is ignored. Without a test value export, a
reachable REPLACE_OP becomes REPLACE with the exported value as
FragStencilRefEXT (or the bounded replay on devices without the
extension), provided both faces compare without the test value and use
no ONES or REPLACE_TEST; early tests throw. The add and subtract
operations, and REPLACE_OP with a test value export, still throw.

The value is read from bits 8-15 of the second MRTZ channel: the
title's pixel shader shifts it left by 8 right before exp mrtz
(v_lshlrev_b32 v0, 8, v0). That is the only evidence for the layout and
it is listed as technical debt. The pixel stage info carries the new
flag into the cache key, the draw keys and request serialization
version 31.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 12:53:13 +02:00
Yunus Shaikh 53cc193a3c Merge main into fix/agc-sample-location-grid-exact
#6503 took request serialization 36 for its float32 flush flag, so this branch's sample order moves to 37. The version relabels in ShaderMemory.cpp and RequestSerializerTests.cpp drop both trailing flags and the sample order.
2026-10-18 22:52:06 -07:00
Adrià Franch 3c95095c21 test(shader): read a version 35 request without the f32 flush flag 2026-10-19 07:00:21 +02:00
ThatsLeo ac14d6317d perf(shader): flush f32 denormals in hardware when a startup probe matches the emulation
Devices with DenormFlushToZero for f32 run the mixed denormal-flush programs with and
without the hardware mode at startup; when every result matches, add, sub, mul, fma,
floor and ceil in the default rounding mode drop their software flush.
2026-10-19 07:00:13 +02:00
Yunus Shaikh 18463ff5c2 Merge main into fix/agc-sample-location-grid-exact
#4650 took request serialization version 35 for its depth remap flag, so this branch's sample order moves to 36. The serialization tests drop #4650's trailing byte from every older version they build, as main's do, along with the iteration fields and the sample order.
2026-10-18 20:56:57 -07:00
Dean Galvin 4d4ae6e5eb Merge main into pr-4650
# Conflicts:
#	core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
#	core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
#	core/shader/recompiler/tests/RequestSerializerTests.cpp
2026-10-19 14:32:36 +13:00
Yunus Shaikh 745f199d5a Merge main into fix/agc-sample-location-grid-exact
Combines this branch's sample order with #6470's once-per-pixel and once-per-sample inputs. The pixel request keeps both sides' fields: #6470's iteration, position location and sample locations are serialized at version 34, and the sample order after them at version 35. The serialization tests move the sample-order bytes after the iteration fields and drop both from older versions. The pixel info collector adds sample order to the SampleLocationsVary inputs, and the draw keys compare and hash both. EmitSampleOffset's iterated index already goes through GuestSampleIndex, since the SampleId builtin does. The shader cache stays at FormatVersion 40, and the sample-location debt entry takes #6470's sentence on the position inputs.
2026-10-18 18:30:37 -07:00
Dean Galvin 5db206aba0 fix(agc): read the depth remap scale and offset from push constants at run time
The remap mode stays a specialization constant and cache key input. Scale and
offset are two push words at byte 104, patched per draw, so draws that differ
only in depth range share one pipeline. The recipe, journal and serializer
carry the mode only.
2026-10-18 19:01:14 +13:00
Dean Galvin 2ec16fb1c2 test(agc): follow request format 33 in the serializer replay tests
The depth remap fields moved to request format 33 when this branch was rebased onto
main's format 32. The replay tests that rebuild older streams now drop and append the
remap tail on top of the linked call fallbacks and the spanned waves flag, and the
depth remap test downgrades to format 32.
2026-10-18 16:38:36 +13:00
Mouad-Scriptz-0andClaude Fable 5.1 53212b18ac feat(agc): remap a viewport depth range the device cannot express into the vertex shader
Without VK_EXT_depth_range_unrestricted a viewport depth range outside
[0, 1] threw. Minecraft (PPSA17221) draws its world with scale 1 and
offset 0 in negative-one-to-one clip space, so its depth is the raw z/w
clamped by PA_SC_VPORT_ZMIN/ZMAX. On such a device the vertex shader now
scales clip z so z/w is the console's depth, the pipeline clamps depth at
the console's bounds, and two clip distances restore the near and far
planes that depth clamping removes. Mode, scale and offset travel as
pipeline specialization constants from the draw's vertex stage info, in
both the per-draw and the registration-module path; mesh and tessellation
draws with such a range still throw.

The console's depth clamp bounds are clipped to [0, 1]: exact for a
normalized depth target or none, and reported once for a tested or
written float depth target, where a depth below 0 is stored as 0
(Minecraft clamps its float depth target to [-1, 1]). The shader
validator accepts the remap's two extra clip distances next to the one
a program may already export.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
2026-10-18 14:27:48 +13:00
Yunus Shaikh f7e1f5d2e8 Merge branch 'fix/agc-sample-location-grid-fallback' into fix/agc-sample-location-grid-exact
Takes #6451's merge of main. Main's spanned-waves flag took request
serialization version 32, so the sample order moves to version 33; a
version 32 request keeps its spanned-waves flag and reads no sample order.
Multisampled color targets now gain storage usage on their first storage
binding; a target whose samples may be reordered still gets it at creation,
and the recorder's storage-usage checks expect that.
2026-10-16 12:46:37 -07:00
Yunus Shaikh bd09c49374 Merge main into fix/recompiler-once-per-pixel-sample-inputs
Main took request serialization versions 31 (output primitive size) and
32 (spanned waves), and #6683 uses 33, so the pixel iteration fields move
to version 34. A version 32 request keeps its spanned-waves flag and reads
no pixel iteration.
2026-10-16 12:41:06 -07:00
Alex ColliniandClaude Opus 5.5 7a6cc71786 feat(agc): carry spanned waves in the target and require full subgroups
APS5_SPANNED_WAVE is now read once by the driver, which sets
SpirvTarget::spannedWaves only on a device with 32-lane compute subgroup
control and computeFullSubgroups. The recompiler no longer reads the
environment. The field is part of the cache key and of the request
serialization (version 32), so a cached or replayed module keeps the mode
it was built in.

A spanned module numbers its lanes SubgroupId * 32 +
SubgroupLocalInvocationId, which needs two full 32-lane subgroups. The
artifact records this as fullSubgroups (disk cache and pipeline identity
included), and the driver creates those pipelines with
REQUIRE_FULL_SUBGROUPS. Compute pipeline captures accept the flag with a
required subgroup size.

The two-lane fallback now catches only SpannedWaveUnsupported, thrown for
a shuffle wider than 32 bits; other emit errors surface as before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 14:12:58 +02:00
billybobpicklioandClaude Opus 5.5 a0347cfed5 feat(agc): draw line-strip output of NGG geometry programs as mesh lines
A geometry program with VGT_GS_OUT_PRIM_TYPE 1 was refused as an
unsupported output assembly. Each primitive export of an NGG line-strip
program is one line whose indices are packed like a triangle's, so the
mesh module now declares OutputLinesEXT with PrimitiveLineIndicesEXT for
it. A subgroup gets VGT_GS_MAX_VERT_OUT - 1 lines per input primitive and
at least GE_MAX_OUTPUT_PER_SUBGROUP line slots; fast launch keeps using
PRIM_AMP_FACTOR. The output size is part of the cache, draw, validation
and pipeline keys, and the request serialization version becomes 31.
Triangle-strip geometry is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 15:39:35 -04:00
Yunus Shaikh 57ceb9e370 fix(agc): keep the guest's sample order where pixel (0,0)'s locations stand in for a 2x2 grid
Village's 2x checkerboard puts its two samples at x = +4/16 and -4/16
and swaps their indices on odd rows. On a device without a 2x2 sample
location grid every pixel takes pixel (0,0)'s locations, so the odd
rows hold the console's sample 1 in sample 0 and the reverse: a pass
that reads the samples by index, as checkerboard reconstruction does,
exchanges the two half-pixels of every odd row, and SampleID, sample
masks and exported coverage name the wrong samples there.

Such a pattern holds one set of positions in every pixel, so drawing
with pixel (0,0)'s locations is exact up to the order of each pixel's
samples. The draw now keeps the guest's order: the pixel shader reads
SampleID, applies the sample mask and exports coverage through each
pixel's order, and every render pass drawing with the stand-in puts the
samples of its multisampled attachments in the stand-in's order before
it and back in the guest's after it. Color targets do that through a
storage view of their texels as unsigned integers, depth through a copy
and a per-sample pass writing FragDepth, and stencil through
VK_EXT_shader_stencil_export or one pass per bit.

It needs shaderStorageImageMultisample with a storage view of the color
format, sampleRateShading, and a depth format FragDepth writes back
exactly (16-bit or 32-bit float); otherwise, and for patterns whose
pixels hold different positions, the stand-in alone is used, and the
log line says why. Devices with the grid are unchanged.

Recompile requests carry the order as serialization version 32 (#6470
takes 31), and the shader cache format becomes 40 (open pull requests
take 37 and 39).
2026-10-15 17:53:11 +00:00
Yunus Shaikh d5cbfd1e12 feat(agc): carry pixel iteration and sample locations in recompile requests
A pixel shader's request now says whether the guest iterates it per
sample (PA_SC_MODE_CNTL_1.PS_ITER_SAMPLE on a multisampled draw), where
SPI_BARYC_CNTL puts POS_X_FLOAT and POS_Y_FLOAT (POS_FLOAT_LOCATION,
bits 17:16, and POS_FLOAT_ULC, bit 20), and the guest's sample
locations for each pixel of the 2x2 quad when the shader reads
PERSP_SAMPLE, LINEAR_SAMPLE or a position at the sample: sample 0's
once per pixel, every sample's when iterated. The fields join the
shader cache key, the draw cache key and the request serialization
(version 31). A missing SPI_BARYC_CNTL reads as the pixel centre and
the reserved location 3 throws.

Devices with sampleRateShading now advertise the InterpolationFunction
capability, which the pixel shader validator accepts.
2026-10-15 16:06:38 +00:00
NikoandClaude Opus 5.5 16ea32c97d feat(agc): blend into color targets with a reversed component order
8_8_8_8 and 16_16_16_16 targets with COMP_SWAP 2 or 3 keep the exported
alpha in their first channel and red or blue in their fourth, so a plain
Vulkan blend would run the alpha equation on a color channel. Such draws
threw "blending into a color target with a reversed component order is
not implemented" (Gran Turismo 7, #4782).

The AMD SI and CIK register references describe CB_TARGET_MASK in the
order of components after blending and before COMP_SWAP is applied, and
RADV programs CB_BLENDn_CONTROL without regard to the swap while it
renders R4G4B4A4, B4G4R4A4, R5G5B5A1 and B5G5R5A1 through SWAP_STD_REV
and SWAP_ALT_REV and passes the CTS blend tests on Navi10. The color
block is therefore taken to blend in export order: the alpha equation
and source-alpha factors use the exported alpha and the destination
alpha is the first channel.

TranslateReversedBlend keeps the factor pairs Vulkan applies per channel
in the pipeline. Other source factors are computed by the pixel shader
from its MRT0 export (clamped for UNORM targets, as BLEND_CLAMP says)
and handed to the blend as a dual-source second color, which the
fragment output post-pass adds at location 0 index 1; when both
positions need it, the export is premultiplied by its source factor.
The code is a pipeline specialization, serialized in request version
26, and stays out of the prepared shader key.

sRGB, SNORM and integer targets, constant and second-source factors,
destination alpha in the color equation, destination factors the two
equations do not share, different color and alpha operations, MIN or
MAX with factors other than ONE, other color exports when the shader
computes factors, and devices without dualSrcBlend still throw, now
with the blend control, mapping and format in the message.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 12:51:27 +02:00
Dean Galvin 5fd9c80faf test(shader): expect request version 29 with the default quad masks in the serializer replays
Requests replayed from versions 22 to 24 now re-serialize at version 29 with
the default quad pixel mask (0xf) and quad sample masks (0xffff) after the dither and front-face flags, plus the empty linked call fallback list.
2026-10-15 13:00:34 +13:00
XairRrR 8dbf06798c fix(shader): honour SPI_BARYC_CNTL.FRONT_FACE_ALL_BITS for the front-face input
The front-face VGPR was always +1.0 / -1.0, which is its form only while
FRONT_FACE_ALL_BITS is clear (current Mesa reads it with fgt 0 / fsign).
With the bit set, as Mesa 22.0 RADV programs it, a back face reads 0 and
a front face non-zero: ACO then tests it with v_cmp_lg_u32 0. Uncharted:
Legacy of Thieves Collection (PPSA05684) sets the bit and its two-sided
cloth shaders test v_cmp_lt_u32 0, so -1.0 (0xbf800000) made every back
face a front face: the insides of the menu skeleton's rags kept their
front normals and were lit white by the spot light behind them.

The pixel stage info now carries the bit (request version 26, cache and
draw keys), the decode reads SPI_BARYC_CNTL when FRONT_FACE is an active
input, and the translator turns the builtin into 0xffffffff / 0. The
exact front value is not measured (docs/dev/debt/shader.md).

AI-assisted: yes
2026-10-14 21:37:48 +02:00
TripyFoxandClaude Opus 5.5 3c1f43948b fix(shader): fault only where a table call misses its linked callees
An s_swappc_b64 whose target is not resolved compiles to a faulting call
only at the fallback the table-call linker emits; the linker lists those
calls in the request (GuestContext::linkedCallFallbacks), and every other
computed call is refused at compile time again, as on main. The new
agc_driver_compute_table_calls test runs a linked two-record table on
Vulkan in wave32 and wave64, with SCC 0 and 1 reaching the callee, and a
record past the table reporting the UnlinkedCall fault.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-15 06:44:25 +13:00
Romans Pokrovskis c8b3a37533 feat(agc): emulate default eight-sample dithered alpha coverage 2026-10-14 12:58:43 +03:00