Commit Graph

29 Commits

Author SHA1 Message Date
Adrià be8a67db1c
Merge pull request #3228 from GustavoGamarra95/feat/agc-alpha-to-coverage
feat(agc): emulate undithered alpha-to-coverage
2026-10-11 09:22:23 +02:00
ThatsLeo 24c4dbae1e fix(shader): keep f64 denormals where the device can preserve them
Shaders with f64 instructions now declare DenormPreserve for 64-bit floats
when the device reports shaderDenormPreserveFloat64. Without it Mesa ANV
flushed the subnormal result of v_fma_f64 to zero.

(cherry picked from commit 7df6c709de994cea0019707d45b6e7b96698fad1)
2026-10-11 03:09:34 +00:00
Gustavo Ariel Gamarra Rojas d152ff833c feat(shader): turn the MRT0 alpha into a sample mask for alpha-to-coverage
A pixel shader whose stage info asks for alpha-to-coverage declares SampleMask, starts with every sample covered and, at its MRT0 export, clears the mask when the alpha is below one half or NaN, running with late fragment tests. The shader keeps running, as a zero coverage mask does on the GPU. The flag is part of the static shader identity and of the request serialization, now version 16.
2026-10-10 22:50:46 -03:00
Adrià Franch 0cbc9586bc feat(shader): carry the shader float mode into the recompile request
Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-08 22:17:07 +02:00
boykopovar 7431e5a6e1 perf(shader): restore prepared vertex inputs + harden buffer specialization 2026-10-08 17:28:55 +03:00
boykopovar 2a117a6e5a fix(shader): apply fragment export mappings at runtime 2026-10-08 17:28:29 +03:00
boykopovar cb57d2502a fix(shader): align prepared graphics with draw stage decoding 2026-10-08 17:27:58 +03:00
boykopovar dc62c432b4 perf(shader): eliminate redundant prepared invocation work 2026-10-08 17:27:26 +03:00
boykopovar b2a4813307 refactor(shader): remove resource specialization from artifact key 2026-10-08 17:26:38 +03:00
boykopovar 27439c43cc feat(shader): version runtime abi + freeze device capabilities 2026-10-08 17:26:01 +03:00
boykopovar ae9a36e075 feat(shader): execute vertex fetch through runtime buffer descriptors 2026-10-08 17:25:35 +03:00
nisbenz f025a9e506 fix(shader): read s_memtime from the device clock where RADV's subgroup clock is 20 bits
On GFX10.3 to GFX11.7, ACO lowers a subgroup-scope OpReadClockKHR to
s_getreg_b32 of SHADER_CYCLES, 20 bits zero-extended to 64, so s_memtime
wrapped every 2^20 cycles and went backwards. Detect those families from
the RADV device name and read the device clock there instead.

Fixes #985

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 14:42:40 +02:00
Celegans12 e1d4e699be feat(agc): implement primitive-ordered pixel shaders with fragment shader interlock
DecodeState and the draw precheck rejected DB_SHADER_CONTROL bit 16,
PRIMITIVE_ORDERED_PIXEL_SHADER (POPS), which runs the ordered section
of overlapping pixels' shaders in primitive order. The bit now reaches
the recompiler as a pixel stage field, and such a pixel shader declares
PixelInterlockOrderedEXT and runs its whole body between
OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT; an
invocation that a BDA read fault kills ends the interlock first. The
POPS collision SGPRs read 0, so a title skips its POPS wait and runs
its per-collision loop once. An image_load still reads a sampled
binding, which misses an earlier overlapping primitive's image_store in
the same draw. The device enables VK_EXT_fragment_shader_interlock when
it has fragmentShaderPixelInterlock; without it the recompile throws,
as does a nonzero POPS_OVERLAP_NUM_SAMPLES. The field is part of the
recompile cache key, the draw key and the serialized request (version 10).
2026-10-08 11:18:46 +02:00
Michon 20e055c244 feat(agc): compute dispatches with scratch memory
A compute program with COMPUTE_PGM_RSRC2.SCRATCH_EN takes its per-lane private size from the AGC
shader header (scratch_size_dw_per_thread) instead of being refused. The size travels in
ShaderComputeStageInfo (cache key, request serialization version 10) to the translator, whose
scratch accesses already lower to a per-invocation Function array of that many dwords.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-08 10:22:40 +02:00
Celegans12 91852719bf feat(agc): implement 8 and 8_8 srgb image loads through unorm views
NVIDIA 610.62 cannot sample R8G8_SRGB, and lavapipe can sample neither
it nor R8_SRGB, so an 8_8 sRGB T# made an image the device does not
support: creating it crashes the NVIDIA driver and lavapipe loads zeros.

