PPSA12361 binds color format 7 (COLOR_11_11_10, float) with COMP_SWAP 0
and stops on "unsupported color format 7 number type 7 component swap 0".
Only the reversed order (COMP_SWAP 2) was accepted.
The format keeps its 10-bit component in the low bits. The standard
swap puts red in the first slot, as Mesa pairs SWAP_STD with
COLOR_10_11_11 for R11G11B10_FLOAT, so COMP_SWAP 0 puts red there and
COMP_SWAP 2 blue. Swap 0 now decodes with the identity export mapping
0xe4 and the same packing; the other swaps still throw.
The decode test accepts swap 0 and keeps refusing swaps 1 and 3. The
execution test renders both orders into tiled and linear targets and
compares each stored word with the packing of the order. Its program
pool grows to fit the second pass. The debt entry names the accepted
orders and says the swap 0 layout is derived, not measured.
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
A FLAT_SHADE input without pass-through that a pixel shader reads
through v_interp_mov_f32 P20 and not P10 stayed an explicit per-vertex
input and read vertex 2 minus vertex 0. For a flat value that is the same
on every vertex the difference is 0, and with the first provoking vertex
nothing refused it.
ps5-opengl lowers every flat input to a load of one vertex: vertex 1
(P10) by default, which #4030 reads as the provoking vertex, and vertex 2
(P20) for triangles when GL's flatshade_first is set. SuperTuxKart's
deferred point lights are drawn that way, so all twelve flat inputs of
pointlight.frag read 0, the attenuation 0 * -inf was NaN, nothing was
discarded, and the starting-line referee's light quad blacked out the
scene behind it (#8364).
A P20-only read now returns the provoking vertex's value, as P10 and P0
do. The lane was not measured on the console either, so FragmentParameter
records it and a pipeline using the last provoking vertex throws. An input
read through both P10 and P20 keeps its per-vertex differences.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A guest read over the depth or HTILE range of a native multisample depth
surface threw even when the host had not written the surface since its
import. Its samples are then still the clear value the import took from
the guest HTILE, so the guest bytes already describe it. Retire such a
surface and its guards instead, and keep the refusal for a surface the
host wrote: draws with depth or stencil writes, depth/stencil copies and
storage write-back.
Onimusha: Way of the Sword (PPSA27836) imports a 4-sample D32 target,
draws into it once with depth tests only and no color target, then reads
the memory back as a structured buffer in a compute dispatch.
Unblocks PPSA27836.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A line list or strip drawn with PA_SC_AA_CONFIG above 1x and
PA_SC_MODE_CNTL_0.MSAA_ENABLE clear threw, and METAL GEAR SOLID: Peace
Walker (PPSA18216) draws such lines into its 4x target. They now take
the path triangles already take in this state: the target's sample
count with every sample at the pixel center, or one sample under a
one-sample color target.
The refusal now reads the primitive the draw rasterizes
(RasterPrimitiveOf) instead of VGT_PRIMITIVE_TYPE: a point list that a
geometry program turns into triangles or lines is drawn as those, and
rasterized points and alpha-to-coverage still throw. No draw on main
rasterizes points in this state, because a vertex-path point list and
a geometry program's point output throw earlier; the point term takes
effect once they are drawable, as with #6801.
The new GPU test decodes a line list and a line strip into a 4x target
in this state with DecodeState, draws the decoded state, and requires
every pixel to be covered in all four samples or in none.
Co-Authored-By: Claude <[email protected]>
An RX 6700 XT hands a geometry shader odd strip triangle i as
(i+1, i, i+2) with the last provoking vertex, which is the order the
translator already uses, and since #7374 last mode takes the flat
outputs of the program's primitives from their last index. Keep the
last-mode refusal for fans only, which reach the program as
(i+1, i+2, 0) while the hardware gives (0, i+1, i+2). TEKKEN DARK
RESURRECTION (PPSA31371) stops on such a strip draw.
Co-Authored-By: Claude <[email protected]>
A read of memory inside a stale D32 Z_X depth plane (FlushDepthPlanes) stored
the whole plane: a copy of the depth image into the mirror, MarkWholeWritten
and a write-back of every byte. In Super Meat Boy 3D (#8840) a read-only
buffer ending about 3 KiB inside a stale 3840x2160 plane makes
ShaderResources::Revalidate flush ~1000 times per 5 s, each one moving
31.9 MiB, bound by transfer bandwidth.
A depth surface now tracks its plane as 64 KiB units, each one 128x128 tile
of the mirror's block units: a stale bit and a write generation per unit
replace memoryStale and the plane-wide syncedGeneration.
- FlushDepthPlanes stores only the stale units the range overlaps: the depth
to mirror copy takes one region per unit rectangle (UnitRects, from the
mirror's slice windows), the mirror marks just those units written
(MarkUnitsWritten) and the write-back covers their hull. The other units
stay stale and the plane stays registered. Stale bits are cleared only
after the copy was recorded, and the stored units' generations advance
only when FlushPending stored them. A depth fast clear still pending at
the store rewrites the whole image, so it makes every unit stale first.
- SyncFromMemory copies from the mirror only the units the guest wrote since
their own generation (one ChangedBlocks scan; untracked memory counts as
unwritten, as WrittenSince did), so a guest write into one unit no longer
replaces GPU depth that is still unstored in the others.
- Flushes followed by a retire keep the whole-plane store: the color target
flush in Draw and a written storage view (DepthPlaneScope::Whole). The
retire of an overwritten surface in DepthSurfaceTexture first stores its
remaining stale units the guest did not write.
- A mirror without block units (APS5_NO_BLOCK_TRACKING, unaligned base)
falls back to the whole-plane copy, and APS5_DEPTH_PLANE_WHOLE_STORE=1
tracks the plane as one unit, the previous behaviour.
- DepthPlaneStoreCounts reports stores, units and bytes stored.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A draw with DB_RENDER_CONTROL.DEPTH_COPY copies one sample of the
Z_32_FLOAT depth surface into color target 0. It now runs as a compute
pass that fetches that sample and stores it into the R32 float target,
when the draw covers the whole surface without depth or stencil tests.
With COPY_CENTROID the sample is the first one the draw covers, which is
sample 0 under the full sample mask the driver requires, as radeonsi
programs its per-sample DB to CB copies.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
PA_SU_SC_MODE_CNTL with POLY_MODE set to a point or line type was refused,
and every triangle was drawn filled. The state decode now takes the polygon
type of the faces that are not culled into State::polygonMode, ignores the
types when POLY_MODE is clear or the primitives are points or lines, and
keeps refusing front and back types that differ while both faces are drawn.
Points are drawn one pixel wide (PA_SU_POINT_SIZE 0x00080008 inside
PA_SU_POINT_MINMAX), the size VK_KHR_maintenance5 gives a point whose
shader does not write PointSize, and lines one pixel wide (PA_SU_LINE_CNTL).
The device enables fillModeNonSolid and maintenance5 when they are
available. The polygon mode joins the pipeline, library and draw keys and
the pipeline journal (format 5).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A store to the trimmed tail of a written buffer would be dropped instead
of failing as an alias of the render target, so only read-only buffers,
such as per-attribute vertex fetches, are trimmed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>