/* * 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 #include #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(resolveDLSSPreset(static_cast(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 T* findStruct(const void* ptr) { auto base = static_cast(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 T* findStruct(const void* ptr) { auto base = static_cast(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 T* findStruct(const void** ptr, uint32_t count) { const BaseStructure* base{}; for (uint32_t i = 0; base == nullptr && i < count; i++) { base = static_cast(ptr[i]); while (base && base->structType != T::s_structType) { base = base->next; } } return (T*)base; } template bool findStructs(const void** ptr, uint32_t count, std::vector& structs) { for (uint32_t i = 0; i < count; i++) { auto base = static_cast(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