The device's format support is read once. An 8 or 8_8 sRGB texture the
device cannot sample is created and viewed as R8_UNORM or R8G8_UNORM,
and SpirvTarget::srgbDecodeFormats makes the materializer mark the
image, so image loads map every channel through a 256-entry table of
the sRGB EOTF rounded to nearest even at bf16 precision, which is what
RDNA2 (gfx1035) returns; both channels of 8_8 are sRGB, and DST_SEL 0
and 1 map to themselves. Samples and gathers of such an image throw,
and its bindless table entries are unmapped like converted formats.
APS5_SRGB_SHADER_DECODE=1 takes this path on every device. Shader disk
cache entries and keys carry the mark: cache format version 7.
2026-10-07 11:52:08 +02:00
Celegans12 4a67b140fc feat(agc): accept conservative Z export in DB_SHADER_CONTROL
DecodeState, the draw precheck and DecodePixelStageInfo rejected every
nonzero CONSERVATIVE_Z_EXPORT (DB_SHADER_CONTROL bits 13-14).
EXPORT_LESS_THAN_Z (1) and EXPORT_GREATER_THAN_Z (2) promise that the
exported Z stays on one side of the interpolated Z. The value now
reaches the recompiler as a pixel stage field, and a pixel shader that
writes FragDepth declares DepthLess or DepthGreater next to
DepthReplacing, the SPIR-V modes RADV maps to these values. Vulkan lets
those modes only add a depth test of the interpolated Z before shading,
so a shader that keeps the promise renders the same. The reserved value
3 still throws.

The field is part of the recompile cache key, the draw key and the
serialized request (version 7), and ValidateShaders accepts both modes.
2026-10-06 00:35:43 +02:00
Dean Galvin 301f3b161e fix(recompiler): sample with texel offsets the guest computes, through maintenance8's Offset
image_sample_*_o takes its texel offset from an address VGPR. The emitter
accepted only an immediate there and failed with "requires a constant texel
offset for image sampling" for any other, including an offset the program
moves into the VGPR under EXEC.

An offset that resolves to a constant at its packed address position stays a
ConstOffset. Any other becomes the Offset image operand, which Vulkan allows
on sampling instructions only with VK_KHR_maintenance8's maintenance8 feature
and the ImageGatherExtended capability. The device enables maintenance8 when
available and reports it through SpirvTarget::nonConstantImageOffsets, which
the cache key, the request serialization (version 6) and the SPIRV-Tools
validator options follow. Without it the sample still fails.

agc_shader_replay --maintenance8 recompiles a request for such a device.
2026-10-02 12:26:31 +13:00
boykopovar 7c5f8b6e12 Revert "Merge pull request #143 from SamG-Coder/codex/shader-geometry-validation"
This reverts commit de49f81697, reversing
changes made to cfb1d76e60.
2026-10-01 22:55:27 +03:00
boykopovar 171c9a97b2
Merge pull request #230 from asimplestray/feat/rt-miss-mode
feat(shader): add ray tracing miss fallback mode
2026-10-01 21:56:27 +03:00
asimplestray c3a740b3e6 feat(shader): add ray tracing miss fallback mode 2026-10-01 17:24:09 +00:00
SamG-Coder 4cd8e35366 fix(shader): preserve NGG passthrough launch and primitive inputs 2026-10-01 20:43:17 +10:00
Dean Galvin cb66ec2004 feat(agc): centroid pixel inputs and NoPerspective by I/J pair
SPI_PS_INPUT_ENA/ADDR with PERSP_CENTROID (bit 2) or LINEAR_CENTROID
(bit 6) was rejected; PPSA21564 binds 0x326 (perspective center and
centroid, linear center, POS_X/Y).

