7269afabe9
- MIT/SPDX copyright headers on the original integration files (The Roofer Dev), stating they are integration code only; DLSS/DLAA/NIS remain NVIDIA tech. - README: bilingual (EN/FR) section for native TAA and for enabling DLSS via a user-supplied 'dlss' folder (no proprietary NVIDIA file is bundled; nvngx is auto-located on the user's machine). Bilingual credits + trademark disclaimer. - THIRDPARTY: MIT notices for NVIDIA NIS and NVIDIA Streamline.
532 lines
21 KiB
C#
532 lines
21 KiB
C#
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2026 The Roofer Dev - Beast Roofer Edition. Clean-room integration code.
|
|
// Built on Ryujinx (MIT). DLSS, DLAA and NIS are NVIDIA technologies; this is integration code only.
|
|
|
|
using Ryujinx.Common.Logging;
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Ryujinx.Graphics.Vulkan.Dlss
|
|
{
|
|
/// <summary>
|
|
/// DLSS-SR evaluation interop: the structs, exported functions and feature functions needed to
|
|
/// actually run DLSS via slEvaluateFeature. Clean-room re-declaration of the public MIT
|
|
/// Streamline headers (sl_core_types.h, sl_consts.h, sl_dlss.h). All blittable, exact x64 layout.
|
|
/// </summary>
|
|
public static unsafe class StreamlineDlss
|
|
{
|
|
private const string Interposer = "sl.interposer";
|
|
private const uint FeatureDLSS = 0;
|
|
|
|
// sl::BufferType (uint32) - the four tags DLSS-SR requires.
|
|
private const uint BufferTypeDepth = 0;
|
|
private const uint BufferTypeMotionVectors = 1;
|
|
private const uint BufferTypeScalingInputColor = 3;
|
|
private const uint BufferTypeScalingOutputColor = 4;
|
|
|
|
// sl::ResourceLifecycle - tag stays valid until the evaluate returns.
|
|
private const uint LifecycleValidUntilEvaluate = 2;
|
|
|
|
// sl::ResourceType::eTex2d
|
|
private const byte ResourceTypeTex2d = 0;
|
|
|
|
// sl::Boolean (char)
|
|
private const byte BoolFalse = 0;
|
|
private const byte BoolTrue = 1;
|
|
|
|
/// <summary>One image to hand to DLSS (input/output/depth/motion).</summary>
|
|
public struct DlssTexture
|
|
{
|
|
public IntPtr Image; // VkImage
|
|
public IntPtr View; // VkImageView
|
|
public uint NativeFormat; // VkFormat (Silk.NET value)
|
|
public uint Layout; // VkImageLayout the image is in when DLSS runs
|
|
public uint Width;
|
|
public uint Height;
|
|
}
|
|
|
|
public enum DlssMode : uint
|
|
{
|
|
Off = 0,
|
|
MaxPerformance,
|
|
Balanced,
|
|
MaxQuality,
|
|
UltraPerformance,
|
|
UltraQuality,
|
|
Dlaa,
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct StructType
|
|
{
|
|
public uint Data1;
|
|
public ushort Data2;
|
|
public ushort Data3;
|
|
public byte B0, B1, B2, B3, B4, B5, B6, B7;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct ViewportHandle
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public uint Value;
|
|
}
|
|
|
|
// sl::Resource - sl_core_types.h. sizeof == 112 on x64.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct Resource
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public byte ResType; // ResourceType : char (32, padded to 40)
|
|
public IntPtr Native; // 40 VkImage
|
|
public IntPtr Memory; // 48
|
|
public IntPtr View; // 56 VkImageView
|
|
public uint State; // 64 VkImageLayout
|
|
public uint Width; // 68
|
|
public uint Height; // 72
|
|
public uint NativeFormat; // 76 VkFormat
|
|
public uint MipLevels; // 80
|
|
public uint ArrayLayers; // 84
|
|
public ulong GpuVirtualAddress; // 88
|
|
public uint Flags; // 96
|
|
public uint Usage; // 100
|
|
public uint Reserved; // 104
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct Extent
|
|
{
|
|
public uint Top, Left, Width, Height;
|
|
}
|
|
|
|
// sl::ResourceTag - sizeof == 64.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct ResourceTag
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public IntPtr ResourcePtr; // Resource*
|
|
public uint BufferType;
|
|
public uint Lifecycle;
|
|
public Extent Extent;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct Mat4
|
|
{
|
|
public float M00, M01, M02, M03;
|
|
public float M10, M11, M12, M13;
|
|
public float M20, M21, M22, M23;
|
|
public float M30, M31, M32, M33;
|
|
|
|
public static Mat4 Identity()
|
|
{
|
|
Mat4 m = default;
|
|
m.M00 = m.M11 = m.M22 = m.M33 = 1f;
|
|
|
|
return m;
|
|
}
|
|
}
|
|
|
|
// sl::Constants (kStructVersion2) - sl_consts.h. sizeof == 456 on x64.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct Constants
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public Mat4 CameraViewToClip;
|
|
public Mat4 ClipToCameraView;
|
|
public Mat4 ClipToLensClip;
|
|
public Mat4 ClipToPrevClip;
|
|
public Mat4 PrevClipToClip;
|
|
public float JitterOffsetX, JitterOffsetY;
|
|
public float MvecScaleX, MvecScaleY;
|
|
public float CameraPinholeOffsetX, CameraPinholeOffsetY;
|
|
public float CameraPosX, CameraPosY, CameraPosZ;
|
|
public float CameraUpX, CameraUpY, CameraUpZ;
|
|
public float CameraRightX, CameraRightY, CameraRightZ;
|
|
public float CameraFwdX, CameraFwdY, CameraFwdZ;
|
|
public float CameraNear;
|
|
public float CameraFar;
|
|
public float CameraFOV;
|
|
public float CameraAspectRatio;
|
|
public float MotionVectorsInvalidValue;
|
|
public byte DepthInverted;
|
|
public byte CameraMotionIncluded;
|
|
public byte MotionVectors3D;
|
|
public byte Reset;
|
|
public byte OrthographicProjection;
|
|
public byte MotionVectorsDilated;
|
|
public byte MotionVectorsJittered;
|
|
public float MinRelativeLinearDepthObjectSeparation;
|
|
}
|
|
|
|
// sl::DLSSOptions (kStructVersion3) - sl_dlss.h. sizeof == 88.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct DlssOptions
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public uint Mode;
|
|
public uint OutputWidth;
|
|
public uint OutputHeight;
|
|
public float Sharpness;
|
|
public float PreExposure;
|
|
public float ExposureScale;
|
|
public byte ColorBuffersHDR;
|
|
public byte IndicatorInvertAxisX;
|
|
public byte IndicatorInvertAxisY;
|
|
public uint DlaaPreset;
|
|
public uint QualityPreset;
|
|
public uint BalancedPreset;
|
|
public uint PerformancePreset;
|
|
public uint UltraPerformancePreset;
|
|
public uint UltraQualityPreset;
|
|
public byte UseAutoExposure;
|
|
public byte AlphaUpscalingEnabled;
|
|
}
|
|
|
|
// sl::DLSSOptimalSettings (kStructVersion1) - sl_dlss.h. sizeof == 64.
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
private struct DlssOptimalSettings
|
|
{
|
|
public IntPtr Next;
|
|
public StructType Type;
|
|
public nuint Version;
|
|
public uint OptimalRenderWidth;
|
|
public uint OptimalRenderHeight;
|
|
public float OptimalSharpness;
|
|
public uint RenderWidthMin;
|
|
public uint RenderHeightMin;
|
|
public uint RenderWidthMax;
|
|
public uint RenderHeightMax;
|
|
}
|
|
|
|
// --- exported functions ---
|
|
[DllImport(Interposer, EntryPoint = "slGetNewFrameToken", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int slGetNewFrameToken(out IntPtr token, in uint frameIndex);
|
|
|
|
[DllImport(Interposer, EntryPoint = "slSetConstants", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int slSetConstants(in Constants values, IntPtr frameToken, in ViewportHandle viewport);
|
|
|
|
[DllImport(Interposer, EntryPoint = "slEvaluateFeature", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int slEvaluateFeature(uint feature, IntPtr frameToken, IntPtr* inputs, uint numInputs, IntPtr cmdBuffer);
|
|
|
|
[DllImport(Interposer, EntryPoint = "slGetFeatureFunction", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int slGetFeatureFunction(uint feature, [MarshalAs(UnmanagedType.LPStr)] string functionName, out IntPtr function);
|
|
|
|
// DLSS feature functions, bound lazily via slGetFeatureFunction (they are not direct exports).
|
|
private static delegate* unmanaged[Cdecl]<in ViewportHandle, in DlssOptions, int> _slDLSSSetOptions;
|
|
private static delegate* unmanaged[Cdecl]<in DlssOptions, ref DlssOptimalSettings, int> _slDLSSGetOptimalSettings;
|
|
private static bool _functionsBound;
|
|
private static bool _loggedSizes;
|
|
|
|
private static StructType Guid(uint d1, ushort d2, ushort d3, byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7)
|
|
{
|
|
return new StructType
|
|
{
|
|
Data1 = d1, Data2 = d2, Data3 = d3,
|
|
B0 = b0, B1 = b1, B2 = b2, B3 = b3, B4 = b4, B5 = b5, B6 = b6, B7 = b7,
|
|
};
|
|
}
|
|
|
|
private static bool BindFunctions()
|
|
{
|
|
if (_functionsBound)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (slGetFeatureFunction(FeatureDLSS, "slDLSSSetOptions", out IntPtr setOptions) != 0 ||
|
|
slGetFeatureFunction(FeatureDLSS, "slDLSSGetOptimalSettings", out IntPtr getOptimal) != 0 ||
|
|
setOptions == IntPtr.Zero || getOptimal == IntPtr.Zero)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Gpu, "DLSS: could not bind DLSS feature functions.");
|
|
|
|
return false;
|
|
}
|
|
|
|
_slDLSSSetOptions = (delegate* unmanaged[Cdecl]<in ViewportHandle, in DlssOptions, int>)setOptions;
|
|
_slDLSSGetOptimalSettings = (delegate* unmanaged[Cdecl]<in DlssOptions, ref DlssOptimalSettings, int>)getOptimal;
|
|
_functionsBound = true;
|
|
|
|
if (!_loggedSizes)
|
|
{
|
|
_loggedSizes = true;
|
|
Logger.Info?.Print(LogClass.Gpu, $"DLSS: struct sizes Resource={Marshal.SizeOf<Resource>()}(112) Constants={Marshal.SizeOf<Constants>()}(456) DLSSOptions={Marshal.SizeOf<DlssOptions>()}(88) Tag={Marshal.SizeOf<ResourceTag>()}(64)");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private static ViewportHandle MakeViewport(uint id)
|
|
{
|
|
ViewportHandle vp = default;
|
|
vp.Type = Guid(0x171b6435, 0x9b3c, 0x4fc8, 0x99, 0x94, 0xfb, 0xe5, 0x25, 0x69, 0xaa, 0xa4);
|
|
vp.Version = 1;
|
|
vp.Value = id;
|
|
|
|
return vp;
|
|
}
|
|
|
|
/// <summary>Sets DLSS options for the viewport (mode + final output size). Call when size/mode changes.</summary>
|
|
public static bool SetOptions(uint viewportId, DlssMode mode, uint outputWidth, uint outputHeight, bool hdr)
|
|
{
|
|
if (!BindFunctions())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DlssOptions opt = default;
|
|
opt.Type = Guid(0x6ac826e4, 0x4c61, 0x4101, 0xa9, 0x2d, 0x63, 0x8d, 0x42, 0x10, 0x57, 0xb8);
|
|
opt.Version = 3;
|
|
opt.Mode = (uint)mode;
|
|
opt.OutputWidth = outputWidth;
|
|
opt.OutputHeight = outputHeight;
|
|
opt.PreExposure = 1.0f;
|
|
opt.ExposureScale = 1.0f;
|
|
opt.ColorBuffersHDR = hdr ? BoolTrue : BoolFalse;
|
|
opt.UseAutoExposure = BoolTrue;
|
|
|
|
// Locked preset matrix (validated presets, no manual override): DLAA (1:1 ratio) gets Preset K
|
|
// (transformer, maximum sharpness); the upscaling modes get Preset F (CNN, ultra-stability /
|
|
// anti-flicker). Every per-mode slot is set, so whichever mode is active uses its mapped preset.
|
|
const uint PresetK = 11; // transformer sharpness, for DLAA
|
|
const uint PresetF = 6; // CNN ultra-stability, for the upscaling modes
|
|
opt.DlaaPreset = PresetK;
|
|
opt.QualityPreset = PresetF;
|
|
opt.BalancedPreset = PresetF;
|
|
opt.PerformancePreset = PresetF;
|
|
opt.UltraPerformancePreset = PresetF;
|
|
opt.UltraQualityPreset = PresetF;
|
|
|
|
ViewportHandle vp = MakeViewport(viewportId);
|
|
int r = _slDLSSSetOptions(in vp, in opt);
|
|
if (r != 0)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Gpu, $"DLSS: slDLSSSetOptions failed ({r}).");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>Queries DLSS's optimal render resolution for a given output size + mode.</summary>
|
|
public static bool GetOptimalRenderSize(DlssMode mode, uint outputWidth, uint outputHeight, out uint renderWidth, out uint renderHeight)
|
|
{
|
|
renderWidth = outputWidth;
|
|
renderHeight = outputHeight;
|
|
|
|
if (!BindFunctions())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DlssOptions opt = default;
|
|
opt.Type = Guid(0x6ac826e4, 0x4c61, 0x4101, 0xa9, 0x2d, 0x63, 0x8d, 0x42, 0x10, 0x57, 0xb8);
|
|
opt.Version = 3;
|
|
opt.Mode = (uint)mode;
|
|
opt.OutputWidth = outputWidth;
|
|
opt.OutputHeight = outputHeight;
|
|
|
|
DlssOptimalSettings settings = default;
|
|
settings.Type = Guid(0xef1d0957, 0xfd58, 0x4df7, 0xb5, 0x04, 0x8b, 0x69, 0xd8, 0xaa, 0x6b, 0x76);
|
|
settings.Version = 1;
|
|
|
|
if (_slDLSSGetOptimalSettings(in opt, ref settings) != 0 || settings.OptimalRenderWidth == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
renderWidth = settings.OptimalRenderWidth;
|
|
renderHeight = settings.OptimalRenderHeight;
|
|
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the dynamic render-resolution range DLSS accepts for a given mode + output size.
|
|
/// The actual input must fall within [min, max] or slEvaluateFeature rejects it.
|
|
/// </summary>
|
|
public static bool GetRenderRange(DlssMode mode, uint outputWidth, uint outputHeight,
|
|
out uint minWidth, out uint minHeight, out uint maxWidth, out uint maxHeight)
|
|
{
|
|
minWidth = minHeight = maxWidth = maxHeight = 0;
|
|
|
|
if (!BindFunctions())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DlssOptions opt = default;
|
|
opt.Type = Guid(0x6ac826e4, 0x4c61, 0x4101, 0xa9, 0x2d, 0x63, 0x8d, 0x42, 0x10, 0x57, 0xb8);
|
|
opt.Version = 3;
|
|
opt.Mode = (uint)mode;
|
|
opt.OutputWidth = outputWidth;
|
|
opt.OutputHeight = outputHeight;
|
|
|
|
DlssOptimalSettings settings = default;
|
|
settings.Type = Guid(0xef1d0957, 0xfd58, 0x4df7, 0xb5, 0x04, 0x8b, 0x69, 0xd8, 0xaa, 0x6b, 0x76);
|
|
settings.Version = 1;
|
|
|
|
if (_slDLSSGetOptimalSettings(in opt, ref settings) != 0 || settings.OptimalRenderWidth == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
minWidth = settings.RenderWidthMin;
|
|
minHeight = settings.RenderHeightMin;
|
|
maxWidth = settings.RenderWidthMax;
|
|
maxHeight = settings.RenderHeightMax;
|
|
|
|
return true;
|
|
}
|
|
|
|
private static Resource MakeResource(in DlssTexture tex)
|
|
{
|
|
Resource r = default;
|
|
r.Type = Guid(0x3a9d70cf, 0x2418, 0x4b72, 0x83, 0x91, 0x13, 0xf8, 0x72, 0x1c, 0x72, 0x61);
|
|
r.Version = 1;
|
|
r.ResType = ResourceTypeTex2d;
|
|
r.Native = tex.Image;
|
|
r.View = tex.View;
|
|
r.State = tex.Layout;
|
|
r.Width = tex.Width;
|
|
r.Height = tex.Height;
|
|
r.NativeFormat = tex.NativeFormat;
|
|
r.MipLevels = 1;
|
|
r.ArrayLayers = 1;
|
|
|
|
return r;
|
|
}
|
|
|
|
private static ResourceTag MakeTag(Resource* resource, uint bufferType, uint width, uint height)
|
|
{
|
|
ResourceTag t = default;
|
|
t.Type = Guid(0x4c6a5aad, 0xb445, 0x496c, 0x87, 0xff, 0x1a, 0xf3, 0x84, 0x5b, 0xe6, 0x53);
|
|
t.Version = 1;
|
|
t.ResourcePtr = (IntPtr)resource;
|
|
t.BufferType = bufferType;
|
|
t.Lifecycle = LifecycleValidUntilEvaluate;
|
|
t.Extent = new Extent { Top = 0, Left = 0, Width = width, Height = height };
|
|
|
|
return t;
|
|
}
|
|
|
|
private static Constants BuildConstants(uint outW, uint outH, uint renderW, uint renderH, bool reset, float jitterX, float jitterY)
|
|
{
|
|
Constants c = default;
|
|
c.Type = Guid(0xdcd35ad7, 0x4e4a, 0x4bad, 0xa9, 0x0c, 0xe0, 0xc4, 0x9e, 0xb2, 0x3a, 0xfe);
|
|
c.Version = 2;
|
|
c.CameraViewToClip = Mat4.Identity();
|
|
c.ClipToCameraView = Mat4.Identity();
|
|
c.ClipToLensClip = Mat4.Identity();
|
|
c.ClipToPrevClip = Mat4.Identity();
|
|
c.PrevClipToClip = Mat4.Identity();
|
|
c.JitterOffsetX = jitterX; // sub-pixel jitter applied to the image this frame (0 unless Mode B)
|
|
c.JitterOffsetY = jitterY;
|
|
// The motion buffer stores vectors in render-resolution pixels, but Streamline expects
|
|
// them normalized (sl_consts.h: "scale factors used to normalize motion vectors ... in
|
|
// [-1,1] range"). Leaving this at 1.0 feeds DLSS vectors ~renderW times too large, so
|
|
// temporal reprojection samples history from far off-screen on any camera motion and the
|
|
// image collapses to a desaturated smear (only correct when still). 1/render normalizes it.
|
|
c.MvecScaleX = renderW != 0 ? 1.0f / renderW : 1f;
|
|
c.MvecScaleY = renderH != 0 ? 1.0f / renderH : 1f;
|
|
c.CameraUpY = 1f;
|
|
c.CameraRightX = 1f;
|
|
c.CameraFwdZ = 1f;
|
|
c.CameraNear = 0.1f;
|
|
c.CameraFar = 10000f;
|
|
c.CameraFOV = 1.0f;
|
|
c.CameraAspectRatio = outH != 0 ? (float)outW / outH : 1.7777f;
|
|
c.MotionVectorsInvalidValue = 0f;
|
|
c.DepthInverted = BoolFalse;
|
|
c.CameraMotionIncluded = BoolTrue;
|
|
c.MotionVectors3D = BoolFalse;
|
|
c.Reset = reset ? BoolTrue : BoolFalse; // history off only on the first frame / scene cut
|
|
c.OrthographicProjection = BoolFalse;
|
|
c.MotionVectorsDilated = BoolFalse;
|
|
c.MotionVectorsJittered = BoolFalse;
|
|
c.MinRelativeLinearDepthObjectSeparation = 40f;
|
|
|
|
return c;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Runs DLSS for one frame: sets constants, tags the four buffers and evaluates into the
|
|
/// output image, recording into <paramref name="cmdBuffer"/>. The caller submits that buffer.
|
|
/// </summary>
|
|
public static bool Evaluate(
|
|
IntPtr cmdBuffer,
|
|
uint viewportId,
|
|
uint frameIndex,
|
|
bool reset,
|
|
float jitterX,
|
|
float jitterY,
|
|
in DlssTexture input,
|
|
in DlssTexture output,
|
|
in DlssTexture depth,
|
|
in DlssTexture motion)
|
|
{
|
|
if (!_functionsBound)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (slGetNewFrameToken(out IntPtr token, in frameIndex) != 0 || token == IntPtr.Zero)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Gpu, "DLSS: slGetNewFrameToken failed.");
|
|
|
|
return false;
|
|
}
|
|
|
|
ViewportHandle vp = MakeViewport(viewportId);
|
|
|
|
Constants constants = BuildConstants(output.Width, output.Height, motion.Width, motion.Height, reset, jitterX, jitterY);
|
|
int rc = slSetConstants(in constants, token, in vp);
|
|
if (rc != 0)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Gpu, $"DLSS: slSetConstants failed ({rc}).");
|
|
|
|
return false;
|
|
}
|
|
|
|
Resource rInput = MakeResource(input);
|
|
Resource rOutput = MakeResource(output);
|
|
Resource rDepth = MakeResource(depth);
|
|
Resource rMotion = MakeResource(motion);
|
|
|
|
ResourceTag tInput = MakeTag(&rInput, BufferTypeScalingInputColor, input.Width, input.Height);
|
|
ResourceTag tOutput = MakeTag(&rOutput, BufferTypeScalingOutputColor, output.Width, output.Height);
|
|
ResourceTag tDepth = MakeTag(&rDepth, BufferTypeDepth, depth.Width, depth.Height);
|
|
ResourceTag tMotion = MakeTag(&rMotion, BufferTypeMotionVectors, motion.Width, motion.Height);
|
|
|
|
// Inputs to slEvaluateFeature: the viewport plus the four local resource tags.
|
|
IntPtr* inputs = stackalloc IntPtr[5];
|
|
inputs[0] = (IntPtr)(&vp);
|
|
inputs[1] = (IntPtr)(&tDepth);
|
|
inputs[2] = (IntPtr)(&tMotion);
|
|
inputs[3] = (IntPtr)(&tInput);
|
|
inputs[4] = (IntPtr)(&tOutput);
|
|
|
|
int re = slEvaluateFeature(FeatureDLSS, token, inputs, 5, cmdBuffer);
|
|
if (re != 0)
|
|
{
|
|
Logger.Warning?.Print(LogClass.Gpu, $"DLSS: slEvaluateFeature failed ({re}).");
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|