DLSS Programming Guide Release
DLSS Programming Guide Release
3.5.10)
Programming Guide
Revision History
Revision Changes Date
2.2.3 - Adjusted the Texture LOD Bias recommendation for preservation 09/02/2021
of sharpness and intricate detail.
2.1.5 - Slightly clarified the usage of DLSS with multiple views, to make it 12/2/2020
clearer that it is not only for use with VR, but can be used in any
multi-view use case
2.1.4 - Added information about the proper use of the SDK API version 11/2/2020
value passed into the SDK at SDK initialization time
- Added information about the NGX app logging hook API
2.0.0 - General edits throughout the document to update for DLSS v2 3/23/2020
- Added renderer requirements
- Added DLSS execution times
- Added deployment checklist
- Added section on jitter troubleshooting
- Added section on resource states
- Added section on DLSS debug logging
1.3.7 - Added sample code to check for minimum driver version 10/15/2019
1.1.0.0 - Added sections for motion vectors, format support and pipeline 7/08/2019
integration.
- Alignment of doc version number with DLSS release version
- Support for debug overlays
- Deprecated scratch buffer setup
- Added links to sample code
DLSS is built and distributed as a feature of NVIDIA NGX which itself is one of the core components of
NVIDIA RTX (https://developer.nvidia.com/rtx). NVIDIA NGX makes it easy to integrate pre-built AI based
features into games and applications. As an NGX feature, DLSS takes advantage of the NGX update
facility. When NVIDIA improves DLSS, the NGX infrastructure can be used to update DLSS for a specific
title on all clients which currently have the game installed.
There are three main components that make up the underlying NGX system:
1. NGX SDK: The SDK provides CUDA, Vulkan, DirectX 11 and DirectX 12 API’s for applications to
use the NVIDIA supplied AI features. This document covers how to integrate the DLSS feature
into a game or application using the DLSS SDK (which is modelled on the NGX SDK but stands
separately).
2. NGX Core Runtime: The NGX Core Runtime is a system component which determines which
shared library to load for each feature and application (or game). The NGX runtime module is
always installed to the end-user’s system as part of the NVIDIA Graphics Driver if supported
NVIDIA RTX hardware is detected.
3. NGX Update Module: Updates to NGX features (including DLSS) are managed by the NGX Core
Runtime itself. When a game or application instantiates an NGX feature, the runtime calls the
NGX Update Module to check for new versions of the feature that is in use. If a newer version is
found, the NGX Update Module downloads and swaps the DLL for the calling application.
2 Getting Started
2.1 System Requirements
The following is needed to load and run DLSS for both Windows and Linux:
- The latest NVIDIA Graphics Driver is recommended. At a minimum for running DLSS 2.4.11+,
you must have NVIDIA driver issued after March 3, 2022 (for instance 512.15). Please see
Section 9.6 for Linux Driver Compatibility information.
- Windows PC with Windows 10 v1709 (Fall 2017 Creators Update 64-bit) or newer
o Microsoft Visual Studio 2012 and 2013 are supported but may be deprecated in the
future.
o Additional note for Vulkan: The Vulkan path of DLSS expects the application to run on a
Vulkan version 1.1 or later.
o The raw color buffer for the frame (in HDR or LDR/SDR space).
o Screen space motion vectors that are: accurate and calculated at 16 or 32 bits per-pixel;
and updated each frame.
- Allow for sub-pixel viewport jitter and have good pixel coverage with at least 16 jitter phases (32
or more is preferred).
- Initialize NGX and DLSS using a valid ProjectID (See Section 5.2.1).
- The ability to negatively bias the LOD for textures and geometry.
To allow for future compatibility and ease ongoing research by NVIDIA, the engine can also optionally
provide additional buffers and data. For information on these, see section 9.4.
NVSDK_NGX_Result NVSDK_NGX_D3D11_GetFeatureRequirements(
IDXGIAdapter *Adapter,
const NVSDK_NGX_FeatureDiscoveryInfo *FeatureDiscoveryInfo,
NVSDK_NGX_FeatureRequirement *OutSupported);
Note: This helper detects NGX feature support for only static system conditions and the feature may still
be determined to be unsupported at runtime when using other SDK entry points (i.e. not enough device
memory may be available).
FeatureDiscoveryInfo contains information common to all NGX Features - required for Feature
discovery, Initialization and Logging:
ApplicationDataPath is a local system path to store logs and other temporary files (write access
required)
FeatureInfo is Information Common to all NGX Features. Currently is a list of paths that NGX can scan to
find Feature specific dlls. In case of of DLSS – nvngx_dlss.dll
ProjectDesc: If using NVSDK_NGX_ProjectIdDescription, this contains the project ID and engine info
required to identify this app
MinOSVersion: String value corresponding to minimum OS version required for NGX Feature Support
NVSDK_NGX_Result NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements(
NVSDK_NGX_Result NVSDK_NGX_UpdateFeature(
const NVSDK_NGX_Application_Identifier &ApplicationId,
const NVSDK_NGX_Feature FeatureID);
FeatureID: Valid NVSDK_NGX_Feature enum corresponding to DLSS v3 Feature which is being queried
for availability
If the update is successful, the update will not be applied until the next time that NGX is Initialized (i.e.,
NVSDK_NGX_<API>_Init() is called again. See section 5.2 ). We recommend using this API, as this
will allow NVIDIA to deliver the most up to date IQ and performance improvements to the
Application.
This API should be called on its own dedicated thread. This is because the time taken to download an
update can vary based on factors outside of control, such as network connectivity / internet speed.
Note that this is a ballpark number - the actual number can be somewhat different. For
instance, using InEnableOutputSubrects flags may result in higher memory usage. On the other
hand, if your output color buffer has RGBA16 format, DLSS might be able to use it to store some
internal temporary data, and then the amount of allocated memory will be smaller.
2. The DLSS algorithm is executed in 16-bit “Performance Mode” where the input is one quarter
the number of pixels as the output:
- 1920x1080 results are generated from an input buffer size of 960x540 pixels.
- 2560x1440 results are generated from an input buffer size of 1280x720 pixels.
- 3840x2160 results are generated from an input buffer size of 1920x1080 pixels.
Item Confirmed
To be clear, if DLSS is placed at the start of post processing, all post effects must be able to handle the
increased resolution and not have assumptions that processing can only occur at render resolution.
1. The range of color values for LDR mode must be from 0.0 to 1.0.
2. In LDR mode, DLSS operates at lower precision and quantizes the data to 8 bits. For color
reproduction to work at this precision, the input color buffer must be in a perceptually linear
3. In LDR mode, the color data must not be provided in linear space. If DLSS processes linear colors
in LDR mode, the output from DLSS exhibits visible color banding, color shifting or other visual
artifacts.
If the input color buffer sent to DLSS meets these requirements, then set DLSS to process using LDR by
setting “NVSDK_NGX_DLSS_Feature_Flags_IsHDR” to “0”.
If the input color buffer sent to DLSS is stored in linear space or does not meet the requirements above
for any reason, set the "NVSDK_NGX_DLSS_Feature_Flags_IsHDR" to "1". HDR mode operates
internally with high range, high precision colors and can process all luminance values (i.e. there is no
upper bound to the acceptable luminance for HDR values).
See section 5.3 for more details on the “NVSDK_NGX_DLSS_Feature_Flags_IsHDR” feature flag.
3. Obtain optimal settings for each display resolution and DLSS Execution Mode (see section 3.2.1).
6. When there are changes to settings which affect DLSS (such as display resolution, toggling RTX,
or changing input/output buffer formats) release the current feature and go back to step 3.
IMPORTANT: DLSS should only replace the primary upscale pass on the main render target and should
not be used on secondary buffers like shadows, reflections etc.
1. Performance Mode
2. Balanced Mode
3. Quality Mode
Additionally, what is referred to as “DLAA” or Deep Learning Anti-Aliasing refers to when the input and
output render sizes are set to the same value (as in a scaling ratio of 1.0) regardless of the Optimal
Settings call. This is kept separate as it should be exposed under a different UI option in game. DLAA is
also a performance quality mode.
Depending on the DLSS algorithm in use and the game performance levels, DLSS may enable all or some
of the modes listed above. All should be checked but sometimes not all are enabled for a given
configuration.
The RTX UI Developer Guideline outlines a DLSS Auto Mode. This is not a specific execution mode, but
an additional user-friendly mode to map default mode to the current output resolution. (Please refer to
DLSS Auto mode and DLSS mode Defaults sections)
In the game settings, only display those modes that are enabled. Completely hide all other modes. For
the enabled modes, allow the end-user to switch between each enabled mode changing the render
target resolution to match.
After querying the DLSS Optimal Setting, if more than one mode is enabled, the default selection (unless
the user has chosen a specific mode) should be “Auto”, “Quality”, “Balanced”, “Performance”, “Ultra-
Performance”.
For information on how to display the user facing DLSS mode selection, please see the “NVIDIA RTX UI
Developer Guidelines” (the latest version is on the GitHub repository in the “docs” directory).
NOTE: If the output resolution (aka display resolution) changes, DLSS must be reinitialized.
To use DLSS with dynamic resolution, initialize NGX and DLSS as detailed in section 5.3. During the DLSS
DLSS Optimal Settings also returns four additional parameters that specify the permittable rendering
resolution range that can be used during the DLSS Evaluate call. The pOutRenderMaxWidth,
pOutRenderMaxHeight and pOutRenderMinWidth, pOutRenderMinHeight values returned are
inclusive: passing values between as well as exactly the Min or exactly the Max dimensions is allowed.
typedef struct NVSDK_NGX_Dimensions
{
unsigned int Width;
unsigned int Height;
} NVSDK_NGX_Dimensions;
The DLSS Evaluate calls for the supported graphics APIs can accept InRenderSubrectDimensions as
an additional Evaluation parameter. That specifies the area of the input buffer to use for the current
frame and can vary from frame to frame (thus enabling dynamic resolution support).
The subrectangle can be offset in the buffer using InColorSubrectBase (or the other *SubrectBase
parameters) which specify the top-left corner of the subrect.
If the the InRenderSubrectDimensions passed to DLSS Evaluate are not in the supported range
(returned by the DLSS Optimal Settings call), the call to DLSS Evaluate fails with an
NVSDK_NGX_Result_FAIL_InvalidParameter error code.
NOTE: Not all combination of PerfQuality mode, resolution and ray tracing, support dynamic
resolution. Additionally, the Preset chosen for the init-time input size will persist across the
lifetime of the feature (presets will not vary even if scaling ratio varies). When dynamic
resolution is not supported, the call to NGX_DLSS_GET_OPTIMAL_SETTINGS returns the same
values for both the minimum and maximum render resolutions. This is also the case for older
DLSS libraries that did not support dynamic resolution.
If changing the mip bias this often is not feasible, the developer can use an estimated bias or
have a limited set of mipmap biases. Some experimentation may be needed to maintain on-
screen texture sharpness.
2. To guarantee the accuracy of the DLSS image reconstruction, the aspect ratio of the render size
must stay constant with the final display size. NVIDIA suggests calculating the projection matrix
with this in mind.
// When rendering to a different resolution than the display resolution, ensure
// geometry appears similar once it is scaled up to the whole window/screen
float aspectRatio = displaySize.x / displaySize.y;
// Compute the projection matrix using this aspect ratio (not the Render ratio)
float4x4 projection =
perspProjD3DStyle(dm::radians(m_CameraVerticalFov), aspectRatio, zNear, zFar);
1. Color input buffer (the main frame): any supported buffer format for the API.
2. Motion vectors: RG32_FLOAT or RG16_FLOAT (for more information see section 3.6.1)
3. Depth buffer: any format with one channel in it (for instance R32_FLOAT or D32_FLOAT), as well
as any depth-stencil format (for instance D24S8)
4. Output buffer (the destination for the processed full resolution frame): any supported buffer
format for the API.
5. Previous Output buffer (used for frame history and accumulation): optional, but if provided
should be RGBA16F.
Note: in situations where an application uses a lower resolution, such as for savings while the window is
minimized, DLSS should not be called.
There is no specified maximum resolution for DLSS. However, resolutions above 7680 x 4320 may not
have been thoroughly tested, and there are no guarantees of performance or quality above this
resolution.
1. Input buffers (e.g. color, motion vectors, depth and optionally history, exposure etc.) be in read
state (also known as a Shader Resource View, HLSL “Texture” or in Vulkan as a “Sample
Image”). This also means that in the case of Vulkan these must be created with the
“VK_IMAGE_USAGE_SAMPLED_BIT” usage flag. For D3D12 - the state must be
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE because those resources will be
read by a compute shader.
2. The Output buffer be in UAV state (also known as an HLSL RWTexture or in Vulkan as a “Storage
Image”). This also means that in case of D3D12 it has to be created with the
"D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS" flag and in case of Vulkan with the
"VK_IMAGE_USAGE_STORAGE_BIT" usage flag.
After the evaluate call, DLSS accesses and processes the buffers and may change their state but always
transitions buffers back to these known states.
As an example, if you use the optimal settings for DLSS Performance mode, the ratio Render
XResolution / Display XResolution = 0.5. As a result, the recommended Miplevel bias is -
2.0 for this Performance mode.
Due to the temporal nature of DLSS, applying the recommended negative LOD Bias to the
input can sometimes lead to increased temporal stability, in the form of flickering and/or moiré.
This will be highly dependent on the scene content such as texture detail. For those scenes and
objects where the flickering can become distracting it will be recommended to adjust the LOD
bias to be less aggressive. You can typically try to adjust it on the problematic content but
without going above log2(Render XResolution / Display XResolution). Anything
less than the recommended value will tend to be softer/blurrier, so this is going to be a tradeoff
between preservation of detail and aliasing.
NOTE: Carefully check texture clarity when DLSS is enabled and confirm that it matches the texture
clarity when rendering at native resolution with the default AA method. Pay attention to
textures with text or other fine detail (e.g. posters on walls, number plates, newspapers etc).
If there is a negative bias applied during native resolution rendering, some art assets may have been
tuned for the default bias. When DLSS is enabled the bias may be too large or too small
compared to the default leading to poor image quality. In such case, adjust the “epsilon” for the
DLSS mip level bias calculation.
NOTE: Some rendering engines have a global clamp for the mipmap bias. If such a clamp exists, disable
it when DLSS is enabled.
IMPORTANT: Incorrect or poor precision motion vectors are the most common cause of visual artifacts
when DLSS is enabled. Please use a visualizer (such as the debug overlay – see section 8.2)
to check motion vectors any time you notice visual artifacts with DLSS.
The values of each motion vector represent the amount of movement given as the number of pixels
calculated in screen space (ie the amount a pixel has moved at the render resolution) and assume:
1. Screen space pixel values use [0,0] as the upper left of the screen and extend to the full
resolution of the render target. As an example, if the render target is a 1080p surface, the pixel
at the bottom right is [1919,1079].
a. DLSS can also optionally accept full resolution motion vectors which are calculated at
display resolution. See section 3.6.2 for more information.
2. Motion vectors can be positive or negative (depending on the movement of the scene objects,
camera and screen).
3. Motion vectors can include full and partial pixel movements (i.e. [3.0f,-1.0f] and [-0.65f,10.1f]
are both valid).
NOTE: If the game or rendering engine uses a custom format for motion vectors, it must be decoded
before calling DLSS.
NOTE: If you use or have merged NVIDIA’s custom branch of UE4 with DLSS integrated, this change (or
something very similar) has already been applied.
Texture2D DepthTexture;
Texture2D VelocityTexture;
float3 HomogenousToEuclidean(float4 V)
{
return V.xyz / V.w;
}
void VelocityResolvePixelShader(
float2 InUV : TEXCOORD0,
float4 SvPosition : SV_Position,
out float4 OutColor : SV_Target0
)
{
OutColor = 0;
if (PrevClipPos.w > 0)
{
float2 PrevClip = HomogenousToEuclidean(PrevClipPos).xy;
Velocity = ClipPos.xy - PrevClip.xy;
}
}
For clarity, if standard input resolution motion vectors are sent they do not need to be dilated,
DLSS dilates them internally. If display resolution motion vectors are sent, they must be dilated.
To allow this data to be used directly, DLSS provides motion vector scale parameters used during
evaluation to enable some modification of the motion vector values when passed to DLSS. They are
generally set from the eval parameters struct NVSDK_NGX_D3D11_DLSS_Eval_Params via
InMVScaleX and InMVScaleY members. These should be set to 1.0 if motion vectors do not need
to be scaled and should never be 0.0f. (see section 5.4 or nvsdk_ngx_helpers.h).
DLSS can sometimes help reconstruct some of that missing geometry but in order to do that it needs
accurate motion vectors. Because those features went out of view, neither the color nor the motion
vector for that missing feature is present in the input that is sent to DLSS. In that scenario shown below,
DLSS will incorrectly associate the previously drawn image of that object with the motion vector of the
background. In that scenario, instead of trying to mend the holes in the object drawing, those holes will
persist.
As a result of using this, the motion of the previously drawn parts of the object will show the correct
amount that the object moved on the screen, and it should allow DLSS to have a better chance at
reconstructing.
Here's an in-game comparison. In this we can see that the left is using conservative raster for its motion
vector and as a result has slightly less visible holes during reconstruction than the right image where we
didn't make use of conservative raster.
Put another way, if we had four or more frames of rendered and rasterized pixels with no motion, the
image DLSS produces should be identical to a 4x super-sampled image. This is the goal for DLSS but is
not always achievable in practice.
If possible, use a Halton sequence for sub-pixel jitter when DLSS is enabled even if a different pattern is
used when TAA or an alternate AA mode is enabled. If other patterns are used, DLSS should still function
A good choice for the number of phases (i.e. the number of unique samples in the pattern before
repeating) is:
The Base Phase Count is the number of phases often used for regular temporal anti-aliasing (like TXAA
or TAA). A good starting value for the Base is “8” which provides good pixel coverage when no scaling is
applied. For DLSS, the Base is then scaled by the scaling ratio of the pixel area.
For instance, with a render target of 1080p and a target output of 2160p (aka 4k), the 1080p pixel is four
times the size of a 4K pixel. Hence, four times as many phases are required to make sure each 4K pixel is
still covered by 8 samples. So, in this example, the total number of phases would be 32:
Speaking in general terms, to render with jitter, apply human imperceptible movement to the camera or
viewport such that when the 3D scene is rasterized there are slight changes to the resulting frame
(especially edges). A typical procedure for applying the jitter offset is to modify the renderer’s projection
matrix:
// Each frame, update the ProjectionJitter values with those from the jitter sequence
// for the current Phase. Then offset the main projection matrix for the frame.
ProjectionMatrix.M[2][0] += ProjectionJitter.X;
ProjectionMatrix.M[2][1] += ProjectionJitter.Y;
Using this method should provide a shift in the camera-space coordinates rather than shifting the world-
space coordinates and then projecting.
1. Should always be between -0.5 and +0.5 (as jitter should always result in movement that is
within a source pixel).
2. Are provided in pixel-space at the render target size (not the output or target size – jitter cannot
be provided at output resolution as is optionally possible with motion vectors).
3. Represent the jitter applied to the projection matrix for viewport jitter irrespective of whether
the offsets were also applied to the motion vectors or not.
a. If the motion vectors do have jitter applied to them, be sure to set the appropriate flag
during the DLSS Create call as detailed in section 3.6.2.
4. Use the same co-ordinate and direction system as motion vectors (see 3.6.1 above) with
“InJitterOffsetX == 0“ and “InJitterOffsetY == 0“ meaning no jitter was applied.
To assist in debugging, NVIDIA has added several tools and visualizers to the SDK version of the DLSS
library. For information on how to use these tools and debug issues with jitter, see section 8.3.
We recommend using nearest upsampling of gbuffer data for post processing shaders that require it.
NOTE: A basic exposure value may be calculated via the following function (where MidGray is the
amount of reflected light which represents the perceptual middle between full reflected brightness and
full absorption - a value of “0.18” is typical for MidGray; and AverageLuma is the average luminance
for the entire frame):
ExposureValue = MidGray / (AverageLuma * (1.0 - MidGray))
The renderer must provide DLSS with the correct ExposureValue during each DLSS evaluate call using
a 1x1 texture referenced in the pInExposureTexture parameter. Only the first channel is sampled in
the texture so multiple formats will work but something such as R16F is preferred.
NOTE: This value is sent to DLSS as a 1x1 texture to avoid a round-trip to the CPU as the value is typically
calculated per-frame on the GPU.
If ExposureValue is missing or DLSS does not receive a correct value (which can vary based on eye
adaptation in some game engines), DLSS may produce a poor reconstruction of the high-resolution
frame with artifacts such as:
2. Blurriness, banding, or pixilation of the final frame or it being too dark or too bright.
4. Exposure lag.
If one or the above issues are present even when ExposureValue is provided, a scale factor and/or
bias may be required.
You can display that pattern in the top right corner by cycling through the debug visualizers (see section
8.2).
If on the other hand the value that you are passing through the exposure scale texture is undervalued,
leading DLSS to see a vastly underexposed image, you should see this pattern below, where everything
is very bright:
And on the opposite side, if you are passing a value through the exposure scale that is overestimated,
that will lead DLSS to see an overexposed image which again will be visible with this pattern below,
where everything is very dark:
Please note that this is not a common use-case and developers are encouraged to confirm visual
artifacts are not being caused by issues such as incorrect sub-pixel jitter or bad motion vectors. Please
check them first and check with a core rendering engine lead as to whether a pre-exposure value is used
or whether the input buffer passed to DLSS is already “eye adapted”.
If there is a pre-exposure value, you must pass it to DLSS during every DLSS evaluation call using the
InPreExposure parameter (available from DLSS v2.1.0).
NOTE: The pre-exposure value is optional and is sent to DLSS is a CPU-side float passed via the
parameter maps. It is not a texture like the main exposure value.
3.10 Auto-exposure
Using the main exposure parameter (see above) is the preferred method, however in some situations,
taking advantage of the optional auto-exposure feature in the DLSS library can provide improved results.
To use the auto-exposure values computed inside the DLSS library instead of pInExposureTexture,
the developer must:
Auto-exposure may be toggled using the DLSS SDK DLL by pressing the CTRL+ALT+Y hotkey while in the
game (overriding the flag passed at creation time).
NOTE: The sharpening and softening pass provided in previous versions of the SDK are now
deprecated. All developers are encouraged to use the Image Scaling SDK via the DLSS SDK or
directly on GitHub.
The following are the Presets that can be set per Performance mode using the
NVSDK_NGX_Parameter_SetUI API :
// These can be set via NVSDK_NGX_Parameter_SetUI and take values (and including) 0 - 4
typedef enum NVSDK_NGX_DLSS_Hint_Render_Preset
{
NVSDK_NGX_DLSS_Hint_Render_Preset_Default, // default behavior, weights may or may not be
updated after OTA
NVSDK_NGX_DLSS_Hint_Render_Preset_A,
NVSDK_NGX_DLSS_Hint_Render_Preset_B,
NVSDK_NGX_DLSS_Hint_Render_Preset_C,
NVSDK_NGX_DLSS_Hint_Render_Preset_D,
NVSDK_NGX_DLSS_Hint_Render_Preset_E,
NVSDK_NGX_DLSS_Hint_Render_Preset_F,
NVSDK_NGX_DLSS_Hint_Render_Preset_G,
} NVSDK_NGX_DLSS_Hint_Render_Preset;
DLSS defaults and presets are subject to change with new versions of DLSS. Note that
NVSDK_NGX_DLSS_Hint_Render_Preset_DLAA will work only when the input and output render
sizes are set to the same value as described above.
Again, presets are subject to change with each revision but the following serves as a general guide for
experimentations with the current presets:
• Titles that opt-in for OTA updates, and have selected a specific model, will keep that model
going forward.
• In the case that the update offers a different underlying default preset that the one originally
integrated - Titles that opt-in for OTA updates, and are using the default model, may have the
default model changed on them as part of the OTA update.
To avoid these artifacts, during the DLSS Evaluation call for the first frame after a major transition, set
the InReset parameter from the DLSS_Eval parameter list to a non-zero value. This instructs DLSS to
void its internal temporal component and restart its processing with the incoming inputs.
Note that the amount of memory that the function returns is a global variable. Therefore, if you created
multiple DLSS instances, the function returns TOTAL amount of memory currently used by all instances.
It also includes any memory that DLSS may cache internally. Therefore, even if you released all DLSS
instances, you may still see non-zero value of allocated memory. All cached memory gets released when
Shutdown() is called though.
Also Note that, by default, when you call ReleaseFeature(), the memory used by the feature isn’t
released – it's being cached internally for such case when you will immediately re-create feature again –
this memory would then be reused. However, DLSS supports a hint
NVSDK_NGX_Parameter_FreeMemOnReleaseFeature which will force memory release on each
ReleaseFeature() call. This hint can be set as follows:
NVSDK_NGX_Parameter_SetI(ngxParams, NVSDK_NGX_Parameter_FreeMemOnReleaseFeature, 1)).
5. Disoccluding objects with motion vectors that have very large values (such as a road surface
disoccluding from under a fast-moving car).
If a problematic asset is discovered during testing, one option is to instruct DLSS to bias the incoming
color buffer over the colors from previous frames. To do so, create a 2D binary mask that flags the non-
occluded pixels that represent the problematic asset and send it to the DLSS evaluate call as the
BiasCurrentColor parameter. The DLSS model then uses an alternate technique for pixels flagged by
the mask.
The mask itself should be the same resolution as the color buffer input, use R8G8B8A8_UNORM
/R16_FLOAT/R8_UNORM format (or any format with an R component) and have a value of “1.0” for
masked pixels with all other pixels set to “0.0”.
To use DLSS with multiple views, create multiple DLSS instances with the standard call to
NGX_<API>_CREATE_DLSS_EXT) and have the DLSS evaluation calls be made on the DLSS instance
handle associated with the view currently being upsampled.
Many VR titles render both eyes to the same render target. In that case, use sub-rectangles to restrict
DLSS to the appropriate region of interest in the render target (see section 5.4 for details). The sub-
rectangle parameters specify:
2. The size of the sub-rectangles assumed to be the input/output dimensions specified at instance
handle creation time or the input dimensions specified at evaluation time, in the case of the
input sub-rectangles, if dynamic resolution is being used (see section 3.2.2 for details).
3. The size of the output sub-rectangle is assumed to be the output dimensions specified at
instance handle creation time regardless of whether dynamic resolution is in use.
NOTE: To use sub-rectangles to specify a subregion of the output resource for DLSS to output to, the flag
InEnableOutputSubrects in NVSDK_NGX_DLSS_Create_Params must be set to true at
DLSS instance handle creation time (see section 5.3 for details). Sub-rectangles are supported on
the input resources regardless of whether InEnableOutputSubrects is set.
NOTE: End-user machines do not show the DLSS parameters and debug lines but some DLSS
information like the version number does appear with a production DLSS library if the
developer’s or tester’s machine has the appropriate registry key set (see next paragraph). This is
not a bug.
For develop and debug builds, registry key that enables DLSS on-screen indicator is:
HKEY_LOCAL_MACHINE\SOFTWARE\NVIDIA Corporation\Global\NGXCore\ShowDlssIndicator
It must be DWORD. Any positive value enables DLSS indicator for Develop and Debug builds of DLSS. On
the contrary, Release build of DLSS requires value 1024 to enable DLSS indicator.
3. Render to target scaling factor. The first number is the input buffer size (i.e. the current render
target size); the second number is the output buffer size (i.e. the display resolution).
4. The remainder of the line shows timing information (depending on the driver in use and setup of the
system, timing may display zero or estimates of execution time).
5. The debugging hotkeys begin on the second line and continue onto the third:
5.1. The current debug overlay name is output first. To cycle through the available debug overlays,
use CTRL+ALT+F12. For a list of debug overlays and how to use them, see section 8.2.
5.2. To toggle between the debug overlay displayed as a window in the top right of the screen and a
fullscreen display, use CTRL+ALT+F11.
5.3. To toggle the debug “Accumulation Mode”, use CTRL+ALT+F6. For more information on how to
use the Accumulation Mode, see section 8.3.
5.4. To toggle NaN visualization, use CTRL+ALT+O. NaNs will be displayed as bright red. To debug
NaNs in the input, cycle through the debug overlays as described above.
5.5. To cycle negation of the different jitter offsets, use CTRL+ALT+F10. For more information on
debugging jitter, see section 8.4 and for a full list of the different combinations, see 3.17.1.1
below.
The latest DLSS debugging registry keys are available in the “utils” directory.
1. The “ngx_log_on.reg” file enables the NGX logging system (meaning log files are generated).
2. The “ngx_log_off.reg” file disables the NGX logging system (meaning no log files are
generated).
a. Certain fullscreen games and applications can exhibit unexpected behavior when the
NGX logging window is used. If that occurs, try running the game in Windowed mode or
disable the NGX logging window by running “ngx_log_window_off.reg”.
IMPORTANT: NGX or DLSS may silently fail to load or initialize if the path provided to NGX for logging
is not writeable. The developer must ensure they provide a valid path if logging is
enabled. Creating a directory in “%USERPROFILE%\AppData\Local\” and using that
for logging is a common option.
In addition, the app may also directly raise the logging level used by NGX, and have the NGX log line
piped back to the app via a callback, among other logging-related settings that the app may set. These
features may be used by the app by setting additional parameters in the
NVSDK_NGX_FeatureCommonInfo struct that the app may pass in when initializing NGX. Please see
section 5.2 below for more details.
− https://developer.nvidia.com/dlss-getting-started
The sample app is written using the NVIDIA “Donut” framework. The application code is in
“.../DLSS_Sample_App/ngx_dlss_demo”. The “NGXWrapper.cpp” file contains the NGX calls,
which are invoked from “DemoMain.cpp”.
• Streamline SDK
• DLSS Plugin for Streamline – sl.dlss.dll available in the Streamline SDK
• DLSS Binary – a compatible nvngx_dlss.dll which can be used by sl.dlss.dll
The DLSS Plugin for Streamline (sl.dlss.dll) serves as a wrapper for nvngx_dlss.dll. For more details on
how to integrate DLSS into applications using the Streamline SDK, please refer to the programming
guide shipped as a part of that SDK:
https://github.com/NVIDIAGameWorks/Streamline
Note: The DLSS library can be loaded from an alternate directory path if required. The entry point,
NVSDK_NGX_D3D12_Init_ext, accepts a parameter, InFeatureInfo which has a
NVSDK_NGX_PathListInfo item which contains a list of paths to search through. For more
information, see sections 5.1 and 5.2 below.
IMPORTANT: If the NVIDIA signature is missing or corrupted on the DLSS DLL, NGX Core is not able to
load the library and DLSS functionality will fail.
Please include the full text of copyright and license blurbs that are found in section 9.5.
− nvsdk_ngx.h
− nvsdk_ngx_defs.h
− nvsdk_ngx_params.h
− nvsdk_ngx_helpers.h
NOTE: Vulkan headers follow the above naming convention with a “_vk” suffix and must be included
with Vulkan applications.
1. nvsdk_ngx_s.lib (if the project uses static runtime library (/MT) linking),
or
2. nvsdk_ngx_d.lib (if the project uses dynamic runtime library (/MD) linking).
and
libstdc++.so
and
libdl.so
Additional note for Vulkan: The application must enable the instance and device extensions as queried
by the APIs mentioned in section 2.3.1.
// A logging callback provided by the app to allow piping log lines back to the app.
// Please take careful note of the signature and calling convention.
// The callback must be able to be called from any thread.
// It must also be fully thread-safe and any number of threads may call into it concurrently.
// It must fully process message by the time it returns, and there is no guarantee that
// message will still be valid or allocated after it returns.
// message will be a null-terminated string and may contain multibyte characters.
#if defined(__GNUC__) || defined(__clang__)
typedef void NVSDK_CONV(*NVSDK_NGX_AppLogCallback)(const char* message,
NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
#else
typedef void(NVSDK_CONV* NVSDK_NGX_AppLogCallback)(const char* message,
NVSDK_NGX_Logging_Level loggingLevel, NVSDK_NGX_Feature sourceComponent);
#endif
// Whether or not to disable writing log lines to sinks other than the app log
//callback.
// This may be useful if the app provides a logging callback. LoggingCallback must be
//non-null and point
// to a valid logging callback if this is set to true.
bool DisableOtherLoggingSinks;
} NGSDK_NGX_LoggingInfo;
NGSDK_NGX_LoggingInfo LoggingInfo;
} NVSDK_NGX_FeatureCommonInfo;
// NVSDK_NGX_Init
// -------------------------------------
//
// InApplicationId:
// Unique Id provided by NVIDIA
//
// InApplicationDataPath:
// Folder to store logs and other temporary files (write access required)
//
// InDevice: [d3d11/12 only]
// DirectX device to use
//
// InFeatureInfo:
// Contains information common to all features, presently only a list of all paths
// feature dlls can be located in, other than the default path - application directory.
//
// InSDKVersion:
// The minimum API version required to be supported by the drivers installed on the
// user’s machine. Certain SDK features require a minimum API version to be supported
// by the user’s installed drivers. The call to the SDK initialization function
// will fail if the drivers do not support at least API version InSDKVersion. The
// application should pass in the appropriate InSDKVersion for its required set of
// SDK features.
//
// DESCRIPTION:
// Initializes new SDK instance.
//
#ifdef __cplusplus
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const
wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice
InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo = nullptr, NVSDK_NGX_Version
InSDKVersion = NVSDK_NGX_Version_API);
#else
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const
wchar_t *InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice
InDevice, const NVSDK_NGX_FeatureCommonInfo *InFeatureInfo, NVSDK_NGX_Version InSDKVersion);
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
/////
// NVSDK_NGX_Init_with_ProjectID
// -------------------------------------
//
// InProjectId:
// Unique Id provided by the rendering engine used
//
// InEngineType:
// Rendering engine used by the application / plugin.
// Use NVSDK_NGX_ENGINE_TYPE_CUSTOM if the specific engine type is not supported
explicitly
//
// InEngineVersion:
// Version number of the rendering engine used by the application / plugin.
//
// InApplicationDataPath:
// Folder to store logs and other temporary files (write access required),
// Normally this would be a location in Documents or ProgramData.
//
// InDevice: [d3d11/12 only]
// DirectX device to use
//
// InFeatureInfo:
// Contains information common to all features, presently only a list of all paths
// feature dlls can be located in, other than the default path - application directory.
//
// DESCRIPTION:
// Initializes new SDK instance.
//
NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Init_with_ProjectID(const char *InProjectId,
NVSDK_NGX_EngineType InEngineType, const char *InEngineVersion, const wchar_t
*InApplicationDataPath, ID3D11Device *InDevice, const NVSDK_NGX_FeatureCommonInfo
*InFeatureInfo = nullptr, NVSDK_NGX_Version InSDKVersion = NVSDK_NGX_Version_API);
5.2.1 Project ID
Project Id refers to a unique ID(InProjectId) that is specific to certain 3rd party engines like Unreal or
Omniverse. The DLSS integration for those engines should already take care of passing the value to DLSS.
Make sure that the Project ID is set in the engine’s editor.
“a0f57b54-1daf-4934-90ae-c4035c19df04"
For CUSTOM engine type the driver validates that passed project ID satisfies GUID-likeness
requirements. If you get error from NVSDK_NGX_*_Init_with_ProjectID(), you can see what exact
problem was by inspecting NGX log.
Use NVSDK_NGX_*_Init_with_ProjectID() function along with a Project ID, Engine Type and Engine
Version, as described in their respective sections.
Note: If your NVIDIA Developer Technologies contact provides you with a NVIDIA Application ID
(InApplicationId), please use the NVSDK_NGX_*_Init() functions to initialize NGX and pass in the
given application ID instead of Project ID.
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_AllocateParameters
// ----------------------------------------------------------
//
// OutParameters:
// Parameters interface used to set any parameter needed by the SDK
//
// DESCRIPTION:
// This interface allows allocating a simple parameter setup using named fields, whose
// lifetime the app must manage.
// For example one can set width by calling Set(NVSDK_NGX_Parameter_Denoiser_Width,100)
// or provide CUDA buffer pointer by calling
// Set(NVSDK_NGX_Parameter_Denoiser_Color,cudaBuffer)
// For more details please see sample code.
// Parameter maps output by NVSDK_NGX_AllocateParameters must NOT be freed using
// the free/delete operator; to free a parameter map
// output by NVSDK_NGX_AllocateParameters, NVSDK_NGX_DestroyParameters should be used.
// Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with
// NVSDK_NGX_AllocateParameters
// must be destroyed by the app using NVSDK_NGX_DestroyParameters.
// Also unlike with NVSDK_NGX_GetParameters, parameter maps output by
// NVSDK_NGX_AllocateParameters
// do not come pre-populated with NGX capabilities and available features.
// To create a new parameter map pre-populated with such information,
// NVSDK_NGX_GetCapabilityParameters
// should be used.
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
// does not support this API call is being used. In such a case, NVSDK_NGX_GetParameters
// may be used as a fallback.
// This function may only be called after a successful call into NVSDK_NGX_Init.
//
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D11_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D12_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_VULKAN_AllocateParameters(NVSDK_NGX_Parameter** OutParameters);
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_GetCapabilityParameters
// ----------------------------------------------------------
//
// OutParameters:
// The parameters interface populated with NGX and feature capabilities
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_DestroyParameters
// ----------------------------------------------------------
//
// InParameters:
// The parameters interface to be destroyed
//
// DESCRIPTION:
// This interface allows the app to destroy the parameter map passed in. Once
// NVSDK_NGX_DestroyParameters is called on a parameter map, it
// must not be used again.
// NVSDK_NGX_DestroyParameters must not be called on any parameter map returned
// by NVSDK_NGX_GetParameters; NGX will manage the lifetime of those
// parameter maps.
// This function may return NVSDK_NGX_Result_FAIL_OutOfDate if an older driver, which
// does not support this API call is being used. This function may only be called
// after a successful call into NVSDK_NGX_Init.
//
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D11_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_VULKAN_DestroyParameters(NVSDK_NGX_Parameter* InParameters);
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_GetParameters
// ----------------------------------------------------------
//
The app should allocate a new parameter map pre-populated with the above-mentioned read-only
parameters provided by NGX, using the NVSDK_NGX_GetCapabilityParameters interface. Note that if
the user is using an older driver, NVSDK_NGX_GetCapabilityParameters may fail with
NVSDK_NGX_Result_FAIL_OutOfDate. In that case, the app may fall back on using
NVSDK_NGX_GetParameters to get a parameter map pre-populated with the above-mentioned read-
only parameters. Note however, that NVSDK_NGX_GetParameters is deprecated, and its use as a
fallback by apps is intended as a stopgap, until a new enough driver version is widely installed.
Sometimes NGX feature is denied for certain apps. It can be also queried using
NVSDK_NGX_GetParameters with enum: NVSDK_NGX_Parameter_SuperSampling_ FeatureInitResult.
For example, to check if DLSS is available on the user’s system when running in Vulkan, use the
following:
int DLSS_Supported = 0;
int needsUpdatedDriver = 0;
unsigned int minDriverVersionMajor = 0;
unsigned int minDriverVersionMinor = 0;
if(Result != NVSDK_NGX_Result_Success)
{
bShouldDestroyCapabilityParams = false;
NVSDK_NGX_VULKAN_GetParameters(&Params);
}
NVSDK_NGX_Result ResultUpdatedDriver =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_NeedsUpdatedDriver, &needsUpdatedDriver);
NVSDK_NGX_Result ResultMinDriverVersionMajor =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMajor, &minDriverVersionMajor);
NVSDK_NGX_Result ResultMinDriverVersionMinor =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_MinDriverVersionMinor, &minDriverVersionMinor);
if (NVSDK_NGX_SUCCEED(ResultUpdatedDriver))
{
if (needsUpdatedDriver)
{
// NVIDIA DLSS cannot be loaded due to outdated driver.
if (NVSDK_NGX_SUCCEED(ResultMinDriverVersionMajor) &&
NVSDK_NGX_SUCCEED(ResultMinDriverVersionMinor))
{
// Min Driver Version required: minDriverVersionMajor.minDriverVersionMinor
}
// Fallback to default AA solution (TAA etc)
}
else
{
// driver update is not required – so application is not expected to
// query minDriverVersion in this case
}
}
NVSDK_NGX_Result ResultDlssSupported =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_Available,&DLSS_Supported);
if (NVSDK_NGX_FAILED(ResultDlssSupported) || !DLSS_Supported )
{
// NVIDIA DLSS not available on this hardward/platform.
ResultDlssSupported =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_FeatureInitResult,&DLSS_Supported);
if (NVSDK_NGX_FAILED(ResultDlssSupported) || !DLSS_Supported )
{
// NVIDIA DLSS is denied on for this application.
if(bShouldDestroyCapabilityParams)
{
NVSDK_NGX_VULKAN_DestroyParameters(Params);
Overriding the feature denial mechanism will have to be supported via windows regkeys (similar to how
most of the other overrides are supported in NGX). All regkeys for this override must be written to
HKLM\SOFTWARE\NVIDIA Corporation\Global\NGXCore.
OverrideFeatureDeny
a. Type: REG_DWORD
b. Values: whether or not to enable overriding - 0 = disable overriding, non-zero: enable
overriding
c. Default behavior: disable overriding
OverrideFeatureDeny_CMSID
a. Type: REG_SZ
b. Values: CMS ID for the specific application being overridden; if app doesn't have a
unique CMS ID or if app dev doesn't know the CMS ID for their app, do not create this
regkey
c. Default behavior: apply override behavior to all apps
OverrideFeatureDeny_Feature
a. Type: REG_SZ
b. Values: feature name for the specific feature being overridden; do not create regkey if
all features are to be overridden
c. Default behavior: apply override behavior to all features
OverrideFeatureDeny_Deny
a. Type: REG_DWORD
b. Values: whether or not to deny the feature - 0 = allow, 1 = deny
c. Default behavior: allow
To obtain the optimal resolution settings for DLSS issue the query below. The developer should confirm
the returned DLSSMode for each combination of:
− PerfQualityValue
NOTE: The PerfQualityValue is currently defined in the NGX DLSS header as having five possible
values. All five PerfQualityValue values should be checked and if they are enabled, they
should be selectable in the Game UI (and hidden if disabled). For more information on these
values, see section 3.2.1.
DLSSMode = NGX_DLSS_GET_OPTIMAL_SETTINGS(
Params,
TargetWidth, TargetHeight,
PerfQualityValue,
&RecommendedOptimalRenderWidth, &RecommendedOptimalRenderHeight,
&DynamicMaximumRenderSizeWidth, &DynamicMaximumRenderSizeHeight,
&DynamicMinimumRenderSizeWidth, &DynamicMinimumRenderSizeHeight,
&Sharpness);
if (RecommendedOptimalRenderWidth == 0 || RecommendedOptimalRenderHeight == 0)
(
{
// This PerfQuality mode has not been made available yet.
// Please request another PerfQuality mode.
}
else
{
// Use DLSS for this combination
// - Create feature with RecommendedOptimalRenderWidth, RecommendedOptimalRenderHeight
// - Render to (RenderWidth, RenderHeight) between Min and Max inclusive
// - Call DLSS to upscale to (TargetWidth, TargetHeight)
}
NVSDK_NGX_DLSS_Feature_Flags_None = 0,
NVSDK_NGX_DLSS_Feature_Flags_IsHDR = 1 << 0,
NVSDK_NGX_DLSS_Feature_Flags_MVLowRes = 1 << 1,
NGX_D3D11_CREATE_DLSS_EXT(
CommandCtx, // Command context
&FeatureHandle[Node], // Handle for the new feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
&DlssCreateParams // Parameters in NVSDK_NGX_DLSS_Create_Params struct
);
NGX_D3D12_CREATE_DLSS_EXT(
CommandList[Node], // Command list for current GPU node
CreationNodeMask, // Multi GPU only (default 1)
VisibilityNodeMask // Multi GPU only (default 1)
&FeatureHandle[Node], // Handle for the new feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
&DlssCreateParams // Parameters in NVSDK_NGX_DLSS_Create_Params struct
);
NGX_VULKAN_CREATE_DLSS_EXT(
VkCommandBuffer, // Vulkan Command Buffer
CreationNodeMask, // Multi GPU only (default 1)
VisibilityNodeMask // Multi GPU only (default 1)
&FeatureHandle[Node], // Handle for the new feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
&DlssCreateParams // Parameters in NVSDK_NGX_DLSS_Create_Params struct
);
Limitation: InTargetWidth and InTargetHeight currently have a limitation on their minimum size. They
must be at least 64 pixels for the width and 32 pixels for the height. The call to Create or
Evaluate the feature may fail as a result of this limitation.
// D3D12 - NVSDK_NGX_D3D12_Feature_Eval_Params
// VULKAN - NVSDK_NGX_VK_Feature_Eval_Params
typedef struct NVSDK_NGX_D3D11_Feature_Eval_Params
{
ID3D11resource* pInColor; // Color buffer
ID3D11resource* pInOutput; // Output buffer
/*** OPTIONAL for DLSS ***/
float InSharpness; // Deprecated, see section 3.11
} NVSDK_NGX_D3D11_Feature_Eval_Params
// D3D12 - D3D12_GBuffer
// VULKAN - VK_GBuffer
typedef struct NVSDK_NGX_D3D11_GBuffer
{
ID3D11Resource* pInAttrib[GBUFFERTYPE_NUM];
} NVSDK_NGX_D3D11_GBuffer;
// D3D12 - NVSDK_NGX_D3D12_DLSS_Eval_Params
// VULKAN - NVSDK_NGX_VK_DLSS_Eval_Params
typedef struct NVSDK_NGX_D3D11_DLSS_Eval_Params
{
NVSDK_NGX_D3D11_Feature_Eval_Params Feature;
ID3D11Resource* pInDepth; // Depth buffer
ID3D11Resource* pInMotionVectors; // MVs buffer
NGX_D3D11_EVALUATE_DLSS_EXT(
Context, // Command context
FeatureHandle, // Handle for the new feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
D3D11DlssEvalParams // Parameters in NVSDK_NGX_D3D11_DLSS_Eval_Params struct
);
NGX_D3D12_EVALUATE_DLSS_EXT(
CommandList[Node], // Command list for GPU node
FeatureHandle[Node], // Handle for the new feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
D3D12DlssEvalParams // Parameters in NVSDK_NGX_D3D12_DLSS_Eval_Params struct
);
NGX_VULKAN_EVALUATE_DLSS_EXT(
VkCommandBuffer, // Vulkan Command Buffer
&FeatureHandle[Node], // Handle for the feature
Params, // Parameters obtained with NVSDK_NGX_AllocateParameters
VkDlssEvalParams // Parameters in NVSDK_NGX_VK_DLSS_Eval_Params struct
);
IMPORTANT: NGX modifies the Vulkan and D3D12 command list states. The calling process must save
and restore its own Vulkan or D3D12 state before and after making the NGX evaluate
feature calls.
// NVSDK_NGX_Release
// -------------------------------------
//
// InHandle:
// Handle to feature to be released
//
A feature handle should only be released once the command lists (Direct3D) or command buffers
(Vulkan) that were used in Evaluate_XXX() calls are no longer in flights as that command list could still
reference internal states and resources associated with the feature.
5.6 Shutdown
To release the NGX SDK instance and all resources allocated with it, use the following method:
// NVSDK_NGX_Shutdown
// -------------------------------------
//
// DESCRIPTION:
// Shuts down the current SDK instance and releases all resources.
//
The Shutdown() function should only be called once when all associated features have been released.
That also means no work associated with those features is still in flight.
6 Resource Management
DLSS requires certain internal resources to be created. If a game requires full control over the NGX
resource lifecycle and VRAM allocation, it is possible to register specific callbacks for resource creation
Params->Set(NVSDK_NGX_Parameter_BufferAllocCallback, NGXBufferAllocCallback);
Params->Set(NVSDK_NGX_Parameter_ResourceAllocCallback, NGXResourceAllocCallback);
6.4 Common
void NGXResourceReleaseCallback(IUnknown *InResource)
{
// Delay release as needed or manage based on use case
SAFE_RELEASE(InResource);
}
Params->Set(NVSDK_NGX_Parameter_ResourceReleaseCallback,
NGXResourceReleaseCallback);
NOTE: NGX does not hold a reference to any DirectX resource passed to it from the client side.
By default, DLSS feature will be evaluated on the GPU where it has been created. It is possible to evaluate
DLSS feature on any node which was included in the VisibilityNodeMask. To evaluate DLSS feature on
another node, use NVSDK_NGX_EParameter_EvaluationNode parameter.
The code example below, shows how to use DLSS in Linked mode
NOTE: When using D3D11 basic multi-GPU/SLI (Alternate Frame Rendering - AFR), multi-GPU support is
provided directly by the NVIDIA driver and there are no additional integration requirements.
Another API relevant to this case is NGX_VULKAN_CreateFeature1(). This API is specifically introduced to
create feature in unlinked mode for VULKAN. The reason that VULKAN is different here is that VULKAN
does not allow inferring Device pointer from command buffer pointer. D3D11 and D3D12 do allow that
so for them NGX_CreateFeature() will work fine in unlinked mode.
Note: this is supported only on 470+ drivers and only if you explicitly specify NGX API Version
>= 0x15 when you call NGX_Init()
8 Troubleshooting
8.1 Common Issues Causing Visual Artifacts
1. Incorrect motion vectors: make sure you can always visualize and validate motion vectors (see
the DLSS debug overlay section below).
a. Make sure the motion vectors are pointing in a direction indicating how to get the pixel
in screen space from the current frame to its position in the previous frame in screen
space. So, if the game is running at 1080p and the object has moved from the left edge
of the screen to the right edge, then the x value of the motion vector for that pixel on
the right edge will be -1080.0.
b. Make sure the motion vectors are expressed in 16-bit or 32-bit floating point values.
Using integer values will not take sub-pixel values into account.
d. Make sure all objects visible on screen have motion vectors calculated correctly.
Common places to miss out motion vectors include animated foliage, the sky.
2. Wrong or out of sync jitter pattern: make sure you are using the sequence provided in section
3.7. The jitter pattern must match regardless of frame time etc.
3. Disabling TAA often changes the way the engine renders (jitter, depth, motion etc.) which can
consequently break DLSS. When integrating DLSS, the TAA rendering pass should be replaced
with DLSS but everything else in the rendering pipeline that is activated when TAA is turned on,
must still be executed as if TAA is still active.
a. Ensure that all input to DLSS is properly jittered. This includes secondary passes that
might otherwise have not been jittered (e.g. object highlighting).
4. Incorrect exposure / or pre-exposure (see section 3.9): make sure you always pass in the correct
exposure texture or pre-exposure value to avoid:
b. Blurriness, banding, or pixilation of the final frame or it being too dark or too bright.
d. A pronounced lag in the scene brightness changing when going from a dark scene to a
bright scene (or vice versa).
5. In low VRAM scenarios, the game may crash if DLSS is invoked while required resources (Color,
Motion Vectors etc.) are evicted from the GPU. If this happens please make sure all resources
are made resident before using DLSS.
6. Use the on-screen debug text (see section 3.8) to verify the resolution of the buffers that are
passed into the DLSS module.
7. Incorrect resource setup: make sure you create the buffers passed to DLSS with the requires
usage flags (see chapter 3.4). Otherwise, the output may be black without further indication as
to what went wrong.
4. The history of submitted jitter offsets in an XY scatter plot [-1, 1] (green is the current offset,
white and red represent old offsets that are within the correct boundary [-0.5, 0.5] and outside
it, respectively). If old, interior offsets are colored yellow, it means that the recommended
number of phases has not been met yet (see section 3.7 for more information)
6. A pattern that helps diagnose bad exposure texture being passed to DLSS.
To toggle the debug visualization between an overlay window in the top right of the screen and
fullscreen, use the CTRL+ALT+F11 hotkey.
NOTE: The DLSS production library does not include the Debug Overlay.
NOTE: If accumulation mode is enabled and anything in the scene moves or if the camera moves, you
will see heavy ghosting and trails. That is expected.
2. Turn off all in-engine AA and turn off all post processing (or just render the albedo from the
gbuffer).
3. With a static scene and no motion, the output from DLSS should match the same scene
rendered at native full resolution (with no AA and no post processing).
a. DLSS on with 50% rendering (typically called “DLSS Performance Mode”); and
5. Use the in-built Microsoft Windows "Screen Magnifier" utility to zoom-in while the game is
running and toggle back and forth between native rendering and DLSS.
a. Screen Magnifier enable hotkey: Windows logo key + Plus sign (+) on the keyboard
c. Go into the Screen Magnifier settings and DISABLE "Smooth edges of images and text"
6. When rendering a static scene or when looking at static objects in a scene, if the output from
DLSS looks blurry or flickers or is otherwise misaligned, something is off between the renderer
and DLSS.
a. Confirm the jitter offset values are always between -0.5 and +0.5. They should never be
outside this range. If they do go beyond that range, the renderer is moving the viewport
outside the pixel (which will usually result in full screen shaking with DLSS on and off; or
heavy blurriness when DLSS is on).
b. Try exchanging the jitter X and Y offsets using the CTRL+ALT+F10 hotkey built into the
DLSS SDK library (see section 3.8 for more information).
i. If exchanging the axes resolves the issue, in the game or engine, exchange the
jitter offsets before calling DLSS.
c. Try negating and scaling the jitter input values using the CTRL+ALT+F9 hotkey built into
the DLSS SDK library (see section 3.8 for more information).
d. Use the DLSS Debug Overlay (see section 8.2 above), or another method, to confirm that
motion vectors are [0.0,0.0] for the entire screen (or at least on all static objects and
areas of the screen where there is no movement).
i. If motion vectors are not correct, fix them for the material, object, terrain or
other system as required. DLSS assumes the engine provides accurate per-pixel
motion vectors every frame.
1. First, add a “1 quadrant jitter” where the renderer always jitters to a specific quadrant every
frame with a hotkey to cycle all four quadrants in order.
a. If possible, add an on-screen indicator or debug text indicating the quadrant to which
the renderer is currently jittering.
2. Second, add a “4 quadrant jitter” where the renderer jitters one frame to each quadrant cycling
each quadrant in order automatically.
2. Ensure the output of DLSS is shown at 1:1 ratio on the screen. This debug mode will not be
useful if ANY amount of scale change happens after DLSS is applied, either through the engine
own upscaling or through the engine window being resized.
3. Find a static scene in the game and render the scene with the renderer jittering to a known and
fixed quadrant.
4. Examine the screen output and use Screen Magnifier to better examine individual pixels.
5. If the renderer is correctly jittering, you should see groups of four pixels with one pixel in each
group colored and three pixels that are completely black.
a. Cycle through each jitter quadrant and confirm the color moves to the correct quadrant
and three pixels become completely black.
b. If there are less than three black pixels in each grouping, the amount of jitter, the scale
of the jitter or the sign of jitter being sent is incorrect.
Single quadrant jitter output under full zoom with correct jitter.
Note the groups of four pixels; three black and one colored/filled.
6. If the test in step 3 shows that the jitter is incorrect, try exchanging, negating or scaling the jitter
vector components using the DLSS debug hotkeys (see section 8.4.1 above).
7. If changing the jitter scale or negating a component does not resolve the issue, find a static
scene and:
a. Capture one screenshot while the renderer jitters to each quadrant (resulting in four
screenshots total).
b. Turn on full resolution rendering, no AA, no post, no DLSS and capture one screenshot.
2. Ensure the output of DLSS is shown at 1:1 ratio on the screen. This debug mode will not be
useful if ANY amount of scale change happens after DLSS is applied, either through the engine
own upscaling or through the engine window being resized.
3. Examine the screen output, using the Screen Magnifier to better examine individual pixels.
4. With the renderer cycling jitter to each of the four quadrants and DLSS enabled, the final image
will be aliased and should match full resolution rendering with no AA, no DLSS and no post-
processing.
a. It is easiest to compare simple static flat objects like planks of wood, tree trunks, metal
posts, fence posts or other objects with straight edges.
5. If the test in step 3 shows differences in what DLSS displays versus native rendering, try
exchanging, negating or scaling the jitter vector components using the DLSS debug hotkeys (see
section 8.4.1 above).
6. If changing the jitter scale or negating a component does not resolve the issue, find a static
scene and look for more aliasing in one direction or if the aliasing is more pronounced vertically
or horizontally. In such case, check the amount of jitter applied in the rendering engine to the
projection matrix:
8.5 Linux
For Linux, kepress Ctrl+Alt+F<NR> can switch terminals. In this case, keypress can be overridden with a
config file named settings.ngxconfig and placed in ~/ngx/. For example, we can have it like in
/root/ngx/settings.ngxconfig. An example of settings.ngxconfig:
- dlss_debug
debug_jitter_config_rotate_key = "ctl+alt+f9", ;
debug_jitter_swap_coordinates_key = "ctl+alt+f10", ;
− NVSDK_NGX_Result_FAIL_FeatureNotSupported
Feature is not supported on current hardware.
− NVSDK_NGX_Result_FAIL_PlatformError
Platform error - for example - check d3d12 debug layer log for more information.
− NVSDK_NGX_Result_FAIL_FeatureAlreadyExists
Feature with given parameters already exists.
− NVSDK_NGX_Result_FAIL_FeatureNotFound
Feature with provided handle does not exist.
− NVSDK_NGX_Result_FAIL_InvalidParameter
Invalid parameter was provided.
− NVSDK_NGX_Result_FAIL_NotInitialized
SDK was not initialized properly.
− NVSDK_NGX_Result_FAIL_UnsupportedInputFormat
Unsupported format used for input/output buffers.
− NVSDK_NGX_Result_FAIL_RWFlagMissing
Feature input/output needs RW access (UAV) (d3d11/d3d12 specific).
− NVSDK_NGX_Result_FAIL_MissingInput
Feature was created with specific input, but none is provided at evaluation.
− NVSDK_NGX_Result_FAIL_UnableToInitializeFeature
Feature is misconfigured or not available on the system.
− NVSDK_NGX_Result_FAIL_OutOfGPUMemory
Feature requires more GPU memory than is available on the system.
− NVSDK_NGX_Result_FAIL_UnsupportedFormat
Format used in input buffer(s) is not supported by feature.
− NVSDK_NGX_Result_FAIL_UnableToWriteToAppDataPath
Path provided in InApplicationDataPath cannot be written to
− NVSDK_NGX_Result_FAIL_UnsupportedParameter
Unsupported parameter was provided (e.g. specific display size or mode is unsupported)
− NVSDK_NGX_Result_FAIL_ Denied
The feature or application was denied (contact NVIDIA for further details)
2. Additional DLSS execution modes “Ultra-Performance” and “Ultra-Quality” (see section 3.2.1)
4. A pre-exposure factor is now supported if the renderer requires it (see section 3.9.2)
For details on how to pass these resources, please see the DLSS header files and if needed, discuss with
your NVIDIA technical contact. Please also check that there is no undue performance impact when
preparing and providing these resources to the DLSS library.
1. G-Buffer:
a. Albedo (supported format – 8-bit integer)
b. Roughness (supported format – 8-bit integer)
c. Metallic (supported format – 8-bit integer)
d. Specular (supported format – 8-bit integer)1
e. Subsurface (supported format – 8-bit integer)
f. Normals (supported format – RGB10A2, Engine-dependent)
g. Shading Model ID / Material ID : unique identifier for drawn object / material,
essentially a segmentation mask for objects - common use case is to not accumulate, if
the warped nearest material identifier is different from the current, (supported format –
8-bit or 16-bit integer, Engine-dependent)
2. HDR Tonemapper type: String, Reinhard, OneOverLuma or ACES
3. 3D motion vectors - (supported format – 16-bit or 32-bit floating-point)
4. Is-particle mask: to identify which pixels contains particles, essentially that are not drawn as part
of base pass (supported format – 8-bit integer)
5. Animated texture mask: A binary mask covering pixels occupied by animated textures
(supported format – 8-bit integer)
6. High Resolution depth: (supported format – D24S8)
7. View-space position: (supported format – 16-bit or 32-bit floating-point)
8. Frame time delta (in milliseconds): helps in determining the amount to denoise or anti-alias
based on the speed of the object from motion vector magnitudes and fps as determined by this
delta
9. Ray tracing hit distance: For Each effect - good approximation to the amount of noise in a ray-
traced color (supported format – 16-bit or 32-bit floating-point)
10. Motion vector for reflections: motion vectors of reflected objects like for mirrored surfaces
(supported format – 16-bit or 32-bit floating-point)
9.5 Notices
The information provided in this specification is believed to be accurate and reliable as of the date
provided. However, NVIDIA Corporation (“NVIDIA”) does not give any representations or warranties,
expressed or implied, as to the accuracy or completeness of such information. NVIDIA shall have no
liability for the consequences or use of such information or for any infringement of patents or other
rights of third parties that may result from its use. This publication supersedes and replaces all other
specifications for the product that may have been previously supplied.
NVIDIA products are sold subject to the NVIDIA standard terms and conditions of sale supplied at the
time of order acknowledgement, unless otherwise agreed in an individual sales agreement signed by
authorized representatives of NVIDIA and customer. NVIDIA hereby expressly objects to applying any
customer general terms and conditions with regard to the purchase of the NVIDIA product referenced in
this specification.
NVIDIA products are not designed, authorized or warranted to be suitable for use in medical, military,
aircraft, space or life support equipment, nor in applications where failure or malfunction of the NVIDIA
product can reasonably be expected to result in personal injury, death or property or environmental
damage. NVIDIA accepts no liability for inclusion and/or use of NVIDIA products in such equipment or
applications and therefore such inclusion and/or use is at customer’s own risk.
NVIDIA makes no representation or warranty that products based on these specifications will be suitable
for any specified use without further testing or modification. Testing of all parameters of each product is
not necessarily performed by NVIDIA. It is customer’s sole responsibility to ensure the product is
suitable and fit for the application planned by customer and to do the necessary testing for the
application in order to avoid a default of the application or the product. Weaknesses in customer’s
product designs may affect the quality and reliability of the NVIDIA product and may result in additional
or different conditions and/or requirements beyond those contained in this specification. NVIDIA does
not accept any liability related to any default, damage, costs or problem which may be based on or
attributable to: (i) the use of the NVIDIA product in any manner that is contrary to this specification, or
(ii) customer product designs.
No license, either expressed or implied, is granted under any NVIDIA patent right, copyright, or other
NVIDIA intellectual property right under this specification. Information published by NVIDIA regarding
third-party products or services does not constitute a license from NVIDIA to use such products or
services or a warranty or endorsement thereof. Use of such information may require a license from a
third party under the patents or other intellectual property rights of the third party, or a license from
NVIDIA under the patents or other intellectual property rights of NVIDIA. Reproduction of information in
this specification is permissible only if reproduction is approved by NVIDIA in writing, is reproduced
without alteration, and is accompanied by all associated conditions, limitations, and notices.
ALL NVIDIA DESIGN SPECIFICATIONS, REFERENCE BOARDS, FILES, DRAWINGS, DIAGNOSTICS, LISTS, AND
OTHER DOCUMENTS (TOGETHER AND SEPARATELY, “MATERIALS”) ARE BEING PROVIDED “AS IS.” NVIDIA
MAKES NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO THE
MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
Notwithstanding any damages that customer might incur for any reason whatsoever, NVIDIA’s
aggregate and cumulative liability towards customer for the products described herein shall be limited
in accordance with the NVIDIA terms and conditions of sale for the product.
9.5.2 Copyright
© 2018-2020 NVIDIA Corporation. All rights reserved.
www.nvidia.com
Copyright © 1996 - 2018, Daniel Stenberg, [email protected], and many contributors, see the THANKS file.
Permission to use, copy, modify, and distribute this software for any purpose with or without fee is
hereby granted, provided that the above copyright notice and this permission notice appear in all
copies.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Software without prior written authorization
of the copyright holder.
9.6.3 d3dx12.h
https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12Multithreading/src/d3dx12.h
9.6.4 xml
https://pugixml.org/license.html
* This library is available to anybody free of charge, under the terms of MIT License:
9.6.5 npy
https://github.com/llohse/libnpy
https://github.com/llohse/libnpy/blob/master/LICENSE
* MIT License
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
9.6.6 stb
https://github.com/nothings/stb/blob/master/LICENSE
/*
* ALTERNATIVE A - MIT License
* Copyright (c) 2017 Sean Barrett
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
9.6.7 DirectX-Graphics-Samples
https://github.com/Microsoft/DirectX-Graphics-
Samples/tree/master/Samples/Desktop/D3D12Multithreading
/*
* Copyright (c) Microsoft. All rights reserved.
* This code is licensed under the MIT License (MIT).
* THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
* IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
* PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
*/
Any NVIDIA Linux driver released starting 22 March 2022 (for instance, NVIDIA Linux driver 510.60.02)
will only support DLSS snippets version >= 2.4.0.
Any NVIDIA Linux driver released prior to that date will only support DLSS snippets version < 2.4.0.
Applications can support both old and new drivers by shipping with two snippets (one < 2.4.0, and one
>= 2.4.0). In that case the application must have the paths to both snippets in
NVSDK_NGX_PathListInfo (first – to the older snippet, then – to a newer snippet). The driver will
access those snippets in order and use the first snippet it is able to load.
Windows versions of DLSS snippets (including those running on Steam Play Proton) are not affected by
this restriction.