Skip to content

docs: add tested-configurations rows for DLSS Frame Generation on an RTX 4090 (Windows) - #2771

Open
Jiro131 wants to merge 1 commit into
NotRexed:mainfrom
Jiro131:docs/tested-config-dlssg-rtx4090
Open

Jiro131 wants to merge 1 commit into
NotRexed:mainfrom
Jiro131:docs/tested-config-dlssg-rtx4090

Conversation

@Jiro131

@Jiro131 Jiro131 commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

These runs belong in the tested-configurations table. They are the first rows for DLSS Frame Generation from NGX on an RTX 40 card under Windows. They also record two open problems with a build and a driver: #2695's 36 fps at 4x, which persists after #2701, and the framegen_record crash that #2658 fixes.

Six rows, all 2026-11-12 on one machine: RTX 4090 (NVIDIA 621.01, 144 Hz display), Windows 11 Home, i9-13900K. main 51da046 was built from source with NGX (SDK 310.9.16). Settings: DLSS DLAA (model K) at 2560x1440, frame generation by Auto, frame pacing on, cap 60, V-Sync Auto. Kokiri Forest from a save.

Figures come from hookshot_log.txt ("N presents, X fps", the frame-interpolation and DLSS Frame Gen lines). "In play" means the 120-present windows after the load. The feel (smooth, pacing, latency) is what the tester saw while playing.

Docs only, no code. #2757 and #2769 also add rows at the top of the same table, so whichever merges later needs a one-line rebase.

Tracking: #2510.

🤖 Generated with Claude Code

@Joey-Magnus Joey-Magnus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are docs only. I read the six rows against the description and against #2701 and #2658. They agree: the 4x rows record the runtime making one frame and the renderer's own interpolation holding 36 fps (the #2695 symptom), and the crash rows point at the framegen_record logs on #2658. The one red job, Python source checks ubuntu part 1/2, is tests/test_release_scripts.py test_nightly_two_runs_at_once_end_at_the_newer_commit. That test is flaky on its own and has nothing to do with a markdown change, so a re-run should clear it. I checked the merges: this PR conflicts with #2769 and #2778 on the first row of the table, so whichever of the three lands later needs that line rebased. One small thing: the last row says the build with #2658 survived 62 swapchain remakes, but #2658 is still open. If #2658 changes before it merges, that row describes a head that no longer exists, so naming #2658's head commit in the Build cell would keep it accurate.

…RTX 4090 (Windows)