The PS input VGPR layout now follows the hardware rule: SPI_PS_INPUT_ADDR
places every input it names in SPI order (two VGPRs per I/J pair, three
for the pull model, one otherwise), loaded or not, and ENA & ADDR selects
the loaded ones. ShaderPixelStageInfo carries inputAddr (replacing
perspectiveCenterVgpr) plus perspectiveCentroid and linearCentroid; the
recompiler places each loaded input with PixelInputVgpr. This also fixes
the system inputs, which were always written from v0 (psSystemInputBase
was never set), so POS_X overwrote the center I in any draw with
barycentrics enabled.

Draws are rasterized single-sampled, where the centroid is the pixel
center: with fragment barycentrics the centroid pairs carry the center
barycentrics (BaryCoordKHR for perspective; the linear center and
centroid pairs now get BaryCoordNoPerspKHR).

NoPerspective was decided for every parameter by one flag (LINEAR_CENTER
loaded). v_interp_p2 now records whether it reads the J of a linear or a
perspective pair, and a parameter is NoPerspective when it is read
through a linear pair; parameters read through neither keep the old
rule. A parameter read through both kinds of pair throws. Only pixel
stages consult this.

The request serializer moves to version 5 (older requests read back with
their loaded inputs as the layout); the cache key and the driver's draw
key compare and hash the new fields. The unsupported-input error names
ENA and ADDR.
2026-10-01 08:37:45 +13:00
asimplestray 976fa82054 feat(shader): configurable ray tracing miss fallback 2026-09-30 16:53:03 +00:00
Dean Galvin 33f9109999 feat(shader): translate NGG geometry programs to mesh shaders
The geometry path's merged ES/GS programs (VGT_SHADER_STAGES_EN.GS_EN)
were compiled as mesh-stage programs whose input metadata was never
filled in, so every such draw failed with "mesh shader translation
configuration is not supported".

Recompiler:
- BuildShaderStageInputInfo takes the draw's MeshConfiguration; the mesh
  input helpers (primitive size, step and counts) are implemented.
- The prologue emulates one NGG subgroup per workgroup: s2 GS_TG_INFO,
  s3 the merged wave info per wave, the GS vertex offsets (ES thread
  index times VGT_ESGS_RING_ITEMSIZE, odd strip triangles swapped), the
  primitive id, and the ES vertex and instance ids. An indexed draw's
  vertex id is read from the index buffer through a raw V# the driver
  puts in hidden user words 4..7.
- s_sendmsg GS_ALLOC_REQ becomes MeshAllocate. The epilogue zeroes the
  allocation first, clamps it to the output limits, culls primitives no
  thread exported and decodes the 9-bit vertex indices.
- The draw parameters live in the last six push dwords. A BDA fault in
  a mesh program no longer stops the invocation (as for other programs
  with barriers, the fault is recorded and the read returns zero), so
  every invocation reaches the subgroup barriers and the epilogue.
- The cache keys cover the mesh configuration; requests serialize its
  new esgsItemSize field (version 4).

Driver:
- DecodeShaderStages reads VGT_ESGS_RING_ITEMSIZE (now in the draw key)
  and sizes the subgroup for its ES vertices, GS primitives and outputs.
- Stages compile below the mesh draw parameters, which every mesh draw
  pushes; the mesh stage always takes part in the push range.
