Doom 3 RTX Initial Checkin.

This commit is contained in:
Justin Marshall
2026-04-22 00:55:07 -07:00
commit 6b65fbd7b1
2056 changed files with 848698 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <limits.h>
#include "sl_struct.h"
#include "sl_consts.h"
#include "sl_version.h"
#include "sl_result.h"
#include "sl_appidentity.h"
#include "sl_device_wrappers.h"
#include "sl_core_api.h"
#include "sl_core_types.h"
#define SL_FUN_DECL(name) PFun_##name* name{}
//! IMPORTANT: Macros which use `slGetFeatureFunction` can only be used AFTER device is set by calling either slSetD3DDevice or slSetVulkanInfo.
#define SL_FEATURE_FUN_IMPORT(feature, func) slGetFeatureFunction(feature, #func, (void*&) ##func)
#define SL_FEATURE_FUN_IMPORT_STATIC(feature, func) \
static PFun_##func* s_ ##func{}; \
if(!s_ ##func) { \
sl::Result res = slGetFeatureFunction(feature, #func, (void*&) s_ ##func); \
if(res != sl::Result::eOk) return res; \
} \
@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include "sl_struct.h"
namespace sl
{
//! Engine types
//!
enum class EngineType : uint32_t
{
eCustom,
eUnreal,
eUnity,
eCount
};
}
+254
View File
@@ -0,0 +1,254 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <stdint.h>
#include <assert.h>
#include <string>
#include "sl_struct.h"
#define SL_ENUM_OPERATORS_64(T) \
inline bool operator&(T a, T b) \
{ \
return ((uint64_t)a & (uint64_t)b) != 0; \
} \
\
inline T& operator&=(T& a, T b) \
{ \
a = (T)((uint64_t)a & (uint64_t)b); \
return a; \
} \
\
inline T operator|(T a, T b) \
{ \
return (T)((uint64_t)a | (uint64_t)b); \
} \
\
inline T& operator |= (T& lhs, T rhs) \
{ \
lhs = (T)((uint64_t)lhs | (uint64_t)rhs); \
return lhs; \
} \
\
inline T operator~(T a) \
{ \
return (T)~((uint64_t)a); \
}
#define SL_ENUM_OPERATORS_32(T) \
inline bool operator&(T a, T b) \
{ \
return ((uint32_t)a & (uint32_t)b) != 0; \
} \
\
inline T& operator&=(T& a, T b) \
{ \
a = (T)((uint32_t)a & (uint32_t)b); \
return a; \
} \
\
inline T operator|(T a, T b) \
{ \
return (T)((uint32_t)a | (uint32_t)b); \
} \
\
inline T& operator |= (T& lhs, T rhs) \
{ \
lhs = (T)((uint32_t)lhs | (uint32_t)rhs); \
return lhs; \
} \
\
inline T operator~(T a) \
{ \
return (T)~((uint32_t)a); \
}
namespace sl
{
//! For cases when value has to be provided and we don't have good default
constexpr float INVALID_FLOAT = 3.40282346638528859811704183484516925440e38f;
constexpr uint32_t INVALID_UINT = 0xffffffff;
//! Normally host would work with no more than 2 frames at the same time but sl.reflex sometimes
//! needs to send markers for previous and next frame so the total number of in-flight frames can be higher
constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 6;
struct uint3
{
uint32_t x;
uint32_t y;
uint32_t z;
};
struct float2
{
float2() : x(INVALID_FLOAT), y(INVALID_FLOAT) {}
float2(float _x, float _y) : x(_x), y(_y) {}
float x, y;
};
struct float3
{
float3() : x(INVALID_FLOAT), y(INVALID_FLOAT), z(INVALID_FLOAT) {}
float3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
float x, y, z;
};
struct float4
{
float4() : x(INVALID_FLOAT), y(INVALID_FLOAT), z(INVALID_FLOAT), w(INVALID_FLOAT) {}
float4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {}
float x, y, z, w;
};
struct float4x4
{
//! All access points take row index as a parameter
inline float4& operator[](uint32_t i) { return row[i]; }
inline const float4& operator[](uint32_t i) const { return row[i]; }
inline void setRow(uint32_t i, const float4& v) { row[i] = v; }
inline const float4& getRow(uint32_t i) { return row[i]; }
//! Row major matrix
float4 row[4];
};
struct Extent
{
uint32_t top{};
uint32_t left{};
uint32_t width{};
uint32_t height{};
inline operator bool() const { return width != 0 && height != 0; }
inline bool operator==(const Extent& rhs) const
{
return top == rhs.top && left == rhs.left &&
width == rhs.width && height == rhs.height;
}
inline bool operator!=(const Extent& rhs) const
{
return !operator==(rhs);
}
inline bool isSameRes(const Extent& rhs) const
{
return width == rhs.width && height == rhs.height;
}
#if defined(_WINDEF_)
// Cast helper for sl::Extent->RECT when windef.h has been included
inline operator RECT() const { return RECT { (LONG)left, (LONG)top, (LONG)(left + width), (LONG)(top + height) }; }
#endif
};
//! For cases when value has to be provided and we don't have good default
enum Boolean : char
{
eFalse,
eTrue,
eInvalid
};
//! Common constants, all parameters must be provided unless they are marked as optional
//!
//! {DCD35AD7-4E4A-4BAD-A90C-E0C49EB23AFE}
SL_STRUCT_BEGIN(Constants, StructType({ 0xdcd35ad7, 0x4e4a, 0x4bad, { 0xa9, 0xc, 0xe0, 0xc4, 0x9e, 0xb2, 0x3a, 0xfe } }), kStructVersion2)
//! IMPORTANT: All matrices are row major (see float4x4 definition) and
//! must NOT contain temporal AA jitter offset (if any). Any jitter offset
//! should be provided as the additional parameter Constants::jitterOffset (see below)
//! Specifies matrix transformation from the camera view to the clip space.
float4x4 cameraViewToClip;
//! Specifies matrix transformation from the clip space to the camera view space.
float4x4 clipToCameraView;
//! Optional - Specifies matrix transformation describing lens distortion in clip space.
float4x4 clipToLensClip;
//! Specifies matrix transformation from the current clip to the previous clip space.
//! clipToPrevClip = clipToView * viewToViewPrev * viewToClipPrev
//! Sample code can be found in sl_matrix_helpers.h
float4x4 clipToPrevClip;
//! Specifies matrix transformation from the previous clip to the current clip space.
//! prevClipToClip = clipToPrevClip.inverse()
float4x4 prevClipToClip;
//! Specifies pixel space jitter offset
float2 jitterOffset;
//! Specifies scale factors used to normalize motion vectors (so the values are in [-1,1] range)
float2 mvecScale;
//! Optional - Specifies camera pinhole offset if used.
float2 cameraPinholeOffset;
//! Specifies camera position in world space.
float3 cameraPos;
//! Specifies camera up vector in world space.
float3 cameraUp;
//! Specifies camera right vector in world space.
float3 cameraRight;
//! Specifies camera forward vector in world space.
float3 cameraFwd;
//! Specifies camera near view plane distance.
float cameraNear = INVALID_FLOAT;
//! Specifies camera far view plane distance.
float cameraFar = INVALID_FLOAT;
//! Specifies camera field of view in radians.
float cameraFOV = INVALID_FLOAT;
//! Specifies camera aspect ratio defined as view space width divided by height.
float cameraAspectRatio = INVALID_FLOAT;
//! Specifies which value represents an invalid (un-initialized) value in the motion vectors buffer
//! NOTE: This is only required if `cameraMotionIncluded` is set to false and SL needs to compute it.
float motionVectorsInvalidValue = INVALID_FLOAT;
//! Specifies if depth values are inverted (value closer to the camera is higher) or not.
Boolean depthInverted = Boolean::eInvalid;
//! Specifies if camera motion is included in the MVec buffer.
Boolean cameraMotionIncluded = Boolean::eInvalid;
//! Specifies if motion vectors are 3D or not.
Boolean motionVectors3D = Boolean::eInvalid;
//! Specifies if previous frame has no connection to the current one (i.e. motion vectors are invalid)
Boolean reset = Boolean::eInvalid;
//! Specifies if orthographic projection is used or not.
Boolean orthographicProjection = Boolean::eFalse;
//! Specifies if motion vectors are already dilated or not.
Boolean motionVectorsDilated = Boolean::eFalse;
//! Specifies if motion vectors are jittered or not.
Boolean motionVectorsJittered = Boolean::eFalse;
//! Version 2 members:
//!
//! Optional heuristic that specifies the minimum depth difference between two objects in screen-space.
//! The units of the value are in linear depth units.
//! Linear depth is computed as:
//! if depthInverted is false: `lin_depth = 1 / (1 - depth)`
//! if depthInverted is true: `lin_depth = 1 / depth`
//!
//! Although unlikely to need to be modified, smaller thresholds are useful when depth units are
//! unusually compressed into a small dynamic range near 1.
//!
//! If not specified, the default value is 40.0f.
float minRelativeLinearDepthObjectSeparation = 40.0f;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
+328
View File
@@ -0,0 +1,328 @@
/*
* Copyright (c) 2022-2024 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <limits.h>
#include "sl_struct.h"
#include "sl_consts.h"
#include "sl_version.h"
#include "sl_result.h"
#include "sl_appidentity.h"
#include "sl_device_wrappers.h"
#include "sl_core_types.h"
#if defined(SL_INTERPOSER)
#if defined(_WIN32)
#define SL_API extern "C" __declspec(dllexport)
#else
#error Unsupported Platform!
#endif
#else
#define SL_API extern "C"
#endif
#pragma region SL_API
//! Streamline core API functions (check feature specific headers for additional APIs)
//!
using PFun_slInit = sl::Result(const sl::Preferences& pref, uint64_t sdkVersion);
using PFun_slShutdown = sl::Result();
using PFun_slIsFeatureSupported = sl::Result(sl::Feature feature, const sl::AdapterInfo& adapterInfo);
using PFun_slIsFeatureLoaded = sl::Result(sl::Feature feature, bool& loaded);
using PFun_slSetFeatureLoaded = sl::Result(sl::Feature feature, bool loaded);
using PFun_slEvaluateFeature = sl::Result(sl::Feature feature, const sl::FrameToken& frame, const sl::BaseStructure** inputs, uint32_t numInputs, sl::CommandBuffer* cmdBuffer);
using PFun_slAllocateResources = sl::Result(sl::CommandBuffer* cmdBuffer, sl::Feature feature, const sl::ViewportHandle& viewport);
using PFun_slFreeResources = sl::Result(sl::Feature feature, const sl::ViewportHandle& viewport);
using PFun_slSetTag
#if __cplusplus >= 201402L
[[deprecated("Use the version of this function that takes a sl::FrameToken instead - slSetTagForFrame and set sl::PreferenceFlags::eUseFrameBasedResourceTagging.")]]
#endif
= sl::Result(const sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer);
using PFun_slSetTagForFrame = sl::Result(const sl::FrameToken& frame, const sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer);
using PFun_slGetFeatureRequirements = sl::Result(sl::Feature feature, sl::FeatureRequirements& requirements);
using PFun_slGetFeatureVersion = sl::Result(sl::Feature feature, sl::FeatureVersion& version);
using PFun_slUpgradeInterface = sl::Result(void** baseInterface);
using PFun_slSetConstants = sl::Result(const sl::Constants& values, const sl::FrameToken& frame, const sl::ViewportHandle& viewport);
using PFun_slGetNativeInterface = sl::Result(void* proxyInterface, void** baseInterface);
using PFun_slGetFeatureFunction = sl::Result(sl::Feature feature, const char* functionName, void*& function);
using PFun_slGetNewFrameToken = sl::Result(sl::FrameToken*& token, const uint32_t* frameIndex);
using PFun_slSetD3DDevice = sl::Result(void* d3dDevice);
//! Initializes the SL module
//!
//! Call this method when the game is initializing.
//!
//! @param pref Specifies preferred behavior for the SL library (SL will keep a copy)
//! @param sdkVersion Current SDK version
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
SL_API sl::Result slInit(const sl::Preferences &pref, uint64_t sdkVersion = sl::kSDKVersion);
//! Shuts down the SL module
//!
//! Call this method when the game is shutting down.
//!
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
SL_API sl::Result slShutdown();
//! Checks if a specific feature is supported or not.
//!
//! Call this method to check if a certain e* (see above) is available.
//!
//! @param feature Specifies which feature to use
//! @param adapterInfo Adapter to check (optional)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! NOTE: If adapter info is null SL will return general feature compatibility with the OS,
//! installed drivers or any other requirements not directly related to the adapter.
//!
//! This method is NOT thread safe.
SL_API sl::Result slIsFeatureSupported(sl::Feature feature, const sl::AdapterInfo& adapterInfo);
//! Checks if specified feature is loaded or not.
//!
//! Call this method to check if feature is loaded.
//! All requested features are loaded by default and have to be unloaded explicitly if needed.
//!
//! @param feature Specifies which feature to check
//! @param loaded Value specifying if feature is loaded or unloaded.
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slIsFeatureLoaded(sl::Feature feature, bool& loaded);
//! Sets the specified feature to either loaded or unloaded state.
//!
//! Call this method to load or unload certain e*.
//!
//! NOTE: All requested features are loaded by default and have to be unloaded explicitly if needed.
//!
//! @param feature Specifies which feature to check
//! @param loaded Value specifying if feature should be loaded or unloaded.
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! NOTE: When this method is called no other DXGI/D3D/Vulkan APIs should be invoked in parallel so
//! make sure to flush your pipeline before calling this method.
//!
//! This method is NOT thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slSetFeatureLoaded(sl::Feature feature, bool loaded);
//! NOTE: sl::PreferenceFlags::eUseFrameBasedResourceTagging must be set when using this API.
//! Tags resource globally
//!
//! Call this method to tag the appropriate buffers in global scope.
//!
//! @param frame Specifies the frame this tag applies to. Frame token can be obtained using slGetNewFrameToken API.
//! @param viewport Specifies viewport this tag applies to
//! @param tags Pointer to resources tags, set to null to remove the specified tag
//! @param numTags Number of resource tags in the provided list
//! @param cmdBuffer Command buffer to use (optional and can be null if ALL tags are null or have eValidUntilPresent life-cycle)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: GPU payload that generates content for the provided tag(s) MUST be either already submitted to the provided command buffer
//! or some other command buffer which is guaranteed, by the host application, to be executed BEFORE the provided command buffer.
//!
//! This method is thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slSetTagForFrame(const sl::FrameToken& frame, const sl::ViewportHandle& viewport, const sl::ResourceTag* resources, uint32_t numResources, sl::CommandBuffer* cmdBuffer);
//! NOTE: This API has now been DEPRECATED in favor of the new slSetTagForFrame API above.
//! Tags resource globally
//!
//! Call this method to tag the appropriate buffers in global scope.
//!
//! @param viewport Specifies viewport this tag applies to
//! @param tags Pointer to resources tags, set to null to remove the specified tag
//! @param numTags Number of resource tags in the provided list
//! @param cmdBuffer Command buffer to use (optional and can be null if ALL tags are null or have eValidUntilPresent life-cycle)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: GPU payload that generates content for the provided tag(s) MUST be either already submitted to the provided command buffer
//! or some other command buffer which is guaranteed, by the host application, to be executed BEFORE the provided command buffer.
//!
//! This method is thread safe and requires DX/VK device to be created before calling it.
SL_API
#if __cplusplus >= 201402L
[[deprecated("Use the version of this function that takes a sl::FrameToken instead - slSetTagForFrame and set sl::PreferenceFlags::eUseFrameBasedResourceTagging.")]]
#endif
sl::Result slSetTag(const sl::ViewportHandle& viewport, const sl::ResourceTag* tags, uint32_t numTags, sl::CommandBuffer* cmdBuffer);
//! Sets common constants.
//!
//! Call this method to provide the required data (SL will keep a copy).
//!
//! @param values Common constants required by SL plugins (SL will keep a copy)
//! @param frame Index of the current frame
//! @param viewport Unique id (can be viewport id | instance id etc.)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slSetConstants(const sl::Constants& values, const sl::FrameToken& frame, const sl::ViewportHandle& viewport);
//! Returns feature's requirements
//!
//! Call this method to check what is required to run certain eFeature* (see above).
//! This method must be called after init otherwise it will always return an error.
//!
//! @param feature Specifies which feature to check
//! @param requirements Data structure with feature's requirements
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
SL_API sl::Result slGetFeatureRequirements(sl::Feature feature, sl::FeatureRequirements& requirements);
//! Returns feature's version
//!
//! Call this method to check version for a certain eFeature* (see above).
//! This method must be called after init otherwise it will always return an error.
//!
//! @param feature Specifies which feature to check
//! @param version Data structure with feature's version
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe.
SL_API sl::Result slGetFeatureVersion(sl::Feature feature, sl::FeatureVersion& version);
//! Allocates resources for the specified feature.
//!
//! Call this method to explicitly allocate resources
//! for an instance of the specified feature.
//!
//! @param cmdBuffer Command buffer to use (must be created on device where feature is supported but can be null if not needed)
//! @param feature Feature we are working with
//! @param viewport Unique id (viewport handle)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slAllocateResources(sl::CommandBuffer* cmdBuffer, sl::Feature feature, const sl::ViewportHandle& viewport);
//! Frees resources for the specified feature.
//!
//! Call this method to explicitly free resources
//! for an instance of the specified feature.
//!
//! @param feature Feature we are working with
//! @param viewport Unique id (viewport handle)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: If slEvaluateFeature is pending on a command list, that command list must be flushed
//! before calling this method to prevent invalid resource access on the GPU.
//!
//! IMPORTANT: If slEvaluateFeature is pending on a command list, that command list must be flushed
//! before calling this method to prevent invalid resource access on the GPU.
//!
//! This method is NOT thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slFreeResources(sl::Feature feature, const sl::ViewportHandle& viewport);
//! NOTE: sl::PreferenceFlags::eUseFrameBasedResourceTagging must be set when using this API to do
//! frame-based resource tagging for multiple frames in flight at the same time.
//! Evaluates feature
//!
//! Use this method to mark the section in your rendering pipeline
//! where specific feature should be injected.
//!
//! @param feature Feature we are working with
//! @param frame Current frame handle obtained from SL
//! @param inputs The chained structures providing the input data (viewport, tags, constants etc)
//! @param numInputs Number of inputs
//! @param cmdBuffer Command buffer to use (must be created on device where feature is supported)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: Frame and viewport must match whatever is used to set common and or feature options and constants (if any)
//!
//! NOTE: It is allowed to pass in buffer tags as inputs, they are considered to be a "local" tags and do NOT interact with
//! same tags sent in the global scope using slSetTag API.
//!
//! This method is NOT thread safe and requires DX/VK device to be created before calling it.
SL_API sl::Result slEvaluateFeature(sl::Feature feature, const sl::FrameToken& frame, const sl::BaseStructure** inputs, uint32_t numInputs, sl::CommandBuffer* cmdBuffer);
//! Upgrade interface
//!
//! Use this method to upgrade basic D3D or DXGI interface to an SL proxy.
//!
//! @param baseInterface Pointer to a pointer to the base interface (for example ID3D12Device etc.) to be replaced in place.
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: This method should ONLY be used to support 3rd party SDKs like AMD AGS
//! which bypass SL or when using manual hooking.
//!
//! This method is NOT thread safe and should be called IMMEDIATELY after base interface is created.
SL_API sl::Result slUpgradeInterface(void** baseInterface);
//! Obtain native interface
//!
//! Use this method to obtain underlying D3D or DXGI interface from an SL proxy.
//!
//! IMPORTANT: When calling NVAPI or other 3rd party SDKs from your application
//! it is recommended to provide native interfaces instead of SL proxies.
//!
//! @param proxyInterface Pointer to the SL proxy (D3D device, swap-chain etc)
//! @param baseInterface Pointer to a pointer to the base interface be returned.
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe
SL_API sl::Result slGetNativeInterface(void* proxyInterface, void** baseInterface);
//! Gets specific feature's function
//!
//! Call this method to obtain various functions for the specified feature. See sl_$feature.h for details.
//!
//! @param feature Feature we are working with
//! @param functionName The name of the API to obtain (declared in sl_[$feature].h
//! @param function Pointer to the function to return
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! IMPORTANT: Must be called AFTER device is set by calling either slSetD3DDevice or slSetVulkanInfo.
//!
//! This method is thread safe.
SL_API sl::Result slGetFeatureFunction(sl::Feature feature, const char* functionName, void*& function);
//! Gets unique frame token
//!
//! Call this method to obtain token for the unique frame identification.
//!
//! @param handle Frame token to return
//! @param frameIndex Frame index (optional, if not provided SL internal frame counting is used)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! NOTE: Normally SL would not expect more that 3 frames in flight due to added latency.
//!
//! This method is thread safe.
SL_API sl::Result slGetNewFrameToken(sl::FrameToken*& token, const uint32_t* frameIndex = nullptr);
//! Set D3D device to use
//!
//! Use this method to specify which D3D device should be used.
//!
//! @param d3dDevice D3D device to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe and should be called IMMEDIATELY after main device is created.
SL_API sl::Result slSetD3DDevice(void* d3dDevice);
#pragma endregion SL_API
@@ -0,0 +1,751 @@
/*
* Copyright (c) 2022-2024 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <limits.h>
#include <vector>
#include "sl_struct.h"
#include "sl_consts.h"
#include "sl_version.h"
#include "sl_result.h"
#include "sl_appidentity.h"
#include "sl_device_wrappers.h"
typedef struct ID3D11Resource ID3D11Resource;
typedef struct ID3D11Buffer ID3D11Buffer;
typedef struct ID3D11Texture2D ID3D11Texture2D;
typedef struct ID3D12Resource ID3D12Resource;
// Forward declarations matching MS and VK specs
#ifdef VK_VERSION_1_0
using SL_VKResult = VkResult;
#else
using SL_VKResult = int;
#endif
using HRESULT = long;
namespace sl {
using CommandBuffer = void;
using Device = void;
//! Buffer types used for tagging
//!
//! IMPORTANT: Each tag must use the unique id
//!
using BufferType = uint32_t;
// Friend function declaration to access private members for ABI validation static_asserts
namespace test
{
constexpr void AbiValidation();
}
//! Depth buffer - IMPORTANT - Must be suitable to use with clipToPrevClip transformation (see Constants below)
constexpr BufferType kBufferTypeDepth = 0;
//! Object and optional camera motion vectors (see Constants below)
constexpr BufferType kBufferTypeMotionVectors = 1;
//! Color buffer with all post-processing effects applied but without any UI/HUD elements
constexpr BufferType kBufferTypeHUDLessColor = 2;
//! Color buffer containing jittered input data for the image scaling pass
constexpr BufferType kBufferTypeScalingInputColor = 3;
//! Color buffer containing results from the image scaling pass
constexpr BufferType kBufferTypeScalingOutputColor = 4;
//! Normals
constexpr BufferType kBufferTypeNormals = 5;
//! Roughness
constexpr BufferType kBufferTypeRoughness = 6;
//! Albedo
constexpr BufferType kBufferTypeAlbedo = 7;
//! Specular Albedo
constexpr BufferType kBufferTypeSpecularAlbedo = 8;
//! Indirect Albedo
constexpr BufferType kBufferTypeIndirectAlbedo = 9;
//! Specular Motion Vectors
constexpr BufferType kBufferTypeSpecularMotionVectors = 10;
//! Disocclusion Mask
constexpr BufferType kBufferTypeDisocclusionMask = 11;
//! Emissive
constexpr BufferType kBufferTypeEmissive = 12;
//! Exposure
constexpr BufferType kBufferTypeExposure = 13;
//! Buffer with normal and roughness in alpha channel
constexpr BufferType kBufferTypeNormalRoughness = 14;
//! Diffuse and camera ray length
constexpr BufferType kBufferTypeDiffuseHitNoisy = 15;
//! Diffuse denoised
constexpr BufferType kBufferTypeDiffuseHitDenoised = 16;
//! Specular and reflected ray length
constexpr BufferType kBufferTypeSpecularHitNoisy = 17;
//! Specular denoised
constexpr BufferType kBufferTypeSpecularHitDenoised = 18;
//! Shadow noisy
constexpr BufferType kBufferTypeShadowNoisy = 19;
//! Shadow denoised
constexpr BufferType kBufferTypeShadowDenoised = 20;
//! AO noisy
constexpr BufferType kBufferTypeAmbientOcclusionNoisy = 21;
//! AO denoised
constexpr BufferType kBufferTypeAmbientOcclusionDenoised = 22;
//! Optional - UI/HUD color and alpha
//! IMPORTANT: Please make sure that alpha channel has enough precision (for example do NOT use formats like R10G10B10A2)
constexpr BufferType kBufferTypeUIColorAndAlpha = 23;
//! Optional - Shadow pixels hint (set to 1 if a pixel belongs to the shadow area, 0 otherwise)
constexpr BufferType kBufferTypeShadowHint = 24;
//! Optional - Reflection pixels hint (set to 1 if a pixel belongs to the reflection area, 0 otherwise)
constexpr BufferType kBufferTypeReflectionHint = 25;
//! Optional - Particle pixels hint (set to 1 if a pixel represents a particle, 0 otherwise)
constexpr BufferType kBufferTypeParticleHint = 26;
//! Optional - Transparency pixels hint (set to 1 if a pixel belongs to the transparent area, 0 otherwise)
constexpr BufferType kBufferTypeTransparencyHint = 27;
//! Optional - Animated texture pixels hint (set to 1 if a pixel belongs to the animated texture area, 0 otherwise)
constexpr BufferType kBufferTypeAnimatedTextureHint = 28;
//! Optional - Bias for current color vs history hint - lerp(history, current, bias) (set to 1 to completely reject history)
constexpr BufferType kBufferTypeBiasCurrentColorHint = 29;
//! Optional - Ray-tracing distance (camera ray length)
constexpr BufferType kBufferTypeRaytracingDistance = 30;
//! Optional - Motion vectors for reflections
constexpr BufferType kBufferTypeReflectionMotionVectors = 31;
//! Optional - Position, in same space as eNormals
constexpr BufferType kBufferTypePosition = 32;
//! Optional - Indicates (via non-zero value) which pixels have motion/depth values that do not match the final color content at that pixel (e.g. overlaid, opaque Picture-in-Picture)
constexpr BufferType kBufferTypeInvalidDepthMotionHint = 33;
//! Alpha
constexpr BufferType kBufferTypeAlpha = 34;
//! Color buffer containing only opaque geometry
constexpr BufferType kBufferTypeOpaqueColor = 35;
//! Optional - Reduce reliance on history instead using current frame hint (0 if a pixel is not at all reactive and default composition should be used, 1 if fully reactive)
constexpr BufferType kBufferTypeReactiveMaskHint = 36;
//! Optional - Pixel lock adjustment hint (set to 1 if pixel lock should be completely removed, 0 otherwise)
constexpr BufferType kBufferTypeTransparencyAndCompositionMaskHint = 37;
//! Optional - Albedo of the reflection ray hit point. For multibounce reflections, this should be the albedo of the first non-specular bounce.
constexpr BufferType kBufferTypeReflectedAlbedo = 38;
//! Optional - Color buffer before particles are drawn.
constexpr BufferType kBufferTypeColorBeforeParticles = 39;
//! Optional - Color buffer before transparent objects are drawn.
constexpr BufferType kBufferTypeColorBeforeTransparency = 40;
//! Optional - Color buffer before fog is drawn.
constexpr BufferType kBufferTypeColorBeforeFog = 41;
//! Optional - Buffer containing the hit distance of a specular ray.
constexpr BufferType kBufferTypeSpecularHitDistance = 42;
//! Optional - Buffer that contains 3 components of a specular ray direction, and 1 component of specular hit distance.
constexpr BufferType kBufferTypeSpecularRayDirectionHitDistance = 43;
//! Optional - Buffer containing normalized direction of a specular ray.
constexpr BufferType kBufferTypeSpecularRayDirection = 44;
// !Optional - Buffer containing the hit distance of a diffuse ray.
constexpr BufferType kBufferTypeDiffuseHitDistance = 45;
//! Optional - Buffer that contains 3 components of a diffuse ray direction, and 1 component of diffuse hit distance.
constexpr BufferType kBufferTypeDiffuseRayDirectionHitDistance = 46;
//! Optional - Buffer containing normalized direction of a diffuse ray.
constexpr BufferType kBufferTypeDiffuseRayDirection = 47;
//! Optional - Buffer containing display resolution depth.
constexpr BufferType kBufferTypeHiResDepth = 48;
//! Required either this or kBufferTypeDepth - Buffer containing linear depth.
constexpr BufferType kBufferTypeLinearDepth = 49;
//! Optional - Bidirectional distortion field. 4 channels in normalized [0,1] pixel space. RG = distorted pixel to undistorted pixel displacement. BA = undistorted pixel to distorted pixel displacement.
constexpr BufferType kBufferTypeBidirectionalDistortionField = 50;
//!Optional - Buffer containing particles or other similar transparent effects rendered into it instead of passing it as part of the input color
constexpr BufferType kBufferTypeTransparencyLayer = 51;
//!Optional - Buffer to be used in addition to TransparencyLayer which allows 3-channels of Opacity versus 1-channel.
// In this case, TransparencyLayer represents Color (RcGcBc), TransparencyLayerOpacity represents alpha (RaGaBa)'
constexpr BufferType kBufferTypeTransparencyLayerOpacity = 52;
//! Optional - Swapchain buffer to be presented
constexpr BufferType kBufferTypeBackbuffer = 53;
//! Optional - Mask for pixels to skip warping
constexpr BufferType kBufferTypeNoWarpMask = 54;
//! Optional - Color buffer after particles are drawn (for research purposes)
constexpr BufferType kBufferTypeColorAfterParticles = 55;
//! Optional - Color buffer after transparent objects are drawn (for research purposes)
constexpr BufferType kBufferTypeColorAfterTransparency = 56;
//! Optional - Color buffer after fog is drawn (for research purposes)
constexpr BufferType kBufferTypeColorAfterFog = 57;
//! Optional - Subsurface scattering guide buffer
constexpr BufferType kBufferTypeScreenSpaceSubsurfaceScatteringGuide = 58;
//! Optional - Color buffer before subsurface scattering (for research purposes)
constexpr BufferType kBufferTypeColorBeforeScreenSpaceSubsurfaceScattering = 59;
//! Optional - Color buffer after subsurface scattering (for research purposes)
constexpr BufferType kBufferTypeColorAfterScreenSpaceSubsurfaceScattering = 60;
//! Optional - Refraction guide buffer (for research purposes)
constexpr BufferType kBufferTypeScreenSpaceRefractionGuide = 61;
//! Optional - Color buffer before refraction (for research purposes)
constexpr BufferType kBufferTypeColorBeforeScreenSpaceRefraction = 62;
//! Optional - Color buffer after refraction (for research purposes)
constexpr BufferType kBufferTypeColorAfterScreenSpaceRefraction = 63;
//! Optional - Depth of Field Buffer (for research purposes)
constexpr BufferType kBufferTypeDepthOfFieldGuide = 64;
//! Optional - Color buffer before Depth of Field (for research purposes)
constexpr BufferType kBufferTypeColorBeforeDepthOfField = 65;
//! Optional - Color buffer after Depth of Field (for research purposes)
constexpr BufferType kBufferTypeColorAfterDepthOfField = 66;
//! Optional - Color buffer that overrides the alpha channel of kBufferTypeScalingOutputColor
constexpr BufferType kBufferTypeScalingOutputAlpha = 67;
//! Features supported with this SDK
//!
//! IMPORTANT: Each feature must use a unique id
//!
using Feature = uint32_t;
//! Deep Learning Super Sampling
constexpr Feature kFeatureDLSS = 0;
//! Real-Time Denoiser (removed)
constexpr Feature kFeatureNRD_INVALID = 1;
//! NVIDIA Image Scaling
constexpr Feature kFeatureNIS = 2;
//! Reflex
constexpr Feature kFeatureReflex = 3;
//! PC Latency
constexpr Feature kFeaturePCL = 4;
//! DeepDVC
constexpr Feature kFeatureDeepDVC = 5;
constexpr Feature kFeatureLatewarp = 6;
//! DLSS Frame Generation
constexpr Feature kFeatureDLSS_G = 1000;
//! DLSS Ray Reconstruction
constexpr Feature kFeatureDLSS_RR = 1001;
constexpr Feature kFeatureNvPerf = 1002;
constexpr Feature kFeatureDirectSR = 1003;
// ImGUI
constexpr Feature kFeatureImGUI = 9999;
//! Common feature, NOT intended to be used directly
constexpr Feature kFeatureCommon = UINT_MAX;
//! Different levels for logging
enum class LogLevel : uint32_t
{
//! No logging
eOff,
//! Default logging
eDefault,
//! Verbose logging
eVerbose,
//! Total count
eCount
};
//! Resource types
enum class ResourceType : char
{
eTex2d,
eBuffer,
eCommandQueue,
eCommandBuffer,
eCommandPool,
eFence,
eSwapchain,
eHostFence,
// this type means that the only thing we know for sure about this resource is that it's castable to IUnknown
eUnknown,
eCount
};
//! Resource allocate information
//!
SL_STRUCT_BEGIN(ResourceAllocationDesc, StructType({ 0xbb57e5, 0x49a2, 0x4c23, { 0xa5, 0x19, 0xab, 0x92, 0x86, 0xe7, 0x40, 0x14 } }), kStructVersion1)
ResourceAllocationDesc(ResourceType _type, void* _desc, uint32_t _state, void* _heap) : BaseStructure(ResourceAllocationDesc::s_structType, kStructVersion1), type(_type),desc(_desc),state(_state),heap(_heap){};
//! Indicates the type of resource
ResourceType type = ResourceType::eTex2d;
//! D3D12_RESOURCE_DESC/VkImageCreateInfo/VkBufferCreateInfo
void* desc{};
//! Initial state as D3D12_RESOURCE_STATES or VkMemoryPropertyFlags
uint32_t state = 0;
//! CD3DX12_HEAP_PROPERTIES or nullptr
void* heap{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Subresource range information, for Vulkan resources
//!
//! {8D4C316C-D402-4524-89A7-14E79E638E3A}
SL_STRUCT_BEGIN(SubresourceRange, StructType({ 0x8d4c316c, 0xd402, 0x4524, { 0x89, 0xa7, 0x14, 0xe7, 0x9e, 0x63, 0x8e, 0x3a } }), kStructVersion1)
//! Vulkan subresource aspectMask
uint32_t aspectMask;
//! Vulkan subresource baseMipLevel
uint32_t baseMipLevel;
//! Vulkan subresource levelCount
uint32_t levelCount;
//! Vulkan subresource baseArrayLayer
uint32_t baseArrayLayer;
//! Vulkan subresource layerCount
uint32_t layerCount;
SL_STRUCT_END()
//! Native resource
//!
//! {3A9D70CF-2418-4B72-8391-13F8721C7261}
SL_STRUCT_BEGIN(Resource, StructType({ 0x3a9d70cf, 0x2418, 0x4b72, { 0x83, 0x91, 0x13, 0xf8, 0x72, 0x1c, 0x72, 0x61 } }), kStructVersion1)
//! Constructors
//!
//! Resource type, native pointer are MANDATORY always
//! Resource state is MANDATORY unless using D3D11
//! Resource view, description etc. are MANDATORY only when using Vulkan
//!
Resource(ResourceType _type, void* _native, void* _mem, void* _view, uint32_t _state = UINT_MAX) : BaseStructure(Resource::s_structType, kStructVersion1), type(_type), native(_native), memory(_mem), view(_view), state(_state){};
Resource(ResourceType _type, void* _native, uint32_t _state = UINT_MAX) : BaseStructure(Resource::s_structType, kStructVersion1), type(_type), native(_native), state(_state) {};
//! Conversion helpers for D3D
inline operator ID3D12Resource* () { return reinterpret_cast<ID3D12Resource*>(native); }
inline operator ID3D11Resource* () { return reinterpret_cast<ID3D11Resource*>(native); }
inline operator ID3D11Buffer* () { return reinterpret_cast<ID3D11Buffer*>(native); }
inline operator ID3D11Texture2D* () { return reinterpret_cast<ID3D11Texture2D*>(native); }
//! Indicates the type of resource
ResourceType type = ResourceType::eTex2d;
//! ID3D11Resource/ID3D12Resource/VkBuffer/VkImage
void* native{};
//! vkDeviceMemory or nullptr
void* memory{};
//! VkImageView/VkBufferView or nullptr
void* view{};
//! State as D3D12_RESOURCE_STATES or VkImageLayout
//!
//! IMPORTANT: State is MANDATORY and needs to be correct when tagged resources are actually used.
//!
uint32_t state = UINT_MAX;
//! Width in pixels
uint32_t width{};
//! Height in pixels
uint32_t height{};
//! Native format
uint32_t nativeFormat{};
//! Number of mip-map levels
uint32_t mipLevels{};
//! Number of arrays
uint32_t arrayLayers{};
//! Virtual address on GPU (if applicable)
uint64_t gpuVirtualAddress{};
//! VkImageCreateFlags
uint32_t flags;
//! VkImageUsageFlags
uint32_t usage{};
//! Reserved for internal use
uint32_t reserved{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Specifies life-cycle for the tagged resource
//!
//! IMPORTANT: Use 'eOnlyValidNow' and 'eValidUntilEvaluate' ONLY when really needed since it can result in wasting VRAM if SL ends up making unnecessary copies.
//!
//! If integrating features, like for example DLSS-G, which require tags to be 'eValidUntilPresent' please try to tag everything as 'eValidUntilPresent' first
//! and only make modifications if upon visual inspection you notice that tags are corrupted when used during the Present frame call.
enum ResourceLifecycle
{
//! Resource can change, get destroyed or reused for other purposes after it is provided to SL
eOnlyValidNow,
//! Resource does NOT change, gets destroyed or reused for other purposes from the moment it is provided to SL until the frame is presented
eValidUntilPresent,
//! Resource does NOT change, gets destroyed or reused for other purposes from the moment it is provided to SL until after the slEvaluateFeature call has returned.
eValidUntilEvaluate
};
//! Tagged resource
//!
//! {4C6A5AAD-B445-496C-87FF-1AF3845BE653}
//! Extensions as part of the `next` ptr:
//! PrecisionInfo
SL_STRUCT_BEGIN(ResourceTag, StructType({ 0x4c6a5aad, 0xb445, 0x496c, { 0x87, 0xff, 0x1a, 0xf3, 0x84, 0x5b, 0xe6, 0x53 } }), kStructVersion1)
ResourceTag(Resource* r, BufferType t, ResourceLifecycle l, const Extent* e = nullptr)
: BaseStructure(ResourceTag::s_structType, kStructVersion1), resource(r), type(t), lifecycle(l)
{
if (e) extent = *e;
};
//! Resource description
Resource* resource{};
//! Type of the tagged buffer
BufferType type{};
//! The life-cycle for the tag, if resource is volatile a valid command buffer must be specified
ResourceLifecycle lifecycle{};
//! The area of the tagged resource to use (if using the entire resource leave as null)
Extent extent{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//
//! Precision info, optional extension for ResourceTag.
//!
//! {98F6E9BA-8D16-4831-A802-4D3B52FF26BF}
//! Extensions as part of the `next` ptr:
//! ResourceTag
SL_STRUCT_BEGIN(PrecisionInfo, StructType({ 0x98f6e9ba, 0x8d16, 0x4831, { 0xa8, 0x2, 0x4d, 0x3b, 0x52, 0xff, 0x26, 0xbf } }), kStructVersion1)
// Formula used to convert the low-precision data to high-precision
enum PrecisionFormula : uint32_t
{
eNoTransform = 0, // hi = lo, essentially no conversion is done
eLinearTransform, // hi = lo * scale + bias
};
PrecisionInfo(PrecisionInfo::PrecisionFormula formula, float bias, float scale)
: BaseStructure(PrecisionInfo::s_structType, kStructVersion1), conversionFormula(formula), bias(bias), scale(scale) {};
static std::string getPrecisionFormulaAsStr(PrecisionFormula formula)
{
switch (formula)
{
case eNoTransform:
return "eNoTransform";
case eLinearTransform:
return "eLinearTransform";
default:
assert("Invalid PrecisionFormula" && false);
return "Unknown";
}
};
PrecisionFormula conversionFormula{ eNoTransform };
float bias{ 0.0f };
float scale{ 1.0f };
inline operator bool() const { return conversionFormula != eNoTransform; }
inline bool operator==(const PrecisionInfo& rhs) const
{
return conversionFormula == rhs.conversionFormula && bias == rhs.bias && scale == rhs.scale;
}
inline bool operator!=(const PrecisionInfo& rhs) const
{
return !operator==(rhs);
}
SL_STRUCT_END()
//! Resource allocation/deallocation callbacks
//!
//! Use these callbacks to gain full control over
//! resource life cycle and memory allocation tracking.
//!
//! @param device - Device to be used (vkDevice or ID3D11Device or ID3D12Device)
//!
//! IMPORTANT: Textures must have the pixel shader resource
//! and the unordered access view flags set
using PFun_ResourceAllocateCallback = Resource(const ResourceAllocationDesc* desc, void* device);
using PFun_ResourceReleaseCallback = void(Resource* resource, void* device);
//! Log type
enum class LogType : uint32_t
{
//! Controlled by LogLevel, SL can show more information in eLogLevelVerbose mode
eInfo,
//! Always shown regardless of LogLevel
eWarn,
eError,
//! Total count
eCount
};
//! Logging callback
//!
//! Use these callbacks to track messages posted in the log.
//! If any of the SL methods returns false use eLogTypeError
//! type to track down what went wrong and why.
using PFun_LogMessageCallback = void(LogType type, const char* msg);
struct APIError
{
union
{
HRESULT hres;
SL_VKResult vkRes;
};
};
//! Returns an error returned by DXGI or Vulkan API calls 'vkQueuePresentKHR' and 'vkAcquireNextImageKHR'
using PFunOnAPIErrorCallback = void(const APIError& lastError);
//! Optional flags
enum class PreferenceFlags : uint64_t
{
//! Set by default - Disables command list state tracking - Host application is responsible for restoring CL state correctly after each 'slEvaluateFeature' call
eDisableCLStateTracking = 1 << 0,
//! Optional - Disables debug text on screen in development builds
eDisableDebugText = 1 << 1,
//! Optional - IMPORTANT: Only to be used in the advanced integration mode, see the 'manual hooking' programming guide for more details
eUseManualHooking = 1 << 2,
//! Optional - Enables downloading of Over The Air (OTA) updates for SL and NGX
//! This will invoke the OTA updater to look for new updates. A separate
//! flag below is used to control whether or not OTA-downloaded SL Plugins are
//! loaded.
eAllowOTA = 1 << 3,
//! Do not check OS version when deciding if feature is supported or not
//!
//! IMPORTANT: ONLY SET THIS FLAG IF YOU KNOW WHAT YOU ARE DOING.
//!
//! VARIOUS WIN APIs INCLUDING BUT NOT LIMITED TO `IsWindowsXXX`, `GetVersionX`, `rtlGetVersion` ARE KNOWN FOR RETURNING INCORRECT RESULTS.
eBypassOSVersionCheck = 1 << 4,
//! Optional - If specified SL will create DXGI factory proxy rather than modifying the v-table for the base interface.
//!
//! This can help with 3rd party overlays which are NOT integrated with the host application but rather operate via injection.
eUseDXGIFactoryProxy = 1 << 5,
//! Optional - Enables loading of plugins downloaded Over The Air (OTA), to
//! be used in conjunction with the eAllowOTA flag.
eLoadDownloadedPlugins = 1 << 6,
//! Optional - allow tagging of resources for frame. This helps distinguish whether slEvaluateFeature needs to do frame-based tagging
//! of resources which wasn't the case earlier.
eUseFrameBasedResourceTagging = 1 << 7,
//! All preference flags. This isn't expected to be used directly by integrations, but may be useful for e.g. writing helpers.
eAll = eDisableCLStateTracking | eDisableDebugText | eUseManualHooking | eAllowOTA | eBypassOSVersionCheck | eUseDXGIFactoryProxy | eLoadDownloadedPlugins | eUseFrameBasedResourceTagging
};
SL_ENUM_OPERATORS_64(PreferenceFlags)
//! Application preferences
//!
//! {1CA10965-BF8E-432B-8DA1-6716D879FB14}
SL_STRUCT_BEGIN(Preferences, StructType({ 0x1ca10965, 0xbf8e, 0x432b, { 0x8d, 0xa1, 0x67, 0x16, 0xd8, 0x79, 0xfb, 0x14 } }), kStructVersion1)
//! Optional - In non-production builds it is useful to enable debugging console window
bool showConsole = false;
//! Optional - Various logging levels
LogLevel logLevel = LogLevel::eDefault;
//! Optional - Absolute paths to locations where to look for plugins, first path in the list has the highest priority
const wchar_t** pathsToPlugins{};
//! Optional - Number of paths to search
uint32_t numPathsToPlugins = 0;
//! Optional - Absolute path to location where logs and other data should be stored
//!
//! NOTE: Set this to nullptr in order to disable logging to a file
const wchar_t* pathToLogsAndData{};
//! Optional - Allows resource allocation tracking on the host side
PFun_ResourceAllocateCallback* allocateCallback{};
//! Optional - Allows resource deallocation tracking on the host side
PFun_ResourceReleaseCallback* releaseCallback{};
//! Optional - Allows log message tracking including critical errors if they occur
PFun_LogMessageCallback* logMessageCallback{};
//! Optional - Flags used to enable or disable advanced options
PreferenceFlags flags = PreferenceFlags::eDisableCLStateTracking | PreferenceFlags::eAllowOTA | PreferenceFlags::eLoadDownloadedPlugins;
//! Required - Features to load (assuming appropriate plugins are found), if not specified NO features will be loaded by default
const Feature* featuresToLoad{};
//! Required - Number of features to load, only used when list is not a null pointer
uint32_t numFeaturesToLoad{};
//! Optional - Id provided by NVIDIA, if not specified then engine type and version are required
uint32_t applicationId{};
//! Optional - Type of the rendering engine used, if not specified then applicationId is required
EngineType engine = EngineType::eCustom;
//! Optional - Version of the rendering engine used
const char* engineVersion{};
//! Optional - GUID (like for example 'a0f57b54-1daf-4934-90ae-c4035c19df04')
const char* projectId{};
//! Optional - Which rendering API host is planning to use
//!
//! NOTE: To ensure correct `slGetFeatureRequirements` behavior please specify if planning to use Vulkan.
RenderAPI renderAPI = RenderAPI::eD3D12;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Frame tracking handle
//!
//! IMPORTANT: Use slGetNewFrameToken to obtain unique instance
//!
//! {830A0F35-DB84-4171-A804-59B206499B18}
SL_STRUCT_PROTECTED_BEGIN(FrameToken, StructType({ 0x830a0f35, 0xdb84, 0x4171, { 0xa8, 0x4, 0x59, 0xb2, 0x6, 0x49, 0x9b, 0x18 } }), kStructVersion1)
//! Helper operator to obtain current frame index
virtual operator uint32_t() const = 0;
SL_STRUCT_END()
//! Handle for the unique viewport
//!
//! {171B6435-9B3C-4FC8-9994-FBE52569AAA4}
SL_STRUCT_BEGIN(ViewportHandle, StructType({ 0x171b6435, 0x9b3c, 0x4fc8, { 0x99, 0x94, 0xfb, 0xe5, 0x25, 0x69, 0xaa, 0xa4 } }), kStructVersion1)
ViewportHandle(uint32_t v) : BaseStructure(ViewportHandle::s_structType, kStructVersion1), value(v) {}
ViewportHandle(int32_t v) : BaseStructure(ViewportHandle::s_structType, kStructVersion1), value(v) {}
operator uint32_t() const { return value; }
private:
uint32_t value = UINT_MAX;
friend constexpr void sl::test::AbiValidation();
SL_STRUCT_END()
//! Specifies feature requirement flags
//!
enum class FeatureRequirementFlags : uint32_t
{
//! Rendering APIs
eD3D11Supported = 1 << 0,
eD3D12Supported = 1 << 1,
eVulkanSupported = 1 << 2,
//! If set V-Sync must be disabled when feature is active
eVSyncOffRequired = 1 << 3,
//! If set GPU hardware scheduling OS feature must be turned on
eHardwareSchedulingRequired = 1 << 4,
//! All feature requirement flags. This isn't expected to be used directly by integrations, but may be useful for e.g. writing helpers.
eAll = eD3D11Supported | eD3D12Supported | eVulkanSupported | eVSyncOffRequired | eHardwareSchedulingRequired
};
SL_ENUM_OPERATORS_32(FeatureRequirementFlags);
//! Specifies feature requirements
//!
//! {66714097-AC6D-4BC6-8915-1E0F55A6B61F}
SL_STRUCT_BEGIN(FeatureRequirements, StructType({ 0x66714097, 0xac6d, 0x4bc6, { 0x89, 0x15, 0x1e, 0xf, 0x55, 0xa6, 0xb6, 0x1f } }), kStructVersion2)
//! Various Flags
FeatureRequirementFlags flags {};
//! Feature will create this many CPU threads
uint32_t maxNumCPUThreads{};
//! Feature supports only this many viewports
uint32_t maxNumViewports{};
//! Required buffer tags
uint32_t numRequiredTags{};
const BufferType* requiredTags{};
//! OS and Driver versions
Version osVersionDetected{};
Version osVersionRequired{};
Version driverVersionDetected{};
Version driverVersionRequired{};
//! Vulkan specific bits
//! Command queues
uint32_t vkNumComputeQueuesRequired{};
uint32_t vkNumGraphicsQueuesRequired{};
//! Device extensions
uint32_t vkNumDeviceExtensions{};
const char** vkDeviceExtensions{};
//! Instance extensions
uint32_t vkNumInstanceExtensions{};
const char** vkInstanceExtensions{};
//! 1.2 features
//!
//! NOTE: Use getVkPhysicalDeviceVulkan12Features from sl_helpers_vk.h
uint32_t vkNumFeatures12{};
const char** vkFeatures12{};
//! 1.3 features
//!
//! NOTE: Use getVkPhysicalDeviceVulkan13Features from sl_helpers_vk.h
uint32_t vkNumFeatures13{};
const char** vkFeatures13{};
//! Vulkan optical flow feature
uint32_t vkNumOpticalFlowQueuesRequired{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Specifies feature's version
//!
//! {6D5B51F0-076B-486D-9995-5A561043F5C1}
SL_STRUCT_BEGIN(FeatureVersion, StructType({ 0x6d5b51f0, 0x76b, 0x486d, { 0x99, 0x95, 0x5a, 0x56, 0x10, 0x43, 0xf5, 0xc1 } }), kStructVersion1)
//! SL version
Version versionSL{};
//! NGX version (if feature is using NGX, null otherwise)
Version versionNGX{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Specifies either DXGI adapter or VK physical device
//!
//! {0677315F-A746-4492-9F42-CB6142C9C3D4}
SL_STRUCT_BEGIN(AdapterInfo, StructType({ 0x677315f, 0xa746, 0x4492, { 0x9f, 0x42, 0xcb, 0x61, 0x42, 0xc9, 0xc3, 0xd4 } }), kStructVersion1)
//! Locally unique identifier
uint8_t* deviceLUID {};
//! Size in bytes
uint32_t deviceLUIDSizeInBytes{};
//! Vulkan Specific, if specified LUID will be ignored
void* vkPhysicalDevice{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! A simple array wrapper designed for safe use across DLL boundaries.
//! Since different DLLs may use different memory allocators, this class
//! relies on an IAllocator pointer to ensure that memory is allocated
//! and freed consistently within the same runtime.
struct IAllocator
{
virtual ~IAllocator() = default;
virtual void *allocate(uint32_t nBytes) = 0;
virtual void free(void *p) = 0;
};
template <class T>
struct Array
{
inline Array() {}
inline ~Array() { destroy(); }
inline uint32_t size() const { return m_size; }
inline void copyFrom(IAllocator *pAllocator, const std::vector<T>& src)
{
// if they give us data - we need the allocator
assert(pAllocator || src.size() == 0);
destroy();
if (src.size() == 0) return;
m_pAllocator = pAllocator;
m_size = static_cast<uint32_t>(src.size());
m_pData = (T*)m_pAllocator->allocate(m_size * sizeof(T));
for (uint32_t i = 0; i < m_size; ++i)
m_pData[i] = src[i];
}
inline void copyTo(std::vector<T>& dst)
{
dst.resize(m_size);
for (uint32_t i = 0; i < m_size; ++i)
dst[i] = m_pData[i];
}
inline T& operator[](uint32_t index)
{
assert(index < m_size);
return m_pData[index];
}
inline const T& operator[](uint32_t index) const
{
assert(index < m_size);
return m_pData[index];
}
inline void destroy()
{
if (m_pData) m_pAllocator->free(m_pData);
m_pAllocator = nullptr;
m_pData = nullptr;
m_size = 0;
}
// Prevent copying
Array(const Array&) = delete;
Array& operator=(const Array&) = delete;
private:
T* m_pData{};
uint32_t m_size{};
// the allocator that was used to allocate memory
IAllocator *m_pAllocator{};
};
}
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl.h"
#include "sl_helpers.h"
namespace sl
{
enum class DeepDVCMode : uint32_t
{
eOff,
eOn,
eCount
};
// {23288AAD-7E7E-BE2A-916F-27DA30A3046B}
SL_STRUCT_BEGIN(DeepDVCOptions, StructType({ 0x23288aad, 0x7e7e, 0xbe2a, { 0x91, 0x67, 0x27, 0xda, 0x30, 0xa3, 0x04, 0x6b } }), kStructVersion1)
//! Specifies which mode should be used
DeepDVCMode mode = DeepDVCMode::eOff;
//! Specifies intensity level in range [0,1]. Default 0.5
float intensity = 0.5f;
//! Specifies saturation boost in range [0,1]. Default 0.25
float saturationBoost = 0.25f;
SL_STRUCT_END()
//! Returned by the DeepDVC plugin
//!
// {934FD3D3-B34C-70A7-A139-F19FE04D91D3}
SL_STRUCT_BEGIN(DeepDVCState, StructType({ 0x934fd3d3, 0xb34c, 0x70a7, { 0xa1, 0x39, 0xf1, 0x9f, 0xe0, 0x4d, 0x91, 0xd3 } }), kStructVersion1)
//! Specified the amount of memory expected to be used
uint64_t estimatedVRAMUsageInBytes {};
SL_STRUCT_END()
}
//! Sets DeepDVC options
//!
//! Call this method to turn DeepDVC on/off, change mode etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies DeepDVC options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDeepDVCSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::DeepDVCOptions& options);
//! Provides DeepDVC state for the given viewport
//!
//! Call this method to obtain VRAM usage and other information.
//!
//! @param viewport Specified viewport we are working with
//! @param state Reference to a structure where state is to be returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDeepDVCGetState = sl::Result(const sl::ViewportHandle& viewport, sl::DeepDVCState& state);
//! HELPERS
//!
inline sl::Result slDeepDVCSetOptions(const sl::ViewportHandle& viewport, const sl::DeepDVCOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDeepDVC, slDeepDVCSetOptions);
return s_slDeepDVCSetOptions(viewport, options);
}
inline sl::Result slDeepDVCGetState(const sl::ViewportHandle& viewport, sl::DeepDVCState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDeepDVC, slDeepDVCGetState);
return s_slDeepDVCGetState(viewport, state);
}
//#define SL_CASE_STR(a) case a : return #a;
inline const char* getDeepDVCModeAsStr(sl::DeepDVCMode v)
{
switch (v)
{
SL_CASE_STR(sl::DeepDVCMode::eOff);
SL_CASE_STR(sl::DeepDVCMode::eOn);
};
return "Unknown";
}
@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include "sl_struct.h"
namespace sl
{
//! Rendering API
//!
enum class RenderAPI : uint32_t
{
eD3D11,
eD3D12,
eVulkan,
eCount
};
}
+173
View File
@@ -0,0 +1,173 @@
/*
* Copyright (c) 2024 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl_struct.h"
#include <dxgi.h>
struct ID3D12CommandQueue;
namespace sl
{
enum class DirectSROptimizationType : uint32_t
{
eBalanced,
eHighQuality,
eMaxQuality,
eHighPerformance,
eMaxPerformance,
ePowerSaving,
eMaxPowerSaving,
eCount
};
enum class DirectSRVariantFlags : uint32_t
{
eNone = 0x0,
eSupportsExposureScaleTexture = 0x1,
eSupportsIgnoreHistoryMask = 0x2,
eNative = 0x4,
eSupportsReactiveMask = 0x8,
eSupportsSharpness = 0x10,
eDisallowsRegionOffsets = 0x20,
eAll = eSupportsExposureScaleTexture | eSupportsIgnoreHistoryMask | eNative | eSupportsReactiveMask | eSupportsSharpness | eDisallowsRegionOffsets
};
// {1AD87504-774E-4BF3-9633-A44D1F7F9CB8}
SL_STRUCT_BEGIN(DirectSROptions, StructType({ 0x1ad87504, 0x774e, 0x4bf3, { 0x96, 0x33, 0xa4, 0x4d, 0x1f, 0x7f, 0x9c, 0xb8 } }), kStructVersion1)
// DirectSR variant index as enumerated
uint32_t variantIndex;
// D3D12 command queue to execute work on
ID3D12CommandQueue *pCommandQueue;
//! Specifies which mode should be used
DirectSROptimizationType optType;
//! Specifies output (final) target width
uint32_t outputWidth = INVALID_UINT;
//! Specifies output (final) target height
uint32_t outputHeight = INVALID_UINT;
//! Specifies sharpening level in range [0,1]
float sharpness = 0.0f;
//! Specifies pre-exposure value
float preExposure = 1.0f;
//! Specifies exposure scale value
float exposureScale = 1.0f;
//! Specifies if tagged color buffers are full HDR or not (DLSS in HDR pipeline or not)
Boolean colorBuffersHDR = Boolean::eTrue;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DirectSR plugin
//!
//! {1BD0C637-A28F-41F2-BC91-B421FAEE8E1E}
SL_STRUCT_BEGIN(DirectSROptimalSettings, StructType({ 0x1bd0c637, 0xa28f, 0x41f2, { 0xbc, 0x91, 0xb4, 0x21, 0xfa, 0xee, 0x8e, 0x1e } }), kStructVersion1)
//! Specifies render area width
uint32_t optimalRenderWidth{};
//! Specifies render area height
uint32_t optimalRenderHeight{};
//! Specifies minimal render area width
uint32_t renderWidthMin{};
//! Specifies minimal render area height
uint32_t renderHeightMin{};
//! Specifies maximal render area width
uint32_t renderWidthMax{};
//! Specifies maximal render area height
uint32_t renderHeightMax{};
// optimal color format
DXGI_FORMAT optimalColorFormat;
// optimal depth format
DXGI_FORMAT optimalDepthFormat;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DirectSR plugin
//!
//! {38216184-79ba-48cb-93f5-7a8a59382fdf}
SL_STRUCT_BEGIN(DirectSRVariantInfo, StructType({ 0x38216184, 0x79ba, 0x48cb, { 0x93, 0xf5, 0x7a, 0x8a, 0x59, 0x38, 0x2f, 0xdf } }), kStructVersion1)
char name[128];
sl::DirectSRVariantFlags flags;
sl::DirectSROptimizationType optimizationRankings[7];
DXGI_FORMAT optimalTargetFormat;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
//! Provides optimal DirectSR settings
//!
//! Call this method to obtain optimal render target size and other DirectSR related settings.
//!
//! @param options Specifies DirectSR options to use
//! @param settings Reference to a structure where settings are returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDirectSRGetOptimalSettings = sl::Result(const sl::DirectSROptions & options, sl::DirectSROptimalSettings & settings);
//! Retrive information about the available DirectSR variants.
using PFun_slDirectSRGetVariantInfo = sl::Result(uint32_t *numVariants, sl::DirectSRVariantInfo *variantInfo);
//! Sets DirectSR options
//!
//! Call this method to turn DirectSR on/off, change mode etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies DirectSR options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDirectSRSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::DirectSROptions& options);
//! HELPERS
//!
inline sl::Result slDirectSRGetOptimalSettings(const sl::DirectSROptions& options, sl::DirectSROptimalSettings& settings)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDirectSR, slDirectSRGetOptimalSettings);
return s_slDirectSRGetOptimalSettings(options, settings);
}
inline sl::Result slDirectSRGetVariantInfo(uint32_t *numVariants, sl::DirectSRVariantInfo *variantInfo)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDirectSR, slDirectSRGetVariantInfo);
return s_slDirectSRGetVariantInfo(numVariants, variantInfo);
}
inline sl::Result slDirectSRSetOptions(const sl::ViewportHandle& viewport, const sl::DirectSROptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDirectSR, slDirectSRSetOptions);
return s_slDirectSRSetOptions(viewport, options);
}
+193
View File
@@ -0,0 +1,193 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#if __cplusplus >= 201402L
#define SR_DEPRECATED_SHARPENING [[deprecated("Sharpness is not supported")]]
#else
#define SR_DEPRECATED_SHARPENING
#endif
namespace sl
{
enum class DLSSMode : uint32_t
{
eOff,
eMaxPerformance,
eBalanced,
eMaxQuality,
eUltraPerformance,
eUltraQuality,
eDLAA,
eCount,
};
enum class DLSSPreset : uint32_t
{
//! Default behavior, may or may not change after an OTA
eDefault,
//! Fixed DL models
// ePresetA removed, use presets J or K
// ePresetB removed, use presets J or K
// ePresetC removed, use presets J or K
// ePresetD removed, use presets J or K
// ePresetE removed, use presets J or K
ePresetF = 6, // Intended for Ultra Perf/DLAA modes. The default preset for Ultra Perf
ePresetG = 7, // Reverts to default, not recommended to use
ePresetH = 8, // Reverts to default, not recommended to use
ePresetI = 9, // Reverts to default, not recommended to use
ePresetJ = 10, // Similar to preset K. Preset J might exhibit slightly less ghosting at the cost of extra flickering. Preset K is generally recommended over preset J
ePresetK = 11, // Default preset for DLAA/Perf/Balanced/Quality modes that is transformer based. Best image quality preset at a higher performance cost
ePresetL = 12, // Reverts to default, not recommended to use
ePresetM = 13, // Reverts to default, not recommended to use
ePresetN = 14, // Reverts to default, not recommended to use
ePresetO = 15, // Reverts to default, not recommended to use
eCount
};
// {6AC826E4-4C61-4101-A92D-638D421057B8}
SL_STRUCT_BEGIN(DLSSOptions, StructType({ 0x6ac826e4, 0x4c61, 0x4101, { 0xa9, 0x2d, 0x63, 0x8d, 0x42, 0x10, 0x57, 0xb8 } }), kStructVersion3)
//! Specifies which mode should be used
DLSSMode mode = DLSSMode::eOff;
//! Specifies output (final) target width
uint32_t outputWidth = INVALID_UINT;
//! Specifies output (final) target height
uint32_t outputHeight = INVALID_UINT;
//! Specifies sharpening level in range [0,1] this is a deprecated field
float sharpness SR_DEPRECATED_SHARPENING = 0.0f;
//! Specifies pre-exposure value
float preExposure = 1.0f;
//! Specifies exposure scale value
float exposureScale = 1.0f;
//! Specifies if tagged color buffers are full HDR or not (DLSS in HDR pipeline or not)
Boolean colorBuffersHDR = Boolean::eTrue;
//! Specifies if indicator on screen should invert axis
Boolean indicatorInvertAxisX = Boolean::eFalse;
//! Specifies if indicator on screen should invert axis
Boolean indicatorInvertAxisY = Boolean::eFalse;
//! Presets
DLSSPreset dlaaPreset = DLSSPreset::eDefault;
DLSSPreset qualityPreset = DLSSPreset::eDefault;
DLSSPreset balancedPreset = DLSSPreset::eDefault;
DLSSPreset performancePreset = DLSSPreset::eDefault;
DLSSPreset ultraPerformancePreset = DLSSPreset::eDefault;
DLSSPreset ultraQualityPreset = DLSSPreset::eDefault;
//! Specifies if the setting for AutoExposure is used
Boolean useAutoExposure = Boolean::eFalse;
//! Whether or not the alpha channel should be upscaled (if false, only RGB is upscaled)
//! Enabling alpha upscaling may impact performance
Boolean alphaUpscalingEnabled = Boolean::eFalse;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DLSS plugin
//!
//! {EF1D0957-FD58-4DF7-B504-8B69D8AA6B76}
SL_STRUCT_BEGIN(DLSSOptimalSettings, StructType({ 0xef1d0957, 0xfd58, 0x4df7, { 0xb5, 0x4, 0x8b, 0x69, 0xd8, 0xaa, 0x6b, 0x76 } }), kStructVersion1)
//! Specifies render area width
uint32_t optimalRenderWidth{};
//! Specifies render area height
uint32_t optimalRenderHeight{};
//! Specifies the optimal sharpness value
float optimalSharpness{};
//! Specifies minimal render area width
uint32_t renderWidthMin{};
//! Specifies minimal render area height
uint32_t renderHeightMin{};
//! Specifies maximal render area width
uint32_t renderWidthMax{};
//! Specifies maximal render area height
uint32_t renderHeightMax{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DLSS plugin
//!
//! {9366B056-8C01-463C-BB91-E68782636CE9}
SL_STRUCT_BEGIN(DLSSState, StructType({ 0x9366b056, 0x8c01, 0x463c, { 0xbb, 0x91, 0xe6, 0x87, 0x82, 0x63, 0x6c, 0xe9 } }), kStructVersion1)
//! Specified the amount of memory expected to be used
uint64_t estimatedVRAMUsageInBytes{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
//! Provides optimal DLSS settings
//!
//! Call this method to obtain optimal render target size and other DLSS related settings.
//!
//! @param options Specifies DLSS options to use
//! @param settings Reference to a structure where settings are returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSGetOptimalSettings = sl::Result(const sl::DLSSOptions & options, sl::DLSSOptimalSettings & settings);
//! Provides DLSS state for the given viewport
//!
//! Call this method to obtain optimal render target size and other DLSS related settings.
//!
//! @param viewport Specified viewport we are working with
//! @param state Reference to a structure where state is to be returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSGetState = sl::Result(const sl::ViewportHandle & viewport, sl::DLSSState & state);
//! Sets DLSS options
//!
//! Call this method to turn DLSS on/off, change mode etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies DLSS options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::DLSSOptions& options);
//! HELPERS
//!
inline sl::Result slDLSSGetOptimalSettings(const sl::DLSSOptions& options, sl::DLSSOptimalSettings& settings)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS, slDLSSGetOptimalSettings);
return s_slDLSSGetOptimalSettings(options, settings);
}
inline sl::Result slDLSSGetState(const sl::ViewportHandle& viewport, sl::DLSSState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS, slDLSSGetState);
return s_slDLSSGetState(viewport, state);
}
inline sl::Result slDLSSSetOptions(const sl::ViewportHandle& viewport, const sl::DLSSOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS, slDLSSSetOptions);
return s_slDLSSSetOptions(viewport, options);
}
+188
View File
@@ -0,0 +1,188 @@
/*
* Copyright (c) 2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl_dlss.h"
namespace sl
{
enum class DLSSDPreset : uint32_t
{
//! Default behavior, may or may not change after an OTA
eDefault,
// ePresetA removed, use preset D or E
// ePresetB removed, use preset D or E
// ePresetC removed, use preset D or E
ePresetD = 4, // Default model (transformer)
ePresetE = 5, // Latest transformer model (must use if DoF guide is needed)
ePresetF = 6, // Reverts to default
ePresetG = 7, // Reverts to default
ePresetH = 8, // Reverts to default
ePresetI = 9, // Reverts to default
ePresetJ = 10, // Reverts to default
ePresetK = 11, // Reverts to default
ePresetL = 12, // Reverts to default
ePresetM = 13, // Reverts to default. Not recommended to use
ePresetN = 14, // Reverts to default. Not recommended to use
ePresetO = 15, // Reverts to default. Not recommended to use
eCount
};
enum class DLSSDNormalRoughnessMode : uint32_t
{
eUnpacked, // App needs to provide Normal resource and Roughness resource separately.
ePacked, // App needs to write Roughness to w channel of Normal resource.
eCount
};
// {0AD87504-774E-4BF3-9633-A44D1F7F9CB8}
SL_STRUCT_BEGIN(DLSSDOptions, StructType({ 0x0ad87504, 0x774e, 0x4bf3, { 0x96, 0x33, 0xa4, 0x4d, 0x1f, 0x7f, 0x9c, 0xb8 } }), kStructVersion3)
//! Specifies which mode should be used
DLSSMode mode = DLSSMode::eOff;
//! Specifies output (final) target width
uint32_t outputWidth = INVALID_UINT;
//! Specifies output (final) target height
uint32_t outputHeight = INVALID_UINT;
//! Specifies sharpening level in range [0,1]
float sharpness = 0.0f;
//! Specifies pre-exposure value
float preExposure = 1.0f;
//! Specifies exposure scale value
float exposureScale = 1.0f;
//! Specifies if tagged color buffers are full HDR or not (DLSS in HDR pipeline or not)
Boolean colorBuffersHDR = Boolean::eTrue;
//! Specifies if indicator on screen should invert axis
Boolean indicatorInvertAxisX = Boolean::eFalse;
//! Specifies if indicator on screen should invert axis
Boolean indicatorInvertAxisY = Boolean::eFalse;
//! Specifies which mode should be used for roughness resource
DLSSDNormalRoughnessMode normalRoughnessMode = DLSSDNormalRoughnessMode::eUnpacked;
//! Specifies matrix transformation from the world space to the camera view space.
float4x4 worldToCameraView;
//! Specifies matrix transformation from the camera view space to the world space.
//! cameraViewToWorld = worldToCameraView.inverse()
float4x4 cameraViewToWorld;
//! Whether or not the alpha channel should be upscaled (if false, only RGB is upscaled)
//! Enabling alpha upscaling may impact performance
Boolean alphaUpscalingEnabled = Boolean::eFalse;
//! Presets
DLSSDPreset dlaaPreset = DLSSDPreset::eDefault;
DLSSDPreset qualityPreset = DLSSDPreset::eDefault;
DLSSDPreset balancedPreset = DLSSDPreset::eDefault;
DLSSDPreset performancePreset = DLSSDPreset::eDefault;
DLSSDPreset ultraPerformancePreset = DLSSDPreset::eDefault;
DLSSDPreset ultraQualityPreset = DLSSDPreset::eDefault;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DLSSD plugin
//!
//! {FBD0C637-A28F-41F2-BC91-B421FAEE8E1E}
SL_STRUCT_BEGIN(DLSSDOptimalSettings, StructType({ 0xfbd0c637, 0xa28f, 0x41f2, { 0xbc, 0x91, 0xb4, 0x21, 0xfa, 0xee, 0x8e, 0x1e } }), kStructVersion1)
//! Specifies render area width
uint32_t optimalRenderWidth{};
//! Specifies render area height
uint32_t optimalRenderHeight{};
//! Specifies the optimal sharpness value
float optimalSharpness{};
//! Specifies minimal render area width
uint32_t renderWidthMin{};
//! Specifies minimal render area height
uint32_t renderHeightMin{};
//! Specifies maximal render area width
uint32_t renderWidthMax{};
//! Specifies maximal render area height
uint32_t renderHeightMax{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by DLSSD plugin
//!
//! {71873C14-F8CA-4767-9EAF-3B4393EA98FA}
SL_STRUCT_BEGIN(DLSSDState, StructType({ 0x71873c14, 0xf8ca, 0x4767, { 0x9e, 0xaf, 0x3b, 0x43, 0x93, 0xea, 0x98, 0xfa } }), kStructVersion1)
//! Specified the amount of memory expected to be used
uint64_t estimatedVRAMUsageInBytes {};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
//! Provides optimal DLSSD settings
//!
//! Call this method to obtain optimal render target size and other DLSSD related settings.
//!
//! @param options Specifies DLSSD options to use
//! @param settings Reference to a structure where settings are returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSDGetOptimalSettings = sl::Result(const sl::DLSSDOptions & options, sl::DLSSDOptimalSettings & settings);
//! Provides DLSSD state for the given viewport
//!
//! Call this method to obtain optimal render target size and other DLSSD related settings.
//!
//! @param viewport Specified viewport we are working with
//! @param state Reference to a structure where state is to be returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSDGetState = sl::Result(const sl::ViewportHandle & viewport, sl::DLSSDState & state);
//! Sets DLSSD options
//!
//! Call this method to turn DLSSD on/off, change mode etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies DLSSD options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSDSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::DLSSDOptions& options);
//! HELPERS
//!
inline sl::Result slDLSSDGetOptimalSettings(const sl::DLSSDOptions& options, sl::DLSSDOptimalSettings& settings)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS_RR, slDLSSDGetOptimalSettings);
return s_slDLSSDGetOptimalSettings(options, settings);
}
inline sl::Result slDLSSDGetState(const sl::ViewportHandle& viewport, sl::DLSSDState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS_RR, slDLSSDGetState);
return s_slDLSSDGetState(viewport, state);
}
inline sl::Result slDLSSDSetOptions(const sl::ViewportHandle& viewport, const sl::DLSSDOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS_RR, slDLSSDSetOptions);
return s_slDLSSDSetOptions(viewport, options);
}
+209
View File
@@ -0,0 +1,209 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl.h"
#include "sl_consts.h"
#include "sl_core_types.h"
#include <vector>
namespace sl
{
enum class DLSSGMode : uint32_t
{
eOff,
eOn,
eAuto,
eCount
};
enum class DLSSGFlags : uint32_t
{
eShowOnlyInterpolatedFrame = 1 << 0,
eDynamicResolutionEnabled = 1 << 1,
eRequestVRAMEstimate = 1 << 2,
eRetainResourcesWhenOff = 1 << 3,
eEnableFullscreenMenuDetection = 1 << 4,
//! All DLSS-FG flags. This isn't expected to be used directly by integrations, but may be useful for e.g. writing helpers.
eAll = eShowOnlyInterpolatedFrame | eDynamicResolutionEnabled | eRequestVRAMEstimate | eRetainResourcesWhenOff | eEnableFullscreenMenuDetection
};
enum class DLSSGQueueParallelismMode : uint32_t
{
//! Default mode in which client's presenting queue is blocked until DLSSG workload execution completes.
eBlockPresentingClientQueue,
//! This mode is only supported on Vulkan presently. Even if set by any D3D client, it would default to
//! eBlockPresentingClientQueue as before. eBlockNoClientQueues mode helps achieve maximum performance benefit
//! from queue-level paralleism in Vulkan during DLSS-G processing. In this mode, client must must wait on
//! DLSSGState::inputsProcessingCompletionFence and associated value, before it can modify or destroy the tagged
//! resources input to DLSS-G enabled for the corresponding previously presented frame on any client queue.
eBlockNoClientQueues,
eCount
};
// Adds various useful operators for our enum
SL_ENUM_OPERATORS_32(DLSSGFlags)
// {FAC5F1CB-2DFD-4F36-A1E6-3A9E865256C5}
SL_STRUCT_BEGIN(DLSSGOptions, StructType({ 0xfac5f1cb, 0x2dfd, 0x4f36, { 0xa1, 0xe6, 0x3a, 0x9e, 0x86, 0x52, 0x56, 0xc5 } }), kStructVersion4)
//! Specifies which mode should be used.
DLSSGMode mode = DLSSGMode::eOff;
//! Number of frames to generate inbetween fully rendered frames. Cannot exceed DLSSGState::numFramesToGenerateMax.
//! For 2x frame multiplier, numFramesToGenerate is 1.
//! For 3x frame multiplier, numFramesToGenerate is 2.
//! For 4x frame multiplier, numFramesToGenerate is 3.
uint32_t numFramesToGenerate = 1;
//! Optional - Flags used to enable or disable certain functionality
DLSSGFlags flags{};
//! Optional - Dynamic resolution optimal width (used only if eDynamicResolutionEnabled is set)
uint32_t dynamicResWidth{};
//! Optional - Dynamic resolution optimal height (used only if eDynamicResolutionEnabled is set)
uint32_t dynamicResHeight{};
//! Optional - Expected number of buffers in the swap-chain
uint32_t numBackBuffers{};
//! Optional - Expected width of the input render targets (depth, motion-vector buffers etc)
uint32_t mvecDepthWidth{};
//! Optional - Expected height of the input render targets (depth, motion-vector buffers etc)
uint32_t mvecDepthHeight{};
//! Optional - Expected width of the back buffers in the swap-chain
uint32_t colorWidth{};
//! Optional - Expected height of the back buffers in the swap-chain
uint32_t colorHeight{};
//! Optional - Indicates native format used for the swap-chain back buffers
uint32_t colorBufferFormat{};
//! Optional - Indicates native format used for eMotionVectors
uint32_t mvecBufferFormat{};
//! Optional - Indicates native format used for eDepth
uint32_t depthBufferFormat{};
//! Optional - Indicates native format used for eHUDLessColor
uint32_t hudLessBufferFormat{};
//! Optional - Indicates native format used for eUIColorAndAlpha
uint32_t uiBufferFormat{};
//! Optional - if specified DLSSG will return any errors which occur when calling underlying API (DXGI or Vulkan)
PFunOnAPIErrorCallback* onErrorCallback{};
// kStructVersion2
Boolean bReserved15 = eInvalid;
// kStructVersion3
//! Optional - determines the level of client and DLSSG queue parallelism to use for performance gain - must be same for all viewports.
DLSSGQueueParallelismMode queueParallelismMode{};
// kStructVersion4
Boolean bReserved16 = eInvalid;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
enum class DLSSGStatus : uint32_t
{
//! Everything is working as expected
eOk = 0,
//! Output resolution (size of the back buffers in the swap-chain) is too low
eFailResolutionTooLow = 1 << 0,
//! Reflex is not active while DLSS-G is running, Reflex must be turned on when DLSS-G is on
eFailReflexNotDetectedAtRuntime = 1 << 1,
//! HDR format not supported, see DLSS-G programming guide for more details
eFailHDRFormatNotSupported = 1 << 2,
//! Some constants are invalid, see programming guide for more details
eFailCommonConstantsInvalid = 1 << 3,
//! D3D integrations must use SwapChain::GetCurrentBackBufferIndex API
eFailGetCurrentBackBufferIndexNotCalled = 1 << 4,
//! Reserved for future use, do not use
eReserved5 = 1 << 5,
eAll = eFailResolutionTooLow | eFailReflexNotDetectedAtRuntime | eFailHDRFormatNotSupported | eFailCommonConstantsInvalid | eFailGetCurrentBackBufferIndexNotCalled | eReserved5
};
// Adds various useful operators for our enum
SL_ENUM_OPERATORS_32(DLSSGStatus)
// {CC8AC8E1-A179-44F5-97FA-E74112F9BC61}
SL_STRUCT_BEGIN(DLSSGState, StructType({ 0xcc8ac8e1, 0xa179, 0x44f5, { 0x97, 0xfa, 0xe7, 0x41, 0x12, 0xf9, 0xbc, 0x61 } }), kStructVersion3)
//! Specifies the amount of memory expected to be used
uint64_t estimatedVRAMUsageInBytes{};
//! Specifies current status of DLSS-G
DLSSGStatus status{};
//! Specifies minimum supported dimension
uint32_t minWidthOrHeight{};
//! Number of frames presented since the last 'slDLSSGGetState' call
uint32_t numFramesActuallyPresented{};
// kStructVersion2
//! Maximum number of frames possible to generate on this gpu architecture.
//! For 2x only supporting devices, numFramesToGenerateMax is 1.
//! For 3x and 4x supporting devices, numFramesToGenerateMax is 3.
uint32_t numFramesToGenerateMax{};
//! Reserved for future use, do not use
sl::Boolean bReserved4{};
//! Hint to the application to display VSync support in the user interface
sl::Boolean bIsVsyncSupportAvailable{};
//! SL client must wait on SL DLSS-G plugin-internal fence and associated value, before it can modify or destroy the tagged resources input
//! to DLSS-G enabled for the corresponding previously presented frame on a non-presenting queue.
//! If modified on client's presenting queue, then it's recommended but not required.
//! However, if DLSSGQueueParallelismMode::eBlockNoClientQueues is set, then it's always required.
//! It must call slDLSSGGetState on the present thread to retrieve the fence value for the inputs consumed by FG, on which client would
//! wait in the frame it would modify those inputs.
void* inputsProcessingCompletionFence{};
uint64_t lastPresentInputsProcessingCompletionFenceValue{};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
//! Provides DLSS-G state
//!
//! Call this method to obtain current state of DLSS-G
//!
//! @param viewport Specified viewport we are working with
//! @param state Reference to a structure where state is returned
//! @param options Specifies DLSS-G options to use (can be null if not needed)
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSGGetState = sl::Result(const sl::ViewportHandle& viewport, sl::DLSSGState& state, const sl::DLSSGOptions* options);
//! Sets DLSS-G options
//!
//! Call this method to turn DLSS-G on/off, change modes etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies DLSS-G options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slDLSSGSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::DLSSGOptions& options);
//! HELPERS
//!
inline sl::Result slDLSSGGetState(const sl::ViewportHandle& viewport, sl::DLSSGState& state, const sl::DLSSGOptions* options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS_G, slDLSSGGetState);
return s_slDLSSGGetState(viewport, state, options);
}
inline sl::Result slDLSSGSetOptions(const sl::ViewportHandle& viewport, const sl::DLSSGOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureDLSS_G, slDLSSGSetOptions);
return s_slDLSSGSetOptions(viewport, options);
}
+475
View File
@@ -0,0 +1,475 @@
/*
* Copyright (c) 2022-2025 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <string.h>
#include <vector>
#define FEATURE_SPECIFIC_BUFFER_TYPE_ID(feature, number) feature << 16 | number
#include "sl.h"
#include "sl_consts.h"
#include "sl_reflex.h"
#include "sl_pcl.h"
#include "sl_dlss.h"
#include "sl_nis.h"
#include "sl_dlss_d.h"
#include "sl_dlss_g.h"
#if defined(__clang__)
#define SL_DISABLE_DEPRECATED_WARNINGS \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")
#define SL_RESTORE_DEPRECATED_WARNINGS \
_Pragma("clang diagnostic pop")
#elif defined(_MSC_VER)
#define SL_DISABLE_DEPRECATED_WARNINGS \
__pragma(warning(push)) \
__pragma(warning(disable: 4996))
#define SL_RESTORE_DEPRECATED_WARNINGS \
__pragma(warning(pop))
#else
#define SL_DISABLE_DEPRECATED_WARNINGS
#define SL_RESTORE_DEPRECATED_WARNINGS
#endif
namespace sl
{
inline float4x4 transpose(const float4x4& m)
{
float4x4 r;
r[0] = { m[0].x, m[1].x, m[2].x, m[3].x };
r[1] = { m[0].y, m[1].y, m[2].y, m[3].y };
r[2] = { m[0].z, m[1].z, m[2].z, m[3].z };
r[3] = { m[0].w, m[1].w, m[2].w, m[3].w };
return r;
};
#define SL_CASE_STR(a) case a : return #a;
// Check for c++17 features
#if __cplusplus >= 201703L
#define SL_FALLTHROUGH [[fallthrough]];
#else
#define SL_FALLTHROUGH
#endif
inline const char* getResultAsStr(Result v)
{
switch (v)
{
SL_CASE_STR(Result::eOk);
SL_CASE_STR(Result::eErrorIO);
SL_CASE_STR(Result::eErrorDriverOutOfDate);
SL_CASE_STR(Result::eErrorOSOutOfDate);
SL_CASE_STR(Result::eErrorOSDisabledHWS);
SL_CASE_STR(Result::eErrorDeviceNotCreated);
SL_CASE_STR(Result::eErrorNoSupportedAdapterFound);
SL_CASE_STR(Result::eErrorAdapterNotSupported);
SL_CASE_STR(Result::eErrorNoPlugins);
SL_CASE_STR(Result::eErrorVulkanAPI);
SL_CASE_STR(Result::eErrorDXGIAPI);
SL_CASE_STR(Result::eErrorD3DAPI);
SL_CASE_STR(Result::eErrorNRDAPI);
SL_CASE_STR(Result::eErrorNVAPI);
SL_CASE_STR(Result::eErrorReflexAPI);
SL_CASE_STR(Result::eErrorNGXFailed);
SL_CASE_STR(Result::eErrorJSONParsing);
SL_CASE_STR(Result::eErrorMissingProxy);
SL_CASE_STR(Result::eErrorMissingResourceState);
SL_CASE_STR(Result::eErrorInvalidIntegration);
SL_CASE_STR(Result::eErrorMissingInputParameter);
SL_CASE_STR(Result::eErrorNotInitialized);
SL_CASE_STR(Result::eErrorComputeFailed);
SL_CASE_STR(Result::eErrorInitNotCalled);
SL_CASE_STR(Result::eErrorExceptionHandler);
SL_CASE_STR(Result::eErrorInvalidParameter);
SL_CASE_STR(Result::eErrorMissingConstants);
SL_CASE_STR(Result::eErrorDuplicatedConstants);
SL_CASE_STR(Result::eErrorMissingOrInvalidAPI);
SL_CASE_STR(Result::eErrorCommonConstantsMissing);
SL_CASE_STR(Result::eErrorUnsupportedInterface);
SL_CASE_STR(Result::eErrorFeatureMissing);
SL_CASE_STR(Result::eErrorFeatureNotSupported);
SL_CASE_STR(Result::eErrorFeatureMissingHooks);
SL_CASE_STR(Result::eErrorFeatureFailedToLoad);
SL_CASE_STR(Result::eErrorFeatureWrongPriority);
SL_CASE_STR(Result::eErrorFeatureMissingDependency);
SL_CASE_STR(Result::eErrorFeatureManagerInvalidState);
SL_CASE_STR(Result::eErrorInvalidState);
SL_CASE_STR(Result::eWarnOutOfVRAM);
};
return "Unknown";
}
inline const char* getNISModeAsStr(NISMode v)
{
switch (v)
{
SL_CASE_STR(NISMode::eOff);
SL_CASE_STR(NISMode::eScaler);
SL_CASE_STR(NISMode::eSharpen);
case NISMode::eCount: break;
};
return "Unknown";
}
inline const char* getNISHDRAsStr(NISHDR v)
{
switch (v)
{
SL_CASE_STR(NISHDR::eNone);
SL_CASE_STR(NISHDR::eLinear);
SL_CASE_STR(NISHDR::ePQ);
case NISHDR::eCount: break;
};
return "Unknown";
}
inline const char* getReflexModeAsStr(ReflexMode mode)
{
switch (mode)
{
SL_CASE_STR(ReflexMode::eOff);
SL_CASE_STR(ReflexMode::eLowLatency);
SL_CASE_STR(ReflexMode::eLowLatencyWithBoost);
case ReflexMode::ReflexMode_eCount: break;
};
return "Unknown";
}
inline const char* getPCLMarkerAsStr(PCLMarker marker)
{
switch (marker)
{
SL_CASE_STR(PCLMarker::eSimulationStart);
SL_CASE_STR(PCLMarker::eSimulationEnd);
SL_CASE_STR(PCLMarker::eRenderSubmitStart);
SL_CASE_STR(PCLMarker::eRenderSubmitEnd);
SL_CASE_STR(PCLMarker::ePresentStart);
SL_CASE_STR(PCLMarker::ePresentEnd);
SL_CASE_STR(PCLMarker::eTriggerFlash);
SL_CASE_STR(PCLMarker::ePCLatencyPing);
SL_CASE_STR(PCLMarker::eOutOfBandRenderSubmitStart);
SL_CASE_STR(PCLMarker::eOutOfBandRenderSubmitEnd);
SL_CASE_STR(PCLMarker::eOutOfBandPresentStart);
SL_CASE_STR(PCLMarker::eOutOfBandPresentEnd);
SL_CASE_STR(PCLMarker::eControllerInputSample);
SL_CASE_STR(PCLMarker::eDeltaTCalculation);
SL_CASE_STR(PCLMarker::eLateWarpPresentStart);
SL_CASE_STR(PCLMarker::eLateWarpPresentEnd);
SL_CASE_STR(PCLMarker::eCameraConstructed);
SL_CASE_STR(PCLMarker::eLateWarpRenderSubmitStart);
SL_CASE_STR(PCLMarker::eLateWarpRenderSubmitEnd);
case PCLMarker::eMaximum: break;
};
return "Unknown";
}
inline const char* getDLSSModeAsStr(DLSSMode mode)
{
switch (mode)
{
SL_CASE_STR(DLSSMode::eOff);
SL_CASE_STR(DLSSMode::eDLAA);
SL_CASE_STR(DLSSMode::eMaxPerformance);
SL_CASE_STR(DLSSMode::eBalanced);
SL_CASE_STR(DLSSMode::eMaxQuality);
SL_CASE_STR(DLSSMode::eUltraPerformance);
SL_CASE_STR(DLSSMode::eUltraQuality);
case DLSSMode::eCount: break;
};
return "Unknown";
}
inline const char* getDLSSGModeAsStr(DLSSGMode mode)
{
switch (mode)
{
SL_CASE_STR(sl::DLSSGMode::eOff);
SL_CASE_STR(sl::DLSSGMode::eOn);
SL_CASE_STR(sl::DLSSGMode::eAuto);
case DLSSGMode::eCount: break;
};
return "Unknown";
}
inline const char* getBufferTypeAsStr(BufferType buf)
{
switch (buf)
{
SL_CASE_STR(kBufferTypeDepth);
SL_CASE_STR(kBufferTypeMotionVectors);
SL_CASE_STR(kBufferTypeHUDLessColor);
SL_CASE_STR(kBufferTypeScalingInputColor);
SL_CASE_STR(kBufferTypeScalingOutputColor);
SL_CASE_STR(kBufferTypeNormals);
SL_CASE_STR(kBufferTypeRoughness);
SL_CASE_STR(kBufferTypeAlbedo);
SL_CASE_STR(kBufferTypeSpecularAlbedo);
SL_CASE_STR(kBufferTypeIndirectAlbedo);
SL_CASE_STR(kBufferTypeSpecularMotionVectors);
SL_CASE_STR(kBufferTypeDisocclusionMask);
SL_CASE_STR(kBufferTypeEmissive);
SL_CASE_STR(kBufferTypeExposure);
SL_CASE_STR(kBufferTypeNormalRoughness);
SL_CASE_STR(kBufferTypeDiffuseHitNoisy);
SL_CASE_STR(kBufferTypeDiffuseHitDenoised);
SL_CASE_STR(kBufferTypeSpecularHitNoisy);
SL_CASE_STR(kBufferTypeSpecularHitDenoised);
SL_CASE_STR(kBufferTypeShadowNoisy);
SL_CASE_STR(kBufferTypeShadowDenoised);
SL_CASE_STR(kBufferTypeAmbientOcclusionNoisy);
SL_CASE_STR(kBufferTypeAmbientOcclusionDenoised);
SL_CASE_STR(kBufferTypeUIColorAndAlpha);
SL_CASE_STR(kBufferTypeShadowHint);
SL_CASE_STR(kBufferTypeReflectionHint);
SL_CASE_STR(kBufferTypeParticleHint);
SL_CASE_STR(kBufferTypeTransparencyHint);
SL_CASE_STR(kBufferTypeAnimatedTextureHint);
SL_CASE_STR(kBufferTypeBiasCurrentColorHint);
SL_CASE_STR(kBufferTypeRaytracingDistance);
SL_CASE_STR(kBufferTypeReflectionMotionVectors);
SL_CASE_STR(kBufferTypePosition);
SL_CASE_STR(kBufferTypeInvalidDepthMotionHint);
SL_CASE_STR(kBufferTypeAlpha);
SL_CASE_STR(kBufferTypeOpaqueColor);
SL_CASE_STR(kBufferTypeReactiveMaskHint);
SL_CASE_STR(kBufferTypeTransparencyAndCompositionMaskHint);
SL_CASE_STR(kBufferTypeReflectedAlbedo);
SL_CASE_STR(kBufferTypeColorBeforeParticles);
SL_CASE_STR(kBufferTypeColorBeforeTransparency);
SL_CASE_STR(kBufferTypeColorBeforeFog);
SL_CASE_STR(kBufferTypeSpecularHitDistance);
SL_CASE_STR(kBufferTypeSpecularRayDirectionHitDistance);
SL_CASE_STR(kBufferTypeSpecularRayDirection);
SL_CASE_STR(kBufferTypeDiffuseHitDistance);
SL_CASE_STR(kBufferTypeDiffuseRayDirectionHitDistance);
SL_CASE_STR(kBufferTypeDiffuseRayDirection);
SL_CASE_STR(kBufferTypeHiResDepth);
SL_CASE_STR(kBufferTypeLinearDepth);
SL_CASE_STR(kBufferTypeColorAfterParticles);
SL_CASE_STR(kBufferTypeColorAfterTransparency);
SL_CASE_STR(kBufferTypeColorAfterFog);
SL_CASE_STR(kBufferTypeScreenSpaceSubsurfaceScatteringGuide);
SL_CASE_STR(kBufferTypeColorBeforeScreenSpaceSubsurfaceScattering);
SL_CASE_STR(kBufferTypeColorAfterScreenSpaceSubsurfaceScattering);
SL_CASE_STR(kBufferTypeScreenSpaceRefractionGuide);
SL_CASE_STR(kBufferTypeColorBeforeScreenSpaceRefraction);
SL_CASE_STR(kBufferTypeColorAfterScreenSpaceRefraction);
SL_CASE_STR(kBufferTypeDepthOfFieldGuide);
SL_CASE_STR(kBufferTypeColorBeforeDepthOfField);
SL_CASE_STR(kBufferTypeColorAfterDepthOfField);
SL_CASE_STR(kBufferTypeScalingOutputAlpha);
SL_CASE_STR(kBufferTypeBidirectionalDistortionField);
SL_CASE_STR(kBufferTypeTransparencyLayer);
SL_CASE_STR(kBufferTypeTransparencyLayerOpacity);
SL_CASE_STR(kBufferTypeBackbuffer);
SL_CASE_STR(kBufferTypeNoWarpMask);
};
return "Unknown";
}
inline const char* getFeatureAsStr(Feature f)
{
switch (f)
{
SL_CASE_STR(kFeatureDLSS);
SL_CASE_STR(kFeatureNIS);
SL_CASE_STR(kFeatureReflex);
SL_CASE_STR(kFeaturePCL);
SL_CASE_STR(kFeatureDLSS_G);
SL_CASE_STR(kFeatureNvPerf);
SL_CASE_STR(kFeatureImGUI);
SL_CASE_STR(kFeatureCommon);
SL_CASE_STR(kFeatureDLSS_RR);
SL_CASE_STR(kFeatureDeepDVC);
SL_CASE_STR(kFeatureDirectSR);
SL_CASE_STR(kFeatureLatewarp);
// Removed features
case kFeatureNRD_INVALID: break;
}
return "Unknown";
}
// Get the feature file name as a string. For a given feature kFeatureDLSS with
// a plugin name sl.dlss.dll the value "dlss" will be returned
inline const char* getFeatureFilenameAsStrNoSL(Feature f)
{
switch (f)
{
case kFeatureDLSS: return "dlss";
case kFeatureNIS: return "nis";
case kFeatureReflex: return "reflex";
case kFeaturePCL: return "pcl";
case kFeatureDLSS_G: return "dlss_g";
case kFeatureNvPerf: return "nvperf";
case kFeatureDeepDVC: return "deepdvc";
case kFeatureImGUI: return "imgui";
case kFeatureCommon: return "common";
case kFeatureDLSS_RR: return "dlss_d";
case kFeatureDirectSR: return "directsr";
case kFeatureLatewarp: return "latewarp";
case kFeatureNRD_INVALID: break;
}
return "Unknown";
}
inline const char* getLogLevelAsStr(LogLevel v)
{
switch (v)
{
SL_CASE_STR(LogLevel::eOff);
SL_CASE_STR(LogLevel::eDefault);
SL_CASE_STR(LogLevel::eVerbose);
case LogLevel::eCount: break;
};
return "Unknown";
}
inline const char* getResourceTypeAsStr(ResourceType v)
{
switch (v)
{
SL_CASE_STR(ResourceType::eTex2d);
SL_CASE_STR(ResourceType::eBuffer);
SL_CASE_STR(ResourceType::eCommandQueue);
SL_CASE_STR(ResourceType::eCommandBuffer);
SL_CASE_STR(ResourceType::eCommandPool);
SL_CASE_STR(ResourceType::eFence);
SL_CASE_STR(ResourceType::eSwapchain);
SL_CASE_STR(ResourceType::eHostFence);
case ResourceType::eUnknown: break;
case ResourceType::eCount: break;
};
return "Unknown";
}
inline const char* getResourceLifecycleAsStr(ResourceLifecycle v)
{
switch (v)
{
SL_CASE_STR(ResourceLifecycle::eOnlyValidNow);
SL_CASE_STR(ResourceLifecycle::eValidUntilPresent);
SL_CASE_STR(ResourceLifecycle::eValidUntilEvaluate);
};
return "Unknown";
}
SL_DISABLE_DEPRECATED_WARNINGS
inline DLSSPreset resolveDLSSPreset(DLSSPreset preset)
{
switch (preset)
{
case DLSSPreset::ePresetF:
case DLSSPreset::ePresetJ:
case DLSSPreset::ePresetK:
return preset;
default:
return DLSSPreset::eDefault;
}
}
SL_RESTORE_DEPRECATED_WARNINGS
inline DLSSDPreset resolveDLSSDPreset(DLSSDPreset preset)
{
return static_cast<DLSSDPreset>(resolveDLSSPreset(static_cast<DLSSPreset>(preset)));
}
// Advanced/internal functions that are not useful or necessary in the vast majority of integrations
// and would just pollute the namespace and/or cause distractions.
// But, may be useful in e.g. intermediary game engine integrations, etc.
#ifndef __INTELLISENSE__
//! Find a struct of type T
template<typename T>
T* findStruct(const void* ptr)
{
auto base = static_cast<const BaseStructure*>(ptr);
while (base && base->structType != T::s_structType)
{
base = base->next;
}
return (T*)base;
}
//! Find a struct of type T, but stop the search if we find a struct of type S
template<typename T, typename S>
T* findStruct(const void* ptr)
{
auto base = static_cast<const BaseStructure*>(ptr);
while (base && base->structType != T::s_structType)
{
base = base->next;
// If we find a struct of type S, we know should stop the search
if (base->structType == S::s_structType)
{
return nullptr;
}
}
return (T*)base;
}
template<typename T>
T* findStruct(const void** ptr, uint32_t count)
{
const BaseStructure* base{};
for (uint32_t i = 0; base == nullptr && i < count; i++)
{
base = static_cast<const BaseStructure*>(ptr[i]);
while (base && base->structType != T::s_structType)
{
base = base->next;
}
}
return (T*)base;
}
template<typename T>
bool findStructs(const void** ptr, uint32_t count, std::vector<T*>& structs)
{
for (uint32_t i = 0; i < count; i++)
{
auto base = static_cast<const BaseStructure*>(ptr[i]);
while (base)
{
if (base->structType == T::s_structType)
{
structs.push_back((T*)base);
}
base = base->next;
}
}
return structs.size() > 0;
}
#endif // __INTELLISENSE__
} // namespace sl
@@ -0,0 +1,256 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl.h"
#include <string.h>
namespace sl
{
#define SL_VK_FEATURE(n) if(strcmp(featureNames[i], #n) == 0) features.n = VK_TRUE;
inline VkPhysicalDeviceVulkan12Features getVkPhysicalDeviceVulkan12Features(uint32_t featureCount, const char** featureNames)
{
VkPhysicalDeviceVulkan12Features features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES };
for (uint32_t i = 0; i < featureCount; i++)
{
SL_VK_FEATURE(samplerMirrorClampToEdge);
SL_VK_FEATURE(drawIndirectCount);
SL_VK_FEATURE(storageBuffer8BitAccess);
SL_VK_FEATURE(uniformAndStorageBuffer8BitAccess);
SL_VK_FEATURE(storagePushConstant8);
SL_VK_FEATURE(shaderBufferInt64Atomics);
SL_VK_FEATURE(shaderSharedInt64Atomics);
SL_VK_FEATURE(shaderFloat16);
SL_VK_FEATURE(shaderInt8);
SL_VK_FEATURE(descriptorIndexing);
SL_VK_FEATURE(shaderInputAttachmentArrayDynamicIndexing);
SL_VK_FEATURE(shaderUniformTexelBufferArrayDynamicIndexing);
SL_VK_FEATURE(shaderStorageTexelBufferArrayDynamicIndexing);
SL_VK_FEATURE(shaderUniformBufferArrayNonUniformIndexing);
SL_VK_FEATURE(shaderSampledImageArrayNonUniformIndexing);
SL_VK_FEATURE(shaderStorageBufferArrayNonUniformIndexing);
SL_VK_FEATURE(shaderStorageImageArrayNonUniformIndexing);
SL_VK_FEATURE(shaderInputAttachmentArrayNonUniformIndexing);
SL_VK_FEATURE(shaderUniformTexelBufferArrayNonUniformIndexing);
SL_VK_FEATURE(shaderStorageTexelBufferArrayNonUniformIndexing);
SL_VK_FEATURE(descriptorBindingUniformBufferUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingSampledImageUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingStorageImageUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingStorageBufferUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingUniformTexelBufferUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingStorageTexelBufferUpdateAfterBind);
SL_VK_FEATURE(descriptorBindingUpdateUnusedWhilePending);
SL_VK_FEATURE(descriptorBindingPartiallyBound);
SL_VK_FEATURE(descriptorBindingVariableDescriptorCount);
SL_VK_FEATURE(runtimeDescriptorArray);
SL_VK_FEATURE(samplerFilterMinmax);
SL_VK_FEATURE(scalarBlockLayout);
SL_VK_FEATURE(imagelessFramebuffer);
SL_VK_FEATURE(uniformBufferStandardLayout);
SL_VK_FEATURE(shaderSubgroupExtendedTypes);
SL_VK_FEATURE(separateDepthStencilLayouts);
SL_VK_FEATURE(hostQueryReset);
SL_VK_FEATURE(timelineSemaphore);
SL_VK_FEATURE(bufferDeviceAddress);
SL_VK_FEATURE(bufferDeviceAddressCaptureReplay);
SL_VK_FEATURE(bufferDeviceAddressMultiDevice);
SL_VK_FEATURE(vulkanMemoryModel);
SL_VK_FEATURE(vulkanMemoryModelDeviceScope);
SL_VK_FEATURE(vulkanMemoryModelAvailabilityVisibilityChains);
SL_VK_FEATURE(shaderOutputViewportIndex);
SL_VK_FEATURE(shaderOutputLayer);
SL_VK_FEATURE(subgroupBroadcastDynamicId);
}
return features;
}
inline VkPhysicalDeviceVulkan13Features getVkPhysicalDeviceVulkan13Features(uint32_t featureCount, const char** featureNames)
{
VkPhysicalDeviceVulkan13Features features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES };
for (uint32_t i = 0; i < featureCount; i++)
{
SL_VK_FEATURE(robustImageAccess);
SL_VK_FEATURE(robustImageAccess);
SL_VK_FEATURE(inlineUniformBlock);
SL_VK_FEATURE(descriptorBindingInlineUniformBlockUpdateAfterBind);
SL_VK_FEATURE(pipelineCreationCacheControl);
SL_VK_FEATURE(privateData);
SL_VK_FEATURE(shaderDemoteToHelperInvocation);
SL_VK_FEATURE(shaderTerminateInvocation);
SL_VK_FEATURE(subgroupSizeControl);
SL_VK_FEATURE(computeFullSubgroups);
SL_VK_FEATURE(synchronization2);
SL_VK_FEATURE(textureCompressionASTC_HDR);
SL_VK_FEATURE(shaderZeroInitializeWorkgroupMemory);
SL_VK_FEATURE(dynamicRendering);
SL_VK_FEATURE(shaderIntegerDotProduct);
SL_VK_FEATURE(maintenance4);
}
return features;
}
inline VkPhysicalDeviceOpticalFlowFeaturesNV getVkPhysicalDeviceOpticalFlowNVFeatures(uint32_t featureCount, const char** featureNames)
{
VkPhysicalDeviceOpticalFlowFeaturesNV features{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV };
for (uint32_t i = 0; i < featureCount; i++)
{
SL_VK_FEATURE(opticalFlow);
}
return features;
}
#define SL_VK_FEATURE_SUPPORT(T, feature, n) ((T*)pPhysicalDeviceFeatures)->n = ((feature) && (((T*)pSupportedFeatures)->n))
#define SL_VK_FEATURE_MERGE_SUPPORT(T, n) (pFeaturesToMerge == NULL) ? \
SL_VK_FEATURE_SUPPORT(T, ((T*)pPhysicalDeviceFeatures)->n, n) : SL_VK_FEATURE_SUPPORT(T, ((((T*)pPhysicalDeviceFeatures)->n) || (((T*)pFeaturesToMerge)->n)), n)
inline void getMergedSupportedVkPhysicalDeviceVulkanFeatures(VkBaseOutStructure* pPhysicalDeviceFeatures, const VkBaseOutStructure* pFeaturesToMerge, const VkBaseOutStructure* pSupportedFeatures)
{
if (pPhysicalDeviceFeatures == NULL || pSupportedFeatures == NULL)
{
return;
}
if (pFeaturesToMerge != NULL)
{
assert(pFeaturesToMerge->sType == pPhysicalDeviceFeatures->sType);
}
assert(pSupportedFeatures->sType == pPhysicalDeviceFeatures->sType);
switch (pPhysicalDeviceFeatures->sType)
{
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES:
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, samplerMirrorClampToEdge);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, samplerMirrorClampToEdge);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, drawIndirectCount);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, storageBuffer8BitAccess);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, uniformAndStorageBuffer8BitAccess);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, storagePushConstant8);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderBufferInt64Atomics);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderSharedInt64Atomics);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderFloat16);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderInt8);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayDynamicIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayDynamicIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayDynamicIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderUniformBufferArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderSampledImageArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderStorageBufferArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderStorageImageArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderInputAttachmentArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderUniformTexelBufferArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderStorageTexelBufferArrayNonUniformIndexing);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformBufferUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingSampledImageUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageImageUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageBufferUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingUniformTexelBufferUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingStorageTexelBufferUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingUpdateUnusedWhilePending);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingPartiallyBound);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, descriptorBindingVariableDescriptorCount);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, runtimeDescriptorArray);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, samplerFilterMinmax);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, scalarBlockLayout);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, imagelessFramebuffer);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, uniformBufferStandardLayout);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderSubgroupExtendedTypes);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, separateDepthStencilLayouts);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, hostQueryReset);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, timelineSemaphore);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, bufferDeviceAddress);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressCaptureReplay);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, bufferDeviceAddressMultiDevice);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, vulkanMemoryModel);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelDeviceScope);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, vulkanMemoryModelAvailabilityVisibilityChains);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderOutputViewportIndex);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, shaderOutputLayer);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan12Features, subgroupBroadcastDynamicId);
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES:
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, robustImageAccess);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, robustImageAccess);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, inlineUniformBlock);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, descriptorBindingInlineUniformBlockUpdateAfterBind);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, pipelineCreationCacheControl);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, privateData);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, shaderDemoteToHelperInvocation);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, shaderTerminateInvocation);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, subgroupSizeControl);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, computeFullSubgroups);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, synchronization2);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, textureCompressionASTC_HDR);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, shaderZeroInitializeWorkgroupMemory);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, dynamicRendering);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, shaderIntegerDotProduct);
SL_VK_FEATURE_MERGE_SUPPORT(VkPhysicalDeviceVulkan13Features, maintenance4);
break;
default:
break;
}
}
//! Interface to provide to slSetVulkanInfo when manually hooking Vulkan API and NOT
//! leveraging vkCreateDevice and vkCreateInstance proxies provided by SL.
//!
//! {0EED6FD5-82CD-43A9-BDB5-47A5BA2F45D6}
SL_STRUCT_BEGIN(VulkanInfo, StructType({ 0xeed6fd5, 0x82cd, 0x43a9, { 0xbd, 0xb5, 0x47, 0xa5, 0xba, 0x2f, 0x45, 0xd6 } }), kStructVersion3)
VkDevice device {};
VkInstance instance{};
VkPhysicalDevice physicalDevice{};
//! IMPORTANT:
//!
//! SL features can request additional graphics or compute queues.
//! The below values provide information about the queue families and
//! starting index at which SL queues are created.
uint32_t computeQueueIndex{};
uint32_t computeQueueFamily{};
uint32_t graphicsQueueIndex{};
uint32_t graphicsQueueFamily{};
uint32_t opticalFlowQueueIndex{};
uint32_t opticalFlowQueueFamily{};
bool useNativeOpticalFlowMode = false;
uint32_t computeQueueCreateFlags{};
uint32_t graphicsQueueCreateFlags{};
uint32_t opticalFlowQueueCreateFlags{};
SL_STRUCT_END()
}
using PFun_slSetVulkanInfo = sl::Result(const sl::VulkanInfo& info);
//! Specify Vulkan specific information
//!
//! Use this method to provide Vulkan device, instance information to SL.
//!
//! IMPORTANT: Only call this API if NOT using vkCreateDevice and vkCreateInstance proxies provided by SL.
//
//! @param info Reference to the structure providing the information
//!
//! This method is NOT thread safe and should be called IMMEDIATELY after base interface is created.
SL_API sl::Result slSetVulkanInfo(const sl::VulkanInfo& info);
+115
View File
@@ -0,0 +1,115 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl.h"
struct VkPhysicalDevice_T;
struct VkDevice_T;
struct VkInstance_T;
using VkPhysicalDevice = VkPhysicalDevice_T*;
using VkDevice = VkDevice_T*;
using VkInstance = VkInstance_T*;
namespace sl
{
//! NOTE: Adding new hooks require sl.interposer to be recompiled
//!
//! IMPORTANT: Since SL interposer proxies supports many different versions of various D3D/DXGI interfaces
//! we use only base interface names for our hooks.
//!
//! For example if API was added in IDXGISwapChain5::FUNCTION it is still named eIDXGISwapChain_FUNCTION (there is no 5 in the name)
//!
enum class FunctionHookID : uint32_t
{
//! Mandatory - IDXGIFactory*
eIDXGIFactory_CreateSwapChain,
eIDXGIFactory_CreateSwapChainForHwnd,
eIDXGIFactory_CreateSwapChainForCoreWindow,
//! Mandatory - IDXGISwapChain*
eIDXGISwapChain_Present,
eIDXGISwapChain_Present1,
eIDXGISwapChain_GetBuffer,
eIDXGISwapChain_GetDesc,
eIDXGISwapChain_ResizeBuffers,
eIDXGISwapChain_ResizeBuffers1,
eIDXGISwapChain_GetCurrentBackBufferIndex,
eIDXGISwapChain_SetFullscreenState,
//! Internal - please ignore when doing manual hooking
eIDXGISwapChain_Destroyed,
//! Mandatory - ID3D12Device*
eID3D12Device_CreateCommandQueue,
//! Mandatory - Vulkan
eVulkan_Present,
eVulkan_CreateSwapchainKHR,
eVulkan_DestroySwapchainKHR,
eVulkan_GetSwapchainImagesKHR,
eVulkan_AcquireNextImageKHR,
eVulkan_DeviceWaitIdle,
eVulkan_CreateWin32SurfaceKHR,
eVulkan_DestroySurfaceKHR,
eMaxNum
};
#ifndef SL_CASE_STR
#define SL_CASE_STR(a) case a : return #a;
#endif
inline const char* getFunctionHookIDAsStr(FunctionHookID v)
{
switch (v)
{
SL_CASE_STR(FunctionHookID::eIDXGIFactory_CreateSwapChain);
SL_CASE_STR(FunctionHookID::eIDXGIFactory_CreateSwapChainForHwnd);
SL_CASE_STR(FunctionHookID::eIDXGIFactory_CreateSwapChainForCoreWindow);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_Present);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_Present1);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_GetBuffer);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_GetDesc);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_ResizeBuffers);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_ResizeBuffers1);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_GetCurrentBackBufferIndex);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_SetFullscreenState);
SL_CASE_STR(FunctionHookID::eIDXGISwapChain_Destroyed);
SL_CASE_STR(FunctionHookID::eID3D12Device_CreateCommandQueue);
SL_CASE_STR(FunctionHookID::eVulkan_Present);
SL_CASE_STR(FunctionHookID::eVulkan_CreateSwapchainKHR);
SL_CASE_STR(FunctionHookID::eVulkan_DestroySwapchainKHR);
SL_CASE_STR(FunctionHookID::eVulkan_GetSwapchainImagesKHR);
SL_CASE_STR(FunctionHookID::eVulkan_AcquireNextImageKHR);
SL_CASE_STR(FunctionHookID::eVulkan_DeviceWaitIdle);
SL_CASE_STR(FunctionHookID::eVulkan_CreateWin32SurfaceKHR);
SL_CASE_STR(FunctionHookID::eVulkan_DestroySurfaceKHR);
case FunctionHookID::eMaxNum: break;
};
return "Unknown";
}
} // namespace sl
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl.h"
#include "sl_consts.h"
namespace sl
{
inline void matrixMul(float4x4& result, const float4x4& a, const float4x4& b)
{
// Alias raw pointers over the input matrices
const float* pA = &a[0].x;
const float* pB = &b[0].x;
result[0].x = (float)((pA[0] * pB[0]) + (pA[1] * pB[4]) + (pA[2] * pB[8]) + (pA[3] * pB[12]));
result[0].y = (float)((pA[0] * pB[1]) + (pA[1] * pB[5]) + (pA[2] * pB[9]) + (pA[3] * pB[13]));
result[0].z = (float)((pA[0] * pB[2]) + (pA[1] * pB[6]) + (pA[2] * pB[10]) + (pA[3] * pB[14]));
result[0].w = (float)((pA[0] * pB[3]) + (pA[1] * pB[7]) + (pA[2] * pB[11]) + (pA[3] * pB[15]));
result[1].x = (float)((pA[4] * pB[0]) + (pA[5] * pB[4]) + (pA[6] * pB[8]) + (pA[7] * pB[12]));
result[1].y = (float)((pA[4] * pB[1]) + (pA[5] * pB[5]) + (pA[6] * pB[9]) + (pA[7] * pB[13]));
result[1].z = (float)((pA[4] * pB[2]) + (pA[5] * pB[6]) + (pA[6] * pB[10]) + (pA[7] * pB[14]));
result[1].w = (float)((pA[4] * pB[3]) + (pA[5] * pB[7]) + (pA[6] * pB[11]) + (pA[7] * pB[15]));
result[2].x = (float)((pA[8] * pB[0]) + (pA[9] * pB[4]) + (pA[10] * pB[8]) + (pA[11] * pB[12]));
result[2].y = (float)((pA[8] * pB[1]) + (pA[9] * pB[5]) + (pA[10] * pB[9]) + (pA[11] * pB[13]));
result[2].z = (float)((pA[8] * pB[2]) + (pA[9] * pB[6]) + (pA[10] * pB[10]) + (pA[11] * pB[14]));
result[2].w = (float)((pA[8] * pB[3]) + (pA[9] * pB[7]) + (pA[10] * pB[11]) + (pA[11] * pB[15]));
result[3].x = (float)((pA[12] * pB[0]) + (pA[13] * pB[4]) + (pA[14] * pB[8]) + (pA[15] * pB[12]));
result[3].y = (float)((pA[12] * pB[1]) + (pA[13] * pB[5]) + (pA[14] * pB[9]) + (pA[15] * pB[13]));
result[3].z = (float)((pA[12] * pB[2]) + (pA[13] * pB[6]) + (pA[14] * pB[10]) + (pA[15] * pB[14]));
result[3].w = (float)((pA[12] * pB[3]) + (pA[13] * pB[7]) + (pA[14] * pB[11]) + (pA[15] * pB[15]));
}
inline void matrixFullInvert(float4x4& result, const float4x4& mat)
{
// Matrix inversion code from https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
// Alias raw pointers over the input matrix and the result
const float* pMat = &mat[0].x;
float* pResult = &result[0].x;
pResult[0] = pMat[5] * pMat[10] * pMat[15] - pMat[5] * pMat[11] * pMat[14] - pMat[9] * pMat[6] * pMat[15] + pMat[9] * pMat[7] * pMat[14] + pMat[13] * pMat[6] * pMat[11] - pMat[13] * pMat[7] * pMat[10];
pResult[4] = -pMat[4] * pMat[10] * pMat[15] + pMat[4] * pMat[11] * pMat[14] + pMat[8] * pMat[6] * pMat[15] - pMat[8] * pMat[7] * pMat[14] - pMat[12] * pMat[6] * pMat[11] + pMat[12] * pMat[7] * pMat[10];
pResult[8] = pMat[4] * pMat[9] * pMat[15] - pMat[4] * pMat[11] * pMat[13] - pMat[8] * pMat[5] * pMat[15] + pMat[8] * pMat[7] * pMat[13] + pMat[12] * pMat[5] * pMat[11] - pMat[12] * pMat[7] * pMat[9];
pResult[12] = -pMat[4] * pMat[9] * pMat[14] + pMat[4] * pMat[10] * pMat[13] + pMat[8] * pMat[5] * pMat[14] - pMat[8] * pMat[6] * pMat[13] - pMat[12] * pMat[5] * pMat[10] + pMat[12] * pMat[6] * pMat[9];
pResult[1] = -pMat[1] * pMat[10] * pMat[15] + pMat[1] * pMat[11] * pMat[14] + pMat[9] * pMat[2] * pMat[15] - pMat[9] * pMat[3] * pMat[14] - pMat[13] * pMat[2] * pMat[11] + pMat[13] * pMat[3] * pMat[10];
pResult[5] = pMat[0] * pMat[10] * pMat[15] - pMat[0] * pMat[11] * pMat[14] - pMat[8] * pMat[2] * pMat[15] + pMat[8] * pMat[3] * pMat[14] + pMat[12] * pMat[2] * pMat[11] - pMat[12] * pMat[3] * pMat[10];
pResult[9] = -pMat[0] * pMat[9] * pMat[15] + pMat[0] * pMat[11] * pMat[13] + pMat[8] * pMat[1] * pMat[15] - pMat[8] * pMat[3] * pMat[13] - pMat[12] * pMat[1] * pMat[11] + pMat[12] * pMat[3] * pMat[9];
pResult[13] = pMat[0] * pMat[9] * pMat[14] - pMat[0] * pMat[10] * pMat[13] - pMat[8] * pMat[1] * pMat[14] + pMat[8] * pMat[2] * pMat[13] + pMat[12] * pMat[1] * pMat[10] - pMat[12] * pMat[2] * pMat[9];
pResult[2] = pMat[1] * pMat[6] * pMat[15] - pMat[1] * pMat[7] * pMat[14] - pMat[5] * pMat[2] * pMat[15] + pMat[5] * pMat[3] * pMat[14] + pMat[13] * pMat[2] * pMat[7] - pMat[13] * pMat[3] * pMat[6];
pResult[6] = -pMat[0] * pMat[6] * pMat[15] + pMat[0] * pMat[7] * pMat[14] + pMat[4] * pMat[2] * pMat[15] - pMat[4] * pMat[3] * pMat[14] - pMat[12] * pMat[2] * pMat[7] + pMat[12] * pMat[3] * pMat[6];
pResult[10] = pMat[0] * pMat[5] * pMat[15] - pMat[0] * pMat[7] * pMat[13] - pMat[4] * pMat[1] * pMat[15] + pMat[4] * pMat[3] * pMat[13] + pMat[12] * pMat[1] * pMat[7] - pMat[12] * pMat[3] * pMat[5];
pResult[14] = -pMat[0] * pMat[5] * pMat[14] + pMat[0] * pMat[6] * pMat[13] + pMat[4] * pMat[1] * pMat[14] - pMat[4] * pMat[2] * pMat[13] - pMat[12] * pMat[1] * pMat[6] + pMat[12] * pMat[2] * pMat[5];
pResult[3] = -pMat[1] * pMat[6] * pMat[11] + pMat[1] * pMat[7] * pMat[10] + pMat[5] * pMat[2] * pMat[11] - pMat[5] * pMat[3] * pMat[10] - pMat[9] * pMat[2] * pMat[7] + pMat[9] * pMat[3] * pMat[6];
pResult[7] = pMat[0] * pMat[6] * pMat[11] - pMat[0] * pMat[7] * pMat[10] - pMat[4] * pMat[2] * pMat[11] + pMat[4] * pMat[3] * pMat[10] + pMat[8] * pMat[2] * pMat[7] - pMat[8] * pMat[3] * pMat[6];
pResult[11] = -pMat[0] * pMat[5] * pMat[11] + pMat[0] * pMat[7] * pMat[9] + pMat[4] * pMat[1] * pMat[11] - pMat[4] * pMat[3] * pMat[9] - pMat[8] * pMat[1] * pMat[7] + pMat[8] * pMat[3] * pMat[5];
pResult[15] = pMat[0] * pMat[5] * pMat[10] - pMat[0] * pMat[6] * pMat[9] - pMat[4] * pMat[1] * pMat[10] + pMat[4] * pMat[2] * pMat[9] + pMat[8] * pMat[1] * pMat[6] - pMat[8] * pMat[2] * pMat[5];
float det = pMat[0] * pResult[0] + pMat[1] * pResult[4] + pMat[2] * pResult[8] + pMat[3] * pResult[12];
if (det != 0.f)
{
det = 1.0f / det;
for (int i = 0; i < 16; ++i)
{
pResult[i] *= det;
}
}
}
// Specialised lightweight matrix invert when the matrix is known to be orthonormal
inline void matrixOrthoNormalInvert(float4x4& result, const float4x4& mat)
{
// Transpose the first 3x3
result[0].x = mat[0].x;
result[0].y = mat[1].x;
result[0].z = mat[2].x;
result[1].x = mat[0].y;
result[1].y = mat[1].y;
result[1].z = mat[2].y;
result[2].x = mat[0].z;
result[2].y = mat[1].z;
result[2].z = mat[2].z;
// Invert the translation
result[3].x = -((mat[3].x * mat[0].x) + (mat[3].y * mat[0].y) + (mat[3].z * mat[0].z));
result[3].y = -((mat[3].x * mat[1].x) + (mat[3].y * mat[1].y) + (mat[3].z * mat[1].z));
result[3].z = -((mat[3].x * mat[2].x) + (mat[3].y * mat[2].y) + (mat[3].z * mat[2].z));
// Fill in the remaining constants
result[0].w = 0.0f;
result[1].w = 0.0f;
result[2].w = 0.0f;
result[3].w = 1.0f;
}
inline void vectorNormalize(float3& v)
{
float k = 1.f / sqrtf((v.x * v.x) + (v.y * v.y) + (v.z * v.z));
v.x *= k;
v.y *= k;
v.z *= k;
}
inline void vectorCrossProduct(float3& result, const float3& a, const float3& b)
{
result.x = a.y * b.z - a.z * b.y;
result.y = a.z * b.x - a.x * b.z;
result.z = a.x * b.y - a.y * b.x;
}
// Calculate a cameraToPrevCamera matrix from cameraToWorld and cameraToWorldPrev matrices
// but do so in such a way as to avoid precision issues.
//
// Traditionally, you might go something like this...
//
// worldToCameraPrev = invert(cameraToWorldPrev)
// cameraToPrevCamera = cameraToWorld * worldToCameraPrev
//
// But if you do that, you will subject yourself to fp32 precision issues if the camera is
// any kind of reasonable distance from the origin, because you'll end up adding small
// numbers to large numbers due to the large translations.
//
// But the camera's absolute position in the world doesn't matter at all to the result.
// What we're interested in is the camera's motion.
// So if we add the same thing to the translations of cameraToWorld and cameraToWorldPrev
// then we should get the same result.
// If we choose to subtract the current camera's translation in world space, then we will
// change a potentially very large translation value into a very small one - thereby
// sidestepping the precision issues.
inline void calcCameraToPrevCamera(float4x4& outCameraToPrevCamera, const float4x4& cameraToWorld, const float4x4& cameraToWorldPrev)
{
// Create translated versions of cameraToWorld and cameraToWorldPrev, translated to
// so that the current camera is effectively at the world origin.
// CC == 'Camera-Centred'
float4x4 cameraToCcWorld = cameraToWorld;
cameraToCcWorld[3] = float4(0, 0, 0, 1);
float4x4 cameraToCcWorldPrev = cameraToWorldPrev;
cameraToCcWorldPrev[3].x -= cameraToWorld[3].x;
cameraToCcWorldPrev[3].y -= cameraToWorld[3].y;
cameraToCcWorldPrev[3].z -= cameraToWorld[3].z;
// We can use an optimised invert if we assume that the camera matrix is orthonormal
float4x4 ccWorldToCameraPrev;
matrixOrthoNormalInvert(ccWorldToCameraPrev, cameraToCcWorldPrev);
matrixMul(outCameraToPrevCamera, cameraToCcWorld, ccWorldToCameraPrev);
}
// Calculate some of the matrix fields in Constants
// This can be used to validate what the app is providing, or tease out precision issues
// The matrices that are recalculated are...
// - clipToCameraView
// - clipToPrevClip
// - prevClipToClip
inline void recalculateCameraMatrices(Constants& values)
{
// Form a camera-to-world matrix from the camera fields
vectorNormalize(values.cameraRight);
vectorNormalize(values.cameraFwd);
vectorCrossProduct(values.cameraUp, values.cameraFwd, values.cameraRight);
vectorNormalize(values.cameraUp);
float4x4 cameraViewToWorld = {
float4(values.cameraRight.x, values.cameraRight.y, values.cameraRight.z, 0.f),
float4(values.cameraUp.x, values.cameraUp.y, values.cameraUp.z, 0.f),
float4(values.cameraFwd.x, values.cameraFwd.y, values.cameraFwd.z, 0.f),
float4(values.cameraPos.x, values.cameraPos.y, values.cameraPos.z, 1.f)
};
// ********* DO NOT USE THIS IN ANYTHING PROPER *********
// Crap storage of cameraViewToWorldPrev and cameraViewToClipPrev
// These should be provided by the app, or stored by association with the view index.
static float4x4 cameraViewToWorldPrev = {
float4(1, 0, 0, 0),
float4(0, 1, 0, 0),
float4(0, 0, 1, 0),
float4(0, 0, 0, 1),
};
static float4x4 cameraViewToClipPrev = {
float4(1, 0, 0, 0),
float4(0, 1, 0, 0),
float4(0, 0, 1, 0),
float4(0, 0, 0, 1),
};
matrixFullInvert(values.clipToCameraView, values.cameraViewToClip);
float4x4 cameraViewToPrevCameraView;
calcCameraToPrevCamera(cameraViewToPrevCameraView, cameraViewToWorld, cameraViewToWorldPrev);
float4x4 clipToPrevCameraView;
matrixMul(clipToPrevCameraView, values.clipToCameraView, cameraViewToPrevCameraView);
matrixMul(values.clipToPrevClip, clipToPrevCameraView, cameraViewToClipPrev);
matrixFullInvert(values.prevClipToClip, values.clipToPrevClip);
// ********* DO NOT USE THIS IN ANYTHING PROPER *********
cameraViewToWorldPrev = cameraViewToWorld;
cameraViewToClipPrev = values.cameraViewToClip;
}
}
+102
View File
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
namespace sl
{
enum class NISMode : uint32_t
{
eOff,
eScaler,
eSharpen,
eCount
};
enum class NISHDR : uint32_t
{
eNone,
eLinear,
ePQ,
eCount
};
// {676610E5-9674-4D3A-9C8A-F495D01B36F3}
SL_STRUCT_BEGIN(NISOptions, StructType({ 0x676610e5, 0x9674, 0x4d3a, { 0x9c, 0x8a, 0xf4, 0x95, 0xd0, 0x1b, 0x36, 0xf3 } }), kStructVersion1)
//! Specifies which mode should be used
NISMode mode = NISMode::eScaler;
//! Specifies which hdr mode should be used
NISHDR hdrMode = NISHDR::eNone;
//! Specifies sharpening level in range [0,1]
float sharpness = 0.0f;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! Returned by the NIS plugin
//!
// {71AB4FD0-D959-4C2A-AF69-ED4850BD4E3D}
SL_STRUCT_BEGIN(NISState, StructType({ 0x71ab4fd0, 0xd959, 0x4c2a, { 0xaf, 0x69, 0xed, 0x48, 0x50, 0xbd, 0x4e, 0x3d } }), kStructVersion1)
//! Specified the amount of memory expected to be used
uint64_t estimatedVRAMUsageInBytes {};
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
//! Sets NIS options
//!
//! Call this method to turn DLSS on/off, change mode etc.
//!
//! @param viewport Specified viewport we are working with
//! @param options Specifies NIS options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slNISSetOptions = sl::Result(const sl::ViewportHandle& viewport, const sl::NISOptions& options);
//! Provides NIS state for the given viewport
//!
//! Call this method to obtain VRAM usage and other information.
//!
//! @param viewport Specified viewport we are working with
//! @param state Reference to a structure where state is to be returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slNISGetState = sl::Result(const sl::ViewportHandle& viewport, sl::NISState& state);
//! HELPERS
//!
inline sl::Result slNISSetOptions(const sl::ViewportHandle& viewport, const sl::NISOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureNIS, slNISSetOptions);
return s_slNISSetOptions(viewport, options);
}
inline sl::Result slNISGetState(const sl::ViewportHandle& viewport, sl::NISState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureNIS, slNISGetState);
return s_slNISGetState(viewport, state);
}
+70
View File
@@ -0,0 +1,70 @@
/*
* Copyright 2014-2023 NVIDIA Corporation. All rights reserved.
*
* NOTICE TO USER:
*
* This source code is subject to NVIDIA ownership rights under U.S. and
* international Copyright laws.
*
* This software and the information contained herein is PROPRIETARY and
* CONFIDENTIAL to NVIDIA and is being provided under the terms and conditions
* of a form of NVIDIA software license agreement.
*
* NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE
* CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR
* IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
* OR PERFORMANCE OF THIS SOURCE CODE.
*
* U.S. Government End Users. This source code is a "commercial item" as
* that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of
* "commercial computer software" and "commercial computer software
* documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995)
* and is provided to the U.S. Government only as a commercial end item.
* Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through
* 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the
* source code with only those rights set forth herein.
*
* Any use of this source code in individual and commercial software must
* include, in the user documentation and internal comments to the code,
* the above Disclaimer and U.S. Government End Users Notice.
*/
#pragma once
namespace sl
{
//! If your plugin does not have any constants then the code below can be removed
//!
enum class NvPerfMode : uint32_t
{
eOff,
eOn,
eCount
};
//! IMPORTANT: Each structure must have a unique GUID assigned, change this as needed
//!
// {29DF7FE0-273A-4D72-B481-2DC823D5B1AD}
SL_STRUCT_BEGIN(NvPerfConstants, StructType({ 0x29df7fe0, 0x273a, 0x4d72, { 0xb4, 0x81, 0x2d, 0xc8, 0x23, 0xd5, 0xb1, 0xad } }), kStructVersion1)
NvPerfMode mode = NvPerfMode::eOff;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! IMPORTANT: Each structure must have a unique GUID assigned, change this as needed
//!
// {39DF7FE0-283A-4D72-B481-2DC823D5B1AD}
SL_STRUCT_BEGIN(NvPerfSettings, StructType({ 0x39df7fe0, 0x283a, 0x4d72, { 0xb4, 0x81, 0x2d, 0xc8, 0x23, 0xd5, 0xb1, 0xad } }), kStructVersion1)
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
+158
View File
@@ -0,0 +1,158 @@
/*
* Copyright (c) 2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <cassert>
namespace sl
{
//! Hot-key which should be used instead of custom message for PC latency marker
enum class PCLHotKey: int16_t
{
eUsePingMessage = 0,
eVK_F13 = 0x7C,
eVK_F14 = 0x7D,
eVK_F15 = 0x7E,
};
// {cfa32f9b-023c-420e-9056-6832b74f89b4}
SL_STRUCT_BEGIN(PCLOptions, StructType({ 0xcfa32f9b, 0x023c, 0x420e, { 0x90, 0x56, 0x68, 0x32, 0xb7, 0x4f, 0x89, 0xb4 } }), kStructVersion1)
//! Specifies the hot-key which should be used instead of custom message for PC latency marker
//! Possible values: VK_F13, VK_F14, VK_F15
PCLHotKey virtualKey = PCLHotKey::eUsePingMessage;
//! ThreadID for PCL messages
uint32_t idThread = 0;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
// {cfa32f9b-023c-420e-9056-6832b74f89b5}
SL_STRUCT_BEGIN(PCLState, StructType({ 0xcfa32f9b, 0x023c, 0x420e, { 0x90, 0x56, 0x68, 0x32, 0xb7, 0x4f, 0x89, 0xb5 } }), kStructVersion1)
//! Specifies PCL Windows message id (if PCLOptions::virtualKey is 0)
uint32_t statsWindowMessage;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
enum class PCLMarker: uint32_t
{
eSimulationStart = 0,
eSimulationEnd = 1,
eRenderSubmitStart = 2,
eRenderSubmitEnd = 3,
ePresentStart = 4,
ePresentEnd = 5,
//eInputSample = 6, // Deprecated
eTriggerFlash = 7,
ePCLatencyPing = 8,
eOutOfBandRenderSubmitStart = 9,
eOutOfBandRenderSubmitEnd = 10,
eOutOfBandPresentStart = 11,
eOutOfBandPresentEnd = 12,
eControllerInputSample = 13,
eDeltaTCalculation = 14,
eLateWarpPresentStart = 15,
eLateWarpPresentEnd = 16,
eCameraConstructed = 17,
eLateWarpRenderSubmitStart = 18,
eLateWarpRenderSubmitEnd = 19,
eMaximum
};
// c++23 has to_underlying implementation
#if __cplusplus == 202302L
using to_underlying = std::to_underlying;
#else
// Return `enum class` member as value of underlying type (i.e. an int). Basically same as:
// static_cast<std::underlying_type_t<decltype(value)>>(value);
// See c++23s std::to_underlying()
template<class T>
constexpr auto to_underlying(T value)
{
return std::underlying_type_t<T>(value);
}
#endif
// {cfa32f9b-023c-420e-9056-6832b74f89b6}
SL_STRUCT_BEGIN(PCLHelper, StructType({ 0xcfa32f9b, 0x023c, 0x420e, { 0x90, 0x56, 0x68, 0x32, 0xb7, 0x4f, 0x89, 0xb6 } }), kStructVersion1)
PCLHelper(PCLMarker m) : BaseStructure(PCLHelper::s_structType, kStructVersion1), marker(m) {};
PCLMarker get() const { return marker; };
private:
PCLMarker marker;
SL_STRUCT_END()
}
//! Provides PCL settings
//!
//! Call this method to get stats etc.
//!
//! @param state Reference to a structure where states are returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slPCLGetState = sl::Result(sl::PCLState& state);
//! Sets PCL marker
//!
//! Call this method to set specific PCL marker
//!
//! @param marker Specifies which marker to use
//! @param frame Specifies current frame
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe.
using PFun_slPCLSetMarker = sl::Result(sl::PCLMarker marker, const sl::FrameToken& frame);
//! Sets PCL options
//!
//! Call this method to set PCL options.
//!
//! @param options Specifies options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slPCLSetOptions = sl::Result(const sl::PCLOptions& options);
//! HELPERS
//!
inline sl::Result slPCLGetState(sl::PCLState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeaturePCL, slPCLGetState);
return s_slPCLGetState(state);
}
inline sl::Result slPCLSetMarker(sl::PCLMarker marker, const sl::FrameToken& frame)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeaturePCL, slPCLSetMarker);
return s_slPCLSetMarker(marker, frame);
}
inline sl::Result slPCLSetOptions(const sl::PCLOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeaturePCL, slPCLSetOptions);
return s_slPCLSetOptions(options);
}
+233
View File
@@ -0,0 +1,233 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include "sl_pcl.h"
namespace sl
{
enum ReflexMode
{
eOff,
eLowLatency,
eLowLatencyWithBoost,
// ReflexMode is a C-enum (rather than enum class) so we can't add an eCount value
// without polluting the global namespace (and conflicts with SMSCGMode::eCount in sl.dlss_g/defines.h)
ReflexMode_eCount
};
// {F03AF81A-6D0B-4902-A651-C4965E215434}
SL_STRUCT_BEGIN(ReflexOptions, StructType({ 0xf03af81a, 0x6d0b, 0x4902, { 0xa6, 0x51, 0xc4, 0x96, 0x5e, 0x21, 0x54, 0x34 } }), kStructVersion1)
//! Specifies which mode should be used
ReflexMode mode = ReflexMode::eOff;
//! Specifies if frame limiting (FPS cap) is enabled (0 to disable, microseconds otherwise).
//! One benefit of using Reflex's FPS cap over other implementations is the driver would be aware and can provide better optimizations.
//! This setting is independent of ReflexOptions::mode; it can even be used with mode == ReflexMode::eOff.
//! The value is used each time you call slReflexSetOptions/slSetData, make sure to initialize when changing one of the other Reflex options during frame limiting.
//! It is overridden (ignored) by frameLimitUs if set in sl.reflex.json in non-production builds.
uint32_t frameLimitUs = 0;
//! This should only be enabled in specific scenarios with subtle caveats.
//! Most integrations should leave unset unless advised otherwise by the Reflex team
bool useMarkersToOptimize = false;
//! Specifies the hot-key which should be used instead of custom message for PC latency marker
//! Possible values: VK_F13, VK_F14, VK_F15
uint16_t virtualKey = 0;
//! ThreadID for PCL Stats messages
//! Most integrations should leave unset unless advised otherwise by the Reflex team
uint32_t idThread = 0;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
// {0D569B37-A1C8-4453-BE4D-40F4DE57952B}
SL_STRUCT_BEGIN(ReflexReport, StructType({ 0xd569b37, 0xa1c8, 0x4453, { 0xbe, 0x4d, 0x40, 0xf4, 0xde, 0x57, 0x95, 0x2b } }), kStructVersion1)
//! Various latency related stats
uint64_t frameID{};
uint64_t inputSampleTime{};
uint64_t simStartTime{};
uint64_t simEndTime{};
uint64_t renderSubmitStartTime{};
uint64_t renderSubmitEndTime{};
uint64_t presentStartTime{};
uint64_t presentEndTime{};
uint64_t driverStartTime{};
uint64_t driverEndTime{};
uint64_t osRenderQueueStartTime{};
uint64_t osRenderQueueEndTime{};
uint64_t gpuRenderStartTime{};
uint64_t gpuRenderEndTime{};
uint32_t gpuActiveRenderTimeUs{};
uint32_t gpuFrameTimeUs{};
//! IMPORTANT: This struct cannot have new members because it is arrayed by ReflexState.
SL_STRUCT_END()
// {68bb0632-5e1c-402b-899d-b49f633c56c2}
SL_STRUCT_BEGIN(ReflexReport2, StructType({ 0x68bb0632, 0x5e1c, 0x402b, { 0x89, 0x9d, 0xb4, 0x9f, 0x63, 0x3c, 0x56, 0xc2 } }), kStructVersion1)
//! Various latency related stats
uint64_t cameraConstructedTime{};
uint32_t crossAdapterCopyTimeUs{};
//! IMPORTANT: This struct cannot have new members because it is arrayed by ReflexState.
SL_STRUCT_END()
constexpr int kReflexFrameReportCount = 64;
// {F0BB5985-DAF9-4728-B2FD-AE80A2BD7989}
SL_STRUCT_BEGIN(ReflexState, StructType({ 0xf0bb5985, 0xdaf9, 0x4728, { 0xb2, 0xfd, 0xae, 0x80, 0xa2, 0xbd, 0x79, 0x89 } }), kStructVersion2)
//! Specifies if low-latency mode is available or not
bool lowLatencyAvailable = false;
//! Specifies if the frameReport below contains valid data or not
bool latencyReportAvailable = false;
//! Specifies low latency Windows message id (if ReflexOptions::virtualKey is 0)
uint32_t statsWindowMessage;
//! Reflex report per frame
ReflexReport frameReport[kReflexFrameReportCount];
//! Specifies ownership of flash indicator toggle (true = driver, false = application)
bool flashIndicatorDriverControlled = false;
// kStructVersion2
//! Reflex report per frame
ReflexReport2 frameReport2[kReflexFrameReportCount];
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
// {c83cbb02-b4e2-4260-9ca2-d0c3de3a9684}
SL_STRUCT_BEGIN(ReflexCameraData, StructType({ 0xc83cbb02, 0xb4e2, 0x4260, { 0x9c, 0xa2, 0xd0, 0xc3, 0xde, 0x3a, 0x96, 0x84 } }), kStructVersion1)
float4x4 worldToViewMatrix;
float4x4 viewToClipMatrix;
float4x4 prevRenderedWorldToViewMatrix;
float4x4 prevRenderedViewToClipMatrix;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
// {8b960090-a807-4c85-b02f-1069950d066c}
SL_STRUCT_BEGIN(ReflexPredictedCameraData, StructType({ 0x8b960090, 0xa807, 0x4c85, { 0xb0, 0x2f, 0x10, 0x69, 0x95, 0x0d, 0x06, 0x6c } }), kStructVersion1)
float4x4 predictedWorldToViewMatrix;
float4x4 predictedViewToClipMatrix;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
using MarkerUnderlying = std::underlying_type_t<PCLMarker>;
// {E268B3DC-F963-4C37-9776-AF048E132621}
SL_STRUCT_BEGIN(ReflexHelper, StructType({ 0xe268b3dc, 0xf963, 0x4c37, { 0x97, 0x76, 0xaf, 0x4, 0x8e, 0x13, 0x26, 0x21 } }), kStructVersion1)
ReflexHelper(MarkerUnderlying m) : BaseStructure(ReflexHelper::s_structType, kStructVersion1), marker(m) {};
ReflexHelper(PCLMarker m) : BaseStructure(ReflexHelper::s_structType, kStructVersion1), marker(to_underlying(m)) {};
operator MarkerUnderlying () const { return marker; };
private:
// May be kReflexMarkerSleep which is not a valid PCLMarker value
MarkerUnderlying marker;
SL_STRUCT_END()
}
//! Provides Reflex settings
//!
//! Call this method to check if Reflex is on, get stats etc.
//!
//! @param state Reference to a structure where states are returned
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slReflexGetState = sl::Result(sl::ReflexState& state);
//! Tells reflex to sleep the app
//!
//! Call this method to invoke Reflex sleep in your application.
//!
//! @param frame Specifies current frame
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe.
using PFun_slReflexSleep = sl::Result(const sl::FrameToken& frame);
//! Sets Reflex options
//!
//! Call this method to turn Reflex on/off, change mode etc.
//!
//! @param options Specifies options to use
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is NOT thread safe.
using PFun_slReflexSetOptions = sl::Result(const sl::ReflexOptions& options);
//! Sets Reflex camera data
//!
//! Call this method to inform Reflex of upcoming camera data
//!
//! @param viewport The viewport the camera corresponds to
//! @param frame The frame to set camera data for
//! @param inCameraData Camera data for an upcoming render frame
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe.
using PFun_slReflexSetCameraData = sl::Result(const sl::ViewportHandle& viewport, const sl::FrameToken& frame, const sl::ReflexCameraData& inCameraData);
//! Gets predicted Reflex camera data
//!
//! Call this method to get a prediction of upcoming camera data
//!
//! @param viewport The viewport the camera corresponds to
//! @param frame The frame to get camera data for (if available)
//! @param outCameraData Predicted Camera data for an upcoming render frame
//! @return sl::ResultCode::eOk if successful, error code otherwise (see sl_result.h for details)
//!
//! This method is thread safe.
using PFun_slReflexGetPredictedCameraData = sl::Result(const sl::ViewportHandle& viewport, const sl::FrameToken& frame, sl::ReflexPredictedCameraData& outCameraData);
//! HELPERS
//!
inline sl::Result slReflexGetState(sl::ReflexState& state)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureReflex, slReflexGetState);
return s_slReflexGetState(state);
}
inline sl::Result slReflexSleep(const sl::FrameToken& frame)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureReflex, slReflexSleep);
return s_slReflexSleep(frame);
}
inline sl::Result slReflexSetOptions(const sl::ReflexOptions& options)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureReflex, slReflexSetOptions);
return s_slReflexSetOptions(options);
}
inline sl::Result slReflexSetCameraData(const sl::ViewportHandle& viewport, const sl::FrameToken& frame, const sl::ReflexCameraData& inCameraData)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureReflex, slReflexSetCameraData);
return s_slReflexSetCameraData(viewport, frame, inCameraData);
}
inline sl::Result slReflexGetPredictedCameraData(const sl::ViewportHandle& viewport, const sl::FrameToken& frame, sl::ReflexPredictedCameraData& outCameraData)
{
SL_FEATURE_FUN_IMPORT_STATIC(sl::kFeatureReflex, slReflexGetPredictedCameraData);
return s_slReflexGetPredictedCameraData(viewport, frame, outCameraData);
}
+77
View File
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2022-2024 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#define SL_CHECK(f) {auto _r = f; if(_r != sl::Result::eOk) return _r;}
#define SL_FAILED(r, f) sl::Result r = f; r != sl::Result::eOk
#define SL_SUCCEEDED(r, f) sl::Result r = f; r == sl::Result::eOk
namespace sl
{
enum class Result
{
eOk,
eErrorIO,
eErrorDriverOutOfDate,
eErrorOSOutOfDate,
eErrorOSDisabledHWS,
eErrorDeviceNotCreated,
eErrorNoSupportedAdapterFound,
eErrorAdapterNotSupported,
eErrorNoPlugins,
eErrorVulkanAPI,
eErrorDXGIAPI,
eErrorD3DAPI,
// NRD was removed
eErrorNRDAPI,
eErrorNVAPI,
eErrorReflexAPI,
eErrorNGXFailed,
eErrorJSONParsing,
eErrorMissingProxy,
eErrorMissingResourceState,
eErrorInvalidIntegration,
eErrorMissingInputParameter,
eErrorNotInitialized,
eErrorComputeFailed,
eErrorInitNotCalled,
eErrorExceptionHandler,
eErrorInvalidParameter,
eErrorMissingConstants,
eErrorDuplicatedConstants,
eErrorMissingOrInvalidAPI,
eErrorCommonConstantsMissing,
eErrorUnsupportedInterface,
eErrorFeatureMissing,
eErrorFeatureNotSupported,
eErrorFeatureMissingHooks,
eErrorFeatureFailedToLoad,
eErrorFeatureWrongPriority,
eErrorFeatureMissingDependency,
eErrorFeatureManagerInvalidState,
eErrorInvalidState,
eWarnOutOfVRAM
};
}
+463
View File
@@ -0,0 +1,463 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#define _UNICODE 1
#define UNICODE 1
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Softpub.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <inttypes.h>
#define GetProc(hModule, procName, proc) (((NULL == proc) && (NULL == (*((FARPROC*)&proc) = GetProcAddress(hModule, procName)))) ? FALSE : TRUE)
typedef BOOL(WINAPI* PfnCryptMsgClose)(IN HCRYPTMSG hCryptMsg);
static PfnCryptMsgClose pfnCryptMsgClose = NULL;
typedef BOOL(WINAPI* PfnCertCloseStore)(IN HCERTSTORE hCertStore, DWORD dwFlags);
static PfnCertCloseStore pfnCertCloseStore = NULL;
typedef HCERTSTORE (WINAPI* PfnCertOpenStore)(
_In_ LPCSTR lpszStoreProvider,
_In_ DWORD dwEncodingType,
_In_opt_ HCRYPTPROV_LEGACY hCryptProv,
_In_ DWORD dwFlags,
_In_opt_ const void* pvPara
);
static PfnCertOpenStore pfnCertOpenStore = NULL;
typedef BOOL(WINAPI* PfnCertFreeCertificateContext)(IN PCCERT_CONTEXT pCertContext);
static PfnCertFreeCertificateContext pfnCertFreeCertificateContext = NULL;
typedef PCCERT_CONTEXT(WINAPI* PfnCertFindCertificateInStore)(
IN HCERTSTORE hCertStore,
IN DWORD dwCertEncodingType,
IN DWORD dwFindFlags,
IN DWORD dwFindType,
IN const void* pvFindPara,
IN PCCERT_CONTEXT pPrevCertContext
);
static PfnCertFindCertificateInStore pfnCertFindCertificateInStore = NULL;
typedef BOOL(WINAPI* PfnCryptMsgGetParam)(
IN HCRYPTMSG hCryptMsg,
IN DWORD dwParamType,
IN DWORD dwIndex,
OUT void* pvData,
IN OUT DWORD* pcbData
);
static PfnCryptMsgGetParam pfnCryptMsgGetParam = NULL;
typedef HCRYPTMSG (WINAPI* PfnCryptMsgOpenToDecode)(
_In_ DWORD dwMsgEncodingType,
_In_ DWORD dwFlags,
_In_ DWORD dwMsgType,
_In_opt_ HCRYPTPROV_LEGACY hCryptProv,
_Reserved_ PCERT_INFO pRecipientInfo,
_In_opt_ PCMSG_STREAM_INFO pStreamInfo
);
PfnCryptMsgOpenToDecode pfnCryptMsgOpenToDecode = {};
typedef BOOL (WINAPI* PfnCryptMsgUpdate)(
_In_ HCRYPTMSG hCryptMsg,
_In_reads_bytes_opt_(cbData) const BYTE* pbData,
_In_ DWORD cbData,
_In_ BOOL fFinal
);
PfnCryptMsgUpdate pfnCryptMsgUpdate = {};
typedef BOOL(WINAPI* PfnCryptQueryObject)(
DWORD dwObjectType,
const void* pvObject,
DWORD dwExpectedContentTypeFlags,
DWORD dwExpectedFormatTypeFlags,
DWORD dwFlags,
DWORD* pdwMsgAndCertEncodingType,
DWORD* pdwContentType,
DWORD* pdwFormatType,
HCERTSTORE* phCertStore,
HCRYPTMSG* phMsg,
const void** ppvContext
);
static PfnCryptQueryObject pfnCryptQueryObject = NULL;
typedef BOOL(WINAPI* PfnCryptDecodeObjectEx)(
IN DWORD dwCertEncodingType,
IN LPCSTR lpszStructType,
IN const BYTE* pbEncoded,
IN DWORD cbEncoded,
IN DWORD dwFlags,
IN PCRYPT_DECODE_PARA pDecodePara,
OUT void* pvStructInfo,
IN OUT DWORD* pcbStructInfo
);
static PfnCryptDecodeObjectEx pfnCryptDecodeObjectEx = NULL;
typedef LONG(WINAPI* PfnWinVerifyTrust)(
IN HWND hwnd,
IN GUID* pgActionID,
IN LPVOID pWVTData
);
static PfnWinVerifyTrust pfnWinVerifyTrust = NULL;
namespace sl
{
namespace security
{
bool isSignedByNVIDIA(const wchar_t* pathToFile)
{
bool valid = false;
// Now let's make sure this is actually signed by NVIDIA
DWORD dwEncoding, dwContentType, dwFormatType;
HCERTSTORE hStore = NULL;
HCRYPTMSG hMsg = NULL;
PCMSG_SIGNER_INFO pSignerInfo = NULL;
DWORD dwSignerInfo;
if (!pfnCertOpenStore)
{
// We only support Win10+ so we can search for module in system32 directly
auto hModCrypt32 = LoadLibraryExW(L"crypt32.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!hModCrypt32 ||
!GetProc(hModCrypt32, "CryptMsgClose", pfnCryptMsgClose) ||
!GetProc(hModCrypt32, "CertOpenStore", pfnCertOpenStore) ||
!GetProc(hModCrypt32, "CertCloseStore", pfnCertCloseStore) ||
!GetProc(hModCrypt32, "CertFreeCertificateContext", pfnCertFreeCertificateContext) ||
!GetProc(hModCrypt32, "CertFindCertificateInStore", pfnCertFindCertificateInStore) ||
!GetProc(hModCrypt32, "CryptMsgGetParam", pfnCryptMsgGetParam) ||
!GetProc(hModCrypt32, "CryptMsgUpdate", pfnCryptMsgUpdate) ||
!GetProc(hModCrypt32, "CryptMsgOpenToDecode", pfnCryptMsgOpenToDecode) ||
!GetProc(hModCrypt32, "CryptQueryObject", pfnCryptQueryObject) ||
!GetProc(hModCrypt32, "CryptDecodeObjectEx", pfnCryptDecodeObjectEx))
{
return false;
}
}
// Get message handle and store handle from the signed file.
auto bResult = pfnCryptQueryObject(CERT_QUERY_OBJECT_FILE,
pathToFile,
CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
CERT_QUERY_FORMAT_FLAG_BINARY,
0,
&dwEncoding,
&dwContentType,
&dwFormatType,
&hStore,
&hMsg,
NULL);
if (!bResult)
{
return false;
}
// Get signer information size.
bResult = pfnCryptMsgGetParam(hMsg,
CMSG_SIGNER_INFO_PARAM,
0,
NULL,
&dwSignerInfo);
if (!bResult)
{
return false;
}
// Allocate memory for signer information.
pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
if (!pSignerInfo)
{
return false;
}
// Get Signer Information.
bResult = pfnCryptMsgGetParam(hMsg,
CMSG_SIGNER_INFO_PARAM,
0,
(PVOID)pSignerInfo,
&dwSignerInfo);
if (!bResult)
{
LocalFree(pSignerInfo);
return false;
}
// Look for nested signature
constexpr const char* kOID_NESTED_SIGNATURE = "1.3.6.1.4.1.311.2.4.1";
for (DWORD i = 0; i < pSignerInfo->UnauthAttrs.cAttr; i++)
{
if (strcmp(kOID_NESTED_SIGNATURE, pSignerInfo->UnauthAttrs.rgAttr[i].pszObjId) == 0)
{
HCRYPTMSG hMsg2 = pfnCryptMsgOpenToDecode(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, 0, NULL, NULL, NULL);
if (hMsg2)
{
if (pfnCryptMsgUpdate(hMsg2,pSignerInfo->UnauthAttrs.rgAttr[i].rgValue->pbData,pSignerInfo->UnauthAttrs.rgAttr[i].rgValue->cbData,TRUE))
{
dwSignerInfo = 0;
pfnCryptMsgGetParam(hMsg2, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo);
if (dwSignerInfo != 0)
{
PCMSG_SIGNER_INFO pSignerInfo2 = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo);
if (pSignerInfo2)
{
if (pfnCryptMsgGetParam(hMsg2, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo2, &dwSignerInfo))
{
CRYPT_DATA_BLOB c7Data;
c7Data.pbData = pSignerInfo->UnauthAttrs.rgAttr[i].rgValue->pbData;
c7Data.cbData = pSignerInfo->UnauthAttrs.rgAttr[i].rgValue->cbData;
auto hStore2 = pfnCertOpenStore(CERT_STORE_PROV_PKCS7, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, 0, &c7Data);
if (!hStore2)
{
LocalFree(pSignerInfo2);
return false;
}
CERT_INFO CertInfo{};
PCCERT_CONTEXT pCertContext = NULL;
// Search for the signer certificate in the temporary certificate store.
CertInfo.Issuer = pSignerInfo2->Issuer;
CertInfo.SerialNumber = pSignerInfo2->SerialNumber;
pCertContext = pfnCertFindCertificateInStore(hStore2,
(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING),
0,
CERT_FIND_SUBJECT_CERT,
(PVOID)&CertInfo,
NULL);
if (!pCertContext)
{
LocalFree(pSignerInfo2);
pfnCertCloseStore(hStore2, CERT_CLOSE_STORE_FORCE_FLAG);
return false;
}
void* decodedPublicKey{};
DWORD decodedPublicLength{};
if (pfnCryptDecodeObjectEx((PKCS_7_ASN_ENCODING | X509_ASN_ENCODING),
CNG_RSA_PUBLIC_KEY_BLOB,
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG,
NULL,
&decodedPublicKey,
&decodedPublicLength))
{
static uint8_t s_rsaStreamlinePublicKey[] =
{
0x52, 0x53, 0x41, 0x31, 0x00, 0x0c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc1, 0x8e, 0x40, 0xc3, 0xf5,
0xa7, 0x01, 0x9a, 0x37, 0x6b, 0x47, 0xa8, 0x58, 0xe8, 0xbe, 0xe3, 0x55, 0x0a, 0xee, 0x0f, 0x0d,
0x32, 0xaa, 0x12, 0xf9, 0x56, 0x7f, 0x5d, 0xfd, 0x82, 0x09, 0x33, 0x21, 0x42, 0xf2, 0xe8, 0x74,
0x98, 0x51, 0xb3, 0x88, 0x74, 0xcd, 0x00, 0x6e, 0xb1, 0x08, 0x10, 0x4b, 0xf1, 0xda, 0xd6, 0x97,
0x87, 0xd4, 0x9c, 0xb1, 0x13, 0xa8, 0xa2, 0x86, 0x15, 0x0e, 0xc1, 0xa5, 0x9c, 0xe5, 0x90, 0x9b,
0xbe, 0x69, 0xdc, 0x6a, 0x82, 0xbe, 0xb4, 0x4b, 0x4b, 0xfa, 0x95, 0x8e, 0xc1, 0xfc, 0x2b, 0x61,
0x95, 0xd1, 0x91, 0xed, 0xeb, 0x87, 0xe7, 0x09, 0x84, 0x05, 0x41, 0x03, 0xb0, 0x2d, 0xd4, 0x39,
0x7f, 0x62, 0x06, 0x56, 0x33, 0x93, 0x7e, 0x77, 0x54, 0x06, 0x77, 0x2b, 0x75, 0x05, 0xbc, 0xeb,
0x98, 0xea, 0xc0, 0xa2, 0xca, 0x98, 0x86, 0x0f, 0x10, 0x65, 0xde, 0x19, 0x2c, 0xa6, 0x1e, 0x93,
0xb0, 0x92, 0x5d, 0x5f, 0x5b, 0x6f, 0x79, 0x6d, 0x2c, 0x76, 0xa6, 0x67, 0x50, 0xaa, 0x8f, 0xc2,
0x4c, 0xf1, 0x08, 0xf7, 0xc0, 0x27, 0x29, 0xf0, 0x68, 0xf4, 0x64, 0x00, 0x1c, 0xb6, 0x28, 0x1e,
0x25, 0xb8, 0xf3, 0x8a, 0xd1, 0x6e, 0x65, 0xa3, 0x61, 0x9d, 0xf8, 0xca, 0x4a, 0x41, 0x60, 0x80,
0x62, 0xdf, 0x41, 0xa4, 0x8b, 0xdc, 0x97, 0xee, 0xeb, 0x64, 0x6f, 0xe4, 0x8f, 0x4b, 0xdf, 0x24,
0x01, 0x80, 0xd9, 0xb4, 0x0a, 0xec, 0x0d, 0x3e, 0xb7, 0x76, 0xba, 0xe9, 0xe7, 0xde, 0x07, 0xdd,
0x30, 0xc8, 0x4a, 0x14, 0x79, 0xec, 0x15, 0xed, 0x5c, 0xc6, 0xcc, 0xd4, 0xe6, 0x06, 0x3c, 0x42,
0x92, 0x10, 0xf7, 0x7c, 0x80, 0x1e, 0x78, 0xd3, 0xb4, 0x9f, 0xc2, 0x3b, 0xa8, 0x7b, 0xa0, 0xe3,
0x0c, 0xd9, 0xad, 0x2e, 0x09, 0x72, 0xe2, 0x8f, 0x54, 0x28, 0x87, 0x3c, 0xba, 0x7c, 0x97, 0x80,
0xdc, 0x09, 0xb5, 0x12, 0x34, 0x78, 0x9a, 0x26, 0xd0, 0xa3, 0xa7, 0xa7, 0x1b, 0x25, 0x19, 0xe5,
0x6e, 0xbe, 0xd7, 0x5a, 0x91, 0x32, 0xc4, 0xa9, 0x2f, 0xcc, 0xd5, 0x82, 0x4b, 0x5b, 0x9f, 0xad,
0xf3, 0x2f, 0xed, 0x4f, 0x33, 0xe1, 0x50, 0x33, 0xd6, 0x90, 0x79, 0x22, 0xe5, 0x1c, 0xc7, 0x35,
0xe7, 0x58, 0xe6, 0xb4, 0x8b, 0xc4, 0x28, 0x20, 0xec, 0xca, 0x70, 0xbb, 0x02, 0x1b, 0x48, 0xd8,
0x84, 0x51, 0x24, 0x33, 0x2a, 0x08, 0xb1, 0x15, 0x4e, 0xbc, 0x88, 0xa5, 0xe1, 0x37, 0x76, 0x70,
0xe6, 0xdf, 0x3f, 0x73, 0xfd, 0x0d, 0x8a, 0xd9, 0x0d, 0xa5, 0x35, 0xb2, 0xb4, 0x01, 0x42, 0x96,
0xc4, 0xaa, 0x1c, 0xeb, 0x68, 0x62, 0x36, 0xbf, 0xef, 0x5e, 0x2a, 0x3d, 0x18, 0x91, 0x8b, 0x92,
0x0a, 0x1e, 0xce, 0x98, 0x5b, 0x7b, 0x64, 0x42, 0x09, 0xb0, 0x1d
};
valid = decodedPublicLength == sizeof(s_rsaStreamlinePublicKey) && memcmp(s_rsaStreamlinePublicKey, decodedPublicKey, decodedPublicLength) == 0;
LocalFree(decodedPublicKey);
}
pfnCertFreeCertificateContext(pCertContext);
pfnCertCloseStore(hStore2, CERT_CLOSE_STORE_FORCE_FLAG);
}
LocalFree(pSignerInfo2);
}
}
}
pfnCryptMsgClose(hMsg2);
}
break;
}
}
LocalFree(pSignerInfo);
pfnCryptMsgClose(hMsg);
pfnCertCloseStore(hStore, CERT_CLOSE_STORE_FORCE_FLAG);
return valid;
}
//! See https://docs.microsoft.com/en-us/windows/win32/seccrypto/example-c-program--verifying-the-signature-of-a-pe-file
//!
//! IMPORTANT: Always pass in the FULL PATH to the file, relative paths are NOT allowed!
bool verifyEmbeddedSignature(const wchar_t* pathToFile)
{
bool valid = true;
LONG lStatus = {};
// Initialize the WINTRUST_FILE_INFO structure.
WINTRUST_FILE_INFO FileData;
memset(&FileData, 0, sizeof(FileData));
FileData.cbStruct = sizeof(WINTRUST_FILE_INFO);
FileData.pcwszFilePath = pathToFile;
FileData.hFile = NULL;
FileData.pgKnownSubject = NULL;
if (!pfnWinVerifyTrust)
{
// We only support Win10+ so we can search for module in system32 directly
auto hModWintrust = LoadLibraryExW(L"wintrust.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
if (!hModWintrust || !GetProc(hModWintrust, "WinVerifyTrust", pfnWinVerifyTrust))
{
return false;
}
}
/*
WVTPolicyGUID specifies the policy to apply on the file
WINTRUST_ACTION_GENERIC_VERIFY_V2 policy checks:
1) The certificate used to sign the file chains up to a root
certificate located in the trusted root certificate store. This
implies that the identity of the publisher has been verified by
a certification authority.
2) In cases where user interface is displayed (which this example
does not do), WinVerifyTrust will check for whether the
end entity certificate is stored in the trusted publisher store,
implying that the user trusts content from this publisher.
3) The end entity certificate has sufficient permission to sign
code, as indicated by the presence of a code signing EKU or no
EKU.
*/
GUID WVTPolicyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_DATA WinTrustData;
// Initialize the WinVerifyTrust input data structure.
// Default all fields to 0.
memset(&WinTrustData, 0, sizeof(WinTrustData));
WinTrustData.cbStruct = sizeof(WinTrustData);
// Use default code signing EKU.
WinTrustData.pPolicyCallbackData = NULL;
// No data to pass to SIP.
WinTrustData.pSIPClientData = NULL;
// Disable WVT UI.
WinTrustData.dwUIChoice = WTD_UI_NONE;
// No revocation checking.
WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
// Verify an embedded signature on a file.
WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
// Verify action.
WinTrustData.dwStateAction = WTD_STATEACTION_VERIFY;
// Verification sets this value.
WinTrustData.hWVTStateData = NULL;
// Not used.
WinTrustData.pwszURLReference = NULL;
// This is not applicable if there is no UI because it changes
// the UI to accommodate running applications instead of
// installing applications.
WinTrustData.dwUIContext = 0;
// Set pFile.
WinTrustData.pFile = &FileData;
// First verify the primary signature (index 0) to determine how many secondary signatures
// are present. We use WSS_VERIFY_SPECIFIC and dwIndex to do this, also setting
// WSS_GET_SECONDARY_SIG_COUNT to have the number of secondary signatures returned.
WINTRUST_SIGNATURE_SETTINGS SignatureSettings = {};
CERT_STRONG_SIGN_PARA StrongSigPolicy = {};
SignatureSettings.cbStruct = sizeof(WINTRUST_SIGNATURE_SETTINGS);
SignatureSettings.dwFlags = WSS_GET_SECONDARY_SIG_COUNT | WSS_VERIFY_SPECIFIC;
SignatureSettings.dwIndex = 0;
WinTrustData.pSignatureSettings = &SignatureSettings;
StrongSigPolicy.cbSize = sizeof(CERT_STRONG_SIGN_PARA);
StrongSigPolicy.dwInfoChoice = CERT_STRONG_SIGN_OID_INFO_CHOICE;
StrongSigPolicy.pszOID = (LPSTR)szOID_CERT_STRONG_SIGN_OS_CURRENT;
WinTrustData.pSignatureSettings->pCryptoPolicy = &StrongSigPolicy;
// WinVerifyTrust verifies signatures as specified by the GUID and Wintrust_Data.
lStatus = pfnWinVerifyTrust(NULL, &WVTPolicyGUID, &WinTrustData);
// First signature must be validated by the OS
valid = lStatus == ERROR_SUCCESS;
if (!valid)
{
printf("File '%S' is NOT correctly signed - Streamline will not load unsecured modules\n", pathToFile);
}
else
{
// Now there has to be a secondary one
valid &= WinTrustData.pSignatureSettings->cSecondarySigs == 1;
if (!valid)
{
printf("File '%S' does not have the secondary NVIDIA signature - Streamline will not load unsecured modules\n", pathToFile);
}
else
{
// The secondary signature must be from NVIDIA
valid &= isSignedByNVIDIA(pathToFile);
if (valid)
{
printf("File '%S' is signed by NVIDIA and the signature was verified.\n", pathToFile);
}
else
{
printf("File '%S' is NOT correctly signed - Streamline will not load unsecured modules\n", pathToFile);
}
}
}
// Any hWVTStateData must be released by a call with close.
WinTrustData.dwStateAction = WTD_STATEACTION_CLOSE;
lStatus = pfnWinVerifyTrust(NULL, &WVTPolicyGUID, &WinTrustData);
return valid;
}
}
}
+139
View File
@@ -0,0 +1,139 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#include <stdint.h>
#include <string.h>
namespace sl
{
//! GUID
struct StructType
{
uint32_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[8];
inline bool operator==(const StructType& rhs) const { return memcmp(this, &rhs, sizeof(*this)) == 0; }
inline bool operator!=(const StructType& rhs) const { return memcmp(this, &rhs, sizeof(*this)) != 0; }
};
//! SL is using typed and versioned structures which can be chained or not.
//!
//! --- OPTION 1 ---
//!
//! New members must be added at the end and version needs to be increased:
//!
//! SL_STRUCT_BEGIN(S1, GUID1, kStructVersion1)
//! A
//! B
//! C
//! SL_STRUCT_END()
//!
//! SL_STRUCT_BEGIN(S1, GUID1, kStructVersion2) // Note that version is bumped
//! // V1
//! A
//! B
//! C
//!
//! //! V2 - new members always go at the end!
//! D
//! E
//! SL_STRUCT_END()
//!
//! Here is one example on how to check for version and handle backwards compatibility:
//!
//! void func(const S1* input)
//! {
//! // Access A, B, C as needed
//! ...
//! if (input->structVersion >= kStructVersion2)
//! {
//! // Safe to access D, E
//! }
//! }
//! --- OPTION 2 ---
//!
//! New members are optional and added to a new struct which is then chained as needed:
//!
//! SL_STRUCT_BEGIN(S1, GUID1, kStructVersion1)
//! A
//! B
//! C
//! SL_STRUCT_END()
//!
//! SL_STRUCT_BEGIN(S2, GUID2, kStructVersion1) // Note that this is a different struct with new GUID
//! D
//! E
//! SL_STRUCT_END()
//!
//! S1 s1;
//! S2 s2
//! s1.next = &s2; // optional parameters in S2
//! IMPORTANT: New members in the structure always go at the end!
//!
constexpr uint32_t kStructVersion1 = 1;
constexpr uint32_t kStructVersion2 = 2;
constexpr uint32_t kStructVersion3 = 3;
constexpr uint32_t kStructVersion4 = 4;
struct BaseStructure
{
BaseStructure() = delete;
BaseStructure(StructType t, uint32_t v) : structType(t), structVersion(v) {};
BaseStructure* next{};
StructType structType{};
size_t structVersion;
};
#define SL_STRUCT_BEGIN(name, guid, version) \
struct name : public sl::BaseStructure \
{ \
name() : sl::BaseStructure(guid, version){} \
constexpr static sl::StructType s_structType = guid;
#define SL_STRUCT_END() };
#define SL_STRUCT_PROTECTED_BEGIN(name, guid, version) \
struct name : public sl::BaseStructure \
{ \
protected: \
name() : sl::BaseStructure(guid, version){} \
public: \
constexpr static sl::StructType s_structType = guid; \
// Deprecated: please use SL_STRUCT_BEGIN/SL_STRUCT_END instead
#define SL_STRUCT(name, guid, version) \
SL_STRUCT_BEGIN(name, guid, version)
// Deprecated: please use SL_STRUCT_PROTECTED_BEGIN/SL_STRUCT_END instead
#define SL_STRUCT_PROTECTED(name, guid, version) \
SL_STRUCT_PROTECTED_BEGIN(name, guid, version)
} // namespace sl
@@ -0,0 +1,57 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
namespace sl
{
//! Each feature must have a unique id, please see sl.h Feature
//!
constexpr uint32_t kFeatureTemplate = 0xffff;
//! If your plugin does not have any constants then the code below can be removed
//!
enum class TemplateMode : uint32_t
{
eOff,
eOn
};
//! IMPORTANT: Each structure must have a unique GUID assigned, change this as needed
//!
// {29DF7FE0-273A-4D72-B481-2DC823D5B1AD}
SL_STRUCT_BEGIN(TemplateConstants, StructType({ 0x29df7fe0, 0x273a, 0x4d72, { 0xb4, 0x81, 0x2d, 0xc8, 0x23, 0xd5, 0xb1, 0xad } }), kStructVersion1)
TemplateMode mode = TemplateMode::eOff;
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
//! IMPORTANT: Each structure must have a unique GUID assigned, change this as needed
//!
// {39DF7FE0-283A-4D72-B481-2DC823D5B1AD}
SL_STRUCT_BEGIN(TemplateSettings, StructType({ 0x39df7fe0, 0x283a, 0x4d72, { 0xb4, 0x81, 0x2d, 0xc8, 0x23, 0xd5, 0xb1, 0xad } }), kStructVersion1)
//! IMPORTANT: New members go here or if optional can be chained in a new struct, see sl_struct.h for details
SL_STRUCT_END()
}
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2022-2023 NVIDIA CORPORATION. All rights reserved
*
* 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 the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* 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.
*/
#pragma once
#define SL_VERSION_MAJOR 2
#define SL_VERSION_MINOR 10
#define SL_VERSION_PATCH 3
#include <cstdint>
#include <string>
namespace sl
{
constexpr uint64_t kSDKVersionMagic = 0xfedc;
constexpr uint64_t kSDKVersion = (uint64_t(SL_VERSION_MAJOR) << 48) | (uint64_t(SL_VERSION_MINOR) << 32) | (uint64_t(SL_VERSION_PATCH) << 16) | kSDKVersionMagic;
struct Version
{
Version() : major(0), minor(0), build(0) {};
Version(uint32_t v1, uint32_t v2, uint32_t v3) : major(v1), minor(v2), build(v3) {};
inline operator bool() const { return major != 0 || minor != 0 || build != 0; }
inline std::string toStr() const
{
return std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(build);
}
inline std::wstring toWStr() const
{
return std::to_wstring(major) + L"." + std::to_wstring(minor) + L"." + std::to_wstring(build);
}
inline std::wstring toWStrOTAId() const
{
return std::to_wstring((major << 16) | (minor << 8) | build);
}
inline bool operator==(const Version& rhs) const
{
return major == rhs.major && minor == rhs.minor && build == rhs.build;
}
inline bool operator>(const Version& rhs) const
{
if (major < rhs.major) return false;
else if (major > rhs.major) return true;
// major version the same
if (minor < rhs.minor) return false;
else if (minor > rhs.minor) return true;
// minor version the same
if (build < rhs.build) return false;
else if (build > rhs.build) return true;
// build version the same
return false;
};
inline bool operator>=(const Version& rhs) const
{
return operator>(rhs) || operator==(rhs);
};
inline bool operator<(const Version& rhs) const
{
if (major > rhs.major) return false;
else if (major < rhs.major) return true;
// major version the same
if (minor > rhs.minor) return false;
else if (minor < rhs.minor) return true;
// minor version the same
if (build > rhs.build) return false;
else if (build < rhs.build) return true;
// build version the same
return false;
};
inline bool operator<=(const Version& rhs) const
{
return operator<(rhs) || operator==(rhs);
};
uint32_t major;
uint32_t minor;
uint32_t build;
};
}