DLSS Programming Guide Release
DLSS Programming Guide Release
1)
Programming Guide
For information on using DLSS in Unreal Engine 4, refer to the official NVIDIA RTX branch of Unreal
Engine 4 (see https://developer.nvidia.com/unrealengine, https://github.com/NvRTX/UnrealEngine;
apply for DLSS access at https://developer.nvidia.com/dlss).
Revision History
Revision Changes Date
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. During an “advanced driver installation” the module may be
listed as “NGX Core”.
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:
- Windows PC with Windows 10 v1709 (Fall 2017 Creators Update 64-bit) or newer
- The latest NVIDIA Graphics Driver is recommended with the minimum supported driver
currently being version 445.75
- The development environment for integrating the DLSS SDK into a game is:
o Microsoft Visual Studio 2012 and 2013 are supported but may be deprecated in the
future.
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 ApplicationID obtained from NVIDIA.
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.2.
1. The DLSS library allocates some RAM on the GPU internally. The mount of allocated memory can
be queried using NVSDK_NGX_DLSS_GetStatsCallback(). The table below shows approximate
amount of RAM allocated depending on output resolution:
- 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
NVIDIA has approved the release build (see section 4.1)
Full production non-watermarked DLSS library (nvngx_dlss.dll) is packaged in the
release build (see section 4.2)
Game specific Application ID is used during initialization (see section 5.2.1)
Mip-map bias set when DLSS is enabled (see section 3.5)
3 DLSS Integration
3.1 Pipeline Placement
The DLSS evaluation call must occur during the post-processing phase of the rendering pipeline. Exactly
where this occurs the developer can select based on the game and rendering engine requirements. For
best image quality place DLSS at the start of post processing before as many post effects as possible are
applied to the frame.
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.
There may also be a performance impact from running post effects at full display resolution which
should be evaluated.
IMPORTANT: Certain post effects, such as bloom, depth of field and chromatic aberration, often cause
visual artifacts in the DLSS output that is difficult (or impossible) to remove. It is highly
recommended that these types of post effects be placed after DLSS and execute on the
fully upscaled target size.
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
encoding (like sRGB). This is often the case after tonemapping but is not guaranteed (for
example if an HDR display panel is detected the tonemapper still outputs to linear space).
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 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
4. Ultra-Performance Mode
5. Ultra-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.
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 “Quality” or failing that “Balanced” or failing that
“Performance”.
For information on how to display the user facing DLSS mode selection, please see the “NVIDIA RTX
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
Optimal Settings calls for each DLSS mode and display resolution, the DLSS library returns the “optimal”
render resolution as pOutRenderOptimalWidth and pOutRenderOptimalHeight. Those values
must then be passed exactly as given to the next NGX_API_CREATE_DLSS_EXT() call.
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. 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.
1. Maintain a consistent texture mipmap bias as detailed in section 3.5. To maintain correct display
resolution sampling, the mip level should be updated each time the render resolution changes
(potentially every frame depending on the update rate of the dynamic resolution system).
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: an FP16 buffer or a supported depth or stencil format for the API.
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.
1. Input buffers (e.g. color, motion vectors, depth and optionally history, exposure etc.) be in pixel
shader read state (also known as a Shader Resource View, HLSL Texture. For vulkan, layout of
the image should be “VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL”).
2. The Output buffer be in UAV state (also known as an HLSL RWTexture. In Vulkan, image layout
should be “VK_IMAGE_LAYOUT_GENERAL”).
After the evaluate call, DLSS accesses and processes the buffers and may change their state but always
transitions buffers back to these known states.
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.
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.
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;
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. (see section 5.4 or nvsdk_ngx_helpers.h).
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
correctly (provided the rest of the jitter requirements in this section are followed) but NVIDIA has not
tested other patterns.
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 fo r 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.
Jitter offset scale diagram. Shaded red area is one full pixel.
The green marking is the origin with red outline the range of expected values.
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.
If this value is missing or DLSS does not receive the 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.
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.
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.
2. Set the InSharpness value between 0.0 and 1.0 on each DLSS Evaluate call.
If the developer enables sharpening, the level of sharpening should be controllable by the end-user. For
information on how to display the user facing selection, please see the “NVIDIA RTX Developer
Guidelines” (the latest version is on the GitHub repository in the “docs” directory).
For testing purposes, developers can force the additional DLSS sharpening filter on with the DLSS SDK
DLL and pressing the CTRL+ALT+F7 hotkey while in the game.
NOTE: Depending on the version of the DLSS algorithm, GPU and output resolution, there may be a
small increase in processing time (0.05-0.3ms) when sharpening is enabled.
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: Improper use of this can result in temporal flickering, heavy aliasing or other visual artifacts.
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”.
NOTE: Only use this mask on problematic assets after the DLSS integration has been completed and
confirmed as fully functional. There may be increased aliasing within the mask borders.
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.
3. Render to target scaling factor. The first number is the input buffer size (ie the current render target
size); the second number is the output buffer size (ie 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 additional sharpening (see section 3.10 above), use CTRL+ALT+F7.
5.4. 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.5. 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.6. 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.15.1.1
below.
5.7. To exchange the X and Y jitter offsets (i.e. have DLSS use the incoming X offset as the Y offset
and vice versa), use CTRL+ALT+F10. For more information on debugging jitter, see section 8.4.
The latest DLSS debugging registry keys are available on the GitHub repository in the “ utils” directory
(https://github.com/NVIDIAGameWorks/dlss_private/tree/master/utils/ ).
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://github.com/NVIDIAGameWorks/dlss_private/releases
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”.
IMPORTANT: The DLSS libraries included on the GitHub repository MUST NOT be included or
distributed in any public release. The libraries include on-screen notices and have an
overlay that is designed for debugging only (see section 8.2). Once a game is approved,
contact your NVIDIA account manager to obtain final production libraries (which do not
include watermarking or the debug overlays).
DLSS nvngx_dlss.dll
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.
The DLSS Dll that will be part of the game or application package includes third party code that needs to
be acknowledged in the public documentation of the final product (the game or application).
Please include the full text of copyright and license blurbs that are found in section 9.4.
− nvsdk_ngx.h
− nvsdk_ngx_defs.h
− nvsdk_ngx_params.h
− nvsdk_ngx_helpers.h
The header files are located in the “./include” folder. In the game project, include
nvsdk_ngx_helpers.h .
NOTE: Vulkan headers follow the above naming convention with a “_vk” suffix and must be included
with Vulkan applications.
In addition to including the NGX header files, the project must also link against:
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).
Both files are located in the “./lib/x64” folder (DLSS is provided as 64bit only libraries).
During development, copy the nvngx_dlss.dll from the “./bin/” directory on GitHub to the folder
where the main game executable or DLL is located so the NGX runtime can properly find and load the
DLL. If required by the game or the game build or packaging system, the DLSS library can be packaged in
a different location to the main executable. In such case, the entry point,
NVSDK_NGX_D3D12_Init_ext, accepts a parameter, InFeatureInfo which has a
// 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
// NGX return-code conversion -to-string utility only as a debug/logging aide - not for
official use.
const wchar_t* NVSDK_CONV GetNGXResultAsString(NVSDK_NGX_Result InNGXResult);
//////////////////////////////////////////////////////////////////////////////////////////////
/////
// 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.
//
Certain SDK features may require a certain minimum driver version. The required features that the
driver must support are gated by the InSDKVersion value passed into the SDK initialization functions
for each API. Thus, if an application requires features only available in SDK API version 0x0000014 or
higher, then it should pass in 0x0000014 for InSDKVersion . If it does not require said features, it
should pass in a lower value (such as 0x0000013, which also generally serves as a good baseline API
version for most applications, since it supports most SDK features, and is also widely supported by the
drivers installed on most user machines; please see the SDK headers to determine if your application
uses SDK features that require a higher API version). The minimum API version required for the various
SDK features is documented in the NGX SDK headers; please see the definition of struct
NVSDK_NGX_FeatureCommonInfo as an example.
5.2.2 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.
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// 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_Get Parameters
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_GetCapabilityParameters
// ----------------------------------------------------------
//
// OutParameters:
// The parameters interface po pulated with NGX and feature capabilities
//
// DESCRIPTION:
// This interface allows the app to create a new parameter map
// pre-populated with NGX capabilities and available features.
// The output parameter map can also be used for any purpose
// parameter maps output by NVSDK_NGX_AllocateParameters can be used for
// but it is not recommended to use NVSDK_NGX_GetCapabilityParameters
// unless querying NGX capabilities and available features
// due to the overhead associated with pre-populating the parameter map.
// Parameter maps output by NVSDK_NGX_GetCapabilityParameters must NOT be freed using
// the free/delete operator; to free a parameter map
// output by NVSDK_NGX_GetCapabilityParameters, NVSDK_NGX_DestroyParameters should be
// used.
// Unlike with NVSDK_NGX_GetParameters, parameter maps allocated with
// NVSDK_NGX_GetCapabilityParameters
// must be destroyed by the app using NVSDK_NGX_DestroyParameters.
// 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.
// If NVSDK_NGX_GetCapabilityParameters fails with NVSDK_NGX_Result_FAIL_OutOfDate,
// NVSDK_NGX_GetParameters may be used as a fallback, to get a parameter map pre-
// populated with NGX capabilities and available features.
//
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D11_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_D3D12_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV
NVSDK_NGX_VULKAN_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters);
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// 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 c alled 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
//////////////////////////////////////////////////////////////////////////////////////////////
//////
// NVSDK_NGX_GetParameters
// ----------------------------------------------------------
//
// OutParameters:
// Parameters interface used to set any parameter needed by the SDK
//
// DESCRIPTION:
// This interface allows simple parameter setup using named fields.
// 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. Please note that allocated memory
// will be freed by NGX so free/delete operator should NOT be called.
// Parameter maps output by NVSDK_NGX_GetParameters are also pre-populated
// with NGX capabilities and available features.
// Unlike with NVSDK_NGX_AllocateParameters, parameter maps output by
// NVSDK_NGX_GetParameters
// have their lifetimes managed by NGX, and must not
// be destroyed by the app using NVSDK_NGX_DestroyParameters.
// NVSDK_NGX_GetParameters is soon to be deprecated and apps should move to using
// NVSDK_NGX_AllocateParameters and NVSDK_NGX_GetCapabilityParameters when possible.
// Nevertheless, due to the possibility that the user will be using an older driver
// version, NVSDK_NGX_GetParameters should still be used as a fallback if
// NVSDK_NGX_AllocateParameters
// or NVSDK_NGX_GetCapabilityParameters return NVSDK_NGX_Result_FAIL_OutOfDate.
//
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter
**OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D12_GetParameters(NVSDK_NGX_Parameter
**OutParameters);
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetParameters(NVSDK_NGX_Parameter
**OutParameters);
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 should 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 soon to be deprecated, and its use
as a fallback by apps is intended as a stopgap, until a new enough driver version is widely installed.
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) &&
NVSDK_NGX_SUCCEED(ResultMinDriverVersionMajor) &&
NVSDK_NGX_SUCCEED(ResultMinDriverVersionMinor))
{
if (needsUpdatedDriver)
{
// NVIDIA DLSS cannot be loaded due to outdated driver.
// Min Driver Version required : minDriverVersionMajor.minDriverVersionMinor
// Fallback to default AA solution (TAA etc)
}
else
{
// NVIDIA DLSS Minimum driver version was reported as:
// minDriverVersionMajor. minDriverVersionMinor
}
}
else
{
// NVIDIA DLSS Minimum driver version was not reported.
}
NVSDK_NGX_Result ResultDlssSupported =
Params->Get(NVSDK_NGX_Parameter_SuperSampling_Available,&DLSS_Supported);
if (NVSDK_NGX_FAILED(ResultDlssSupported) || !DLSS_Supported )
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);
Params = nullptr;
}
Overriding the f eature denial mechanism will have to be supported via windows regkeys (similar to
how most of the other overrides are supported in NGX). All regkeys f or this override must be written
to HKLM\SOFTWARE\NVIDIA Corporation\Global\NGXCore.
OverrideFeatureDeny
a. Type: REG_DWORD
OverrideFeatureDeny_CMSID
a. Type: REG_SZ
b. Values: CMS ID f or the specif ic application being overridden; if app doesn't have a
unique CMS ID or if app dev doesn't know the CMS ID f or their app, do not create
this regkey
c. Def ault behavior: apply override behavior to all apps
OverrideFeatureDeny_Feature
a. Type: REG_SZ
b. Values: f eature name f or the specif ic feature being overridden; do not create regkey
if all f eatures are to be overridden
OverrideFeatureDeny_Deny
a. Type: REG_DWORD
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
NVSDK_NGX_DLSS_Feature_Flags_None = 0,
NVSDK_NGX_DLSS_Feature_Flags_IsHDR = 1 << 0,
NVSDK_NGX_DLSS_Feature_Flags_MVLowRes = 1 << 1,
NVSDK_NGX_DLSS_Feature_Flags_MVJittered = 1 << 2,
NVSDK_NGX_DLSS_Feature_Flags_DepthInverted = 1 << 3,
NVSDK_NGX_DLSS_Feature_Flags_Reserved_0 = 1 << 4,
NVSDK_NGX_DLSS_Feature_Flags_DoSharpening = 1 << 5,
} NVSDK_NGX_DLSS_Feature _Flags;
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
);
NOTE: Feature handles do not use reference counting. If a request is made to create a new feature
with parameters matching an existing feature, the SDK will return the error code
“NVSDK_NGX_Result_FAIL_FeatureAlreadyExists ”.
// 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; // Set between 0.0f and 1.0f
} 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
/* Jitter Offsets in pixel space */
float InJitterOffsetX;
float InJitterOffsetY;
NVSDK_NGX_Dimensions InRenderSubrectDimensions;
/*** OPTIONAL ***/
int InReset;// Resets history buffer for scene transitions.
float InMVScaleX; // MotionVector Scale X
float InMVScaleY; // MotionVector Scale Y
ID3D11Resource* pInTransparencyMask;
ID3D11Resource* pInExposureTexture; // Exposure texture 1x1
NVSDK_NGX_Coordinates InColorSubrectBase;// Offsets into input/output buffers
NVSDK_NGX_Coordinates InDepthSubrectBase;
NVSDK_NGX_Coordinates InMVSubrectBase;
NVSDK_NGX_Coordinates InTranslucencySubrectBase;
NVSDK_NGX_Coordinates InOutputSubrectBase;
float InPreExposure;// Pre-exposure if applicable
/*** OPTIONAL - only for research purposes ***/
/* per pixel mask identifying alpha-blended objects like particles etc. */
NVSDK_NGX_D3D11_GBuffer GBufferSurface;
NVSDK_NGX_ToneMapperType InToneMapperType;
ID3D11Resource* pInMotionVectors3D;
ID3D11Resource* pInIsParticleMask;
ID3D11Resource* pInAnimatedTextureMask;
ID3D11Resource* pInDepthHighRes;
ID3D11Resource* pInPositionViewSpace;
float InFrameTimeDeltaInMsec;
ID3D11Resource* pInRayTracingHitDistance;
ID3D11Resource* pInMotionVectorsReflections;
} NVSDK_NGX_D3D11_DLSS_Eval_Params;
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
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
//
// DESCRIPTION:
// Releases feature with a given handle.
// Handles are not reference counted so
// after this call it is invalid to use provided handle.
//
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.
As a result, using NGX with multiple devices at the same time is currently not supported. Please contact
us if you have a need for this particular use scenario.
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
and destruction. As well, parameter maps allocated using NVSDK_NGX_AllocateParameters or
NVSDK_NGX_GetCapabilityParameters must be destroyed by the app using
NVSDK_NGX_DestroyParameters. This can be achieved by doing the following:
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.
2. DLSS feature need to be used with appropriate command lists generated on the same GPU node
The code example below, shows how to generate the DLSS feature per node.
Status = NGX_D3D12_CREATE_DLSS(&FeatureHandle[Node],Params,
MyCommandList[Node],Width,Height, PerfQualityValue,
RTXValue, CreationNodeMask, VisibilityNodeMask));
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.
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.
c. Make sure motion vectors are in screen space and take dynamic object movements 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.
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.
3. Current frame’s depth buffer (black is the near plane passing through blue, purple, pink with
white being the far plane)
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
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).
i. If negating or scaling one or both axes resolves the issue, in the game or engine,
negate or scale the value of the appropriate component (or components) before
calling DLSS.
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.
2. Second, add a “4 quadrant jitter” where the renderer jitters one frame to each quadrant cycling
each quadrant in order automatically.
2. Examine the screen output and use Screen Magnifier to better examine individual pixels.
3. 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.
4. 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).
5. 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.
c. Combine the four DLSS screenshots (using Adobe Photoshop or another tool) and
examine the resulting image (which will show heavy aliasing – that is expected).
Compare the combined DLSS image against the full resolution screen capture. 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:
2. Examine the screen output, using the Screen Magnifier to better examine individual pixels.
3. 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 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:
− 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_OutOfDate
NGX runtime libraries are old and need an update. Inform user to install latest display driver
provided by NVIDIA.
− 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.1)
The following is a list of rendering engine resources that the DLSS library can optionally accept and
which may be used in future DLSS algorithms. If the developer can include some, or all, of these
parameters, it can assist NVIDIA’s ongoing research and may allow future improved algorithms to be
used without game or engine code changes.
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)
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)
9.3 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 reserves the right to make corrections, modifications, enhancements, improvements, and other
changes to this specification, at any time and/or to discontinue any product or service without notice.
Customer should obtain the latest relevant specification before placing orders and should verify that
such information is current and complete.
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 a ny
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
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.3.1 Trademarks
NVIDIA and the NVIDIA logo are trademarks and/or registered trademarks of NVIDIA Corporation in the
U.S. and other countries. Other company and product names may be trademarks of the respective
companies with which they are associated.
9.3.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.
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.