- The index-buffer V# is set per draw (per record on the CPU-resolved
  indirect path); the index-buffer alias check spares read-only
  elements.
- The workgroup and LocalSize checks count two guest lanes per
  invocation on 32-wide subgroups; mesh draws may carry a first vertex
  or instance.

agc_driver_mesh_tests (EXCLUDE_FROM_ALL, needs VK_EXT_mesh_shader)
recompiles a hand-assembled merged ES/GS program in the PS5 compiler's
layout and draws indexed and non-indexed triangle lists in one- and
two-wave subgroups and a triangle strip across odd-starting subgroups,
reading the pixels back. agc_shader_replay prints a request's draw and
mesh configuration.
2026-09-30 23:57:47 +13:00
STL1te 000d0bf4f0 feat(shader): retire threads past a partial thread-dimension dispatch
A dispatch sized in threads (USE_THREAD_DIMENSIONS) launches a partial last
workgroup on RDNA2, but the host rounds it up to whole groups, so the extra
threads ran: past the end of a node list they read past it and wrote over
live records.

Such dispatches now compile a separate variant (ShaderComputeStageInfo::
partialThreads, keyed only on whether it is set) whose entry EXEC excludes
threads at or past the requested size. The size reaches the shader as three
shader data dwords after the memory offsets (StageInputKind::
DispatchThreadLimit), is mixed into the dispatch cache key and the result
memo hash, and serialized in recompile requests (version 3). Whole-group
dispatches keep their variant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 21:22:19 +03:00
SamG-Coder 8cef034172 fix(shader): safely destroy compiler thread-local storage on Windows 2026-09-28 19:54:01 +10:00
devilismyfriend 29b4601564 perf(agc): dispatch and draw recipes, data-only cache hits, unit shadows, bindless image tables
Dispatch cache with per-key value variants and data-only hits (flat-SRT leaves the recompiler
proves pure are refreshed into the resource template instead of re-captured), dispatch and draw
recipes replaying a proven prepare, register-keyed draw entries, template data refresh, unit
shadows in device-local slabs, 64 KiB block-unit storage tracking with windowed detile, DCC
clear-key proofs, per-class GPU timing, a CPU copy path with batch read tracking, present slot
ring, rate-limited reaps and lazy completion counting, plan-failure and poisoned source memos,
bindless image tables (runtime-indexed descriptor arrays from a CPU-read table) so the
per-frame compute program that failed its plan now compiles. Worker affinity opt-in, per-draw
logs behind APS5_TRACE_DRAWS, wait-timeout reports include the recorder's view of the label.
Fixes a use-after-free behind BDA-miss dispatch snapshots and the CPU-write stamp of
UnchangedSinceCollected. Intro-video stage: 154 -> ~500 presents per 10 s at 4K.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-26 19:00:40 -07:00
devilismyfriend 87911b3bb5 fix(recompiler): saveexec operand order, atomic-zero rewrite, cache keys
- s_*_saveexec reads its source before writing the old EXEC into the
  destination, so the aliased form (vcc, vcc) computes exec & vcc; the
  per-lane exec bit comes from the lane's own bit. Every Bink 2 decoder
  kernel uses that form; this was the video corruption.
- buffer atomics add/sub/or/xor with a zero operand become an atomic
  load or nothing.
- DescriptorBinding carries bufferWritten/bufferAtomic/imageWritten;
  results expose a variantId and share SPIR-V copy-on-write; source
  keys use a length plus 64-bit hash; captures can be reused.
- wave-LDS ordering barriers, v_movrels/v_movreld lowering, SMEM with a
  VCC base, f16 conversion opcode fix, a per-function SPIRV-Tools pass
  list, env-gated IR dumps and probes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177gthrWEBBfBu5xJDXgBfo
2026-09-25 16:27:49 -07:00
boykopovar bf43995e8e feat(shader): implement enable cache field in recompile request 2026-09-24 20:59:34 +03:00