From fe2fa45e0e56e7fd1cf565d5abecda4ff04d4c76 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Wed, 28 Oct 2026 19:41:06 +0100 Subject: [PATCH] Add XeSS MaxResponsiveMaskValue support Slopped. Fixes XeSS inputs in BeamNG --- OptiScaler/inputs/XeSS_Common.cpp | 25 +++++++++ OptiScaler/inputs/XeSS_Common.h | 2 + OptiScaler/proxies/XeSS_Proxy.h | 56 +++++++++++++++++++ .../upscalers/xess/XeSSFeature_Dx11.cpp | 11 ++++ .../upscalers/xess/XeSSFeature_Dx12.cpp | 11 ++++ OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp | 11 ++++ 6 files changed, 116 insertions(+) diff --git a/OptiScaler/inputs/XeSS_Common.cpp b/OptiScaler/inputs/XeSS_Common.cpp index 4e7aa958..280382d2 100644 --- a/OptiScaler/inputs/XeSS_Common.cpp +++ b/OptiScaler/inputs/XeSS_Common.cpp @@ -413,6 +413,31 @@ xess_result_t hk_xessSetExposureMultiplier(xess_context_handle_t hContext, float return XESS_RESULT_SUCCESS; } +xess_result_t hk_xessSetMaxResponsiveMaskValue(xess_context_handle_t hContext, float value) +{ + LOG_DEBUG("hContext: {}, value: {}", (size_t) hContext, value); + + if (!_nvParams.contains(hContext)) + return XESS_RESULT_ERROR_INVALID_CONTEXT; + + _nvParams[hContext]->Set("XeSS.MaxResponsiveMaskValue", value); + + return XESS_RESULT_SUCCESS; +} + +xess_result_t hk_xessGetMaxResponsiveMaskValue(xess_context_handle_t hContext, float* pValue) +{ + LOG_DEBUG("hContext: {}", (size_t) hContext); + + if (!_nvParams.contains(hContext)) + return XESS_RESULT_ERROR_INVALID_CONTEXT; + + if (_nvParams[hContext]->Get("XeSS.MaxResponsiveMaskValue", pValue) != NVSDK_NGX_Result_Success) + *pValue = 0.0f; + + return XESS_RESULT_SUCCESS; +} + xess_result_t hk_xessSetContextParameterF() { LOG_DEBUG(""); diff --git a/OptiScaler/inputs/XeSS_Common.h b/OptiScaler/inputs/XeSS_Common.h index 0f5cc381..23e403a0 100644 --- a/OptiScaler/inputs/XeSS_Common.h +++ b/OptiScaler/inputs/XeSS_Common.h @@ -28,6 +28,8 @@ xess_result_t hk_xessGetOptimalInputResolution(xess_context_handle_t hContext, c xess_result_t hk_xessGetVelocityScale(xess_context_handle_t hContext, float* pX, float* pY); xess_result_t hk_xessSetJitterScale(xess_context_handle_t hContext, float x, float y); xess_result_t hk_xessSetExposureMultiplier(xess_context_handle_t hContext, float scale); +xess_result_t hk_xessSetMaxResponsiveMaskValue(xess_context_handle_t hContext, float value); +xess_result_t hk_xessGetMaxResponsiveMaskValue(xess_context_handle_t hContext, float* pValue); xess_result_t hk_xessSetContextParameterF(); xess_result_t hk_xessAILGetDecision(); xess_result_t hk_xessAILGetVersion(); diff --git a/OptiScaler/proxies/XeSS_Proxy.h b/OptiScaler/proxies/XeSS_Proxy.h index 22e053b1..60a17acc 100644 --- a/OptiScaler/proxies/XeSS_Proxy.h +++ b/OptiScaler/proxies/XeSS_Proxy.h @@ -48,6 +48,8 @@ typedef decltype(&xessGetJitterScale) PFN_xessGetJitterScale; typedef decltype(&xessGetOptimalInputResolution) PFN_xessGetOptimalInputResolution; typedef decltype(&xessSetExposureMultiplier) PFN_xessSetExposureMultiplier; typedef decltype(&xessSetJitterScale) PFN_xessSetJitterScale; +typedef decltype(&xessSetMaxResponsiveMaskValue) PFN_xessSetMaxResponsiveMaskValue; +typedef decltype(&xessGetMaxResponsiveMaskValue) PFN_xessGetMaxResponsiveMaskValue; typedef decltype(&xessD3D12GetResourcesToDump) PFN_xessD3D12GetResourcesToDump; typedef decltype(&xessD3D12GetProfilingData) PFN_xessD3D12GetProfilingData; @@ -101,6 +103,8 @@ struct XeSSModule PFN_xessGetOptimalInputResolution xessGetOptimalInputResolution = nullptr; PFN_xessSetExposureMultiplier xessSetExposureMultiplier = nullptr; PFN_xessSetJitterScale xessSetJitterScale = nullptr; + PFN_xessSetMaxResponsiveMaskValue xessSetMaxResponsiveMaskValue = nullptr; + PFN_xessGetMaxResponsiveMaskValue xessGetMaxResponsiveMaskValue = nullptr; PFN_xessD3D12GetResourcesToDump xessD3D12GetResourcesToDump = nullptr; PFN_xessD3D12GetProfilingData xessD3D12GetProfilingData = nullptr; @@ -146,6 +150,8 @@ struct XeSSDx11Module PFN_xessGetOptimalInputResolution xessGetOptimalInputResolutionDx11 = nullptr; PFN_xessSetExposureMultiplier xessSetExposureMultiplierDx11 = nullptr; PFN_xessSetJitterScale xessSetJitterScaleDx11 = nullptr; + PFN_xessSetMaxResponsiveMaskValue xessSetMaxResponsiveMaskValueDx11 = nullptr; + PFN_xessGetMaxResponsiveMaskValue xessGetMaxResponsiveMaskValueDx11 = nullptr; PFN_xessSetContextParameterF xessSetContextParameterFDx11 = nullptr; PFN_xessGetPipelineBuildStatus xessGetPipelineBuildStatusDx11 = nullptr; }; @@ -305,6 +311,12 @@ class XeSSProxy _module.dll, "xessSetExposureMultiplier"); _module.xessSetJitterScale = (PFN_xessSetJitterScale) KernelBaseProxy::GetProcAddress_()(_module.dll, "xessSetJitterScale"); + _module.xessSetMaxResponsiveMaskValue = + (PFN_xessSetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module.dll, + "xessSetMaxResponsiveMaskValue"); + _module.xessGetMaxResponsiveMaskValue = + (PFN_xessGetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module.dll, + "xessGetMaxResponsiveMaskValue"); _module.xessD3D12GetResourcesToDump = (PFN_xessD3D12GetResourcesToDump) KernelBaseProxy::GetProcAddress_()( _module.dll, "xessD3D12GetResourcesToDump"); @@ -388,6 +400,12 @@ class XeSSProxy "xessSetExposureMultiplier"); _module_hooked.xessSetJitterScale = (PFN_xessSetJitterScale) KernelBaseProxy::GetProcAddress_()(_module_hooked.dll, "xessSetJitterScale"); + _module_hooked.xessSetMaxResponsiveMaskValue = + (PFN_xessSetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module_hooked.dll, + "xessSetMaxResponsiveMaskValue"); + _module_hooked.xessGetMaxResponsiveMaskValue = + (PFN_xessGetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module_hooked.dll, + "xessGetMaxResponsiveMaskValue"); _module_hooked.xessD3D12GetResourcesToDump = (PFN_xessD3D12GetResourcesToDump) KernelBaseProxy::GetProcAddress_()(_module_hooked.dll, @@ -498,6 +516,12 @@ class XeSSProxy if (_module_hooked.xessSetJitterScale != nullptr) DetourAttach(&(PVOID&) _module_hooked.xessSetJitterScale, hk_xessSetJitterScale); + if (_module_hooked.xessSetMaxResponsiveMaskValue != nullptr) + DetourAttach(&(PVOID&) _module_hooked.xessSetMaxResponsiveMaskValue, hk_xessSetMaxResponsiveMaskValue); + + if (_module_hooked.xessGetMaxResponsiveMaskValue != nullptr) + DetourAttach(&(PVOID&) _module_hooked.xessGetMaxResponsiveMaskValue, hk_xessGetMaxResponsiveMaskValue); + if (_module_hooked.xessD3D12GetResourcesToDump != nullptr) DetourAttach(&(PVOID&) _module_hooked.xessD3D12GetResourcesToDump, hk_xessD3D12GetResourcesToDump); @@ -565,6 +589,8 @@ class XeSSProxy _module_hooked.xessGetOptimalInputResolution = nullptr; _module_hooked.xessSetExposureMultiplier = nullptr; _module_hooked.xessSetJitterScale = nullptr; + _module_hooked.xessSetMaxResponsiveMaskValue = nullptr; + _module_hooked.xessGetMaxResponsiveMaskValue = nullptr; _module_hooked.xessD3D12GetResourcesToDump = nullptr; _module_hooked.xessD3D12GetProfilingData = nullptr; _module_hooked.xessSetContextParameterF = nullptr; @@ -702,6 +728,12 @@ class XeSSProxy "xessSetExposureMultiplier"); _module11.xessSetJitterScaleDx11 = (PFN_xessSetJitterScale) KernelBaseProxy::GetProcAddress_()(_module11.dll, "xessSetJitterScale"); + _module11.xessSetMaxResponsiveMaskValueDx11 = + (PFN_xessSetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module11.dll, + "xessSetMaxResponsiveMaskValue"); + _module11.xessGetMaxResponsiveMaskValueDx11 = + (PFN_xessGetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module11.dll, + "xessGetMaxResponsiveMaskValue"); _module11.xessSetLoggingCallbackDx11 = (PFN_xessSetLoggingCallback) KernelBaseProxy::GetProcAddress_()( _module11.dll, "xessSetLoggingCallback"); _module11.xessSetVelocityScaleDx11 = @@ -763,6 +795,12 @@ class XeSSProxy "xessSetExposureMultiplier"); _module11_hooked.xessSetJitterScaleDx11 = (PFN_xessSetJitterScale) KernelBaseProxy::GetProcAddress_()(_module11_hooked.dll, "xessSetJitterScale"); + _module11_hooked.xessSetMaxResponsiveMaskValueDx11 = + (PFN_xessSetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module11_hooked.dll, + "xessSetMaxResponsiveMaskValue"); + _module11_hooked.xessGetMaxResponsiveMaskValueDx11 = + (PFN_xessGetMaxResponsiveMaskValue) KernelBaseProxy::GetProcAddress_()(_module11_hooked.dll, + "xessGetMaxResponsiveMaskValue"); _module11_hooked.xessSetLoggingCallbackDx11 = (PFN_xessSetLoggingCallback) KernelBaseProxy::GetProcAddress_()(_module11_hooked.dll, "xessSetLoggingCallback"); @@ -844,6 +882,14 @@ class XeSSProxy if (_module11_hooked.xessSetJitterScaleDx11 != nullptr) DetourAttach(&(PVOID&) _module11_hooked.xessSetJitterScaleDx11, hk_xessSetJitterScale); + if (_module11_hooked.xessSetMaxResponsiveMaskValueDx11 != nullptr) + DetourAttach(&(PVOID&) _module11_hooked.xessSetMaxResponsiveMaskValueDx11, + hk_xessSetMaxResponsiveMaskValue); + + if (_module11_hooked.xessGetMaxResponsiveMaskValueDx11 != nullptr) + DetourAttach(&(PVOID&) _module11_hooked.xessGetMaxResponsiveMaskValueDx11, + hk_xessGetMaxResponsiveMaskValue); + if (_module11_hooked.xessSetLoggingCallbackDx11 != nullptr) DetourAttach(&(PVOID&) _module11_hooked.xessSetLoggingCallbackDx11, hk_xessSetLoggingCallback); @@ -877,6 +923,8 @@ class XeSSProxy _module11_hooked.xessSetContextParameterFDx11 = nullptr; _module11_hooked.xessSetExposureMultiplierDx11 = nullptr; _module11_hooked.xessSetJitterScaleDx11 = nullptr; + _module11_hooked.xessSetMaxResponsiveMaskValueDx11 = nullptr; + _module11_hooked.xessGetMaxResponsiveMaskValueDx11 = nullptr; _module11_hooked.xessSetLoggingCallbackDx11 = nullptr; _module11_hooked.xessSetVelocityScaleDx11 = nullptr; _module11_hooked.xessStartDumpDx11 = nullptr; @@ -962,6 +1010,10 @@ class XeSSProxy } static PFN_xessSetExposureMultiplier SetExposureMultiplier() { return _module.xessSetExposureMultiplier; } static PFN_xessSetJitterScale SetJitterScale() { return _module.xessSetJitterScale; } + static PFN_xessSetMaxResponsiveMaskValue SetMaxResponsiveMaskValue() + { + return _module.xessSetMaxResponsiveMaskValue; + } static PFN_xessD3D12GetResourcesToDump D3D12GetResourcesToDump() { return _module.xessD3D12GetResourcesToDump; } static PFN_xessD3D12GetProfilingData D3D12GetProfilingData() { return _module.xessD3D12GetProfilingData; } static PFN_xessSetContextParameterF SetContextParameterF() { return _module.xessSetContextParameterF; } @@ -1017,4 +1069,8 @@ class XeSSProxy return _module11.xessSetExposureMultiplierDx11; } static PFN_xessSetJitterScale D3D11SetJitterScale() { return _module11.xessSetJitterScaleDx11; } + static PFN_xessSetMaxResponsiveMaskValue D3D11SetMaxResponsiveMaskValue() + { + return _module11.xessSetMaxResponsiveMaskValueDx11; + } }; diff --git a/OptiScaler/upscalers/xess/XeSSFeature_Dx11.cpp b/OptiScaler/upscalers/xess/XeSSFeature_Dx11.cpp index 9394cb1b..51fb8b25 100644 --- a/OptiScaler/upscalers/xess/XeSSFeature_Dx11.cpp +++ b/OptiScaler/upscalers/xess/XeSSFeature_Dx11.cpp @@ -416,6 +416,17 @@ bool XeSSFeature_Dx11::EvaluateInternal(ID3D11DeviceContext* DeviceContext, NVSD else LOG_WARN("Can't get motion vector scales!"); + float maxResponsiveMaskValue = 1.0f; + + if (InParameters->Get("XeSS.MaxResponsiveMaskValue", &maxResponsiveMaskValue) == NVSDK_NGX_Result_Success && + XeSSProxy::D3D11SetMaxResponsiveMaskValue() != nullptr) + { + xessResult = XeSSProxy::D3D11SetMaxResponsiveMaskValue()(_xessContext, maxResponsiveMaskValue); + + if (xessResult != XESS_RESULT_SUCCESS) + LOG_ERROR("xessSetMaxResponsiveMaskValue: {0}", ResultToString(xessResult)); + } + InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, ¶ms.inputColorBase.x); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, ¶ms.inputColorBase.y); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, ¶ms.inputDepthBase.x); diff --git a/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp b/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp index 36309946..2a6be74c 100644 --- a/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp +++ b/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp @@ -286,6 +286,17 @@ bool XeSSFeatureDx12::EvaluateInternal(ID3D12GraphicsCommandList* InCommandList, else LOG_WARN("Can't get motion vector scales!"); + float maxResponsiveMaskValue = 1.0f; + + if (InParameters->Get("XeSS.MaxResponsiveMaskValue", &maxResponsiveMaskValue) == NVSDK_NGX_Result_Success && + XeSSProxy::SetMaxResponsiveMaskValue() != nullptr) + { + xessResult = XeSSProxy::SetMaxResponsiveMaskValue()(_xessContext, maxResponsiveMaskValue); + + if (xessResult != XESS_RESULT_SUCCESS) + LOG_ERROR("xessSetMaxResponsiveMaskValue: {0}", ResultToString(xessResult)); + } + InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, ¶ms.inputColorBase.x); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, ¶ms.inputColorBase.y); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, ¶ms.inputDepthBase.x); diff --git a/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp b/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp index f622cee1..2efec482 100644 --- a/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp +++ b/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp @@ -438,6 +438,17 @@ bool XeSSFeature_Vk::EvaluateInternal(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Par else LOG_WARN("Can't get motion vector scales!"); + float maxResponsiveMaskValue = 1.0f; + + if (InParameters->Get("XeSS.MaxResponsiveMaskValue", &maxResponsiveMaskValue) == NVSDK_NGX_Result_Success && + XeSSProxy::SetMaxResponsiveMaskValue() != nullptr) + { + xessResult = XeSSProxy::SetMaxResponsiveMaskValue()(_xessContext, maxResponsiveMaskValue); + + if (xessResult != XESS_RESULT_SUCCESS) + LOG_ERROR("xessSetMaxResponsiveMaskValue: {0}", ResultToString(xessResult)); + } + InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_X, ¶ms.inputColorBase.x); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Color_Subrect_Base_Y, ¶ms.inputColorBase.y); InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Depth_Subrect_Base_X, ¶ms.inputDepthBase.x);