Six runs on 2026-11-12, main 51da046 built with NGX: DLSS-G 2x with
Reflex off and on (60 fps, DLSS-G makes every frame), 4x in a window
and fullscreen (the runtime makes 1 frame, the renderer's own takes
over on mailbox, and the game stays at 36.0 fps on a 144 Hz display,
as NotRexed#2695), the two framegen_record crashes on main, and main plus

Assisted-by: Claude Code
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Jiro131
Jiro131 force-pushed the docs/tested-config-dlssg-rtx4090 branch from 7741da5 to 0b48ed4 Compare November 12, 2026 17:45
hckrman101 pushed a commit that referenced this pull request Nov 12, 2026
GPUs using the compute mesh fallback were asked for a dynamic
vertex-buffer stride even though those draws bind no vertex buffers.
This removes that unused requirement, keeps topology and primitive
restart dynamic, and restores dynamic strides before returning to an
ordinary draw.

**Head `805eb0b3`:** the five commits rebased onto main `15d4ae8c`; the
changed lines of both code commits are identical to `5dbdfe0b` (on
`65a4d874`), which is the head the fork's Windows run and the full-suite
figures below were made on. The focused test passes on the new base too.

**What this is for:** the Vulkan state error reported in #2494/#1001 and
the ordinary-draw cache transition Joey-Magnus found in review. **What
is measured:** production construction/cache decisions with GCC and
Clang, earlier fork Windows source checks, Intel UHD 770 game counters
(2,829 omitted restores before; all 2,880 returns rebound after), and
stock-build Khronos validation: **VUID-04913 968 → 0, with no new
message IDs**. The existing fragment-output warning remains. **Not
measured:** performance, Windows gameplay, other GPUs' gameplay, or
gameplay on the rebased head.

Refs #2494. Part of #1001; this does not close the wider no-mesh-shader
tracker.

## Problem

- The fallback's generated vertex shader reads records by vertex index.
`build_graphics` already gives it no vertex bindings or attributes.
- The same function nevertheless added
`VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE` to every non-native-mesh
pipeline.
- The fallback issues `vkCmdDrawIndirect` and returns before the
ordinary vertex-buffer/stride binding code. This is the unset dynamic
state reported as `VUID-vkCmdDrawIndirect-pStrides-04913`.
- The owner closed #2494 to collect it in #1001, not because it was
fixed. This change does not claim that the validation error caused a
crash.
- Joey-Magnus caught the second step: binding the now-static-stride
fallback invalidates previous dynamic strides, while two vertex-bind
caches still said they were valid. An ordinary → fallback → ordinary
sequence with unchanged buffers could therefore omit the necessary
restore. Both cache-validity flags are now cleared at the fallback bind.

## What changed

- `gpu/vk/vk_draw.cpp`: add dynamic binding stride only for ordinary
vertex-input programs. At a fallback graphics-pipeline bind, clear
`last_vb_valid` and `vertex_set.on`; the next ordinary draw restores
stride even with unchanged buffers. Resolved buffer references stay
cached. The fallback itself still binds no dummy vertex buffer.
Topology/restart and shader translation are unchanged.
- `tests/test_fallback_pipeline_state.py`: retain the
production-construction checks and add the exact ordinary → fallback →
ordinary cache sequence. Replay the actual pipeline-bind and
vertex-cache blocks; model Vulkan state lifetime, not a driver.
`_CRT_SECURE_NO_WARNINGS` precedes the first fixture include. The direct
fallback library-construction case is extra fixture coverage: runtime
fallback programs do not use pipeline libraries.
- `docs/design.md`: describe the pipeline-state requirements and
ordinary/fallback cache transition under the renderer architecture.
- `docs/tested-configurations.md`: retain one stock Intel build row with
the validation comparison and its limitations; diagnostic-counter runs
stay in this description.

## How it was tested

Arch Linux, kernel 7.2.15-1-omarchy, Core i9-13900K; GCC 16.2.1, Clang
23.1.3, Python 3.12.16. Base `51da0464b4cf0c7f56b81ebd6bb309325835e175`;
product/test commit `20635b20214826d1d6be63ac873b6fc80824414f`. Checks
run on 2026-11-12.

### Initial construction checks — `20635b20`

The test extracts `build_graphics` unmodified and copies its real Vulkan
create-info at the pipeline-creation boundary. Program/state/driver
collaborators are authored stand-ins; no Vulkan device or game is
involved.

| Source | GCC | Clang |
|---|---|---|
| Base | Fails: fallback whole pipeline and vertex-input library demand
dynamic stride | Same |
| Initial change (`20635b20`) | Passes all five pipeline creations |
Same |
| Incorrect alternative: omit all three states for fallback | Fails:
both topology and primitive restart are missing, in whole pipeline and
library | Same |

The ordinary program keeps its binding, attribute and stride. Native
mesh retains its task/mesh graphics stages without vertex-input states.
The fallback has no vertex bindings/attributes or dynamic stride and
keeps topology/restart.

```
fallback pipeline state: ordinary, native mesh and fallback pass (5 pipeline creations)
476 passed, 0 failed, 20 skipped in 267 s (linux, 8 at once)
```

The initial Windows-target syntax pass was insufficient: its MinGW
headers had Microsoft-compatibility deprecation annotations disabled,
and the real Windows job then rejected `getenv` in the Microsoft UCRT
headers. The review fix and stronger check are described below. The
original Linux suite result above belongs to `20635b20`, not the review
commit; no core dumps were left by the checks.

An initial version of the new fixture failed to compile because its
direct packed-NVN include needed production-specific compiler
conventions and it used a wrong driver enum spelling. That failure is
retained separately; the fail-before rows above are the corrected
fixture's **runtime assertions**, not compiler errors.

### Initial Intel game runs — before the cache-transition review fix

Same system as above, Intel UHD 770 (Raptor Lake-S), **Mesa ANV
26.2.5-arch1.1**, Vulkan driver `0x6802005`. The device has no mesh
shaders, so Automatic uses the compute fallback. Both runs loaded the
same copied child save in **Kokiri Forest** with the same initial cache,
then stood still. Output 1920×1080 offscreen, captures 1280×720; Minimum
first-start preset, frame generation off. Startup precompile, warm-up
preparation and prediction were off (`RX_VK_PRECOMPILE=0`,
`RX_VK_NO_WARM=1`, `RX_VK_NO_PREDICT=1`); each process had a 32 GiB
memory limit. This avoids repeating the known Intel startup-precompile
OOM, not a fix for it.

```
vk: no mesh shaders: task and mesh programs run as compute shaders (issue 640 fallback)
vk: Intel(R) Graphics (RPL-S), Vulkan 1.4, driver 0x6802005; mesh shaders no, host memory import yes, pipeline libraries yes
vk: driver: Intel open-source Mesa driver Mesa 26.2.5-arch1.1
vk: no window: presents render offscreen (1920x1080)
```

| Build | Local interval, 2026-11-12 (UTC−06) | Wall / exit | Captures |
Fallback draws in three queried frames | Game crash / device loss /
driver faults | Virtual-core escape lines |
|---|---|---|---:|---|---|---:|
| Before: `51da0464`, source `18ed87b5` | 07:09:58–07:17:49 | 471.1 s /
124 (requested stop) | 42 | 43 / 43 / 43 | 0 / 0 / 0 | 1 |
| After: `20635b20`, source `f6f995e7` | 07:25:15–07:33:06 | 470.7 s /
124 (requested stop) | 45 | 43 / 42 / 45 | 0 / 0 / 0 | 3 |

The renderer's GPU pipeline-statistics capture reports nonzero vertex
invocations and clipping input for fallback draws in **all six sampled
frames**. Before: 63,081 / 74,685 / 70,290 vertex invocations; after:
74,685 / 62,898 / 74,685. Native task/mesh invocations are zero. This
establishes that the changed path actually drew, rather than merely
being available at startup. Both late control-status samples report play
in the same forest, with loading and event false.

Other builds/checks were running. Load averages (1/5/15 minutes) were
10.81/13.73/29.55 → 63.20/60.55/47.84 before, and 48.46/54.11/49.78 →
16.84/35.54/44.43 after. **No timing or speed comparison is made**, and
the differing virtual-core diagnostics are retained.

![1 and 3: before the change, frames 4800 and 5040. 2 and 4: after it,
the same frames. Kokiri Forest on the Intel UHD 770 with this iGPU's
known false colours on both
builds](https://gist.githubusercontent.com/mooki000/b86bd3f35969803fb032f71f035844f8/raw/59dbd892c70426dc97b019940dd03f4ae2084553/hookshot-fallback-stride-intel-before-after.jpg)

Four labelled panels show frames 4800 and 5040 before and after. The
same forest layout, foliage, Link/Navi and HUD remain visible; Intel's
existing false colours remain on both builds. Five original captures and
the composed panel were inspected. These stills are not a claim of
correct colours, identical pixels or no transient defects.

The Khronos validation layer was absent for these initial runs.
Available manifests were Mesa anti-lag, Mesa device selection and
NVIDIA's implicit layers, not `VK_LAYER_KHRONOS_validation`. These
initial runs therefore show continued fallback drawing, not VUID
disappearance. The later stock-build validation comparison below
supplies that missing check.

## Review correction — `5da2d634`

Credit to **Joey-Magnus** for both findings. The [Vulkan dynamic-state
lifetime
rule](https://docs.vulkan.org/spec/latest/chapters/pipelines.html#dynamic-state-lifetime)
requires dynamic state to be set after the last pipeline bind that made
it static. Native mesh omits vertex-input state and does not disturb it;
the fallback includes that state with no bindings. Among
`vkCmdBindVertexBuffers2` values, **stride** is the affected dynamic
pipeline state, not buffer handles, offsets or bound sizes. Both skip
flags must be invalidated; the resolved-buffer lookup cache,
index-buffer cache and unrelated dynamic-state caches remain usable.

### Local checks for the correction

- GCC 16.2.1 and Clang 23.1.3: the reviewed `e76c32dd` fails the
third-draw rebind assertion; `5da2d634` passes. Keeping either one of
the two cache flags valid also fails. The original stride and
topology/restart negative controls remain and still fail as intended.
- The sequence also checks that repeated ordinary draws and an
intervening native mesh draw do not add redundant binds, and that the
resolved buffer is looked up only once. This is an authored
state-lifetime model around production cache decisions, not driver
validation.
- Complete local source check: **475 passed, 1 failed, 20 skipped**. All
four C++ unit tests pass. The one failure is **the known release-script
race the reviewer named as flaky**
(`test_nightly_two_runs_at_once_end_at_the_newer_commit`, checksum
publication after five uploads). It is retained, not rerun or called
green.
- The repaired Windows-target check rejects the old generated fixture,
including real `getenv` deprecation errors, and accepts the fix. It
enables MinGW's compatibility annotations and treats deprecation
warnings as errors, and checks for the CRT define before the first
include. It does not silently supply that define itself. Ten new rule
tests and eleven existing check-tool tests pass. This local compile is
still syntax-only.

### Real Windows checks on the fork, before this push

For `5da2d634`, the project's **Python source checks (windows-2022, part
1/2)** and **(part 2/2)** both passed on [the fork's scratch PR
#3](mooki000#3) before the commit was
pushed here. The Windows Vulkan back ends, DLSS/FSR link check, SPIR-V
fixtures, Builder package, dav1d and actionlint also passed there. The
two Linux parts and AppImage job were still running when those results
were read. **This pull request's own run is the authoritative check; the
fork result is not a claim that this PR's current run is green.**

### Real Intel cache-transition counters

Same Arch Linux / Core i9-13900K / Intel UHD 770 / Mesa ANV
26.2.5-arch1.1 system and Kokiri Forest child save as above. One
ordinary windowless run per renderer, identical warmed save/cache and
settings, precompile off, 32 GiB process limit. **The host is unchanged
`20635b20` in both copies**; only the renderer is rebuilt from
`e76c32dd` or `5da2d634`, with identical local-only counters. The two
renderer sources differ only by the six committed invalidation lines. No
counters are included in this commit.

The counters follow an ordinary binding path, a fallback graphics bind,
and a return to the same guest buffer addresses/sizes/strides and pool
generation within that recording. They count whether the real
vertex-buffer bind call is recorded, without changing the cache
decision. Values below end at each run's last logged checkpoint, not
necessarily its final draw.

| Renderer | Interval on 2026-11-12 (UTC−06) | Fallback binds |
Same-buffer returns | Rebinds recorded | Restores skipped | Game crash /
device loss / GPU faults |
|---|---|---:|---:|---:|---:|---|
| `e76c32dd` | 09:14:03–09:18:04 | 45,087 | 2,829 | 0 | 2,829 | 0 / 0 /
0 |
| `5da2d634` | 09:18:05–09:22:06 | 45,992 | 2,880 | 2,880 | 0 | 0 / 0 /
0 |

Both stopped at the requested limit (exit 124), recorded 27 captures,
and had no virtual-core escape or driver-error lines. Both late status
samples report the same forest in play, with loading/event false. The
runs were not quiet: load averages were 76.03/36.34/22.38 →
13.47/24.84/21.05 before, and 12.63/24.48/20.95 → 8.53/15.41/17.99
after. Exclusive holds can pause Intel games too, so **the verdict uses
counters, not wall time**; no speed comparison is made.

The inspected frame-3240 pair shows the same forest/HUD with the
pre-existing false colours.

![Kokiri Forest on the Intel UHD 770: 1, the reviewed renderer; 2, the
fixed renderer. The same forest and HUD, with this iGPU's known false
colours on
both](https://gist.githubusercontent.com/mooki000/b86bd3f35969803fb032f71f035844f8/raw/1eae2688d3d053a1e386b89e35b0fcb9952a7023/hookshot-fallback-stride-review-rebinds.jpg)

This shows continued drawing, not a visual cure for the separate Intel
colour problem. The binding counters establish the missing restore
before and the emitted restores after; **they are not validation-layer
error counts**. The later stock-build validation comparison below checks
VUID disappearance directly.

## Khronos validation comparison — stock builds, before rebase

The requested check is now complete:
**VUID-vkCmdDrawIndirect-pStrides-04913 occurs 968 times on main and
zero times on the fixed branch**. There are **no new message IDs** on
the branch, and no branch error messages. The existing
unused-fragment-output warning remains; this is not a claim that the
game is free of validation warnings.

These runs used stock host and renderer binaries, without the earlier
diagnostic counters: main `51da0464b4cf0c7f56b81ebd6bb309325835e175`
(source `18ed87b5`) and pre-rebase branch
`b7d175e4f2e6f5167257cc2e23964ed07b1dd58c` (source `43edcbeb`). **The
validation counts belong to those two commits, not the rebased head.**

Same Intel UHD 770, Mesa ANV 26.2.5-arch1.1, Arch Linux kernel
7.2.15-1-omarchy and Core i9-13900K as above; same copied warmed child
save and initial cache, Kokiri Forest, 1920×1080 offscreen, Minimum
preset, FG off, 32 GiB process limit. Precompile, warm-up preparation
and prediction stayed off. Each run reached the forest and accumulated
60 seconds of sampled active play with progressing frames and
loading/event false before a normal requested quit. Start-up/loading
messages are included in the whole-run columns; the scene-only columns
isolate those play windows.

| Layer ID (`MessageID`) | Severity | Main `51da0464`, whole run |
Branch `b7d175e4`, whole run | Main, 60 s of play | Branch, 60 s of play
|
|---|---|---:|---:|---:|---:|
| `VUID-vkCmdDrawIndirect-pStrides-04913` (`0x3252797`) | Error | 968 |
0 | 957 | 0 |
| `Undefined-Value-ShaderOutputNotConsumed-DynamicRendering`
(`0x46877e3e`) | Warning | 120,333 | 145,510 | 114,916 | 121,291 |
| `CURRENT-VALIDATION-ENABLED` (`0xfd7b2292`) | Information | 1 | 1 | 0
| 0 |
| `WARNING-cache-file-error` (`0xb8515d13`) | Information | 1 | 1 | 0 |
0 |

This table contains every distinct layer message, including its two
information messages. Counts are of JSON message records, not
occurrences of the ID in repeated specification text. All first complete
messages were retained. The warning says the fragment shader writes
`frag_color0` at location 0 without a corresponding colour attachment;
it appears on both builds. Despite its name, `WARNING-cache-file-error`
has Information severity: the per-copy shader-validation cache did not
yet exist. `CURRENT-VALIDATION-ENABLED` confirms core,
stateless-parameter, object-lifetime and thread-safety checks, plus
handle wrapping.

The layer was originally absent from the system and project
dependencies. For these runs, Arch's **vulkan-validation-layers
1.4.363.0-1** package was downloaded from the distribution mirror, its
SHA-256 matched against the local sync database, and it was privately
unpacked with no system installation. The loader reported the private
Khronos layer inserted for both the instance and device and enabled **by
the application**. The game used `RX_VK_VALIDATION=1`; the layer
settings included `khronos_validation.enable_message_limit = false`,
core validation enabled, and all error/warning/performance/information
reports. The 968 repeated target errors in the control are also direct
evidence that the default duplicate cap was not hiding them.

| Stock run | Interval on 2026-11-12 (UTC−06) | Exit | Game crash /
device loss / GPU faults | Captures | Virtual-core escape lines |
|---|---|---:|---|---:|---:|
| Main `51da0464` | 11:29:37–11:31:45 | 0 | 0 / 0 / 0 | 30 | 2 |
| Branch `b7d175e4` | 11:41:08–11:42:59 | 0 | 0 / 0 / 0 | 29 | 0 |

The final captures on both runs still show the forest and HUD with the
known Intel false colours. These were ordinary shared-machine runs, not
exclusive performance holds: loads were 126.63/108.22/67.84 →
140.24/118.03/76.42 on main and 31.16/66.61/70.58 → 22.50/52.59/65.06 on
the branch. Other exclusive holds can pause Intel games too. The
conclusion uses the message counts and sampled active-play windows,
**not wall time or a speed comparison**.

## Rebase and documentation review

Rebased onto freshly fetched main
`65a4d874fd83a2c8fe2e230befb144f1668b900c` on a new local branch,
leaving the old branch at `b7d175e4` untouched. Only
`docs/tested-configurations.md` conflicted: both sides' independent rows
were preserved in both replayed documentation commits. Range-diff shows
the two code/test commits unchanged; the two old documentation commits
differ only in surrounding table context, with identical added/removed
payloads.

A separate documentation commit,
`5dbdfe0b860c4033229b6a2b1441c7963eaca91d`, keeps just one reproducible
stock-build row for this PR, moves the pipeline-state explanation to
`docs/design.md`, and records the validation run. The diagnostic-counter
history stays here rather than in the tested-configurations table.

On that rebased head, the fixture passes with GCC 16.2.1 and Clang
23.1.3. With both compilers it rejects the new-main source at the
missing-stride assertion and the pre-cache-fix source at the third-draw
rebind assertion. The complete game-free suite reports **501 passed, 2
failed, 20 skipped**; all four C++ unit tests pass. The two failures are
inherited from the fetched base: `test_program_cache_one_variant.py`
fails to compile its extracted cache code because the fixture lacks the
new zstd declarations, and `test_readme_menu_rows.py` finds the newly
added “Skip opening” row missing from the README table. The failing
fixtures and all compiled/readme inputs are byte-identical to the base.
This is **not** the earlier release-script race, and the full suite is
not green.

The pre-push check passes. Main advanced during the checks; the branch
still merged cleanly at that check. No game run or Windows CI result is
claimed for this rebased head; the runtime evidence remains pinned to
the stock pre-rebase builds above, and this pull request's own CI
remains authoritative.

## Not tested

- Gameplay on the rebased head: the stock validation comparison is
explicitly pinned to pre-rebase `51da0464` and `b7d175e4`.
- Windows gameplay. The revised game-free fixture is covered by the
fork's Windows source-check jobs described above; this PR's own run
remains authoritative.
- AMD, Pascal/Maxwell, Intel Arc, Steam Deck, native mesh gameplay, a
real window/swapchain, physical input, sound or a long session.
- Performance. These checks do not establish a speed improvement or
repair Intel's separate colour/startup-memory problems.

## Risks

The change affects fallback pipeline state on every driver. The
regression checks preserve the states the fallback still uses, plus
ordinary and native mesh behavior, but cannot replace execution on other
drivers. Existing pipeline keys and shader translation are unchanged.

## Overlaps

At initial submission, no competing pull request naming #2494 or
“dynamic stride” was found and no product-code conflict was reported.
That initial overlap check found competing additions at the top of
`docs/tested-configurations.md` with #2414, #2715, #2738, #2755, #2756,
#2757, #2759, #2769, #2771 and #2788. Each hunk was read: our two Intel
rows meet independent measurements, so both sets should be retained when
either lands. This does not duplicate the other work on fallback
dispatches, program caching or Intel compilation.

Assisted-by: GPT-6 Astra
Co-Authored-By: GPT-6 Astra <noreply@openai.com>

**Head note:** `711c6585` is `805eb0b3` rebased onto main `3c2d80cf` to
pick up main's test fixes (#2861, #2883). All five commits are unchanged
(`git range-diff` marks each `=`); the measurements above were made on
`805eb0b3` and earlier heads as stated, and no game run was repeated for
the rebase.

---------

Co-authored-by: GPT-6 Astra <noreply@openai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants