From 6446cc8dcc76e2c2b786384300e217f352b2c18b Mon Sep 17 00:00:00 2001 From: cmh1448 Date: Sat, 5 Sep 2026 14:29:50 +0900 Subject: [PATCH] Fix DLSS NR motion vector metadata handling --- OptiScaler/dlssnr/DlssNrFeature_Vk.cpp | 42 +++++++++++++++++-- OptiScaler/dlssnr/DlssNr_Proxy.cpp | 17 ++++---- OptiScaler/dlssnr/DlssNr_Proxy.h | 5 ++- .../dlssnr/forwarder/dlssnr_forwarder.cpp | 32 ++++++++------ OptiScaler/shaders/dlssnr/DlssNr_Common.h | 9 ++++ OptiScaler/shaders/dlssnr/DlssNr_Dx12.cpp | 41 ++++++++++++++---- 6 files changed, 110 insertions(+), 36 deletions(-) diff --git a/OptiScaler/dlssnr/DlssNrFeature_Vk.cpp b/OptiScaler/dlssnr/DlssNrFeature_Vk.cpp index ae54c6ed0..d752bf073 100644 --- a/OptiScaler/dlssnr/DlssNrFeature_Vk.cpp +++ b/OptiScaler/dlssnr/DlssNrFeature_Vk.cpp @@ -30,6 +30,7 @@ using PFN_VkInit = int(__cdecl*)(const wchar_t*, const wchar_t*, void*, void*, v using PFN_VkCreate = void*(__cdecl*)(void*, void*, unsigned int, unsigned int, int, float, int, float, float, float, int, int); using PFN_VkEvaluate = int(__cdecl*)(void*, void*, void*, void*, void*, void*, void*, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int, int, float, int, float, float, float, int, float, float); using PFN_VkRelease = void(__cdecl*)(void*); @@ -602,8 +603,10 @@ void EvaluateAfterUpscaleVk(VkCommandBuffer cmdBuffer, NVSDK_NGX_Parameter* para const uint32_t width = colour->Resource.ImageViewInfo.Width; const uint32_t height = colour->Resource.ImageViewInfo.Height; - const uint32_t guideWidth = depth->Resource.ImageViewInfo.Width; - const uint32_t guideHeight = depth->Resource.ImageViewInfo.Height; + uint32_t guideWidth = depth->Resource.ImageViewInfo.Width; + uint32_t guideHeight = depth->Resource.ImageViewInfo.Height; + const uint32_t motionAllocationWidth = motion->Resource.ImageViewInfo.Width; + const uint32_t motionAllocationHeight = motion->Resource.ImageViewInfo.Height; if (width == 0 || height == 0) return; @@ -801,6 +804,33 @@ void EvaluateAfterUpscaleVk(VkCommandBuffer cmdBuffer, NVSDK_NGX_Parameter* para const unsigned int createFlags = GameCreateFlags(params); const bool gameSaysHdr = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_IsHDR) != 0; const bool depthInverted = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_DepthInverted) != 0; + const bool lowResolutionMotion = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_MVLowRes) != 0; + + uint32_t renderWidth = guideWidth; + uint32_t renderHeight = guideHeight; + params->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width, &renderWidth); + params->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, &renderHeight); + + uint32_t depthBaseX = 0, depthBaseY = 0, motionBaseX = 0, motionBaseY = 0; + params->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, &depthBaseX); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, &depthBaseY); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, &motionBaseX); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, &motionBaseY); + + depthBaseX = std::min(depthBaseX, guideWidth); + depthBaseY = std::min(depthBaseY, guideHeight); + guideWidth = std::min(renderWidth, guideWidth - depthBaseX); + guideHeight = std::min(renderHeight, guideHeight - depthBaseY); + motionBaseX = std::min(motionBaseX, motionAllocationWidth); + motionBaseY = std::min(motionBaseY, motionAllocationHeight); + const uint32_t motionWidth = std::min(lowResolutionMotion ? renderWidth : width, + motionAllocationWidth - motionBaseX); + const uint32_t motionHeight = std::min(lowResolutionMotion ? renderHeight : height, + motionAllocationHeight - motionBaseY); + + float mvScaleX = 1.0f, mvScaleY = 1.0f; + params->Get(NVSDK_NGX_Parameter_MV_Scale_X, &mvScaleX); + params->Get(NVSDK_NGX_Parameter_MV_Scale_Y, &mvScaleY); // The game asking the upscaler to forget its history -- a cut, a teleport, a load. Same omission // as the D3D12 path had: the model's history was only ever reset by things that happened to us, @@ -1045,12 +1075,16 @@ void EvaluateAfterUpscaleVk(VkCommandBuffer cmdBuffer, NVSDK_NGX_Parameter* para Transition(cmdBuffer, g_vk.output, VK_IMAGE_LAYOUT_GENERAL); + const float mvToWorkX = width != 0 ? (float) workWidth / (float) width : 1.0f; + const float mvToWorkY = height != 0 ? (float) workHeight / (float) height : 1.0f; const int evaluated = g_vk.evaluate( (void*) cmdBuffer, g_vk.feature, g_vk.capabilityParams, &modelInput->ngx, depth, motion, &g_vk.output.ngx, - workWidth, workHeight, guideWidth, guideHeight, depthInverted ? 1 : 0, g_vk.reset ? 1 : 0, + workWidth, workHeight, guideWidth, guideHeight, motionWidth, motionHeight, depthBaseX, depthBaseY, + motionBaseX, motionBaseY, depthInverted ? 1 : 0, g_vk.reset ? 1 : 0, cfg.DlssNrIntensity.value_or_default(), (int) cfg.DlssNrStyle.value_or_default(), cfg.DlssNrLocalStructure.value_or_default(), cfg.DlssNrLocalTone.value_or_default(), - cfg.DlssNrSkinStructure.value_or_default(), cfg.DlssNrAutoMask.value_or_default() ? 1 : 0, 1.0f, 1.0f); + cfg.DlssNrSkinStructure.value_or_default(), cfg.DlssNrAutoMask.value_or_default() ? 1 : 0, + mvScaleX * mvToWorkX, mvScaleY * mvToWorkY); g_vk.reset = false; g_vk.frames++; diff --git a/OptiScaler/dlssnr/DlssNr_Proxy.cpp b/OptiScaler/dlssnr/DlssNr_Proxy.cpp index e59eebf7c..a5227c5c9 100644 --- a/OptiScaler/dlssnr/DlssNr_Proxy.cpp +++ b/OptiScaler/dlssnr/DlssNr_Proxy.cpp @@ -147,8 +147,9 @@ void Release() unsigned int Run(ID3D12GraphicsCommandList* cmdList, ID3D12Device* device, ID3D12Resource* color, ID3D12Resource* depth, ID3D12Resource* motion, ID3D12Resource* output, unsigned int width, unsigned int height, unsigned int guideWidth, - unsigned int guideHeight, bool depthInverted, bool reset, float mvScaleX, - float mvScaleY) + unsigned int guideHeight, unsigned int motionWidth, unsigned int motionHeight, + unsigned int depthBaseX, unsigned int depthBaseY, unsigned int motionBaseX, + unsigned int motionBaseY, bool depthInverted, bool reset, float mvScaleX, float mvScaleY) { if (g_proxy.failed || !Available()) return 0; @@ -266,14 +267,14 @@ unsigned int Run(ID3D12GraphicsCommandList* cmdList, ID3D12Device* device, ID3D1 SetUInt(params, "DLSSNR.OutputSubrectBaseY", 0u); SetUInt(params, "DLSSNR.OutputSubrectWidth", width); SetUInt(params, "DLSSNR.OutputSubrectHeight", height); - SetUInt(params, "DLSSNR.DepthSubrectBaseX", 0u); - SetUInt(params, "DLSSNR.DepthSubrectBaseY", 0u); + SetUInt(params, "DLSSNR.DepthSubrectBaseX", depthBaseX); + SetUInt(params, "DLSSNR.DepthSubrectBaseY", depthBaseY); SetUInt(params, "DLSSNR.DepthSubrectWidth", guideWidth); SetUInt(params, "DLSSNR.DepthSubrectHeight", guideHeight); - SetUInt(params, "DLSSNR.MVecSubrectBaseX", 0u); - SetUInt(params, "DLSSNR.MVecSubrectBaseY", 0u); - SetUInt(params, "DLSSNR.MVecSubrectWidth", guideWidth); - SetUInt(params, "DLSSNR.MVecSubrectHeight", guideHeight); + SetUInt(params, "DLSSNR.MVecSubrectBaseX", motionBaseX); + SetUInt(params, "DLSSNR.MVecSubrectBaseY", motionBaseY); + SetUInt(params, "DLSSNR.MVecSubrectWidth", motionWidth); + SetUInt(params, "DLSSNR.MVecSubrectHeight", motionHeight); // The game's own encoding, passed through. Deriving this from the resolutions was a guess, and // at native resolution it came out as exactly 1.0 -- so a game using normalised vectors was diff --git a/OptiScaler/dlssnr/DlssNr_Proxy.h b/OptiScaler/dlssnr/DlssNr_Proxy.h index 6e990a68c..2ef510499 100644 --- a/OptiScaler/dlssnr/DlssNr_Proxy.h +++ b/OptiScaler/dlssnr/DlssNr_Proxy.h @@ -43,8 +43,9 @@ bool Available(); unsigned int Run(ID3D12GraphicsCommandList* cmdList, ID3D12Device* device, ID3D12Resource* color, ID3D12Resource* depth, ID3D12Resource* motion, ID3D12Resource* output, unsigned int width, unsigned int height, unsigned int guideWidth, - unsigned int guideHeight, bool depthInverted, bool reset, float mvScaleX, - float mvScaleY); + unsigned int guideHeight, unsigned int motionWidth, unsigned int motionHeight, + unsigned int depthBaseX, unsigned int depthBaseY, unsigned int motionBaseX, + unsigned int motionBaseY, bool depthInverted, bool reset, float mvScaleX, float mvScaleY); // Drops the feature and its parameter block, for a resolution change or shutdown. void Release(); diff --git a/OptiScaler/dlssnr/forwarder/dlssnr_forwarder.cpp b/OptiScaler/dlssnr/forwarder/dlssnr_forwarder.cpp index dd8264d02..ae254704a 100644 --- a/OptiScaler/dlssnr/forwarder/dlssnr_forwarder.cpp +++ b/OptiScaler/dlssnr/forwarder/dlssnr_forwarder.cpp @@ -668,6 +668,9 @@ __declspec(dllexport) int dlssnr_vk_evaluate(void *cmdBuffer, void *feature, voi void *color, void *depth, void *motion, void *output, unsigned int width, unsigned int height, unsigned int guideWidth, unsigned int guideHeight, + unsigned int motionWidth, unsigned int motionHeight, + unsigned int depthBaseX, unsigned int depthBaseY, + unsigned int motionBaseX, unsigned int motionBaseY, int depthInverted, int reset, float intensity, int style, float localStructure, float localTone, float skinStructure, int useAutoMask, float mvScaleX, float mvScaleY) { @@ -696,14 +699,14 @@ __declspec(dllexport) int dlssnr_vk_evaluate(void *cmdBuffer, void *feature, voi setUInt(capabilityParams, "DLSSNR.OutputSubrectBaseY", 0); setUInt(capabilityParams, "DLSSNR.OutputSubrectWidth", width); setUInt(capabilityParams, "DLSSNR.OutputSubrectHeight", height); - setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseX", 0); - setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseY", 0); + setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseX", depthBaseX); + setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseY", depthBaseY); setUInt(capabilityParams, "DLSSNR.DepthSubrectWidth", guideWidth); setUInt(capabilityParams, "DLSSNR.DepthSubrectHeight", guideHeight); - setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseX", 0); - setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseY", 0); - setUInt(capabilityParams, "DLSSNR.MVecSubrectWidth", guideWidth); - setUInt(capabilityParams, "DLSSNR.MVecSubrectHeight", guideHeight); + setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseX", motionBaseX); + setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseY", motionBaseY); + setUInt(capabilityParams, "DLSSNR.MVecSubrectWidth", motionWidth); + setUInt(capabilityParams, "DLSSNR.MVecSubrectHeight", motionHeight); // The game's own encoding, passed through rather than derived. Deriving it from the resolutions // came out as exactly 1.0 at native, which told the model almost nothing had moved. @@ -785,7 +788,10 @@ __declspec(dllexport) int dlssnr_call_evaluate(ID3D12GraphicsCommandList *cmd, v ID3D12Resource *depth, ID3D12Resource *motion, ID3D12Resource *output, unsigned int width, unsigned int height, unsigned int guideWidth, - unsigned int guideHeight, int depthInverted, int reset, + unsigned int guideHeight, unsigned int motionWidth, + unsigned int motionHeight, unsigned int depthBaseX, + unsigned int depthBaseY, unsigned int motionBaseX, + unsigned int motionBaseY, int depthInverted, int reset, float intensity, int style, float localStructure, float localTone, float skinStructure, int useAutoMask, float mvScaleX, float mvScaleY) { @@ -813,14 +819,14 @@ __declspec(dllexport) int dlssnr_call_evaluate(ID3D12GraphicsCommandList *cmd, v setUInt(capabilityParams, "DLSSNR.OutputSubrectBaseY", 0); setUInt(capabilityParams, "DLSSNR.OutputSubrectWidth", width); setUInt(capabilityParams, "DLSSNR.OutputSubrectHeight", height); - setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseX", 0); - setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseY", 0); + setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseX", depthBaseX); + setUInt(capabilityParams, "DLSSNR.DepthSubrectBaseY", depthBaseY); setUInt(capabilityParams, "DLSSNR.DepthSubrectWidth", guideWidth); setUInt(capabilityParams, "DLSSNR.DepthSubrectHeight", guideHeight); - setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseX", 0); - setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseY", 0); - setUInt(capabilityParams, "DLSSNR.MVecSubrectWidth", guideWidth); - setUInt(capabilityParams, "DLSSNR.MVecSubrectHeight", guideHeight); + setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseX", motionBaseX); + setUInt(capabilityParams, "DLSSNR.MVecSubrectBaseY", motionBaseY); + setUInt(capabilityParams, "DLSSNR.MVecSubrectWidth", motionWidth); + setUInt(capabilityParams, "DLSSNR.MVecSubrectHeight", motionHeight); // The game's own encoding, passed through. Deriving this from the resolutions was a guess, and at // native resolution it came out as exactly 1.0 -- so a game using normalised vectors was telling diff --git a/OptiScaler/shaders/dlssnr/DlssNr_Common.h b/OptiScaler/shaders/dlssnr/DlssNr_Common.h index 72f8e48eb..c67646671 100644 --- a/OptiScaler/shaders/dlssnr/DlssNr_Common.h +++ b/OptiScaler/shaders/dlssnr/DlssNr_Common.h @@ -96,6 +96,15 @@ struct DlssNrFrameInfo // available and is what gets used. unsigned int RenderSubrectWidth = 0; unsigned int RenderSubrectHeight = 0; + + unsigned int DepthSubrectBaseX = 0; + unsigned int DepthSubrectBaseY = 0; + unsigned int MotionSubrectBaseX = 0; + unsigned int MotionSubrectBaseY = 0; + + // DLSS permits motion vectors at either render or output resolution. This flag comes from the + // feature-create flags and decides which valid-region dimensions apply to the motion texture. + bool MotionVectorsLowResolution = false; }; struct alignas(256) DlssNrConstants diff --git a/OptiScaler/shaders/dlssnr/DlssNr_Dx12.cpp b/OptiScaler/shaders/dlssnr/DlssNr_Dx12.cpp index bb74ef57a..6e2dc4efc 100644 --- a/OptiScaler/shaders/dlssnr/DlssNr_Dx12.cpp +++ b/OptiScaler/shaders/dlssnr/DlssNr_Dx12.cpp @@ -154,8 +154,9 @@ using PFN_NrCreate = void*(__cdecl*) (const wchar_t*, const wchar_t*, ID3D12Devi float, int, float, float, float, int, int); using PFN_NrEvaluate = int(__cdecl*) (ID3D12GraphicsCommandList*, void*, void*, ID3D12Resource*, ID3D12Resource*, ID3D12Resource*, ID3D12Resource*, unsigned int, - unsigned int, unsigned int, unsigned int, int, int, float, int, - float, float, float, int, float, float); + unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, unsigned int, int, int, float, + int, float, float, float, int, float, float); using PFN_NrRelease = void(__cdecl*) (void*); using PFN_NrSetExtras = void(__cdecl*) (void*, float, ID3D12Resource*, ID3D12Resource*, ID3D12Resource*, unsigned int, unsigned int, unsigned int, unsigned int); @@ -1538,6 +1539,7 @@ void DlssNr_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* c // one less thing a call site can get wrong, and the model takes the difference as a subrect per // resource rather than needing anything resampled. const D3D12_RESOURCE_DESC guideDesc = depth->GetDesc(); + const D3D12_RESOURCE_DESC motionDesc = motion->GetDesc(); unsigned int guideWidth = (unsigned int) guideDesc.Width; unsigned int guideHeight = guideDesc.Height; @@ -1580,6 +1582,19 @@ void DlssNr_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* c guideHeight = subH; } + const unsigned int depthBaseX = std::min(frame.DepthSubrectBaseX, (unsigned int) guideDesc.Width); + const unsigned int depthBaseY = std::min(frame.DepthSubrectBaseY, guideDesc.Height); + guideWidth = std::min(guideWidth, (unsigned int) guideDesc.Width - depthBaseX); + guideHeight = std::min(guideHeight, guideDesc.Height - depthBaseY); + + const unsigned int motionBaseX = std::min(frame.MotionSubrectBaseX, (unsigned int) motionDesc.Width); + const unsigned int motionBaseY = std::min(frame.MotionSubrectBaseY, motionDesc.Height); + const unsigned int wantedMotionWidth = frame.MotionVectorsLowResolution ? guideWidth : width; + const unsigned int wantedMotionHeight = frame.MotionVectorsLowResolution ? guideHeight : height; + const unsigned int motionWidth = + std::min(wantedMotionWidth, (unsigned int) motionDesc.Width - motionBaseX); + const unsigned int motionHeight = std::min(wantedMotionHeight, motionDesc.Height - motionBaseY); + g_nr.guideWidth = guideWidth; g_nr.guideHeight = guideHeight; g_nr.guideDepthInverted = frame.DepthInverted; @@ -2149,7 +2164,8 @@ void DlssNr_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* c // The vectors were scaled to full-frame pixels; the image the model reprojects is the working size. // The vectors were scaled to full-frame pixels; the image the model reprojects is the // working size. - const float mvToWork = width != 0 ? (float) workWidth / (float) width : 1.0f; + const float mvToWorkX = width != 0 ? (float) workWidth / (float) width : 1.0f; + const float mvToWorkY = height != 0 ? (float) workHeight / (float) height : 1.0f; SetExtras(cfg, nullptr, nullptr, 0, 0, 0, 0); @@ -2162,8 +2178,9 @@ void DlssNr_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* c { const unsigned int proxyResult = DlssNr::Proxy::Run( cmdList, device, modelInput, depthIn, motionIn, g_nr.output, workWidth, workHeight, - guideWidth, guideHeight, g_nr.guideDepthInverted, g_nr.reset, - g_nr.guideMvScaleX * mvToWork, g_nr.guideMvScaleY * mvToWork); + guideWidth, guideHeight, motionWidth, motionHeight, depthBaseX, depthBaseY, motionBaseX, + motionBaseY, g_nr.guideDepthInverted, g_nr.reset, + g_nr.guideMvScaleX * mvToWorkX, g_nr.guideMvScaleY * mvToWorkY); g_nr.reset = false; @@ -2187,12 +2204,13 @@ void DlssNr_Dx12::Dispatch(ID3D12GraphicsCommandList* cmdList, ID3D12Resource* c // feature-creation hang, and the colour core is not settled enough to build on. One evaluate. const int result = g_nr.evaluate( cmdList, g_nr.feature, g_nr.capabilityParams, modelInput, depthIn, motionIn, g_nr.output, - workWidth, workHeight, guideWidth, guideHeight, g_nr.guideDepthInverted ? 1 : 0, - g_nr.reset ? 1 : 0, cfg.DlssNrIntensity.value_or_default(), + workWidth, workHeight, guideWidth, guideHeight, motionWidth, motionHeight, depthBaseX, + depthBaseY, motionBaseX, motionBaseY, g_nr.guideDepthInverted ? 1 : 0, g_nr.reset ? 1 : 0, + cfg.DlssNrIntensity.value_or_default(), (int) cfg.DlssNrStyle.value_or_default(), cfg.DlssNrLocalStructure.value_or_default(), cfg.DlssNrLocalTone.value_or_default(), cfg.DlssNrSkinStructure.value_or_default(), - cfg.DlssNrAutoMask.value_or_default() ? 1 : 0, g_nr.guideMvScaleX * mvToWork, - g_nr.guideMvScaleY * mvToWork); + cfg.DlssNrAutoMask.value_or_default() ? 1 : 0, g_nr.guideMvScaleX * mvToWorkX, + g_nr.guideMvScaleY * mvToWorkY); if (g_ngxTime != nullptr) g_ngxTime->End(cmdList); @@ -2525,6 +2543,7 @@ void EvaluateAfterUpscale(ID3D12GraphicsCommandList* cmdList, NVSDK_NGX_Paramete DlssNrFrameInfo frame {}; frame.DepthInverted = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_DepthInverted) != 0; frame.ColourIsLinearHdr = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_IsHDR) != 0; + frame.MotionVectorsLowResolution = (createFlags & NVSDK_NGX_DLSS_Feature_Flags_MVLowRes) != 0; // The game telling the upscaler to forget everything it has accumulated: a cut, a teleport, a // load. Every upscaler in this tree reads it and this pass did not, so the model's history was @@ -2544,6 +2563,10 @@ void EvaluateAfterUpscale(ID3D12GraphicsCommandList* cmdList, NVSDK_NGX_Paramete // How much of the guides is real. See DlssNrFrameInfo -- zero means the game did not say. params->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Width, &frame.RenderSubrectWidth); params->Get(NVSDK_NGX_Parameter_DLSS_Render_Subrect_Dimensions_Height, &frame.RenderSubrectHeight); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, &frame.DepthSubrectBaseX); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_Y, &frame.DepthSubrectBaseY); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_X, &frame.MotionSubrectBaseX); + params->Get(NVSDK_NGX_Parameter_DLSS_Input_MV_SubrectBase_Y, &frame.MotionSubrectBaseY); if (params->Get(NVSDK_NGX_Parameter_MV_Scale_X, &frame.MvScaleX) != NVSDK_NGX_Result_Success) frame.MvScaleX = 1.0f;