DLSS-NR: probe the float vtable slot on Vulkan, as D3D12 does - #44
Open
RobertRautenbach wants to merge 1 commit into
Open
Conversation
The forwarder writes floats to the NGX parameter block through a raw vtable index, g_floatSlot, which defaults to the slot the public header declares. The driver's own block does not keep floats there: one written to it reads back as FAIL_UnsupportedParameter while every uint lands. The D3D12 path resolves dlssnr_call_probe_float and dlssnr_call_set_float_slot and round trips a value through each candidate slot before writing anything. The Vulkan path resolved neither export and never probed, so every float the model is given went into the discarding slot: DLSSNR.MVecScaleX and MVecScaleY on each evaluate, and Intensity, LocalStructureStrength, LocalToneStrength and SkinStructureStrength at create. The motion vector scale is the one that shows, since without it the model reprojects its history with no idea how the game encodes its vectors. Run the same probe on g_vk.capabilityParams before the first write. - Both forwarder calls are optional. Where they are absent the slot keeps the header's value and this path behaves exactly as it did before. - g_floatSlot is a single global inside the forwarder, so a process running both paths probes twice and agrees with itself. - No Vulkan resource is created, freed or resized, and nothing here runs when neural rendering is off.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Vulkan path never works out which vtable slot the NGX parameter block keeps floats in, so every float it hands the model is discarded. Run the same probe the D3D12 path already runs.
Problem
The forwarder writes floats into the parameter block through a raw vtable index, starting at the slot the public header declares:
The driver's own capability block does not keep floats there, as the forwarder's own comment records: a float written to slot 1 reads back as
FAIL_UnsupportedParameterwhile every uint lands.dlssnr/FORWARDER_INVESTIGATION.mdin this tree puts the real one at 6:DlssNr_Dx12.cpptherefore resolvesdlssnr_call_probe_floatanddlssnr_call_set_float_slotand runsDiscoverFloatSlotbefore it writes anything.DlssNrFeature_Vk.cppresolves neither export and never probes, so on Vulkan the index stays at 1 and everysetFloatis thrown away:DLSSNR.MVecScaleXandDLSSNR.MVecScaleY, on every evaluateDLSSNR.Intensity,DLSSNR.LocalStructureStrength,DLSSNR.LocalToneStrengthandDLSSNR.SkinStructureStrength, at create and on every evaluateThe uint parameters were unaffected, which is why the pass otherwise looked healthy. Settings carried in
DlssNrConstantsare unaffected too, since they never go through the block.Changes
One file, 46 added lines, nothing removed:
dlssnr_call_set_float_slotanddlssnr_call_probe_floatinLoadForwarder. Both optional.DiscoverFloatSlot, a port of the D3D12 one: same probe key, same candidate order, same0.375fround-trip sentinel.g_vk.capabilityParamsimmediately after allocation, before the first write.Result
The motion vector scale is the one that shows. Without it the model reprojects its history with no idea how the game encodes its vectors, which is wrong only while something is moving and exact while it is still.
In Baldur's Gate 3 on the Vulkan renderer that presented as shadows shimmering slightly darker whenever the camera turned. It survived DLAA, it survived #42, and it survived every host-side setting, because the host arithmetic was always correct and the value simply never arrived. With the probe in place it is gone, and the log reports the slot it found.
The four tuning sliders were inert on Vulkan as well, and now take effect.
Relationship to #42
This is a precondition for #42 on Vulkan rather than an alternative to it. #42 computes the correct motion vector metadata and forwards the scale; the scale is a float, so on Vulkan it was being discarded after being correctly computed. That both of #42's Vulkan boxes are unticked is consistent with this. The two changes are independent, and this one applies to
dlss-neural-renderingon its own.Testing
Linux, Proton (proton-cachyos, Wine 11), RTX 5080, driver 610.57.04, Baldur's Gate 3 at 3840x2160 on the native Vulkan renderer with
VulkanUpscaler=dlss. Exercised at three super-resolution ratios (2953x1661, 2560x1440, 2258x1270) and at DLAA; the model received-1 x -1in each, and the probe reported slot 6. Built with this repo's unsigned workflow. Formatting checked against.clang-format: the file's pre-existing complaint count is unchanged and none falls on an added line.Default-identical where the forwarder lacks the two exports: the index keeps the header's value and this path behaves exactly as before. No Vulkan resource is created, freed or resized, and nothing here runs when neural rendering is off.
Developed with AI assistance (Claude). I tested it in game and reviewed the change before submitting.