Commit Graph
121 Commits
Author SHA1 Message Date
Dean bcf29de5d0 Merge pull request #8273 from thuanquang/test/large-cache-file-cleanup
test(agc): remove the large cache file test directory when the test fails
2026-10-21 02:53:04 +13:00
Maz 18da29b898 fix(shader): keep recompiler diagnostics off guest stdio 2026-10-20 16:01:02 +04:00
Romans Pokrovskis 56778c97d2 test(shader): exercise long-path mapped cache persistence
(cherry picked from commit 83ad99879035e1418a5fa500cf061b236ec0a867)
2026-10-20 14:25:57 +06:00
thuanquangandClaude a8f47b3322 test(agc): remove the large cache file test directory when the test fails
runLargeFileWrite writes a 2 GiB pipelines.bin into a randomly named
temporary directory, and only the passing path removed it. A failing
require after the write and the 200 s hang limit (std::_Exit) left the
file behind, and the two skips left the empty directory. A local Cleanup
now removes the directory when the function returns or throws, and the
hang path removes it before std::_Exit and prints the error when it
cannot, as on Windows while the write still holds the file open.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-10-20 15:01:18 +07:00
Adrià 9b4b3cf463 Merge pull request #6941 from kq62/fix/mesh-barycentric-emulation
feat(shader): emulate barycentrics and per-vertex parameters on the mesh path
2026-10-20 00:17:49 +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 <noreply@anthropic.com>
2026-10-19 17:26:37 +02:00
thuanquangandClaude Opus 5.5 1ed8eb6d8b fix(shader): sample a 3D T# through DIM 2D_ARRAY as a volume
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:19:13 +02:00
Dean Galvin 41764f27ac Merge main into pr-4650
# Conflicts:
#	core/shader/recompiler/ShaderDiskCache.cpp
2026-10-19 15:36:07 +13:00
Karan Vora 6d92220829 perf(agc): stage raw buffer elements a dispatch sweeps
Since 2688b7646 a read and written V# element is staged in device memory
up to 16 MiB when the direct dispatch's threads times the V# stride cover
at least half of it. A raw buffer has stride 0, so it never passed and
kept the 2 MiB written window: GL storage buffers compiled by Mesa stay
bound in place in the host import however hard a dispatch sweeps them.

The PS5 OpenGL Showcase's particle update (262,144 threads, each loading
and storing its own 32-byte record of an 8 MiB SSBO) took about 53 ms of
GPU per frame on an RTX 4060 bound in place; staged it takes about 0.1 ms
plus 2.2 ms of bulk copies.

The recompiler already records the furthest byte each buffer resource's
accesses reach past their base (maxByteExtent). The binding plan now
carries it per guest buffer element (DescriptorBinding::bufferExtent,
shader disk cache format 37), and a raw element uses it as its record
size in the sweep test. Strided elements are unchanged.
2026-10-19 03:43:19 +02:00
Yunus Shaikh 10b798fb99 Merge main into perf/shader-image-table-reuse-v3-pr
Keeps this branch's tagVariantRuns declaration next to main's dumpRequest suffix parameter in Driver.hpp, and reads #6232's pointer-chain test words from its table's snapshot, where this branch keeps them.
2026-10-18 17:03:39 -07:00
Dean Galvin cf4d1f4a97 Merge main into pr-4650
# Conflicts:
#	core/shader/recompiler/ShaderDiskCache.cpp
2026-10-19 11:15:57 +13:00
Adrià c7e28608b1 Merge pull request #6232 from ANONYMOUSZED-beep/feat/image-table-pointer-chains
feat(shader): follow pointer chains from image-table records to the T#
2026-10-18 22:50:22 +02:00
Adrià fb9a1eb8f3 Merge pull request #6178 from MarcZX10/codex/release-undrawn-resource-plans-6139
perf(agc): release unused registered shader resource plans
2026-10-18 22:20:27 +02:00
ANONYMOUSZED-beep 486f3069ae feat(shader): follow pointer chains from image-table records to the T# 2026-10-18 20:49:04 +02:00
Yunus Shaikh d0325058f7 Merge main into perf/shader-image-table-reuse-v3-pr
#7527's selected-record limit test reads a record's descriptor words through the
table snapshot's shared words list; this branch keeps a snapshot's words per column,
so the test reads them from its column instead.
2026-10-18 11:33:00 -07:00
Gjon Gojcevic a2e79fb3fd fix(shader): bind an unnormalized S# normalized when it samples only null images
An S# that forces unnormalized coordinates was refused when it samples a
T# the shader declares 3D, 2D-array, cube or multisampled, since Vulkan
allows unnormalized coordinates only with a single-level 1D or 2D view.
A null T# reads zeros at any coordinate, and a T# whose channels all
select constants is emitted as those constants without a sample, so when
the S# samples no other T# its coordinates cannot change a result. Such
an S# is now marked in its binding (samplerCoordinatesIgnored) and the
driver creates its sampler without FORCE_UNNORMALIZED. The flag is part
of the binding content key and of the shader disk cache, whose format
version is raised to 38. An S# that also samples a real T# while a null
T# of such a shape shares it is still refused. PPSA01317 pairs an
unnormalized clamped bilinear S# with a null 3D T# and a 3D T# whose
channels all select 0 for image_sample_lz in a compute shader during
boot.

