The LOD warning lwe adds to the texel status is texture-streaming feedback,
which is not reported for the T# MIN_LOD_WARN either. Accept lwe on sample
and gather instructions as it already is on loads and stores; lwe on
image_get_lod still throws.
image_atomic_* with a two-dword data mask (four for cmpswap) is the
64-bit form of an integer image atomic. The decoder rejected it with
"invalid MIMG data mask". PPSA14632 (Unreal Engine) uses
image_atomic_umax this way in a compute shader during its first frames.
Swap, add, sub, signed and unsigned min/max, and, or, xor and cmpswap
now decode with 64-bit data and translate to new ImageAtomic*64 IR
opcodes. An image updated by them gets its own descriptor binding
range, declared as an R64ui image of 64-bit integers, and the module
uses Int64ImageEXT from SPV_EXT_shader_image_int64. The driver enables
shaderImageInt64Atomics when the device offers it and binds an
R64_UINT view of the 32_32 UINT, SINT or FLOAT surface. Without the
feature, recompiling such a shader throws.
64-bit inc, dec and the float atomics still throw, as does any other
access in the same shader to an image it updates with 64-bit atomics.
The new agc_driver_image_atomics64 test runs every operation on 32_32
UINT, SINT and FLOAT surfaces and checks the returned and stored values
against edge cases across the dword boundary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decode MIMG opcode 0x80 on 2D MSAA and 2D MSAA array images with a
single-bit dmask and return four dwords: the selected component of the
fragment named in the address and the three that follow it. Each fragment
is read with its own image fetch, adding the fragment step to the packed
address dword so a16 layouts keep working.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
image_sample_cd takes its derivatives in the image_sample_d address
layout; only the hardware LOD selection differs (one LOD per quad instead
of per pixel). The decoder refused it. It now samples with the given
gradients per lane, which matches whenever the lanes of a quad pass equal
derivatives.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
MIMG 0xe7 is the node test of image_bvh_intersect_ray with a 64-bit node
pointer: the pointer takes the first two address dwords (low, high), so
the instruction addresses 12 dwords, or 9 with A16.
The node index and address are computed from the whole pointer. A zero
base in the T# is a null BVH only for the 32-bit form: with 64-bit
pointers the T# may cover all of memory from base 0 and the pointer then
carries the node address, so only the T# size bounds the node.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a16 the bias is a half that occupies a full address dword and the
coordinates start in the next one. The layout packed the first
coordinate into the upper half of the bias dword, so image_sample_b,
image_sample_b_cl, image_sample_b_o and the biased gathers read their
coordinates from the wrong halves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The three MIMG float atomics threw as unknown opcodes. They now run as a
compare-and-swap loop on the 32-bit texel with the bit-level rules the
float buffer atomics already use (NaN, signed zero and sNaN quieting as
measured on RDNA2), so no float atomic feature is needed from the driver.
Co-Authored-By: Claude <noreply@anthropic.com>
Write the raw texel bits: dmask bit i selects texel dword i, taken from the
next data register, and every other dword of the texel is written as 0; the
descriptor swizzle is ignored (measured on RDNA2 hardware). Only formats whose
bits go through the storage view unchanged are accepted (unsigned integer
components, raw 32-bit signed integer and 32-bit float); normalized, 16-bit
float, narrow signed and 96-bit formats throw.
Co-Authored-By: Claude <noreply@anthropic.com>
Return the raw texel bits: dmask bit i selects texel dword i, dwords past the
texel read 0 and the _sgn forms sign-extend texels narrower than 32 bits
(measured on RDNA2 hardware). Only formats whose bits are exactly recoverable
from the sampled view are accepted (unsigned/signed integer, unorm up to 16
bits, 32-bit float components), on a direct sampled image with identity
swizzle; anything else throws.
Co-Authored-By: Claude <noreply@anthropic.com>
MIMG opcode 0x33 samples with explicit derivatives, an LOD clamp and a
texel offset. The three address flags already exist; only the opcode was
missing from the decoder table.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decode MIMG image_atomic_cmpswap, sub, smin, smax, inc and dec and
recompile them on the image texel pointer. sub, smin and smax map to
the SPIR-V atomic of the same name. cmpswap takes the new value from
VDATA[0] and the comparand from VDATA[1] (dmask 0x3) and returns the
previous value in VDATA[0]. inc and dec use the compare-exchange loop
of ds_inc/ds_dec, whose replacement helpers are now shared.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the lines this branch added lose their comments; the commits before
keep them, with the reasoning behind each change, for whoever digs into
that code later.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every ray query returned a miss (a stub). The node test is now the GFX10
(RT IP 1.1) one AMD's GPURT software fallback defines (IntersectCommon.hlsl)
with the TriangleNode1_0 and BoxNode1_0 layouts, as SharpEmu ports it: the T#
(base, size, box grow and sort, triangle return mode) and the node pointer
are run-time values, triangle nodes return t over its denominator with the
barycentric numerators or the triangle id, float16/float32 box nodes the hit
children (clipped slabs, NaN misses, optionally sorted by entry time); an
inactive lane, a null BVH, an out-of-range node or another type returns four
invalid dwords.
The decoder addresses 11 dwords (8 with A16, the directions as halves), the
translation emits ImageBvhIntersectRay with the T#, MakeImageAddress and exec,
and the program takes the BDA path: one probe covers the node and direct loads
read it (a node the table does not map as one range records an Unmapped
fault); EmitBdaDwordReads can read every dword for the per-byte fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- MIMG word0 bit 12 (UNORM) is accepted on every op without a sampler
(compute image stores set it, as the ISA asks); sample and gather still
reject it, and rejections name the instruction words.
- The image_sample_*_a opcodes keep the plain address layout, as in Kyty.
- The _cl LOD clamp becomes the MinLod image operand (or clamps an
explicit level) on devices with shaderResourceMinLod; a gather with a
clamp fails loudly.
- v_add_co_ci_u32, v_sub_co_ci_u32 and v_subrev_co_ci_u32 in VOP3 form
take their carry-in from the SGPR pair of their third source, not VCC:
a glyph upload's reciprocal division corrected its quotient on the
wrong lanes and UI text came out stippled.
- Pixel exports follow each MRT slot's component mapping and write only
the components of their export format (32_R, 32_GR, 32_AR).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comments in this codebase may only mark technical debt (human-added
only), the end of #endif, and the end of a namespace, per
docs/dev/CONVENTIONS.md. Remove the inline rationale comments added in
the AGC PM4 opcode and shader recompiler robustness commits; the code
itself, the commit history, and the PR description now carry that
context instead.
Notably, Command::WriteMemSemaphore takes the corrected 4-argument
form (address, waitForMailbox, signalType, operation): an earlier
revision of this helper used a different, incompatible argument
order. sceAgc*MemSemaphore callers derive waitForMailbox/signalType
from the low two bits of clientCode, and operation from action
(0 = signal, 1 = wait). This ABI note previously lived as an inline
comment; it is recorded here instead per the no-comments convention.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Optimization/SrtWalker/SrtPlanBuilder.cpp: PlanBuilder::Collect now requires
RuntimeValidator(...).Run(inst) before folding an offset built from a Phi merging a
constant on one path with a per-invocation value on another. Confirmed upstream's
Collect is unchanged since the fork (still just offset->HasImmediate()), so a Phi
that reports HasImmediate() on its constant edge alone could still be folded into
the wrong, divergent SRT slot.
- RdnaDecoder + Translation: adds an IMAGE_BVH_INTERSECT_RAY (opcode 0xE6) decode path
and a TranslationContext::imageBvhIntersectRay stub that reports a clean hardware
miss (all result dwords 0xFFFFFFFF) instead of faulting on an undefined MIMG opcode.
No BVH/ray-tracing support exists upstream at all, so this is an honest "not
supported yet" stub, not a silent wrong answer.
- SpirvBackend/RectListShaders.cpp: raises the accepted spirvVersion ceiling to
0x10500 and truncates excess fragment interpolants to the tightest per-vertex
tessellation component limit instead of hard-refusing the whole rect-list draw.
A rect-list draw is a tile clear, so a pixel shader's result comes from its
constants and render target; truncated interpolants are simply left unwritten,
which upstream's own "missing" (unexported) parameter handling already tolerates.
Dropped after checking against current upstream (both would be redundant or
out of scope):
- ResourcePlanKnownToFail / SpirvWords (Recompiler.cpp/hpp): upstream already has an
equivalent mechanism for both. SourceEntry::planFailure (std::exception_ptr) already
memoizes and rethrows a failed IrResourcePlan build, and RecompileResult::spirv is
already the refcounted/hashed SharedSpirv class (see Recompiler.hpp), not a plain
vector. Porting either would have added a second, competing mechanism.
- ScalarInstructions.cpp SAVEEXEC changes: skipped. The audit could only confirm 3 of
6 64-bit SAVEEXEC cases were converted in the prior patch, which is a half-finished
edit rather than a complete correctness fix; not safe to port without re-deriving
sSaveexec()'s full semantics from scratch.
- ControlFlowInstructions.cpp vMovrelsB32/vMovreldB32 hardening (offset & 0xFF mask +
kMaxM0RelativeWindow cap): skipped as optional per review; upstream's core fix for
this file is otherwise already in place.
- All diagnostic-only stderr tracing (IrBuilderCore.cpp, ResourceTracker.cpp,
ShaderInfoCollector.cpp, SrtDescriptorEvaluation.cpp, SrtEvaluator.cpp,
SpirvMemoryInstructions.cpp) and the superseded Optimization/ResourceProgram.hpp
API (replaced upstream by CaptureResources/SourceHandle/ResourceCapture): not
ported, no functional change or already gone upstream.