AI-assisted: yes
2026-10-18 09:02:31 -04:00
Dean Galvin b876d43fb1 fix(agc): journal whether a vertex shader reads the depth remap push words
The flag that adds the vertex stage to the push constant stages was not part
of the encoded result, so a journalled remapped vertex shader replayed
without it. Encode and decode it with the invocation and cover it in the
result round trip and the push stage test.
2026-10-18 23:28:51 +13:00
Yunus Shaikh 6720211da1 Merge main into perf/shader-image-table-reuse-v3-pr 2026-10-17 19:24:20 -07:00
Dean 0e94c5d434 Merge pull request #6243 from EagleBearerYS/perf/shader-direct-cpu-evaluable-images
perf(shader): select the record of a T# whose offset the CPU evaluates
2026-10-18 15:00:57 +13:00
Dean 63da333b7a Merge pull request #4048 from Mouad-Scriptz-0/perf/recompiler-select-load-guards
perf(recompiler): select guest memory loads instead of branching around them
2026-10-18 13:56:36 +13:00
Yunus Shaikh a53d23f810 Merge main into perf/shader-image-table-reuse-v3-pr
Main's #6402 stores to image tables: a table with a written entry takes
the fresh path, as it does on main, and so does one without a sampled
table binding, whose entries the fresh path rejects. The shared place
step uses the binding as a pointer. Main's #6614 frees descriptor sets
from shared pools one by one, while this branch keeps only dedicated
pools, so both stay. #7101's bulk key read counts its unmapped-page
skips as unmapped, and its key words sit next to this branch's write
stamp and compared runs.
2026-10-17 16:05:44 -07:00
Yunus Shaikh 4cb0512329 Merge main into perf/shader-direct-cpu-evaluable-images
Main's #7101 reads a key buffer's words in one call where this branch
names the reason a narrowing is skipped. Keep main's bulk read and
count both of its unmapped-page skips as unmapped.
2026-10-17 15:58:42 -07:00
thuanquangandClaude Opus 5.5 7b45d1034e fix(shader): run buffer atomics through a V# off a DWORD boundary
The binding plan refused every buffer atomic through a V# whose base is
not a multiple of 4. On RDNA2 such an atomic works when base + offset is
on a DWORD boundary and stops the dispatch otherwise, which the runtime
buffer atomic already does, so the refusal is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:22:06 +07:00
Adrià FranchandClaude Sonnet 5.5 28b3ce0fe3 fix(main): run the large cache file test alone with a longer hang limit
Windows run 39061030084: agc_shader_disk_cache_large_file wrote 2 GiB in 141 s next to 1399 parallel tests (limit 120 s), and conventions_function_bodies_shard_4 timed out at 30 s on the same loaded runner. The test is now RUN_SERIAL and its hang limit is 200 s (ctest timeout stays 240 s).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-17 21:26:00 +02:00
Adrià Franch b54018e341 fix(main): unique directory for the large cache file test
Culprit: a03ccc6be (large cache files in chunks); failing run 39057904312.
The test used a fixed directory in the temp dir; the runners of one host
share it, so a concurrent run left a second entry behind.
2026-10-17 20:57:28 +02:00
thibautandClaude Opus 5.5 a03ccc6be1 fix(shader): write cache files of 2 GiB and more in chunks
On Windows (MinGW libstdc++) one std::ofstream::write of 2 GiB or more
never returns: the whole temporary file is written but WriteFileAtomically
hangs, the entry is never replaced and the temporary file stays behind.
A Vulkan pipeline cache of 2.1 GB hung every save and left a 2 GB .tmp
per run. Write in chunks of at most 1 GiB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XBXM4pgkMHYEtqN1EQni2P
2026-10-17 14:48:47 +02:00
Dean 1e4ec0e3f7 Merge pull request #6415 from GitamarT045T3R/fix/shader-cache-test-windows
test(agc): delete mapped shader cache entries with POSIX semantics on Windows
2026-10-18 00:28:40 +13:00
Mouad-Scriptz-0andClaude Fable 5.1 ccaeeed416 fix(recompiler): point selected guest loads at locations nothing writes
A load selected instead of branched still accesses memory, so its fallback
element must be one no write can race with: scratch keeps element 0, LDS in
workgroup or function memory reads a sentinel dword appended after the
program's LDS and lock, and storage buffers read element 0xfffffffe, which
robustBufferAccess2 turns into a zero load without a memory access. The
device enables robustBufferAccess2 when it has it and the target carries the
flag; without it, and for LDS in device memory, buffer loads keep their
selections. The aligned high word of a buffer read re-reads the low word's
element instead of word 0. agc_guarded_memory_loads traces the emitted loads
in both device modes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-17 12:18:50 +13:00
fdfawef324andClaude Opus 5.5 d8911150d9 test(shader): cover plan reloads behind a relocated push layout
A prepared artifact also serves draws whose push constants start at another
offset. When such a capture reloads a released plan that is missing from the
disk cache, the rebuilt resource program must not stay on the source entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 15:24:12 +00: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 <noreply@anthropic.com>
2026-10-16 14:12:58 +02:00
Yunus Shaikh 19907d6ed4 Merge main into perf/shader-image-table-reuse-v3-pr
Resolves #4943's draw relocation against this branch: tagVariantRuns, which now builds a draw variant's runs and words, also records the captured words it shares with a table's supplied blocks, per region as before. A variant whose runs relocation splits keeps sharing for the draw cache's word compare, and skips the vouched validation, which already requires one run per region.
2026-10-16 03:25:29 -07:00
Yunus Shaikh d21b0801a4 Merge upstream main into perf/shader-image-table-reuse-v3
Brings the series onto main 4e9a2a871 (#1193, #1201, #1202, #6060,
#6333 and the descriptor word tracking of 682b07eb0).

Resolutions:
- ShaderMemory: the column memo's supplied and spilled blocks now sit
  on #1193's page vector, page pool and word masks. Pages are found by
  binary search, since a spilled block can add many pages, and a block
  placed into a lazily read page fills the rest of the 16-word blocks it
  touches, so a later lazy read never overwrites placed words.
- ResourceMaterializer and SharedValues: the selected-record path and
  the words index carry availableDwordMask, as the snapshot hash does.
  A selected record's dwords past the end of its buffer count as read
  zeros, which is what a scalar buffer load returns there, so a key past
  the heap still selects a null image without reading the heap.
- DescriptorCache: kept table sets live beside #1201's recycled sets.
- Tests and CMake: both sides' tests are kept.
2026-10-15 08:54:44 -07:00
Yunus Shaikh 19ab974b03 fix(shader): keep the disk cache keys when the image table reuse is switched off
The shader disk cache keys every plan and variant with the recompiler's APS5_* switches that are
set (ShaderDiskCache's switch key), except the ones listed as neutral. APS5_NO_TABLE_SNAPSHOT_REUSE
and APS5_NO_TABLE_RESOLUTION_REUSE were not listed, so turning the table reuse off for a comparison
run gave every shader a new key: a cache filled with the reuse on missed throughout the boot, and
the other way round, and the comparison measured recompiles instead of the reuse.

Both switches only choose between building a column or a resolution and taking the same contents
by reference, so the output does not depend on them: they are now neutral switches. The cache
format is unchanged and FormatVersion stays as it is; only a process that sets one of them now
finds the entries stored without it.

The plan loading test gains a process with both switches set, which must load every stored plan
and variant without running the front end and produce the same output as the first process.
Before this change it failed with every plan and variant missed (17 plan misses, 17 variant
misses); now it loads all 17 with the same output.
2026-10-15 08:54:43 -07:00
Scott SchusterandClaude Opus 5.5 2ea25c53f7 fix(recompiler): the shader disk cache carries a result's shader-data user words
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:53:53 -05:00
Itamar Medyoni 402a1d0556 test(agc): delete mapped shader cache entries with POSIX semantics on Windows
The disk cache keeps loaded and persisted entries mapped for the life of
the process. On Windows 10 DeleteFileW refuses a file that still has a
mapped view with ERROR_ACCESS_DENIED, so agc_shader_disk_cache failed in
its final remove_all after every check had passed and left its directory
in the temp folder.

Delete each file with FILE_DISPOSITION_FLAG_POSIX_SEMANTICS before
removing the directories, as WriteFileAtomically already renames with
POSIX semantics. The mapped views stay valid, and the test still fails
when a file or the directory cannot be removed. Linux is unchanged.
2026-10-15 17:24:26 +03:00
Yunus Shaikh 4344c1dc29 Merge branch 'main' into perf/shader-direct-cpu-evaluable-images 2026-10-15 06:38:09 -07:00
Adrià 821c69e504 Merge pull request #5509 from billythemenace2/fix/shader-cube-tsharp-2d-access
fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0
2026-10-15 13:25:34 +02:00
MarcZX100 c00b0dfb9f fix(shader): avoid retaining IR after plan cache misses 2026-10-15 10:15:33 +00:00
MarcZX100 f95dc97134 perf(agc): release unused registered shader resource plans 2026-10-15 10:15:33 +00:00
Yunus Shaikh 43855cb5e8 test(shader): cover selected image table records and their fallbacks
agc_shader_memory and agc_shader_bindless: an invalid selected T# is
poisoned with its words without changing the artifact; a key past the
heap selects a null image without reading the heap; an unmapped selected
record is Unmapped poison and is not read; a key loaded from a constant
buffer at an SRT offset selects its record, and one that cannot be read
faults the table instead of throwing; a key loaded from a buffer the
shader writes keeps the whole table; a key chosen per lane keeps the
table; a record past the 65,536-key cap is selected; and a selected
record whose second load carries past 32 bits is OffsetCarry poison while
the record past the wrap is read.

agc_driver_image_table: a dispatch keyed from a constant buffer at an SRT
offset samples three records exactly as their direct bindings do, with
one module and one bound image; samples zeros for a key past the table;
does not fault for an invalid record under a clear EXEC; reports the
invalid record's address, words and reason when it selects it; and faults
when it stores over its selected record.

agc_shader_disk_cache: a selected column round-trips in the hand-built
plan, a fixture plans one and materializes it after a round trip, and a
selection past the sources is rejected.
2026-10-14 20:52:46 -07:00
Dean 8ae436891a Merge pull request #5181 from ThatsLeo/perf/shader-compact-resource-plans
perf(shader): keep only evaluable branch conditions in resource plans
2026-10-15 10:56:57 +13:00
billythemenace2andClaude Opus 5.5 3b96840e68 fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-14 23:37:33 +02:00
Adrià 33001cebda Merge pull request #5466 from fdfawef324/codex/stencil-export-emulation
feat(agc): replay proven finite stencil reference exports
2026-10-14 22:49:30 +02:00
fdfawef324andCodex 383c8a6515 fix(agc): retain table feedback guards after cache refresh
Check sampled image-table entries with the existing stencil replay depth-feedback refusal. Keep the cache regression tied to current upstream format 33 while stencil artifacts use format 34.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex ce83818dc5 test(agc): use current resource plan codec coverage
Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex 97a0a4d098 refactor(agc): separate stencil replay from its follow-up topics
Move bounded vertex folding and empty-image feedback into separate topics. Keep the replay coverage proof, stage contracts, finite-reference tests and mapped cache regressions; version the stencil layout separately as format 34.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:48 +02:00
fdfawef324andCodex 92f0d1ad6a test(recompiler): reject the current upstream cache format
Keep format 33 and its previous-format 32 refusal; also cover the current main format 31 explicitly.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex b0c7cef616 fix(recompiler): distinguish stencil cache artifacts from format 32
Advance stencil artifacts to format 33 after main's format 32 change. Keep explicit rejection of upstream format 32 while preserving the existing stencil fields and runtime image metadata.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex 46a6f26f55 fix(recompiler): refresh stencil cache schema after rebase
Advance the stencil artifact schema past current main format 31 and retain explicit rejection of that format. Update Linux artifact size guards for main runtime image resource metadata.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00
fdfawef324andCodex b41bf66ca8 fix(recompiler): version stencil artifacts after disk resource plans
Main now uses disk cache format30 for persisted resource plans. Stencil replay
adds artifact and binding fields, so reject that format instead of sharing its
version. Keep format31 for the combined codec and cover rejection of a format30
artifact header.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-14 22:08:36 +02:00