From 086113a546bd7e1af93fbee67eb29a26369a705c Mon Sep 17 00:00:00 2001 From: Maple <8961085+MapleHinata@users.noreply.github.com> Date: Thu, 19 Jun 2025 05:41:08 -0300 Subject: [PATCH 01/10] Fix unity dx11 (#532) * Revert "Improve typeless texture support of Dx11 native upscalers" This reverts commit e38fa9262b2e86ab4390674adeb46a09eff54f46. * Fix FSR Dispatch not working thanks to bound RTVs. * Fix clang format --- OptiScaler/upscalers/IFeature_Dx11.cpp | 6 - OptiScaler/upscalers/IFeature_Dx11.h | 2 - .../upscalers/fsr2/FSR2Feature_Dx11.cpp | 201 ++---------------- OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.h | 5 - .../upscalers/fsr31/FSR31Feature_Dx11.cpp | 170 ++------------- .../upscalers/fsr31/FSR31Feature_Dx11.h | 4 - 6 files changed, 39 insertions(+), 349 deletions(-) diff --git a/OptiScaler/upscalers/IFeature_Dx11.cpp b/OptiScaler/upscalers/IFeature_Dx11.cpp index 916407ec..1485c863 100644 --- a/OptiScaler/upscalers/IFeature_Dx11.cpp +++ b/OptiScaler/upscalers/IFeature_Dx11.cpp @@ -36,10 +36,4 @@ IFeature_Dx11::~IFeature_Dx11() Bias.reset(); Bias = nullptr; } - - if (DT != nullptr && DT.get() != nullptr) - { - DT.reset(); - DT = nullptr; - } } diff --git a/OptiScaler/upscalers/IFeature_Dx11.h b/OptiScaler/upscalers/IFeature_Dx11.h index b80ec0e6..c5e84673 100644 --- a/OptiScaler/upscalers/IFeature_Dx11.h +++ b/OptiScaler/upscalers/IFeature_Dx11.h @@ -4,7 +4,6 @@ #include #include #include -#include class IFeature_Dx11 : public virtual IFeature { @@ -16,7 +15,6 @@ class IFeature_Dx11 : public virtual IFeature std::unique_ptr OutputScaler = nullptr; std::unique_ptr RCAS = nullptr; std::unique_ptr Bias = nullptr; - std::unique_ptr DT = nullptr; public: virtual bool Init(ID3D11Device* InDevice, ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters) = 0; diff --git a/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.cpp b/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.cpp index 28ea990f..e9b23e52 100644 --- a/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.cpp +++ b/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.cpp @@ -4,8 +4,6 @@ #include "FSR2Feature_Dx11.h" -#include - #define ASSIGN_DESC(dest, src) \ dest.Width = src.Width; \ dest.Height = src.Height; \ @@ -22,48 +20,6 @@ } \ } while ((void) 0, 0); -static inline DXGI_FORMAT resolveTypelessFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - - case DXGI_FORMAT_R16G16_TYPELESS: - return DXGI_FORMAT_R16G16_FLOAT; - - case DXGI_FORMAT_R32G32_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UNORM; - - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; - - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_FLOAT; - - case DXGI_FORMAT_R8G8_TYPELESS: - return DXGI_FORMAT_R8G8_UNORM; - - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_R16_FLOAT; - - case DXGI_FORMAT_R8_TYPELESS: - return DXGI_FORMAT_R8_UNORM; - - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - - default: - return format; // Already typed or unknown - } -} - bool FSR2FeatureDx11::Init(ID3D11Device* InDevice, ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters) { LOG_FUNC(); @@ -101,9 +57,8 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE return false; originalTexture->GetDesc(&desc); - auto format = resolveTypelessFormat(desc.Format); - if ((bindFlags == 9999 || desc.BindFlags == bindFlags) && desc.Format == format) + if (desc.BindFlags == bindFlags) { ASSIGN_DESC(OutTextureRes->Desc, desc); OutTextureRes->Texture = originalTexture; @@ -112,7 +67,7 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE } if (OutTextureRes->usingOriginal || OutTextureRes->Texture == nullptr || desc.Width != OutTextureRes->Desc.Width || - desc.Height != OutTextureRes->Desc.Height || format != OutTextureRes->Desc.Format || + desc.Height != OutTextureRes->Desc.Height || desc.Format != OutTextureRes->Desc.Format || desc.BindFlags != OutTextureRes->Desc.BindFlags) { if (OutTextureRes->Texture != nullptr) @@ -123,7 +78,6 @@ bool FSR2FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RE OutTextureRes->Texture = nullptr; } - desc.Format = format; OutTextureRes->usingOriginal = false; ASSIGN_DESC(OutTextureRes->Desc, desc); @@ -151,31 +105,6 @@ void FSR2FeatureDx11::ReleaseResources() { SAFE_RELEASE(bufferColor.Texture); } - - if (!bufferDepth.usingOriginal) - { - SAFE_RELEASE(bufferDepth.Texture); - } - - if (!bufferExposure.usingOriginal) - { - SAFE_RELEASE(bufferExposure.Texture); - } - - if (!bufferReactive.usingOriginal) - { - SAFE_RELEASE(bufferReactive.Texture); - } - - if (!bufferVelocity.usingOriginal) - { - SAFE_RELEASE(bufferVelocity.Texture); - } - - if (!bufferTransparency.usingOriginal) - { - SAFE_RELEASE(bufferTransparency.Texture); - } } bool FSR2FeatureDx11::InitFSR2(const NVSDK_NGX_Parameter* InParameters) @@ -308,37 +237,6 @@ FSR2FeatureDx11::FSR2FeatureDx11(unsigned int InHandleId, NVSDK_NGX_Parameter* I { } -void FSR2FeatureDx11::LogResource(std::string name, ID3D11Texture2D* resource) -{ - if (_frameCount > 1) - return; - - D3D11_TEXTURE2D_DESC desc {}; - resource->GetDesc(&desc); - - LOG_DEBUG("{}: {}x{}, Format: {}, Usage: {}, Bind: {:X}, Misc: {:X}, CPU: {:X}, ArraySize: {}, MipLevels: {}, " - "SD.Count: {}, SD.Quality: {}", - name, desc.Width, desc.Height, magic_enum::enum_name(desc.Format), magic_enum::enum_name(desc.Usage), - desc.BindFlags, desc.MiscFlags, desc.CPUAccessFlags, desc.ArraySize, desc.MipLevels, - desc.SampleDesc.Count, desc.SampleDesc.Quality); -} - -void FSR2FeatureDx11::LogParams(FfxFsr2DispatchDescription* params) -{ - if (_frameCount > 1) - return; - - LOG_DEBUG("Color: {}x{}, Format: {}", params->color.description.width, params->color.description.height, - magic_enum::enum_name(params->color.description.format)); - LOG_DEBUG("Depth: {}x{}, Format: {}", params->depth.description.width, params->depth.description.height, - magic_enum::enum_name(params->depth.description.format)); - LOG_DEBUG("Velocity: {}x{}, Format: {}", params->motionVectors.description.width, - params->motionVectors.description.height, - magic_enum::enum_name(params->motionVectors.description.format)); - LOG_DEBUG("Output: {}x{}, Format: {}", params->output.description.width, params->output.description.height, - magic_enum::enum_name(params->output.description.format)); -} - bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Parameter* InParameters) { LOG_FUNC(); @@ -353,6 +251,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet ID3D11SamplerState* restoreSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {}; ID3D11Buffer* restoreCBVs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {}; ID3D11UnorderedAccessView* restoreUAVs[D3D11_1_UAV_SLOT_COUNT] = {}; + ID3D11RenderTargetView* restoreRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; + ID3D11DepthStencilView* restoreDSV = nullptr; // backup compute shader resources for (UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) @@ -379,6 +279,12 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet InContext->CSGetUnorderedAccessViews(i, 1, &restoreUAVs[i]); } + DeviceContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, &restoreDSV); + + // Unbind RenderTargets + ID3D11RenderTargetView* nullRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; + DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRTVs, nullptr); + FfxFsr2DispatchDescription params {}; params.commandList = InContext; @@ -422,8 +328,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet { LOG_DEBUG("Color exist.."); - LogResource("Color", (ID3D11Texture2D*) paramColor); - if (!CopyTexture(paramColor, &bufferColor, 40, true)) { LOG_DEBUG("Can't copy Color!"); @@ -447,20 +351,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet if (paramVelocity) { - LogResource("Velocity", (ID3D11Texture2D*) paramVelocity); - - if (!CopyTexture(paramVelocity, &bufferVelocity, 9999, true)) - { - LOG_DEBUG("Can't copy Velocity!"); - return false; - } - LOG_DEBUG("MotionVectors exist.."); - if (bufferVelocity.Texture != nullptr) - params.motionVectors = - ffxGetResourceDX11(&_context, bufferVelocity.Texture, (wchar_t*) L"FSR2_MotionVectors"); - else - params.motionVectors = ffxGetResourceDX11(&_context, paramVelocity, (wchar_t*) L"FSR2_MotionVectors"); + params.motionVectors = ffxGetResourceDX11(&_context, paramVelocity, (wchar_t*) L"FSR2_MotionVectors"); } else { @@ -476,8 +368,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet if (paramOutput) { - LogResource("Output", (ID3D11Texture2D*) paramOutput); - LOG_DEBUG("Output exist.."); if (useSS) @@ -518,38 +408,7 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet if (paramDepth) { LOG_DEBUG("Depth exist.."); - auto depthTexture = (ID3D11Texture2D*) paramDepth; - LogResource("Depth", depthTexture); - - D3D11_TEXTURE2D_DESC desc {}; - depthTexture->GetDesc(&desc); - - if (desc.Format == DXGI_FORMAT_R24G8_TYPELESS || desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS) - { - if (DT == nullptr || DT.get() == nullptr) - DT = std::make_unique("DT", Device); - - if (DT->Buffer() == nullptr) - DT->CreateBufferResource(Device, paramDepth); - - if (DT->CanRender() && DT->Dispatch(Device, DeviceContext, depthTexture, DT->Buffer())) - params.depth = ffxGetResourceDX11(&_context, DT->Buffer(), (wchar_t*) L"FSR2_Depth"); - else - params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth"); - } - else - { - if (!CopyTexture(paramDepth, &bufferDepth, 9999, true)) - { - LOG_DEBUG("Can't copy Depth!"); - return false; - } - - if (bufferDepth.Texture != nullptr) - params.depth = ffxGetResourceDX11(&_context, bufferDepth.Texture, (wchar_t*) L"FSR2_Depth"); - else - params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth"); - } + params.depth = ffxGetResourceDX11(&_context, paramDepth, (wchar_t*) L"FSR2_Depth"); } else { @@ -569,19 +428,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet if (paramExp) { - LogResource("Exposure", (ID3D11Texture2D*) paramExp); - - if (!CopyTexture(paramExp, &bufferExposure, 9999, true)) - { - LOG_DEBUG("Can't copy Exposure!"); - return false; - } - + params.exposure = ffxGetResourceDX11(&_context, paramExp, (wchar_t*) L"FSR2_Exposure"); LOG_DEBUG("ExposureTexture exist.."); - if (bufferExposure.Texture != nullptr) - params.exposure = ffxGetResourceDX11(&_context, bufferExposure.Texture, (wchar_t*) L"FSR2_Exposure"); - else - params.exposure = ffxGetResourceDX11(&_context, paramExp, (wchar_t*) L"FSR2_Exposure"); } else { @@ -601,27 +449,12 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet { if (paramReactiveMask) { - LogResource("Input Bias", (ID3D11Texture2D*) paramReactiveMask); - LOG_DEBUG("Input Bias mask exist.."); Config::Instance()->DisableReactiveMask.set_volatile_value(false); if (Config::Instance()->FsrUseMaskForTransparency.value_or_default()) - { - if (!CopyTexture(paramReactiveMask, &bufferTransparency, 9999, true)) - { - LOG_DEBUG("Can't copy Exposure!"); - return false; - } - - if (bufferTransparency.Texture != nullptr) - params.transparencyAndComposition = - ffxGetResourceDX11(&_context, bufferTransparency.Texture, (wchar_t*) L"FSR2_Transparency", - FFX_RESOURCE_STATE_COMPUTE_READ); - else - params.transparencyAndComposition = ffxGetResourceDX11( - &_context, paramReactiveMask, (wchar_t*) L"FSR2_Transparency", FFX_RESOURCE_STATE_COMPUTE_READ); - } + params.transparencyAndComposition = ffxGetResourceDX11( + &_context, paramReactiveMask, (wchar_t*) L"FSR2_Transparency", FFX_RESOURCE_STATE_COMPUTE_READ); if (Config::Instance()->DlssReactiveMaskBias.value_or_default() > 0.0f && Bias->IsInit() && Bias->CreateBufferResource(Device, paramReactiveMask) && Bias->CanRender()) @@ -695,8 +528,6 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, ¶ms.preExposure) != NVSDK_NGX_Result_Success) params.preExposure = 1.0f; - LogParams(¶ms); - LOG_DEBUG("Dispatch!!"); auto result = ffxFsr2ContextDispatch(&_context, ¶ms); @@ -800,6 +631,8 @@ bool FSR2FeatureDx11::Evaluate(ID3D11DeviceContext* InContext, NVSDK_NGX_Paramet InContext->CSSetUnorderedAccessViews(i, 1, &restoreUAVs[i], 0); } + DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, restoreDSV); + _frameCount++; return true; diff --git a/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.h b/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.h index 619019cd..9c710385 100644 --- a/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.h +++ b/OptiScaler/upscalers/fsr2/FSR2Feature_Dx11.h @@ -27,16 +27,11 @@ class FSR2FeatureDx11 : public FSR2Feature, public IFeature_Dx11 D3D11_TEXTURE2D_RESOURCE_C bufferColor = {}; D3D11_TEXTURE2D_RESOURCE_C bufferDepth = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferExposure = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferTransparency = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferReactive = {}; D3D11_TEXTURE2D_RESOURCE_C bufferVelocity = {}; bool CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RESOURCE_C* OutTextureDesc, UINT bindFlags, bool InCopy); void ReleaseResources(); - void LogResource(std::string name, ID3D11Texture2D* resource); - void LogParams(FfxFsr2DispatchDescription* params); protected: bool InitFSR2(const NVSDK_NGX_Parameter* InParameters) override; diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp index 455464ed..b5a80fa0 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp @@ -52,48 +52,6 @@ bool FSR31FeatureDx11::Init(ID3D11Device* InDevice, ID3D11DeviceContext* InConte return false; } -static inline DXGI_FORMAT resolveTypelessFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - - case DXGI_FORMAT_R16G16_TYPELESS: - return DXGI_FORMAT_R16G16_FLOAT; - - case DXGI_FORMAT_R32G32_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UNORM; - - case DXGI_FORMAT_R32G8X24_TYPELESS: - return DXGI_FORMAT_R32G32_FLOAT; - - case DXGI_FORMAT_R32_TYPELESS: - return DXGI_FORMAT_R32_FLOAT; - - case DXGI_FORMAT_R8G8_TYPELESS: - return DXGI_FORMAT_R8G8_UNORM; - - case DXGI_FORMAT_R16_TYPELESS: - return DXGI_FORMAT_R16_FLOAT; - - case DXGI_FORMAT_R8_TYPELESS: - return DXGI_FORMAT_R8_UNORM; - - case DXGI_FORMAT_R24G8_TYPELESS: - return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - - default: - return format; // Already typed or unknown - } -} - // register a DX11 resource to the backend Fsr31::FfxResource ffxGetResource(ID3D11Resource* dx11Resource, wchar_t const* ffxResName, Fsr31::FfxResourceStates state = Fsr31::FFX_RESOURCE_STATE_COMPUTE_READ) @@ -125,9 +83,8 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R return false; originalTexture->GetDesc(&desc); - auto format = resolveTypelessFormat(desc.Format); - if ((bindFlags == 9999 || desc.BindFlags == bindFlags) && desc.Format == format) + if (desc.BindFlags == bindFlags) { ASSIGN_DESC(OutTextureRes->Desc, desc); OutTextureRes->Texture = originalTexture; @@ -136,7 +93,7 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R } if (OutTextureRes->usingOriginal || OutTextureRes->Texture == nullptr || desc.Width != OutTextureRes->Desc.Width || - desc.Height != OutTextureRes->Desc.Height || format != OutTextureRes->Desc.Format || + desc.Height != OutTextureRes->Desc.Height || desc.Format != OutTextureRes->Desc.Format || desc.BindFlags != OutTextureRes->Desc.BindFlags) { if (OutTextureRes->Texture != nullptr) @@ -147,7 +104,6 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R OutTextureRes->Texture = nullptr; } - desc.Format = format; OutTextureRes->usingOriginal = false; ASSIGN_DESC(OutTextureRes->Desc, desc); @@ -171,35 +127,12 @@ bool FSR31FeatureDx11::CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_R void FSR31FeatureDx11::ReleaseResources() { + LOG_FUNC(); + if (!bufferColor.usingOriginal) { SAFE_RELEASE(bufferColor.Texture); } - - if (!bufferDepth.usingOriginal) - { - SAFE_RELEASE(bufferDepth.Texture); - } - - if (!bufferExposure.usingOriginal) - { - SAFE_RELEASE(bufferExposure.Texture); - } - - if (!bufferReactive.usingOriginal) - { - SAFE_RELEASE(bufferReactive.Texture); - } - - if (!bufferVelocity.usingOriginal) - { - SAFE_RELEASE(bufferVelocity.Texture); - } - - if (!bufferTransparency.usingOriginal) - { - SAFE_RELEASE(bufferTransparency.Texture); - } } bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Parameter* InParameters) @@ -219,6 +152,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa ID3D11SamplerState* restoreSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT] = {}; ID3D11Buffer* restoreCBVs[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT] = {}; ID3D11UnorderedAccessView* restoreUAVs[D3D11_1_UAV_SLOT_COUNT] = {}; + ID3D11RenderTargetView* restoreRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; + ID3D11DepthStencilView* restoreDSV = nullptr; // backup compute shader resources for (UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) @@ -245,6 +180,12 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa DeviceContext->CSGetUnorderedAccessViews(i, 1, &restoreUAVs[i]); } + DeviceContext->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, &restoreDSV); + + // Unbind RenderTargets + ID3D11RenderTargetView* nullRTVs[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT] = {}; + DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, nullRTVs, nullptr); + Fsr31::FfxFsr3DispatchUpscaleDescription params {}; if (Config::Instance()->FsrDebugView.value_or_default()) @@ -325,19 +266,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa if (paramVelocity) { LOG_DEBUG("MotionVectors exist.."); - - if (!CopyTexture(paramVelocity, &bufferVelocity, 9999, true)) - { - LOG_DEBUG("Can't copy Velocity!"); - return false; - } - - if (bufferVelocity.Texture != nullptr) - params.motionVectors = ffxGetResource(bufferVelocity.Texture, L"FSR3_InputMotionVectors", - Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - else - params.motionVectors = - ffxGetResource(paramVelocity, L"FSR3_InputMotionVectors", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); + params.motionVectors = + ffxGetResource(paramVelocity, L"FSR3_InputMotionVectors", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); } else { @@ -390,39 +320,7 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa if (paramDepth) { LOG_DEBUG("Depth exist.."); - - auto depthTexture = (ID3D11Texture2D*) paramDepth; - - D3D11_TEXTURE2D_DESC desc {}; - depthTexture->GetDesc(&desc); - - if (desc.Format == DXGI_FORMAT_R24G8_TYPELESS || desc.Format == DXGI_FORMAT_R32G8X24_TYPELESS) - { - if (DT == nullptr || DT.get() == nullptr) - DT = std::make_unique("DT", Device); - - if (DT->Buffer() == nullptr) - DT->CreateBufferResource(Device, paramDepth); - - if (DT->CanRender() && DT->Dispatch(Device, DeviceContext, depthTexture, DT->Buffer())) - params.depth = - ffxGetResource(DT->Buffer(), L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - else - ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - } - else - { - if (!CopyTexture(paramDepth, &bufferDepth, 9999, true)) - { - LOG_DEBUG("Can't copy Depth!"); - return false; - } - - if (bufferDepth.Texture != nullptr) - ffxGetResource(bufferDepth.Texture, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - else - ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - } + params.depth = ffxGetResource(paramDepth, L"FSR3_InputDepth", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); } else { @@ -444,20 +342,9 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa if (paramExp) { + params.exposure = + ffxGetResource(paramExp, L"FSR3_InputExposure", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); LOG_DEBUG("ExposureTexture exist.."); - - if (!CopyTexture(paramExp, &bufferExposure, 9999, true)) - { - LOG_DEBUG("Can't copy Exposure!"); - return false; - } - - if (bufferVelocity.Texture != nullptr) - params.exposure = ffxGetResource(bufferVelocity.Texture, L"FSR3_InputExposure", - Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - else - params.exposure = - ffxGetResource(paramExp, L"FSR3_InputExposure", Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); } else { @@ -481,22 +368,9 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa Config::Instance()->DisableReactiveMask.set_volatile_value(false); if (Config::Instance()->FsrUseMaskForTransparency.value_or_default()) - { - if (!CopyTexture(paramReactiveMask, &bufferTransparency, 9999, true)) - { - LOG_DEBUG("Can't copy Transparency!"); - return false; - } - - if (bufferVelocity.Texture != nullptr) - params.transparencyAndComposition = - ffxGetResource(bufferVelocity.Texture, L"FSR3_TransparencyAndCompositionMap", - Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - else - params.transparencyAndComposition = - ffxGetResource(paramReactiveMask, L"FSR3_TransparencyAndCompositionMap", - Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); - } + params.transparencyAndComposition = + ffxGetResource(paramReactiveMask, L"FSR3_TransparencyAndCompositionMap", + Fsr31::FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ); if (Config::Instance()->DlssReactiveMaskBias.value_or_default() > 0.0f && Bias->IsInit() && Bias->CreateBufferResource(Device, paramReactiveMask) && Bias->CanRender()) @@ -701,6 +575,8 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa DeviceContext->CSSetUnorderedAccessViews(i, 1, &restoreUAVs[i], 0); } + DeviceContext->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, restoreRTVs, restoreDSV); + _frameCount++; return true; @@ -711,8 +587,6 @@ FSR31FeatureDx11::~FSR31FeatureDx11() if (!IsInited()) return; - ReleaseResources(); - if (!State::Instance().isShuttingDown) { auto errorCode = Fsr31::ffxFsr3ContextDestroy(&_upscalerContext); diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.h b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.h index 243cefea..4c39c3a7 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.h +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.h @@ -81,14 +81,10 @@ class FSR31FeatureDx11 : public FSR31Feature, public IFeature_Dx11 D3D11_TEXTURE2D_RESOURCE_C bufferColor = {}; D3D11_TEXTURE2D_RESOURCE_C bufferDepth = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferExposure = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferTransparency = {}; - D3D11_TEXTURE2D_RESOURCE_C bufferReactive = {}; D3D11_TEXTURE2D_RESOURCE_C bufferVelocity = {}; bool CopyTexture(ID3D11Resource* InResource, D3D11_TEXTURE2D_RESOURCE_C* OutTextureDesc, UINT bindFlags, bool InCopy); - void ReleaseResources(); protected: From 06f9c7e1f38089b6fc808a21959fdcc7f975301e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Lewandowski?= <49685661+FakeMichau@users.noreply.github.com> Date: Thu, 19 Jun 2025 10:41:19 +0200 Subject: [PATCH 02/10] Implement comparisons for feature_version (#528) --- OptiScaler/framegen/ffx/FSRFG_Dx12.cpp | 2 +- OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp | 2 +- OptiScaler/inputs/XeSS_Dx12.cpp | 4 +- OptiScaler/inputs/XeSS_Vulkan.cpp | 4 +- OptiScaler/menu/menu_common.cpp | 40 ++++---- OptiScaler/nvapi/fakenvapi.cpp | 2 +- OptiScaler/pch.h | 39 ++++---- OptiScaler/upscalers/dlss/DLSSFeature.cpp | 2 +- .../upscalers/dlss/DLSSFeature_Dx11.cpp | 2 +- .../upscalers/dlss/DLSSFeature_Dx12.cpp | 2 +- OptiScaler/upscalers/dlssd/DLSSDFeature.cpp | 2 +- .../upscalers/fsr31/FSR31Feature_Dx11.cpp | 2 +- .../upscalers/fsr31/FSR31Feature_Dx11On12.cpp | 94 +++++++++---------- .../upscalers/fsr31/FSR31Feature_Dx12.cpp | 93 +++++++++--------- .../upscalers/fsr31/FSR31Feature_Vk.cpp | 93 +++++++++--------- .../upscalers/xess/XeSSFeature_Dx12.cpp | 8 +- OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp | 6 +- 17 files changed, 196 insertions(+), 201 deletions(-) diff --git a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp index 12e74702..674004ef 100644 --- a/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp +++ b/OptiScaler/framegen/ffx/FSRFG_Dx12.cpp @@ -23,7 +23,7 @@ void FSRFG_Dx12::ConfigureFramePaceTuning() { State::Instance().FSRFGFTPchanged = false; - if (_swapChainContext == nullptr || !isVersionOrBetter(Version(), { 3, 1, 3 })) + if (_swapChainContext == nullptr || Version() < feature_version { 3, 1, 3 }) return; FfxSwapchainFramePacingTuning fpt {}; diff --git a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp index e9f67eba..c181f00c 100644 --- a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp +++ b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp @@ -1253,7 +1253,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom auto* feature = deviceContext->feature.get(); // FSR 3.1 supports upscaleSize that doesn't need reinit to change output resolution - if (!(feature->Name().starts_with("FSR") && isVersionOrBetter(feature->Version(), { 3, 1, 0 })) && + if (!(feature->Name().starts_with("FSR") && feature->Version() >= feature_version { 3, 1, 0 }) && feature->UpdateOutputResolution(InParameters)) State::Instance().changeBackend[handleId] = true; } diff --git a/OptiScaler/inputs/XeSS_Dx12.cpp b/OptiScaler/inputs/XeSS_Dx12.cpp index e0cc3d7a..0ed0cfce 100644 --- a/OptiScaler/inputs/XeSS_Dx12.cpp +++ b/OptiScaler/inputs/XeSS_Dx12.cpp @@ -235,8 +235,8 @@ xess_result_t hk_xessD3D12Execute(xess_context_handle_t hContext, ID3D12Graphics params->Set(NVSDK_NGX_Parameter_Depth, pExecParams->pDepthTexture); params->Set(NVSDK_NGX_Parameter_ExposureTexture, pExecParams->pExposureScaleTexture); - if (!isVersionOrBetter({ XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch }, - { 2, 0, 1 })) + if (feature_version { XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch } < + feature_version { 2, 0, 1 }) params->Set(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, pExecParams->pResponsivePixelMaskTexture); else params->Set("FSR.reactive", pExecParams->pResponsivePixelMaskTexture); diff --git a/OptiScaler/inputs/XeSS_Vulkan.cpp b/OptiScaler/inputs/XeSS_Vulkan.cpp index 5f04f666..4407b874 100644 --- a/OptiScaler/inputs/XeSS_Vulkan.cpp +++ b/OptiScaler/inputs/XeSS_Vulkan.cpp @@ -288,8 +288,8 @@ xess_result_t hk_xessVKExecute(xess_context_handle_t hContext, VkCommandBuffer c { CreateNVRes(&pExecParams->responsivePixelMaskTexture, &biasNVRes[index]); - if (!isVersionOrBetter({ XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch }, - { 2, 0, 1 })) + if (feature_version { XeSSProxy::Version().major, XeSSProxy::Version().minor, XeSSProxy::Version().patch } < + feature_version { 2, 0, 1 }) params->Set(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, &biasNVRes[index]); else params->Set("FSR.reactive", &biasNVRes[index]); diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index f2626f36..4bcda384 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -2250,7 +2250,7 @@ bool MenuCommon::RenderMenu() if (State::Instance().currentFG != nullptr) fsrFG = reinterpret_cast(State::Instance().currentFG); - if (fsrFG != nullptr && isVersionOrBetter(FfxApiProxy::VersionDx12(), { 3, 1, 3 })) + if (fsrFG != nullptr && FfxApiProxy::VersionDx12() >= feature_version { 3, 1, 3 }) { ImGui::Spacing(); if (ImGui::TreeNode("Frame Pacing Tuning")) @@ -2570,7 +2570,7 @@ bool MenuCommon::RenderMenu() } ImGui::Spacing(); - if (isVersionOrBetter(currentFeature->Version(), { 3, 1, 1 }) && + if (currentFeature->Version() >= feature_version { 3, 1, 1 } && ImGui::CollapsingHeader("Upscaler Settings")) { ImGui::PushItemWidth(280.0f * Config::Instance()->MenuScale.value_or_default()); @@ -2583,28 +2583,25 @@ bool MenuCommon::RenderMenu() "Lower values are more stable with ghosting\n" "Higher values are more pixelly but less ghosting."); - if (isVersionOrBetter(currentFeature->Version(), { 3, 1, 4 })) + if (currentFeature->Version() >= feature_version { 3, 1, 4 }) { + // Reactive Scale float reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); if (ImGui::SliderFloat("Reactive Scale", &reactiveScale, 0.0f, 100.0f, "%.1f")) Config::Instance()->FsrReactiveScale = reactiveScale; ShowHelpMarker("Meant for development purpose to test if\n" "writing a larger value to reactive mask, reduces ghosting."); - } - if (isVersionOrBetter(currentFeature->Version(), { 3, 1, 4 })) - { + // Shading Scale float shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); if (ImGui::SliderFloat("Shading Scale", &shadingScale, 0.0f, 100.0f, "%.1f")) Config::Instance()->FsrShadingScale = shadingScale; ShowHelpMarker("Increasing this scales fsr3.1 computed shading\n" "change value at read to have higher reactiveness."); - } - if (isVersionOrBetter(currentFeature->Version(), { 3, 1, 4 })) - { + // Accumulation Added Per Frame float accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); if (ImGui::SliderFloat("Acc. Added Per Frame", &accAddPerFrame, 0.00f, 1.0f, "%.2f")) @@ -2617,10 +2614,8 @@ bool MenuCommon::RenderMenu() "drawing the ghosting object (IE no mv) to reactive mask \n" "with value close to 1.0f can decrease temporal ghosting.\n" "Decreasing this could result in more thin feature pixels flickering."); - } - if (isVersionOrBetter(currentFeature->Version(), { 3, 1, 4 })) - { + // Min Disocclusion Accumulation float minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); if (ImGui::SliderFloat("Min. Disocclusion Acc.", &minDisOccAcc, -1.0f, 1.0f, "%.2f")) @@ -2842,10 +2837,9 @@ bool MenuCommon::RenderMenu() // xess or dlss version >= 2.5.1 constexpr feature_version requiredDlssVersion = { 2, 5, 1 }; - rcasEnabled = - (currentBackend == "xess" || - (currentBackend == "dlss" && - isVersionOrBetter(State::Instance().currentFeature->Version(), requiredDlssVersion))); + rcasEnabled = (currentBackend == "xess" || + (currentBackend == "dlss" && + State::Instance().currentFeature->Version() >= requiredDlssVersion)); if (bool rcas = Config::Instance()->RcasEnabled.value_or(rcasEnabled); ImGui::Checkbox("Enable RCAS", &rcas)) @@ -3330,12 +3324,16 @@ bool MenuCommon::RenderMenu() auto accessToReactiveMask = State::Instance().currentFeature->AccessToReactiveMask(); ImGui::BeginDisabled(!accessToReactiveMask); - bool rm = Config::Instance()->DisableReactiveMask.value_or( - !accessToReactiveMask || currentBackend == "dlss" || - (currentBackend == "xess" && !isVersionOrBetter(currentFeature->Version(), { 2, 0, 1 }))); - if (ImGui::Checkbox("Disable Reactive Mask", &rm)) + bool canUseReactiveMask = + accessToReactiveMask && currentBackend != "dlss" && + (currentBackend != "xess" || currentFeature->Version() >= feature_version { 2, 0, 1 }); + + bool disableReactiveMask = + Config::Instance()->DisableReactiveMask.value_or(!canUseReactiveMask); + + if (ImGui::Checkbox("Disable Reactive Mask", &disableReactiveMask)) { - Config::Instance()->DisableReactiveMask = rm; + Config::Instance()->DisableReactiveMask = disableReactiveMask; if (currentBackend == "xess") { diff --git a/OptiScaler/nvapi/fakenvapi.cpp b/OptiScaler/nvapi/fakenvapi.cpp index 0d61637d..74b6f81f 100644 --- a/OptiScaler/nvapi/fakenvapi.cpp +++ b/OptiScaler/nvapi/fakenvapi.cpp @@ -46,7 +46,7 @@ void fakenvapi::reportFGPresent(IDXGISwapChain* pSwapChain, bool fg_state, bool // and it will call SetFrameGenFrameType for us auto static ffxApiVersion = FfxApiProxy::VersionDx12(); constexpr feature_version requiredVersion = { 3, 1, 1 }; - if (isVersionOrBetter(ffxApiVersion, requiredVersion) && updateModeAndContext()) + if (ffxApiVersion >= requiredVersion && updateModeAndContext()) { if (_lowLatencyContext != nullptr && _lowLatencyMode == Mode::AntiLag2) { diff --git a/OptiScaler/pch.h b/OptiScaler/pch.h index a40b7247..fec2ed33 100644 --- a/OptiScaler/pch.h +++ b/OptiScaler/pch.h @@ -71,35 +71,34 @@ inline DWORD processId; #define LOG_FUNC_RESULT(result) spdlog::trace(__FUNCTION__ " result: {0:X}", (UINT64) result) -typedef struct _feature_version +struct feature_version { unsigned int major; unsigned int minor; unsigned int patch; -} feature_version; -inline static bool isVersionOrBetter(const feature_version& current, const feature_version& required) -{ - if (current.major > required.major) + bool operator==(const feature_version& other) const { - return true; + return major == other.major && minor == other.minor && patch == other.patch; } - if (current.major == required.major) + + bool operator!=(const feature_version& other) const { return !(*this == other); } + + bool operator<(const feature_version& other) const { - if (current.minor > required.minor) - { - return true; - } - if (current.minor == required.minor) - { - if (current.patch >= required.patch) - { - return true; - } - } + if (major != other.major) + return major < other.major; + if (minor != other.minor) + return minor < other.minor; + return patch < other.patch; } - return false; -} + + bool operator>(const feature_version& other) const { return other < *this; } + + bool operator<=(const feature_version& other) const { return !(other < *this); } + + bool operator>=(const feature_version& other) const { return !(*this < other); } +}; inline static std::string wstring_to_string(const std::wstring& wide_str) { diff --git a/OptiScaler/upscalers/dlss/DLSSFeature.cpp b/OptiScaler/upscalers/dlss/DLSSFeature.cpp index a29a3206..f5c325dc 100644 --- a/OptiScaler/upscalers/dlss/DLSSFeature.cpp +++ b/OptiScaler/upscalers/dlss/DLSSFeature.cpp @@ -192,7 +192,7 @@ void DLSSFeature::ReadVersion() _version = GetVersionUsingNGXSnippet(possibleDlls); - if (isVersionOrBetter(_version, { 0, 0, 0 })) + if (_version > feature_version { 0, 0, 0 }) LOG_INFO("DLSS v{0}.{1}.{2} loaded.", _version.major, _version.minor, _version.patch); else LOG_WARN("Failed to get version using NVSDK_NGX_GetSnippetVersion!"); diff --git a/OptiScaler/upscalers/dlss/DLSSFeature_Dx11.cpp b/OptiScaler/upscalers/dlss/DLSSFeature_Dx11.cpp index 9d32bb6f..e887ea28 100644 --- a/OptiScaler/upscalers/dlss/DLSSFeature_Dx11.cpp +++ b/OptiScaler/upscalers/dlss/DLSSFeature_Dx11.cpp @@ -93,7 +93,7 @@ bool DLSSFeatureDx11::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_NGX_P NVSDK_NGX_Result nvResult; - bool rcasEnabled = isVersionOrBetter(Version(), { 2, 5, 1 }); + bool rcasEnabled = Version() >= feature_version { 2, 5, 1 }; if (Config::Instance()->RcasEnabled.value_or(rcasEnabled) && (RCAS == nullptr || RCAS.get() == nullptr || !RCAS->IsInit())) diff --git a/OptiScaler/upscalers/dlss/DLSSFeature_Dx12.cpp b/OptiScaler/upscalers/dlss/DLSSFeature_Dx12.cpp index af14d043..d8e35c61 100644 --- a/OptiScaler/upscalers/dlss/DLSSFeature_Dx12.cpp +++ b/OptiScaler/upscalers/dlss/DLSSFeature_Dx12.cpp @@ -99,7 +99,7 @@ bool DLSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N return false; } - bool rcasEnabled = isVersionOrBetter(Version(), { 2, 5, 1 }); + bool rcasEnabled = Version() >= feature_version { 2, 5, 1 }; if (Config::Instance()->RcasEnabled.value_or(rcasEnabled) && (RCAS == nullptr || RCAS.get() == nullptr || !RCAS->IsInit())) diff --git a/OptiScaler/upscalers/dlssd/DLSSDFeature.cpp b/OptiScaler/upscalers/dlssd/DLSSDFeature.cpp index f8360602..30ae4590 100644 --- a/OptiScaler/upscalers/dlssd/DLSSDFeature.cpp +++ b/OptiScaler/upscalers/dlssd/DLSSDFeature.cpp @@ -186,7 +186,7 @@ void DLSSDFeature::ReadVersion() _version = GetVersionUsingNGXSnippet(possibleDlls); - if (isVersionOrBetter(_version, { 0, 0, 0 })) + if (_version > feature_version { 0, 0, 0 }) LOG_INFO("DLSSD v{0}.{1}.{2} loaded.", _version.major, _version.minor, _version.patch); else LOG_WARN("Failed to get version using NVSDK_NGX_GetSnippetVersion!"); diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp index b5a80fa0..7032e638 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11.cpp @@ -453,7 +453,7 @@ bool FSR31FeatureDx11::Evaluate(ID3D11DeviceContext* DeviceContext, NVSDK_NGX_Pa params.upscaleSize.width = TargetWidth(); params.upscaleSize.height = TargetHeight(); - if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default()) + if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default()) { _velocity = Config::Instance()->FsrVelocity.value_or_default(); auto result = ffxFsr3SetUpscalerConstant( diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11On12.cpp b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11On12.cpp index e412e32f..3123f170 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11On12.cpp +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx11On12.cpp @@ -331,8 +331,7 @@ bool FSR31FeatureDx11on12::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_ params.viewSpaceToMetersFactor = 1.0f; // Version 3.1.1 check - if (isVersionOrBetter(Version(), { 3, 1, 1 }) && - _velocity != Config::Instance()->FsrVelocity.value_or_default()) + if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default()) { _velocity = Config::Instance()->FsrVelocity.value_or_default(); ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; @@ -345,60 +344,59 @@ bool FSR31FeatureDx11on12::Evaluate(ID3D11DeviceContext* InDeviceContext, NVSDK_ LOG_WARN("Velocity configure result: {}", (UINT) result); } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + if (Version() >= feature_version { 3, 1, 4 }) { - _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; - m_upscalerKeyValueConfig.ptr = &_reactiveScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + { + _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; + m_upscalerKeyValueConfig.ptr = &_reactiveScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Reactive Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Reactive Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) - { - _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; - m_upscalerKeyValueConfig.ptr = &_shadingScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) + { + _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; + m_upscalerKeyValueConfig.ptr = &_shadingScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Shading Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Shading Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) - { - _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; - m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) + { + _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; + m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) - { - _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; - m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) + { + _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; + m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + if (result != FFX_API_RETURN_OK) + LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + } } if (InParameters->Get("FSR.upscaleSize.width", ¶ms.upscaleSize.width) == NVSDK_NGX_Result_Success && diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx12.cpp b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx12.cpp index 41acc377..27cf7caf 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Dx12.cpp +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Dx12.cpp @@ -421,7 +421,7 @@ bool FSR31FeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_ if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, ¶ms.preExposure) != NVSDK_NGX_Result_Success) params.preExposure = 1.0f; - if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default()) + if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default()) { _velocity = Config::Instance()->FsrVelocity.value_or_default(); ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; @@ -434,60 +434,59 @@ bool FSR31FeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_ LOG_WARN("Velocity configure result: {}", (UINT) result); } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + if (Version() >= feature_version { 3, 1, 4 }) { - _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; - m_upscalerKeyValueConfig.ptr = &_reactiveScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + { + _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; + m_upscalerKeyValueConfig.ptr = &_reactiveScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Reactive Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Reactive Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) - { - _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; - m_upscalerKeyValueConfig.ptr = &_shadingScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) + { + _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; + m_upscalerKeyValueConfig.ptr = &_shadingScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Shading Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Shading Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) - { - _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; - m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) + { + _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; + m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) - { - _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; - m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) + { + _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; + m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + if (result != FFX_API_RETURN_OK) + LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + } } if (InParameters->Get("FSR.upscaleSize.width", ¶ms.upscaleSize.width) == NVSDK_NGX_Result_Success && diff --git a/OptiScaler/upscalers/fsr31/FSR31Feature_Vk.cpp b/OptiScaler/upscalers/fsr31/FSR31Feature_Vk.cpp index 94f493a8..f64d0833 100644 --- a/OptiScaler/upscalers/fsr31/FSR31Feature_Vk.cpp +++ b/OptiScaler/upscalers/fsr31/FSR31Feature_Vk.cpp @@ -512,7 +512,7 @@ bool FSR31FeatureVk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* if (InParameters->Get(NVSDK_NGX_Parameter_DLSS_Pre_Exposure, ¶ms.preExposure) != NVSDK_NGX_Result_Success) params.preExposure = 1.0f; - if (isVersionOrBetter(Version(), { 3, 1, 1 }) && _velocity != Config::Instance()->FsrVelocity.value_or_default()) + if (Version() >= feature_version { 3, 1, 1 } && _velocity != Config::Instance()->FsrVelocity.value_or_default()) { _velocity = Config::Instance()->FsrVelocity.value_or_default(); ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; @@ -525,60 +525,59 @@ bool FSR31FeatureVk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* LOG_WARN("Velocity configure result: {}", (UINT) result); } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + if (Version() >= feature_version { 3, 1, 4 }) { - _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; - m_upscalerKeyValueConfig.ptr = &_reactiveScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_reactiveScale != Config::Instance()->FsrReactiveScale.value_or_default()) + { + _reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FREACTIVENESSSCALE; + m_upscalerKeyValueConfig.ptr = &_reactiveScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Reactive Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Reactive Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) - { - _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; - m_upscalerKeyValueConfig.ptr = &_shadingScale; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_shadingScale != Config::Instance()->FsrShadingScale.value_or_default()) + { + _shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FSHADINGCHANGESCALE; + m_upscalerKeyValueConfig.ptr = &_shadingScale; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Shading Scale configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Shading Scale configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) - { - _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; - m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_accAddPerFrame != Config::Instance()->FsrAccAddPerFrame.value_or_default()) + { + _accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FACCUMULATIONADDEDPERFRAME; + m_upscalerKeyValueConfig.ptr = &_accAddPerFrame; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); - } + if (result != FFX_API_RETURN_OK) + LOG_WARN("Acc. Add Per Frame configure result: {}", (UINT) result); + } - if (isVersionOrBetter(Version(), { 3, 1, 4 }) && - _minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) - { - _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); - ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; - m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; - m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; - m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; - auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); + if (_minDisOccAcc != Config::Instance()->FsrMinDisOccAcc.value_or_default()) + { + _minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); + ffxConfigureDescUpscaleKeyValue m_upscalerKeyValueConfig {}; + m_upscalerKeyValueConfig.header.type = FFX_API_CONFIGURE_DESC_TYPE_UPSCALE_KEYVALUE; + m_upscalerKeyValueConfig.key = FFX_API_CONFIGURE_UPSCALE_KEY_FMINDISOCCLUSIONACCUMULATION; + m_upscalerKeyValueConfig.ptr = &_minDisOccAcc; + auto result = FfxApiProxy::D3D12_Configure()(&_context, &m_upscalerKeyValueConfig.header); - if (result != FFX_API_RETURN_OK) - LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + if (result != FFX_API_RETURN_OK) + LOG_WARN("Minimum Disocclusion Acc. configure result: {}", (UINT) result); + } } if (InParameters->Get("FSR.upscaleSize.width", ¶ms.upscaleSize.width) == NVSDK_NGX_Result_Success && diff --git a/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp b/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp index 49446483..36488650 100644 --- a/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp +++ b/OptiScaler/upscalers/xess/XeSSFeature_Dx12.cpp @@ -241,12 +241,13 @@ bool XeSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N else LOG_DEBUG("AutoExposure enabled!"); + bool supportsFloatResponsivePixelMask = Version() >= feature_version { 2, 0, 1 }; ID3D12Resource* paramReactiveMask = nullptr; - if (isVersionOrBetter(Version(), { 2, 0, 1 }) && + if (supportsFloatResponsivePixelMask && InParameters->Get("FSR.reactive", ¶mReactiveMask) == NVSDK_NGX_Result_Success) { - if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 }))) + if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask)) params.pResponsivePixelMaskTexture = paramReactiveMask; } else @@ -255,8 +256,7 @@ bool XeSSFeatureDx12::Evaluate(ID3D12GraphicsCommandList* InCommandList, NVSDK_N NVSDK_NGX_Result_Success) InParameters->Get(NVSDK_NGX_Parameter_DLSS_Input_Bias_Current_Color_Mask, (void**) ¶mReactiveMask); - if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 })) && - paramReactiveMask) + if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask) && paramReactiveMask) { LOG_DEBUG("Input Bias mask exist.."); Config::Instance()->DisableReactiveMask = false; diff --git a/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp b/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp index 0b956b56..5c8c12c7 100644 --- a/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp +++ b/OptiScaler/upscalers/xess/XeSSFeature_Vk.cpp @@ -505,8 +505,10 @@ bool XeSSFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* else LOG_DEBUG("AutoExposure enabled!"); + bool supportsFloatResponsivePixelMask = Version() >= feature_version { 2, 0, 1 }; NVSDK_NGX_Resource_VK* paramReactiveMask = nullptr; - if (isVersionOrBetter(Version(), { 2, 0, 1 }) && + + if (supportsFloatResponsivePixelMask && InParameters->Get("FSR.reactive", (void**) ¶mReactiveMask) == NVSDK_NGX_Result_Success) { if (!Config::Instance()->DisableReactiveMask.value_or(true)) @@ -521,7 +523,7 @@ bool XeSSFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* LOG_DEBUG("Input Bias mask exist.."); Config::Instance()->DisableReactiveMask = false; - if (!Config::Instance()->DisableReactiveMask.value_or(!isVersionOrBetter(Version(), { 2, 0, 1 }))) + if (!Config::Instance()->DisableReactiveMask.value_or(!supportsFloatResponsivePixelMask)) params.responsivePixelMaskTexture = NV_to_XeSS(paramReactiveMask); } else From 70f9bb6ae426b28018394865d5a59015d51fd284 Mon Sep 17 00:00:00 2001 From: FakeMichau <49685661+FakeMichau@users.noreply.github.com> Date: Thu, 19 Jun 2025 20:01:53 +0200 Subject: [PATCH 03/10] Stop log spam with older fakenvapi builds --- OptiScaler/nvapi/fakenvapi.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OptiScaler/nvapi/fakenvapi.cpp b/OptiScaler/nvapi/fakenvapi.cpp index 74b6f81f..4999f7be 100644 --- a/OptiScaler/nvapi/fakenvapi.cpp +++ b/OptiScaler/nvapi/fakenvapi.cpp @@ -91,12 +91,10 @@ bool fakenvapi::updateModeAndContext() // fallback for older fakenvapi builds if (Fake_GetAntiLagCtx) { - _lowLatencyMode = Mode::LatencyFlex; - auto result = Fake_GetAntiLagCtx(&_lowLatencyContext); if (result != NVAPI_OK) - LOG_ERROR("Can't get AntiLag 2 context from fakenvapi"); + _lowLatencyMode = Mode::LatencyFlex; else _lowLatencyMode = Mode::AntiLag2; From c488135b80be601c557f81aca2466146b2fecfef Mon Sep 17 00:00:00 2001 From: cdozdil Date: Fri, 20 Jun 2025 11:18:34 +0300 Subject: [PATCH 04/10] Fix for BF2042 crash --- OptiScaler/upscalers/IFeature.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OptiScaler/upscalers/IFeature.cpp b/OptiScaler/upscalers/IFeature.cpp index fcff8fbf..7978a6a1 100644 --- a/OptiScaler/upscalers/IFeature.cpp +++ b/OptiScaler/upscalers/IFeature.cpp @@ -98,12 +98,13 @@ bool IFeature::SetInitParameters(NVSDK_NGX_Parameter* InParameters) LOG_INFO("Init Flag SharpenEnabled: {}", _initFlags.SharpenEnabled); } - if (InParameters->Get(NVSDK_NGX_Parameter_Width, &width) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_Height, &height) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue) == NVSDK_NGX_Result_Success) + if (InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success && + InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success) { + InParameters->Get(NVSDK_NGX_Parameter_Width, &width); + InParameters->Get(NVSDK_NGX_Parameter_Height, &height); + InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue); + GetDynamicOutputResolution(InParameters, &outWidth, &outHeight); // Thanks to Crytek added these checks From aaffd7a6b79551a0bd06220c66cfc464ae73e094 Mon Sep 17 00:00:00 2001 From: cdozdil Date: Fri, 20 Jun 2025 11:18:34 +0300 Subject: [PATCH 05/10] Fix for crash at SetInitParameters --- OptiScaler/upscalers/IFeature.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/OptiScaler/upscalers/IFeature.cpp b/OptiScaler/upscalers/IFeature.cpp index fcff8fbf..7978a6a1 100644 --- a/OptiScaler/upscalers/IFeature.cpp +++ b/OptiScaler/upscalers/IFeature.cpp @@ -98,12 +98,13 @@ bool IFeature::SetInitParameters(NVSDK_NGX_Parameter* InParameters) LOG_INFO("Init Flag SharpenEnabled: {}", _initFlags.SharpenEnabled); } - if (InParameters->Get(NVSDK_NGX_Parameter_Width, &width) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_Height, &height) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success && - InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue) == NVSDK_NGX_Result_Success) + if (InParameters->Get(NVSDK_NGX_Parameter_OutWidth, &outWidth) == NVSDK_NGX_Result_Success && + InParameters->Get(NVSDK_NGX_Parameter_OutHeight, &outHeight) == NVSDK_NGX_Result_Success) { + InParameters->Get(NVSDK_NGX_Parameter_Width, &width); + InParameters->Get(NVSDK_NGX_Parameter_Height, &height); + InParameters->Get(NVSDK_NGX_Parameter_PerfQualityValue, &pqValue); + GetDynamicOutputResolution(InParameters, &outWidth, &outHeight); // Thanks to Crytek added these checks From 1324f8d97118b855e6bfd2db4eb0950324359bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Lewandowski?= <49685661+FakeMichau@users.noreply.github.com> Date: Mon, 23 Jun 2025 12:17:14 +0200 Subject: [PATCH 06/10] Workaround the ntdll-Hide_Wine_Exports patch (#538) --- OptiScaler/dllmain.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp index c23dcaa7..07f1b862 100644 --- a/OptiScaler/dllmain.cpp +++ b/OptiScaler/dllmain.cpp @@ -42,6 +42,46 @@ static std::vector _asiHandles; typedef const char*(CDECL* PFN_wine_get_version)(void); typedef void (*PFN_InitializeASI)(void); +static inline void* ManualGetProcAddress(HMODULE hModule, const char* functionName) +{ + if (!hModule) + return nullptr; + + // Verify the alignment + auto dosHeader = (IMAGE_DOS_HEADER*) hModule; + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return nullptr; + + auto ntHeaders = (IMAGE_NT_HEADERS*) ((BYTE*) hModule + dosHeader->e_lfanew); + if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) + return nullptr; + + // Look at the export directory + IMAGE_DATA_DIRECTORY exportData = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + if (!exportData.VirtualAddress) + return nullptr; + + auto exportDir = (IMAGE_EXPORT_DIRECTORY*) ((BYTE*) hModule + exportData.VirtualAddress); + + DWORD* nameRvas = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfNames); + WORD* ordinalTable = (WORD*) ((BYTE*) hModule + exportDir->AddressOfNameOrdinals); + DWORD* functionTable = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfFunctions); + + // Iterate over exported names + for (DWORD i = 0; i < exportDir->NumberOfNames; ++i) + { + const char* name = (const char*) hModule + nameRvas[i]; + if (_stricmp(name, functionName) == 0) + { + WORD ordinal = ordinalTable[i]; + DWORD funcRva = functionTable[ordinal]; + return (BYTE*) hModule + funcRva; + } + } + + return nullptr; // Not found +} + static bool IsRunningOnWine() { LOG_FUNC(); @@ -56,6 +96,10 @@ static bool IsRunningOnWine() auto pWineGetVersion = (PFN_wine_get_version) KernelBaseProxy::GetProcAddress_()(ntdll, "wine_get_version"); + // Workaround for the ntdll-Hide_Wine_Exports patch + if (!pWineGetVersion && KernelBaseProxy::GetProcAddress_()(ntdll, "wine_server_call") != nullptr) + pWineGetVersion = (PFN_wine_get_version) ManualGetProcAddress(ntdll, "wine_get_version"); + if (pWineGetVersion) { LOG_INFO("Running on Wine {0}!", pWineGetVersion()); From 512c5420f551e8a44a6a2c4ca1819d9e9c87a3ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Lewandowski?= <49685661+FakeMichau@users.noreply.github.com> Date: Mon, 23 Jun 2025 13:19:24 +0200 Subject: [PATCH 07/10] Menu elements reordering (#536) * Menu elements reordering also fixes minor bugs in the menu * Formatting * Don't hide the FG options when no is currently supported. The tooltip might still be useful --- OptiScaler/menu/log/ImguiSpdLog.cpp | 363 ------- OptiScaler/menu/log/ImguiSpdLog.h | 4 - OptiScaler/menu/menu_common.cpp | 1432 ++++++++++++++------------- 3 files changed, 739 insertions(+), 1060 deletions(-) delete mode 100644 OptiScaler/menu/log/ImguiSpdLog.cpp delete mode 100644 OptiScaler/menu/log/ImguiSpdLog.h diff --git a/OptiScaler/menu/log/ImguiSpdLog.cpp b/OptiScaler/menu/log/ImguiSpdLog.cpp deleted file mode 100644 index 4406ef9c..00000000 --- a/OptiScaler/menu/log/ImguiSpdLog.cpp +++ /dev/null @@ -1,363 +0,0 @@ -#include "ImguiSpdLog.h" - -class SinkLineContent -{ - public: - spdlog::level::level_enum LogLevel; // If n_levels, the message pushed counts to the previous pushed line - - int32_t BeginIndex; // Base offset into the text buffer - - struct ColorDataRanges - { - uint32_t SubStringBegin : 12; - uint32_t SubStringEnd : 12; - uint32_t FormatTag : 8; - }; - - ImVector FormattedStringRanges; -}; - -// TODO: work on filters, they are really needed, did optimize the memory storage quite a bit tho -class ImGuiSpdLogAdaptor : public spdlog::sinks::base_sink -{ - - using sink_t = spdlog::sinks::base_sink; - - public: - void DrawLogWindow() - { - - if (ImGui::Begin("CyberXeSS Log", &ShowWindow)) - { - - // Options submenu menu - if (ImGui::BeginPopup("Options")) - { - - ImGui::Checkbox("Auto-scroll", &EnableAutoScrolling); - ImGui::EndPopup(); - } - - if (ImGui::Button("Options")) - ImGui::OpenPopup("Options"); - - ImGui::SameLine(); - ImGui::SameLine(); - - if (ImGui::Button("Clear")) - ClearLogBuffers(); - - ImGui::SameLine(); - - ImGui::Text("%d messages logged, using %dmb memory", NumberOfLogEntries, - (LoggedContent.size() + IndicesInBytes) / (1024 * 1024)); - - // Filter out physical messgaes through logger - static const char* LogLevels[] = SPDLOG_LEVEL_NAMES; - - static const auto LogSelectionWidth = []() -> float - { - float LongestTextWidth = 0; - for (auto LogLevelText : LogLevels) - { - - auto TextWidth = ImGui::CalcTextSize(LogLevelText).x; - if (TextWidth > LongestTextWidth) - LongestTextWidth = TextWidth; - } - - return LongestTextWidth + ImGui::GetStyle().FramePadding.x * 2 + ImGui::GetFrameHeight(); - }(); - - auto ComboBoxRightAlignment = - ImGui::GetWindowSize().x - (LogSelectionWidth + ImGui::GetStyle().WindowPadding.x); - auto ActiveLogLevel = spdlog::get_level(); - - ImGui::SetNextItemWidth(LogSelectionWidth); - ImGui::SameLine(ComboBoxRightAlignment); - - ImGui::Combo("##ActiveLogLevel", reinterpret_cast(&ActiveLogLevel), LogLevels, - sizeof(LogLevels) / sizeof(LogLevels[0])); - spdlog::set_level(ActiveLogLevel); - - // Filter out messages on display - FilterTextMatch.Draw("##LogFilter", - ImGui::GetWindowSize().x - (LogSelectionWidth + ImGui::GetStyle().WindowPadding.x * 2 + - ImGui::GetStyle().FramePadding.x)); - - ImGui::SetNextItemWidth(LogSelectionWidth); - ImGui::SameLine(ComboBoxRightAlignment); - ImGui::Combo("##FilterLogLevel", &FilterLogLevel, LogLevels, sizeof(LogLevels) / sizeof(LogLevels[0])); - - // Draw main log window - ImGui::Separator(); - ImGui::BeginChild("LogTextView", ImVec2(0, 0), false, - ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar); - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); - const std::lock_guard LogLock(sink_t::mutex_); - - RebuildFilterWithPreviousStates(); - - ImGuiListClipper ViewClipper; - ViewClipper.Begin(FilteredView.size()); - - while (ViewClipper.Step()) - { - int32_t StylesPushedToStack = 0; - for (auto ClipperLineNumber = ViewClipper.DisplayStart; ClipperLineNumber < ViewClipper.DisplayEnd; - ++ClipperLineNumber) - { - auto& LogMetaDataEntry = LogMetaData[FilteredView[ClipperLineNumber]]; - - if (LogMetaDataEntry.LogLevel == spdlog::level::n_levels) - ImGui::Indent(); - - for (auto i = 0; i < LogMetaDataEntry.FormattedStringRanges.size(); ++i) - { - static const ImVec4 BrightColorsToVec[] { - { 0, 0, 0, 1 }, // COLOR_BRIGHTBLACK - { 1, 0, 0, 1 }, // COLOR_BRIGHTRED - { 0, 1, 0, 1 }, // COLOR_BRIGHTGREEN - { 1, 1, 0, 1 }, // COLOR_BRIGHTYELLOW - { 0, 0, 1, 1 }, // COLOR_BRIGHTBLUE - { 1, 0, 1, 1 }, // COLOR_BRIGHTMAGENTA - { 0, 1, 1, 1 }, // COLOR_BRIGHTCYAN - { 1, 1, 1, 1 } // COLOR_BRIGHTWHITE - }; - - ImGui::PushStyleColor(ImGuiCol_Text, - BrightColorsToVec[LogMetaDataEntry.FormattedStringRanges[i].FormatTag]); - ++StylesPushedToStack; - - auto FormatRangeBegin = LoggedContent.begin() + LogMetaDataEntry.BeginIndex + - LogMetaDataEntry.FormattedStringRanges[i].SubStringBegin; - auto FormatRangeEnd = LoggedContent.begin() + LogMetaDataEntry.BeginIndex + - LogMetaDataEntry.FormattedStringRanges[i].SubStringEnd; - ImGui::TextUnformatted(FormatRangeBegin, FormatRangeEnd); - - if (LogMetaDataEntry.FormattedStringRanges.size() - (i + 1)) - ImGui::SameLine(); - } - - if (LogMetaDataEntry.LogLevel == spdlog::level::n_levels) - ImGui::Unindent(); - } - - ImGui::PopStyleColor(StylesPushedToStack); - } - - ViewClipper.End(); - ImGui::PopStyleVar(); - - if (EnableAutoScrolling && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) - ImGui::SetScrollHereY(1.0f); - - ImGui::EndChild(); - } - - ImGui::End(); - } - - void ClearLogBuffers(IN bool DisableLock = false) - { - if (!DisableLock) - sink_t::mutex_.lock(); - - LoggedContent.clear(); - LogMetaData.clear(); - NumberOfLogEntries = 0; - IndicesInBytes = 0; - - if (!DisableLock) - sink_t::mutex_.unlock(); - } - - protected: - // Writing version 2, this will accept ansi escape sequences for colors - void sink_it_(IN const spdlog::details::log_msg& LogMessage) final - { - // This is all protected by the base sink under a mutex - ++NumberOfLogEntries; - - // Format the logged message and push it into the text buffer - spdlog::memory_buf_t FormattedBuffer; - - sink_t::formatter_->format(LogMessage, FormattedBuffer); - - std::string FormattedText = FormattedBuffer; - - // Process string by converting the color range passed to an escape sequence first, - // yes may not be the nicest way of doing this but its way easier to process later. - const char* ColorToEscapeSequence[] { ESC_BRIGHTMAGENTA, ESC_CYAN, ESC_BRIGHTGREEN, - ESC_BRIGHTYELLOW, ESC_BRIGHTRED, ESC_RED }; - - FormattedText.insert(LogMessage.color_range_start, ColorToEscapeSequence[LogMessage.level]); - FormattedText.insert(LogMessage.color_range_end + 5, "\x1b[0m"); - - bool FilterPassing = LogMessage.level >= FilterLogLevel; - FilterPassing &= - FilterTextMatch.PassFilter(FormattedText.c_str(), FormattedText.c_str() + FormattedText.size()); - - // Parse formatted logged string for ansi escape sequences - auto OldTextBufferSize = LoggedContent.size(); - SinkLineContent MessageData2 { LogMessage.level, OldTextBufferSize }; - - AnsiEscapeSequenceTag LastSequenceTagSinceBegin = FORMAT_RESET_COLORS; - - // Prematurely filter out immediately starting non default formats, - // and then enter the main processing loop - switch (FormattedText[0]) - { - case '\x1b': - case '\n': - break; - - default: - - SinkLineContent::ColorDataRanges FormatPush { 0, 0, LastSequenceTagSinceBegin }; - MessageData2.FormattedStringRanges.push_back(FormatPush); - break; - } - - for (auto i = 0; i < FormattedText.size(); ++i) - { - switch (FormattedText[i]) - { - case '\n': - { - - // Handle new line bullshit, spdlog will terminate any logged message witha new line - // we can also assume this may not be the last line, so we continue the previous sequence into - // the next logically text line if necessary and reconfigure pushstate - if (MessageData2.FormattedStringRanges.size()) - MessageData2.FormattedStringRanges.back().SubStringEnd = i; - if (FilterPassing) - FilteredView.push_back(LogMetaData.size()); - LogMetaData.push_back(MessageData2); - - IndicesInBytes += MessageData2.FormattedStringRanges.size() * sizeof(SinkLineContent::ColorDataRanges) + - sizeof(SinkLineContent); - MessageData2.LogLevel = spdlog::level::n_levels; - MessageData2.BeginIndex = OldTextBufferSize + i + 1; - MessageData2.FormattedStringRanges.clear(); - - // Continue previous escape sequences pushed in the previous line - SinkLineContent::ColorDataRanges FormatPush { i + 1, 0, LastSequenceTagSinceBegin }; - MessageData2.FormattedStringRanges.push_back(FormatPush); - } - break; - case '\x1b': - { - - // Handle ansi escape sequence, convert textual to operand - if (FormattedText[i + 1] != '[') - throw std::runtime_error("Invalid ansi escape sequence passed"); - - size_t PositionProcessed = 0; - auto EscapeSequenceCode = static_cast( - std::stoi(&FormattedText[i + 2], - &PositionProcessed)); // this may throw, in which case we let it pass down - - if (FormattedText[i + 2 + PositionProcessed] != 'm') - throw std::runtime_error("Invalid ansi escape sequence operand was passed"); - ++PositionProcessed; - LastSequenceTagSinceBegin = EscapeSequenceCode; - - SinkLineContent::ColorDataRanges FormatPush { i, 0, EscapeSequenceCode }; - if (MessageData2.FormattedStringRanges.size()) - MessageData2.FormattedStringRanges.back().SubStringEnd = FormatPush.SubStringBegin; - MessageData2.FormattedStringRanges.push_back(FormatPush); - - // Now the escape code has to be removed from the string, - // the iterator has to be kept stable, otherwise the next round could skip a char - FormattedText.erase(FormattedText.begin() + i--, FormattedText.begin() + (i + 2 + PositionProcessed)); - } - } - } - - // Append processed string to log text buffer - LoggedContent.append(FormattedText.c_str(), FormattedText.c_str() + FormattedText.size()); - } - - void flush_() {} - - private: - // TODO: Need to implement double buffering for the filter - void RebuildFilterWithPreviousStates() - { - int32_t RebuildType = PreviousFilterLevel != FilterLogLevel; - - RebuildType |= memcmp(PreviousFilterText, FilterTextMatch.InputBuf, sizeof(PreviousFilterText)); - - if (RebuildType) - { - // Filter was completely changed, have to rebuild array (very expensive, - // this may result in short freezes or stuttering on really large logs, - // one way to solve this could be to defer the calculation of the filter view - // to a thread pool and use a double buffering mechanism) - - auto NewLinePasses = false; - FilteredView.clear(); - - for (auto i = 0; i < LogMetaData.size(); ++i) - { - - if (LogMetaData[i].LogLevel == spdlog::level::n_levels&&) - { - FilteredView.push_back(i); - continue; - } - - if (LogMetaData[i].LogLevel < FilterLogLevel) - { - NewLinePasses = false; - continue; - } - - auto LineBegin = LoggedContent.begin() + LogMetaData[i].BeginIndex + - LogMetaData[i].FormattedStringRanges.front().SubStringBegin; - auto LineEnd = LoggedContent.begin() + LogMetaData[i].BeginIndex + - LogMetaData[i].FormattedStringRanges.back().SubStringEnd; - - if (!FilterTextMatch.PassFilter(LineBegin, LineEnd)) - { - NewLinePasses = false; - continue; - } - - NewLinePasses = true; - FilteredView.push_back(i); - } - } - - PreviousFilterLevel = FilterLogLevel; - memcpy(PreviousFilterText, FilterTextMatch.InputBuf, sizeof(PreviousFilterText)); - } - - // Using faster more efficient replacements of stl types for rendering - ImGuiTextBuffer LoggedContent; - - // Cannot use ImVetctor here as the type is not trivially copyable - std::vector LogMetaData; - - // the type has to be moved into, slightly more expensive - // but overall totally fine, at least no weird hacks - ImGuiTextFilter FilterTextMatch; - - // A filtered array of indexes into the LogMetaData vector - ImVector FilteredView; - - // this view is calculated once any filter changes - int32_t FilterLogLevel = spdlog::level::trace; - - // Counts the number of entries logged - uint32_t NumberOfLogEntries = 0; - - // Keeps track of the amount of memory allocated by indices - uint32_t IndicesInBytes = 0; - bool EnableAutoScrolling = true; - - // Previous Frame's filterdata, if any of these change to the new values the filter has to be recalculated - int32_t PreviousFilterLevel = spdlog::level::trace; - decltype(ImGuiTextFilter::InputBuf) PreviousFilterText {}; -}; diff --git a/OptiScaler/menu/log/ImguiSpdLog.h b/OptiScaler/menu/log/ImguiSpdLog.h deleted file mode 100644 index e0f46b92..00000000 --- a/OptiScaler/menu/log/ImguiSpdLog.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -#include "../pch.h" -#include "spdlog/sinks/base_sink.h" -#include "imgui/imgui.h" diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 4bcda384..c3608e4c 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -16,6 +16,10 @@ #include +#define MARK_ALL_BACKENDS_CHANGED() \ + for (auto& singleChangeBackend : State::Instance().changeBackend) \ + singleChangeBackend.second = true; + constexpr float fontSize = 14.0f; // just changing this doesn't make other elements scale ideally static ImVec2 overlayPosition(-1000.0f, -1000.0f); static bool _hdrTonemapApplied = false; @@ -70,8 +74,7 @@ inline void MenuCommon::ReInitUpscaler() else State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; + MARK_ALL_BACKENDS_CHANGED(); } void MenuCommon::SeparatorWithHelpMarker(const char* label, const char* tip) @@ -868,7 +871,7 @@ void MenuCommon::AddDx11Backends(std::string* code, std::string* name) else selectedUpscalerName = "XeSS w/Dx12"; - if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str())) + if (ImGui::BeginCombo("", selectedUpscalerName.c_str())) { if (ImGui::Selectable("XeSS", *code == "xess")) State::Instance().newBackend = "xess"; @@ -914,7 +917,7 @@ void MenuCommon::AddDx12Backends(std::string* code, std::string* name) else selectedUpscalerName = "XeSS"; - if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str())) + if (ImGui::BeginCombo("", selectedUpscalerName.c_str())) { if (ImGui::Selectable("XeSS", *code == "xess")) State::Instance().newBackend = "xess"; @@ -951,7 +954,7 @@ void MenuCommon::AddVulkanBackends(std::string* code, std::string* name) else selectedUpscalerName = "FSR 2.2.1"; - if (ImGui::BeginCombo("Select", selectedUpscalerName.c_str())) + if (ImGui::BeginCombo("", selectedUpscalerName.c_str())) { if (ImGui::Selectable("XeSS", *code == "xess")) State::Instance().newBackend = "xess"; @@ -1765,6 +1768,8 @@ bool MenuCommon::RenderMenu() std::string spoofingText; + ImGui::PushItemWidth(180.0f * Config::Instance()->MenuScale.value_or_default()); + switch (State::Instance().api) { case DX11: @@ -1835,9 +1840,13 @@ bool MenuCommon::RenderMenu() AddVulkanBackends(¤tBackend, ¤tBackendName); } + ImGui::PopItemWidth(); + if (State::Instance().currentFeature->Name() != "DLSSD") { - if (ImGui::Button("Apply") && State::Instance().newBackend != "" && + ImGui::SameLine(0.0f, 6.0f); + + if (ImGui::Button("Change Upscaler##2") && State::Instance().newBackend != "" && State::Instance().newBackend != currentBackend) { if (State::Instance().newBackend == "xess") @@ -1847,14 +1856,378 @@ bool MenuCommon::RenderMenu() Config::Instance()->DlssReactiveMaskBias.reset(); } - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; + MARK_ALL_BACKENDS_CHANGED(); } + } + } + + if (currentFeature != nullptr && !currentFeature->IsFrozen()) + { + // Dx11 with Dx12 + if (State::Instance().api == DX11 && + Config::Instance()->Dx11Upscaler.value_or_default() != "fsr22" && + Config::Instance()->Dx11Upscaler.value_or_default() != "dlss" && + Config::Instance()->Dx11Upscaler.value_or_default() != "fsr31") + { + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Dx11 with Dx12 Settings")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + if (bool dontUseNTShared = Config::Instance()->DontUseNTShared.value_or_default(); + ImGui::Checkbox("Don't Use NTShared", &dontUseNTShared)) + Config::Instance()->DontUseNTShared = dontUseNTShared; + + ImGui::Spacing(); + ImGui::Spacing(); + } + } + + // UPSCALER SPECIFIC ----------------------------- + + // XeSS ----------------------------- + if (currentBackend == "xess" && State::Instance().currentFeature->Name() != "DLSSD") + { + ImGui::Spacing(); + if (ImGui::CollapsingHeader("XeSS Settings")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + const char* models[] = { "KPSS", "SPLAT", "MODEL_3", "MODEL_4", "MODEL_5", "MODEL_6" }; + auto configModes = Config::Instance()->NetworkModel.value_or_default(); + + if (configModes < 0 || configModes > 5) + configModes = 0; + + const char* selectedModel = models[configModes]; + + if (ImGui::BeginCombo("Network Models", selectedModel)) + { + for (int n = 0; n < 6; n++) + { + if (ImGui::Selectable(models[n], + (Config::Instance()->NetworkModel.value_or_default() == n))) + { + Config::Instance()->NetworkModel = n; + State::Instance().newBackend = currentBackend; + MARK_ALL_BACKENDS_CHANGED(); + } + } + + ImGui::EndCombo(); + } + ShowHelpMarker("Likely don't do much"); + + if (bool dbg = State::Instance().xessDebug; ImGui::Checkbox("Dump (Shift+Del)", &dbg)) + State::Instance().xessDebug = dbg; + + ImGui::SameLine(0.0f, 6.0f); + int dbgCount = State::Instance().xessDebugFrames; + + ImGui::PushItemWidth(95.0f * Config::Instance()->MenuScale.value_or_default()); + if (ImGui::InputInt("frames", &dbgCount)) + { + if (dbgCount < 4) + dbgCount = 4; + else if (dbgCount > 999) + dbgCount = 999; + + State::Instance().xessDebugFrames = dbgCount; + } + + ImGui::PopItemWidth(); + + ImGui::Spacing(); + ImGui::Spacing(); + } + } + + // FFX ----------------- + if (currentBackend.rfind("fsr", 0) == 0 && State::Instance().currentFeature->Name() != "DLSSD" && + (currentBackend == "fsr31" || currentBackend == "fsr31_12" || + State::Instance().currentFeature->AccessToReactiveMask())) + { + ImGui::SeparatorText("FFX Settings"); + + if (_fsr3xIndex < 0) + _fsr3xIndex = Config::Instance()->Fsr3xIndex.value_or_default(); + + if (currentBackend == "fsr31" || + currentBackend == "fsr31_12" && State::Instance().fsr3xVersionNames.size() > 0) + { + ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); + + auto currentName = std::format("FSR {}", State::Instance().fsr3xVersionNames[_fsr3xIndex]); + if (ImGui::BeginCombo("FFX Upscaler", currentName.c_str())) + { + for (int n = 0; n < State::Instance().fsr3xVersionIds.size(); n++) + { + auto name = std::format("FSR {}", State::Instance().fsr3xVersionNames[n]); + if (ImGui::Selectable(name.c_str(), + Config::Instance()->Fsr3xIndex.value_or_default() == n)) + _fsr3xIndex = n; + } + + ImGui::EndCombo(); + } + ImGui::PopItemWidth(); + + ShowHelpMarker("List of upscalers reported by FFX SDK"); + + ImGui::SameLine(0.0f, 6.0f); + + if (ImGui::Button("Change Upscaler") && + _fsr3xIndex != Config::Instance()->Fsr3xIndex.value_or_default()) + { + Config::Instance()->Fsr3xIndex = _fsr3xIndex; + State::Instance().newBackend = currentBackend; + MARK_ALL_BACKENDS_CHANGED(); + } + + auto majorFsrVersion = currentFeature->Version().major; + + if (majorFsrVersion >= 4) + { + ImGui::Spacing(); + + if (ImGui::BeginTable("nonLinear", 2, ImGuiTableFlags_SizingStretchProp)) + { + ImGui::TableNextColumn(); + + if (bool nlSRGB = Config::Instance()->FsrNonLinearSRGB.value_or_default(); + ImGui::Checkbox("Non-Linear sRGB Input", &nlSRGB)) + { + Config::Instance()->FsrNonLinearSRGB = nlSRGB; + + if (nlSRGB) + Config::Instance()->FsrNonLinearPQ = false; + + State::Instance().newBackend = currentBackend; + MARK_ALL_BACKENDS_CHANGED(); + } + ShowHelpMarker("Indicates input color resource contains perceptual sRGB colors\n" + "Might improve upscaling quality of FSR4"); + + ImGui::TableNextColumn(); + + if (bool nlPQ = Config::Instance()->FsrNonLinearPQ.value_or_default(); + ImGui::Checkbox("Non-Linear PQ Input", &nlPQ)) + { + Config::Instance()->FsrNonLinearPQ = nlPQ; + + if (nlPQ) + Config::Instance()->FsrNonLinearSRGB = false; + + State::Instance().newBackend = currentBackend; + MARK_ALL_BACKENDS_CHANGED(); + } + ShowHelpMarker("Indicates input color resource contains perceptual PQ colors\n" + "Might improve upscaling quality of FSR4"); + + ImGui::EndTable(); + } + } + + if (majorFsrVersion == 3) + { + if (bool dView = Config::Instance()->FsrDebugView.value_or_default(); + ImGui::Checkbox("FSR Upscaling Debug View", &dView)) + Config::Instance()->FsrDebugView = dView; + ShowHelpMarker("Top left: Dilated Motion Vectors\n" + "Top middle: Protected Areas\n" + "Top right: Dilated Depth\n" + "Middle: Upscaled frame\n" + "Bottom left: Disocclusion mask\n" + "Bottom middle: Reactiveness\n" + "Bottom right: Detail Protection Takedown"); + } + + if (State::Instance().currentFeature->AccessToReactiveMask()) + { + ImGui::BeginDisabled(Config::Instance()->DisableReactiveMask.value_or(false)); + + auto useAsTransparency = + Config::Instance()->FsrUseMaskForTransparency.value_or_default(); + if (ImGui::Checkbox("Use Reactive Mask as Transparency Mask", &useAsTransparency)) + Config::Instance()->FsrUseMaskForTransparency = useAsTransparency; + + ImGui::EndDisabled(); + } + + ImGui::Spacing(); + + if (currentFeature->Version() >= feature_version { 3, 1, 1 } && + currentFeature->Version() < feature_version { 4, 0, 0 } && + ImGui::CollapsingHeader("FSR 3 Upscaler Fine Tuning")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + ImGui::PushItemWidth(220.0f * Config::Instance()->MenuScale.value_or_default()); + + float velocity = Config::Instance()->FsrVelocity.value_or_default(); + if (ImGui::SliderFloat("Velocity Factor", &velocity, 0.00f, 1.0f, "%.2f")) + Config::Instance()->FsrVelocity = velocity; + + ShowHelpMarker("Value of 0.0f can improve temporal stability of bright pixels\n" + "Lower values are more stable with ghosting\n" + "Higher values are more pixelly but less ghosting."); + + if (currentFeature->Version() >= feature_version { 3, 1, 4 }) + { + // Reactive Scale + float reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); + if (ImGui::SliderFloat("Reactive Scale", &reactiveScale, 0.0f, 100.0f, "%.1f")) + Config::Instance()->FsrReactiveScale = reactiveScale; + + ShowHelpMarker("Meant for development purpose to test if\n" + "writing a larger value to reactive mask, reduces ghosting."); + + // Shading Scale + float shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); + if (ImGui::SliderFloat("Shading Scale", &shadingScale, 0.0f, 100.0f, "%.1f")) + Config::Instance()->FsrShadingScale = shadingScale; + + ShowHelpMarker("Increasing this scales fsr3.1 computed shading\n" + "change value at read to have higher reactiveness."); + + // Accumulation Added Per Frame + float accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); + if (ImGui::SliderFloat("Acc. Added Per Frame", &accAddPerFrame, 0.00f, 1.0f, + "%.2f")) + Config::Instance()->FsrAccAddPerFrame = accAddPerFrame; + + ShowHelpMarker( + "Corresponds to amount of accumulation added per frame\n" + "at pixel coordinate where disocclusion occured or when\n" + "reactive mask value is > 0.0f. Decreasing this and \n" + "drawing the ghosting object (IE no mv) to reactive mask \n" + "with value close to 1.0f can decrease temporal ghosting.\n" + "Decreasing this could result in more thin feature pixels flickering."); + + // Min Disocclusion Accumulation + float minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); + if (ImGui::SliderFloat("Min. Disocclusion Acc.", &minDisOccAcc, -1.0f, 1.0f, + "%.2f")) + Config::Instance()->FsrMinDisOccAcc = minDisOccAcc; + + ShowHelpMarker("Increasing this value may reduce white pixel temporal\n" + "flickering around swaying thin objects that are disoccluding \n" + "one another often. Too high value may increase ghosting."); + } + + ImGui::PopItemWidth(); + + ImGui::Spacing(); + ImGui::Spacing(); + } + } + } + + // DLSS ----------------- + if ((Config::Instance()->DLSSEnabled.value_or_default() && currentBackend == "dlss" && + State::Instance().currentFeature->Version().major > 2) || + State::Instance().currentFeature->Name() == "DLSSD") + { + const bool usesDlssd = State::Instance().currentFeature->Name() == "DLSSD"; + + if (usesDlssd) + ImGui::SeparatorText("DLSSD Settings"); + else + ImGui::SeparatorText("DLSS Settings"); + + auto overridden = usesDlssd ? State::Instance().dlssdPresetsOverriddenExternally + : State::Instance().dlssPresetsOverriddenExternally; + + if (overridden) + { + ImGui::TextColored(ImVec4(1.f, 0.f, 0.f, 1.f), "Presets are overridden externally"); + ShowHelpMarker("This usually happens due to using tools\n" + "such as Nvidia App or Nvidia Inspector"); + ImGui::Text("Selecting setting below will disable that external override\n" + "but you need to Save INI and restart the game"); + + ImGui::Spacing(); + } + + if (bool pOverride = Config::Instance()->RenderPresetOverride.value_or_default(); + ImGui::Checkbox("Render Presets Override", &pOverride)) + Config::Instance()->RenderPresetOverride = pOverride; + ShowHelpMarker("Each render preset has it strengths and weaknesses\n" + "Override to potentially improve image quality"); + + ImGui::BeginDisabled(!Config::Instance()->RenderPresetOverride.value_or_default() || + overridden); + + ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); + if (usesDlssd) + AddDLSSDRenderPreset("Override Preset", &Config::Instance()->RenderPresetForAll); + else + AddDLSSRenderPreset("Override Preset", &Config::Instance()->RenderPresetForAll); + + ImGui::PopItemWidth(); ImGui::SameLine(0.0f, 6.0f); - if (ImGui::Button("Revert")) - State::Instance().newBackend = ""; + if (ImGui::Button("Apply Changes")) + { + if (usesDlssd) + State::Instance().newBackend = "dlssd"; + else + State::Instance().newBackend = currentBackend; + + MARK_ALL_BACKENDS_CHANGED(); + } + + ImGui::EndDisabled(); + + ImGui::Spacing(); + + if (ImGui::CollapsingHeader(usesDlssd ? "Advanced DLSSD Settings" : "Advanced DLSS Settings")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + bool appIdOverride = Config::Instance()->UseGenericAppIdWithDlss.value_or_default(); + if (ImGui::Checkbox("Use Generic App Id with DLSS", &appIdOverride)) + Config::Instance()->UseGenericAppIdWithDlss = appIdOverride; + + ShowHelpMarker("Use generic appid with NGX\n" + "Fixes OptiScaler preset override not working with certain games\n" + "Requires a game restart."); + + ImGui::BeginDisabled(!Config::Instance()->RenderPresetOverride.value_or_default() || + overridden); + ImGui::Spacing(); + ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); + + if (usesDlssd) + { + AddDLSSDRenderPreset("DLAA Preset", &Config::Instance()->RenderPresetDLAA); + AddDLSSDRenderPreset("UltraQ Preset", &Config::Instance()->RenderPresetUltraQuality); + AddDLSSDRenderPreset("Quality Preset", &Config::Instance()->RenderPresetQuality); + AddDLSSDRenderPreset("Balanced Preset", &Config::Instance()->RenderPresetBalanced); + AddDLSSDRenderPreset("Perf Preset", &Config::Instance()->RenderPresetPerformance); + AddDLSSDRenderPreset("UltraP Preset", + &Config::Instance()->RenderPresetUltraPerformance); + } + else + { + AddDLSSRenderPreset("DLAA Preset", &Config::Instance()->RenderPresetDLAA); + AddDLSSRenderPreset("UltraQ Preset", &Config::Instance()->RenderPresetUltraQuality); + AddDLSSRenderPreset("Quality Preset", &Config::Instance()->RenderPresetQuality); + AddDLSSRenderPreset("Balanced Preset", &Config::Instance()->RenderPresetBalanced); + AddDLSSRenderPreset("Perf Preset", &Config::Instance()->RenderPresetPerformance); + AddDLSSRenderPreset("UltraP Preset", &Config::Instance()->RenderPresetUltraPerformance); + } + ImGui::PopItemWidth(); + ImGui::EndDisabled(); + + ImGui::Spacing(); + ImGui::Spacing(); + } } } @@ -1903,26 +2276,22 @@ bool MenuCommon::RenderMenu() fgDesc[2] = "Missing the dlssg_to_fsr3_amd_is_better.dll file"; } - auto disabledCount = std::ranges::count(disabledMask, 1); constexpr auto fgOptionsCount = sizeof(fgOptions) / sizeof(char*); if (!Config::Instance()->FGType.has_value()) Config::Instance()->FGType = Config::Instance()->FGType.value_or_default(); // need to have a value before combo - if (disabledCount < fgOptionsCount - 1) // maybe always show it anyway? + ImGui::SeparatorText("Frame Generation"); + + PopulateCombo("FG Type", reinterpret_cast*>(&Config::Instance()->FGType), + fgOptions, fgDesc.data(), fgOptionsCount, disabledMask.data(), false); + + if (State::Instance().showRestartWarning) { - ImGui::SeparatorText("Frame Generation"); - - PopulateCombo("FG Type", reinterpret_cast*>(&Config::Instance()->FGType), - fgOptions, fgDesc.data(), fgOptionsCount, disabledMask.data(), false); - - if (State::Instance().showRestartWarning) - { - ImGui::Spacing(); - ImGui::TextColored(ImVec4(1.f, 0.f, 0.0f, 1.f), "Save INI and restart to apply the changes"); - ImGui::Spacing(); - } + ImGui::Spacing(); + ImGui::TextColored(ImVec4(1.f, 0.f, 0.0f, 1.f), "Save INI and restart to apply the changes"); + ImGui::Spacing(); } State::Instance().showRestartWarning = @@ -2086,6 +2455,7 @@ bool MenuCommon::RenderMenu() { ScopedIndent indent {}; ImGui::Spacing(); + ImGui::Checkbox("FG Only Generated", &State::Instance().FGonlyGenerated); ShowHelpMarker("Display only FSR 3.1 generated frames"); @@ -2310,9 +2680,10 @@ bool MenuCommon::RenderMenu() ImGui::TreePop(); } } + + ImGui::Spacing(); + ImGui::Spacing(); } - ImGui::Spacing(); - ImGui::Spacing(); } else if (currentFeature == nullptr || currentFeature->IsFrozen()) { @@ -2394,248 +2765,9 @@ bool MenuCommon::RenderMenu() if (currentFeature != nullptr && !currentFeature->IsFrozen()) { - // Dx11 with Dx12 - if (State::Instance().api == DX11 && - Config::Instance()->Dx11Upscaler.value_or_default() != "fsr22" && - Config::Instance()->Dx11Upscaler.value_or_default() != "dlss" && - Config::Instance()->Dx11Upscaler.value_or_default() != "fsr31") - { - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Dx11 with Dx12 Settings")) - { - if (bool dontUseNTShared = Config::Instance()->DontUseNTShared.value_or_default(); - ImGui::Checkbox("Don't Use NTShared", &dontUseNTShared)) - Config::Instance()->DontUseNTShared = dontUseNTShared; - } - ImGui::Spacing(); - ImGui::Spacing(); - } - - // UPSCALER SPECIFIC ----------------------------- - - // XeSS ----------------------------- - if (currentBackend == "xess" && State::Instance().currentFeature->Name() != "DLSSD") - { - ImGui::Spacing(); - if (ImGui::CollapsingHeader("XeSS Settings")) - { - ScopedIndent indent {}; - ImGui::Spacing(); - const char* models[] = { "KPSS", "SPLAT", "MODEL_3", "MODEL_4", "MODEL_5", "MODEL_6" }; - auto configModes = Config::Instance()->NetworkModel.value_or_default(); - - if (configModes < 0 || configModes > 5) - configModes = 0; - - const char* selectedModel = models[configModes]; - - if (ImGui::BeginCombo("Network Models", selectedModel)) - { - for (int n = 0; n < 6; n++) - { - if (ImGui::Selectable(models[n], - (Config::Instance()->NetworkModel.value_or_default() == n))) - { - Config::Instance()->NetworkModel = n; - State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - } - - ImGui::EndCombo(); - } - ShowHelpMarker("Likely don't do much"); - - if (bool dbg = State::Instance().xessDebug; ImGui::Checkbox("Dump (Shift+Del)", &dbg)) - State::Instance().xessDebug = dbg; - - ImGui::SameLine(0.0f, 6.0f); - int dbgCount = State::Instance().xessDebugFrames; - - ImGui::PushItemWidth(95.0f * Config::Instance()->MenuScale.value_or_default()); - if (ImGui::InputInt("frames", &dbgCount)) - { - if (dbgCount < 4) - dbgCount = 4; - else if (dbgCount > 999) - dbgCount = 999; - - State::Instance().xessDebugFrames = dbgCount; - } - - ImGui::PopItemWidth(); - } - ImGui::Spacing(); - ImGui::Spacing(); - } - - // FSR ----------------- - if (currentBackend.rfind("fsr", 0) == 0 && State::Instance().currentFeature->Name() != "DLSSD" && - (currentBackend == "fsr31" || currentBackend == "fsr31_12" || - State::Instance().currentFeature->AccessToReactiveMask())) - { - ImGui::SeparatorText("FSR Settings"); - - if (_fsr3xIndex < 0) - _fsr3xIndex = Config::Instance()->Fsr3xIndex.value_or_default(); - - if (currentBackend == "fsr31" || - currentBackend == "fsr31_12" && State::Instance().fsr3xVersionNames.size() > 0) - { - ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); - - auto currentName = std::format("FSR {}", State::Instance().fsr3xVersionNames[_fsr3xIndex]); - if (ImGui::BeginCombo("Upscaler", currentName.c_str())) - { - for (int n = 0; n < State::Instance().fsr3xVersionIds.size(); n++) - { - auto name = std::format("FSR {}", State::Instance().fsr3xVersionNames[n]); - if (ImGui::Selectable(name.c_str(), - Config::Instance()->Fsr3xIndex.value_or_default() == n)) - _fsr3xIndex = n; - } - - ImGui::EndCombo(); - } - ImGui::PopItemWidth(); - - ShowHelpMarker("List of upscalers reported by FFX SDK"); - - ImGui::SameLine(0.0f, 6.0f); - - if (ImGui::Button("Change Upscaler") && - _fsr3xIndex != Config::Instance()->Fsr3xIndex.value_or_default()) - { - Config::Instance()->Fsr3xIndex = _fsr3xIndex; - State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - - if (currentBackend == "fsr31" || currentBackend == "fsr31_12") - { - if (bool nlSRGB = Config::Instance()->FsrNonLinearSRGB.value_or_default(); - ImGui::Checkbox("FSR4 Non-Linear sRGB Input", &nlSRGB)) - { - Config::Instance()->FsrNonLinearSRGB = nlSRGB; - - if (nlSRGB) - Config::Instance()->FsrNonLinearPQ = false; - - State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - ShowHelpMarker("Indicates input color resource contains perceptual sRGB colors\n" - "Might improve upscaling quality of FSR4"); - - if (bool nlPQ = Config::Instance()->FsrNonLinearPQ.value_or_default(); - ImGui::Checkbox("FSR4 Non-Linear PQ Input", &nlPQ)) - { - Config::Instance()->FsrNonLinearPQ = nlPQ; - - if (nlPQ) - Config::Instance()->FsrNonLinearSRGB = false; - - State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - ShowHelpMarker("Indicates input color resource contains perceptual PQ colors\n" - "Might improve upscaling quality of FSR4"); - - if (bool dView = Config::Instance()->FsrDebugView.value_or_default(); - ImGui::Checkbox("FSR 3.X Debug View", &dView)) - Config::Instance()->FsrDebugView = dView; - ShowHelpMarker("Top left: Dilated Motion Vectors\n" - "Top middle: Protected Areas\n" - "Top right: Dilated Depth\n" - "Middle: Upscaled frame\n" - "Bottom left: Disocclusion mask\n" - "Bottom middle: Reactiveness\n" - "Bottom right: Detail Protection Takedown"); - } - - if (State::Instance().currentFeature->AccessToReactiveMask()) - { - ImGui::BeginDisabled(Config::Instance()->DisableReactiveMask.value_or(false)); - - auto useAsTransparency = - Config::Instance()->FsrUseMaskForTransparency.value_or_default(); - if (ImGui::Checkbox("Use Reactive Mask as Transparency Mask", &useAsTransparency)) - Config::Instance()->FsrUseMaskForTransparency = useAsTransparency; - - ImGui::EndDisabled(); - } - - ImGui::Spacing(); - if (currentFeature->Version() >= feature_version { 3, 1, 1 } && - ImGui::CollapsingHeader("Upscaler Settings")) - { - ImGui::PushItemWidth(280.0f * Config::Instance()->MenuScale.value_or_default()); - - float velocity = Config::Instance()->FsrVelocity.value_or_default(); - if (ImGui::SliderFloat("Velocity Factor", &velocity, 0.00f, 1.0f, "%.2f")) - Config::Instance()->FsrVelocity = velocity; - - ShowHelpMarker("Value of 0.0f can improve temporal stability of bright pixels\n" - "Lower values are more stable with ghosting\n" - "Higher values are more pixelly but less ghosting."); - - if (currentFeature->Version() >= feature_version { 3, 1, 4 }) - { - // Reactive Scale - float reactiveScale = Config::Instance()->FsrReactiveScale.value_or_default(); - if (ImGui::SliderFloat("Reactive Scale", &reactiveScale, 0.0f, 100.0f, "%.1f")) - Config::Instance()->FsrReactiveScale = reactiveScale; - - ShowHelpMarker("Meant for development purpose to test if\n" - "writing a larger value to reactive mask, reduces ghosting."); - - // Shading Scale - float shadingScale = Config::Instance()->FsrShadingScale.value_or_default(); - if (ImGui::SliderFloat("Shading Scale", &shadingScale, 0.0f, 100.0f, "%.1f")) - Config::Instance()->FsrShadingScale = shadingScale; - - ShowHelpMarker("Increasing this scales fsr3.1 computed shading\n" - "change value at read to have higher reactiveness."); - - // Accumulation Added Per Frame - float accAddPerFrame = Config::Instance()->FsrAccAddPerFrame.value_or_default(); - if (ImGui::SliderFloat("Acc. Added Per Frame", &accAddPerFrame, 0.00f, 1.0f, - "%.2f")) - Config::Instance()->FsrAccAddPerFrame = accAddPerFrame; - - ShowHelpMarker( - "Corresponds to amount of accumulation added per frame\n" - "at pixel coordinate where disocclusion occured or when\n" - "reactive mask value is > 0.0f. Decreasing this and \n" - "drawing the ghosting object (IE no mv) to reactive mask \n" - "with value close to 1.0f can decrease temporal ghosting.\n" - "Decreasing this could result in more thin feature pixels flickering."); - - // Min Disocclusion Accumulation - float minDisOccAcc = Config::Instance()->FsrMinDisOccAcc.value_or_default(); - if (ImGui::SliderFloat("Min. Disocclusion Acc.", &minDisOccAcc, -1.0f, 1.0f, - "%.2f")) - Config::Instance()->FsrMinDisOccAcc = minDisOccAcc; - - ShowHelpMarker("Increasing this value may reduce white pixel temporal\n" - "flickering around swaying thin objects that are disoccluding \n" - "one another often. Too high value may increase ghosting."); - } - - ImGui::PopItemWidth(); - } - - ImGui::Spacing(); - ImGui::Spacing(); - } - } - // FSR Common ----------------- - if (State::Instance().activeFgType == FGType::OptiFG || currentBackend.rfind("fsr", 0) == 0) + if (currentFeature != nullptr && !currentFeature->IsFrozen() && + (State::Instance().activeFgType == FGType::OptiFG || currentBackend.rfind("fsr", 0) == 0)) { SeparatorWithHelpMarker("FSR Common Settings", "Affects both FSR-FG & Upscalers"); @@ -2646,6 +2778,8 @@ bool MenuCommon::RenderMenu() ImGui::Spacing(); if (ImGui::CollapsingHeader("FoV & Camera Values")) { + ScopedIndent indent {}; + ImGui::Spacing(); bool useVFov = Config::Instance()->FsrVerticalFov.has_value() || !Config::Instance()->FsrHorizontalFov.has_value(); @@ -2720,197 +2854,10 @@ bool MenuCommon::RenderMenu() : 500000.0f, State::Instance().lastFsrCameraFar < 500000.0f ? State::Instance().lastFsrCameraFar : 500000.0f); - } - - ImGui::Spacing(); - ImGui::Spacing(); - } - - // DLSS ----------------- - if ((Config::Instance()->DLSSEnabled.value_or_default() && currentBackend == "dlss" && - State::Instance().currentFeature->Version().major > 2) || - State::Instance().currentFeature->Name() == "DLSSD") - { - const bool usesDlssd = State::Instance().currentFeature->Name() == "DLSSD"; - - if (usesDlssd) - ImGui::SeparatorText("DLSSD Settings"); - else - ImGui::SeparatorText("DLSS Settings"); - - auto overridden = usesDlssd ? State::Instance().dlssdPresetsOverriddenExternally - : State::Instance().dlssPresetsOverriddenExternally; - - if (overridden) - { - ImGui::TextColored(ImVec4(1.f, 0.f, 0.f, 1.f), "Presets are overridden externally"); - ShowHelpMarker("This usually happens due to using tools\n" - "such as Nvidia App or Nvidia Inspector"); - ImGui::Text("Selecting setting below will disable that external override\n" - "but you need to Save INI and restart the game"); ImGui::Spacing(); - } - - if (bool pOverride = Config::Instance()->RenderPresetOverride.value_or_default(); - ImGui::Checkbox("Render Presets Override", &pOverride)) - Config::Instance()->RenderPresetOverride = pOverride; - ShowHelpMarker("Each render preset has it strengths and weaknesses\n" - "Override to potentially improve image quality"); - - ImGui::BeginDisabled(!Config::Instance()->RenderPresetOverride.value_or_default() || - overridden); - - ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); - if (usesDlssd) - AddDLSSDRenderPreset("Override Preset", &Config::Instance()->RenderPresetForAll); - else - AddDLSSRenderPreset("Override Preset", &Config::Instance()->RenderPresetForAll); - - ImGui::PopItemWidth(); - - ImGui::SameLine(0.0f, 6.0f); - - if (ImGui::Button("Apply Changes")) - { - if (usesDlssd) - State::Instance().newBackend = "dlssd"; - else - State::Instance().newBackend = currentBackend; - - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - - ImGui::EndDisabled(); - - ImGui::Spacing(); - - if (ImGui::CollapsingHeader(usesDlssd ? "Advanced DLSSD Settings" : "Advanced DLSS Settings")) - { - ScopedIndent indent {}; ImGui::Spacing(); - bool appIdOverride = Config::Instance()->UseGenericAppIdWithDlss.value_or_default(); - if (ImGui::Checkbox("Use Generic App Id with DLSS", &appIdOverride)) - Config::Instance()->UseGenericAppIdWithDlss = appIdOverride; - - ShowHelpMarker("Use generic appid with NGX\n" - "Fixes OptiScaler preset override not working with certain games\n" - "Requires a game restart."); - - ImGui::BeginDisabled(!Config::Instance()->RenderPresetOverride.value_or_default() || - overridden); - ImGui::Spacing(); - ImGui::PushItemWidth(135.0f * Config::Instance()->MenuScale.value_or_default()); - - if (usesDlssd) - { - AddDLSSDRenderPreset("DLAA Preset", &Config::Instance()->RenderPresetDLAA); - AddDLSSDRenderPreset("UltraQ Preset", &Config::Instance()->RenderPresetUltraQuality); - AddDLSSDRenderPreset("Quality Preset", &Config::Instance()->RenderPresetQuality); - AddDLSSDRenderPreset("Balanced Preset", &Config::Instance()->RenderPresetBalanced); - AddDLSSDRenderPreset("Perf Preset", &Config::Instance()->RenderPresetPerformance); - AddDLSSDRenderPreset("UltraP Preset", - &Config::Instance()->RenderPresetUltraPerformance); - } - else - { - AddDLSSRenderPreset("DLAA Preset", &Config::Instance()->RenderPresetDLAA); - AddDLSSRenderPreset("UltraQ Preset", &Config::Instance()->RenderPresetUltraQuality); - AddDLSSRenderPreset("Quality Preset", &Config::Instance()->RenderPresetQuality); - AddDLSSRenderPreset("Balanced Preset", &Config::Instance()->RenderPresetBalanced); - AddDLSSRenderPreset("Perf Preset", &Config::Instance()->RenderPresetPerformance); - AddDLSSRenderPreset("UltraP Preset", &Config::Instance()->RenderPresetUltraPerformance); - } - ImGui::PopItemWidth(); - ImGui::EndDisabled(); } - - ImGui::Spacing(); - ImGui::Spacing(); - } - - // RCAS ----------------- - if (State::Instance().api == DX12 || State::Instance().api == DX11) - { - ImGui::SeparatorText("RCAS Settings"); - - // xess or dlss version >= 2.5.1 - constexpr feature_version requiredDlssVersion = { 2, 5, 1 }; - rcasEnabled = (currentBackend == "xess" || - (currentBackend == "dlss" && - State::Instance().currentFeature->Version() >= requiredDlssVersion)); - - if (bool rcas = Config::Instance()->RcasEnabled.value_or(rcasEnabled); - ImGui::Checkbox("Enable RCAS", &rcas)) - Config::Instance()->RcasEnabled = rcas; - ShowHelpMarker("A sharpening filter\n" - "By default uses a sharpening value provided by the game\n" - "Select 'Override' under 'Sharpness' and adjust the slider to change it\n\n" - "Some upscalers have it's own sharpness filter so RCAS is not always needed"); - - ImGui::BeginDisabled(!Config::Instance()->RcasEnabled.value_or(rcasEnabled)); - - if (bool contrastEnabled = Config::Instance()->ContrastEnabled.value_or_default(); - ImGui::Checkbox("Contrast Enabled", &contrastEnabled)) - Config::Instance()->ContrastEnabled = contrastEnabled; - - ShowHelpMarker("Increases sharpness at high contrast areas."); - - if (Config::Instance()->ContrastEnabled.value_or_default() && - Config::Instance()->Sharpness.value_or_default() > 1.0f) - Config::Instance()->Sharpness = 1.0f; - - ImGui::BeginDisabled(!Config::Instance()->ContrastEnabled.value_or_default()); - - float contrast = Config::Instance()->Contrast.value_or_default(); - if (ImGui::SliderFloat("Contrast", &contrast, 0.0f, 2.0f, "%.2f")) - Config::Instance()->Contrast = contrast; - - ShowHelpMarker("Higher values increases sharpness at high contrast areas.\n" - "High values might cause graphical GLITCHES \n" - "when used with high sharpness values !!!"); - - ImGui::EndDisabled(); - - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Motion Adaptive Sharpness##2")) - { - ScopedIndent indent {}; - ImGui::Spacing(); - if (bool overrideMotionSharpness = - Config::Instance()->MotionSharpnessEnabled.value_or_default(); - ImGui::Checkbox("Motion Adaptive Sharpness", &overrideMotionSharpness)) - Config::Instance()->MotionSharpnessEnabled = overrideMotionSharpness; - ShowHelpMarker("Applies more sharpness to things in motion"); - - ImGui::BeginDisabled(!Config::Instance()->MotionSharpnessEnabled.value_or_default()); - - ImGui::SameLine(0.0f, 6.0f); - - if (bool overrideMSDebug = Config::Instance()->MotionSharpnessDebug.value_or_default(); - ImGui::Checkbox("MAS Debug", &overrideMSDebug)) - Config::Instance()->MotionSharpnessDebug = overrideMSDebug; - ShowHelpMarker("Areas that are more red will have more sharpness applied\n" - "Green areas will get reduced sharpness"); - - float motionSharpness = Config::Instance()->MotionSharpness.value_or_default(); - ImGui::SliderFloat("MotionSharpness", &motionSharpness, -1.3f, 1.3f, "%.3f"); - Config::Instance()->MotionSharpness = motionSharpness; - - float motionThreshod = Config::Instance()->MotionThreshold.value_or_default(); - ImGui::SliderFloat("MotionThreshod", &motionThreshod, 0.0f, 100.0f, "%.2f"); - Config::Instance()->MotionThreshold = motionThreshod; - - float motionScale = Config::Instance()->MotionScaleLimit.value_or_default(); - ImGui::SliderFloat("MotionRange", &motionScale, 0.01f, 100.0f, "%.2f"); - Config::Instance()->MotionScaleLimit = motionScale; - - ImGui::EndDisabled(); - } - ImGui::Spacing(); - ImGui::Spacing(); - ImGui::EndDisabled(); } // DLSS Enabler ----------------- @@ -2955,6 +2902,7 @@ bool MenuCommon::RenderMenu() { ScopedIndent indent {}; ImGui::Spacing(); + std::string selected; if (Config::Instance()->DE_Generator.value_or("auto") == "auto") @@ -3092,101 +3040,49 @@ bool MenuCommon::RenderMenu() } } - if (currentFeature != nullptr && !currentFeature->IsFrozen()) + // FAKENVAPI --------------------------- + if (fakenvapi::isUsingFakenvapi()) { - // OUTPUT SCALING ----------------------------- - if (State::Instance().api == DX12 || State::Instance().api == DX11) + ImGui::SeparatorText("fakenvapi"); + + if (bool logs = Config::Instance()->FN_EnableLogs.value_or_default(); + ImGui::Checkbox("Enable Logging To File", &logs)) + Config::Instance()->FN_EnableLogs = logs; + + ImGui::BeginDisabled(!Config::Instance()->FN_EnableLogs.value_or_default()); + + ImGui::SameLine(0.0f, 6.0f); + if (bool traceLogs = Config::Instance()->FN_EnableTraceLogs.value_or_default(); + ImGui::Checkbox("Enable Trace Logs", &traceLogs)) + Config::Instance()->FN_EnableTraceLogs = traceLogs; + + ImGui::EndDisabled(); + + if (bool forceLFX = Config::Instance()->FN_ForceLatencyFlex.value_or_default(); + ImGui::Checkbox("Force LatencyFlex", &forceLFX)) + Config::Instance()->FN_ForceLatencyFlex = forceLFX; + ShowHelpMarker( + "AntiLag 2 / XeLL is used when available, this setting let's you force LatencyFlex instead"); + + const char* lfx_modes[] = { "Conservative", "Aggressive", "Reflex ID" }; + const std::string lfx_modesDesc[] = { + "The safest but might not reduce latency well", + "Improves latency but in some cases will lower fps more than expected", + "Best when can be used, some games are not compatible (i.e. cyberpunk) and will fallback to " + "aggressive" + }; + + PopulateCombo("LatencyFlex mode", &Config::Instance()->FN_LatencyFlexMode, lfx_modes, lfx_modesDesc, + 3); + + const char* rfx_modes[] = { "Follow in-game", "Force Disable", "Force Enable" }; + const std::string rfx_modesDesc[] = { "", "", "" }; + + PopulateCombo("Force Reflex", &Config::Instance()->FN_ForceReflex, rfx_modes, rfx_modesDesc, 3); + + if (ImGui::Button("Apply##2")) { - // if motion vectors are not display size - ImGui::BeginDisabled(!currentFeature->LowResMV()); - - ImGui::SeparatorText("Output Scaling"); - - float defaultRatio = 1.5f; - - if (_ssRatio == 0.0f) - { - _ssRatio = Config::Instance()->OutputScalingMultiplier.value_or(defaultRatio); - _ssEnabled = Config::Instance()->OutputScalingEnabled.value_or_default(); - _ssUseFsr = Config::Instance()->OutputScalingUseFsr.value_or_default(); - _ssDownsampler = Config::Instance()->OutputScalingDownscaler.value_or_default(); - } - - ImGui::BeginDisabled((currentBackend == "xess" || currentBackend == "dlss") && - State::Instance().currentFeature->RenderWidth() > - State::Instance().currentFeature->DisplayWidth()); - ImGui::Checkbox("Enable", &_ssEnabled); - ImGui::EndDisabled(); - - ShowHelpMarker("Upscales the image internally to a selected resolution\n" - "Then scales it to your resolution\n\n" - "Values <1.0 might make upscaler less expensive\n" - "Values >1.0 might make image sharper at the cost of performance\n\n" - "You can see each step at the bottom of this menu"); - - ImGui::SameLine(0.0f, 6.0f); - - ImGui::BeginDisabled(!_ssEnabled); - { - ImGui::Checkbox("Use FSR 1", &_ssUseFsr); - ShowHelpMarker("Use FSR 1 for scaling"); - - ImGui::SameLine(0.0f, 6.0f); - - ImGui::BeginDisabled(_ssUseFsr || _ssRatio < 1.0f); - { - const char* ds_modes[] = { "Bicubic", "Lanczos", "Catmull-Rom", "MAGC" }; - const std::string ds_modesDesc[] = { "", "", "", "" }; - - ImGui::PushItemWidth(75.0f * Config::Instance()->MenuScale.value()); - PopulateCombo("Downscaler", &Config::Instance()->OutputScalingDownscaler, ds_modes, - ds_modesDesc, 4); - ImGui::PopItemWidth(); - } - ImGui::EndDisabled(); - } - ImGui::EndDisabled(); - - bool applyEnabled = - _ssEnabled != Config::Instance()->OutputScalingEnabled.value_or_default() || - _ssRatio != Config::Instance()->OutputScalingMultiplier.value_or(defaultRatio) || - _ssUseFsr != Config::Instance()->OutputScalingUseFsr.value_or_default() || - (_ssRatio > 1.0f && - _ssDownsampler != Config::Instance()->OutputScalingDownscaler.value_or_default()); - - ImGui::BeginDisabled(!applyEnabled); - if (ImGui::Button("Apply Change")) - { - Config::Instance()->OutputScalingEnabled = _ssEnabled; - Config::Instance()->OutputScalingMultiplier = _ssRatio; - Config::Instance()->OutputScalingUseFsr = _ssUseFsr; - _ssDownsampler = Config::Instance()->OutputScalingDownscaler.value_or_default(); - - if (State::Instance().currentFeature->Name() == "DLSSD") - State::Instance().newBackend = "dlssd"; - else - State::Instance().newBackend = currentBackend; - - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; - } - ImGui::EndDisabled(); - - ImGui::BeginDisabled(!_ssEnabled || State::Instance().currentFeature->RenderWidth() > - State::Instance().currentFeature->DisplayWidth()); - ImGui::SliderFloat("Ratio", &_ssRatio, 0.5f, 3.0f, "%.2f"); - ImGui::EndDisabled(); - - if (currentFeature != nullptr && !currentFeature->IsFrozen()) - { - ImGui::Text( - "Output Scaling is %s, Target Res: %dx%d\nJitter Count: %d", - Config::Instance()->OutputScalingEnabled.value_or_default() ? "ENABLED" : "DISABLED", - (uint32_t) (currentFeature->DisplayWidth() * _ssRatio), - (uint32_t) (currentFeature->DisplayHeight() * _ssRatio), currentFeature->JitterCount()); - } - - ImGui::EndDisabled(); + Config::Instance()->SaveFakenvapiIni(); } } @@ -3206,8 +3102,7 @@ bool MenuCommon::RenderMenu() if (currentBackend == "dlss" && State::Instance().currentFeature->Version().major < 3) { State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; + MARK_ALL_BACKENDS_CHANGED(); } } ShowHelpMarker("Ignores the value sent by the game\n" @@ -3225,89 +3120,259 @@ bool MenuCommon::RenderMenu() ImGui::EndDisabled(); + // RCAS + if (State::Instance().api == DX12 || State::Instance().api == DX11) + { + // xess or dlss version >= 2.5.1 + constexpr feature_version requiredDlssVersion = { 2, 5, 1 }; + rcasEnabled = (currentBackend == "xess" || + (currentBackend == "dlss" && + State::Instance().currentFeature->Version() >= requiredDlssVersion)); + + if (bool rcas = Config::Instance()->RcasEnabled.value_or(rcasEnabled); + ImGui::Checkbox("Enable RCAS", &rcas)) + Config::Instance()->RcasEnabled = rcas; + ShowHelpMarker("A sharpening filter\n" + "By default uses a sharpening value provided by the game\n" + "Select 'Override' under 'Sharpness' and adjust the slider to change it\n\n" + "Some upscalers have it's own sharpness filter so RCAS is not always needed"); + + ImGui::BeginDisabled(!Config::Instance()->RcasEnabled.value_or(rcasEnabled)); + + if (bool contrastEnabled = Config::Instance()->ContrastEnabled.value_or_default(); + ImGui::Checkbox("Contrast Enabled", &contrastEnabled)) + Config::Instance()->ContrastEnabled = contrastEnabled; + + ShowHelpMarker("Increases sharpness at high contrast areas."); + + if (Config::Instance()->ContrastEnabled.value_or_default() && + Config::Instance()->Sharpness.value_or_default() > 1.0f) + Config::Instance()->Sharpness = 1.0f; + + ImGui::BeginDisabled(!Config::Instance()->ContrastEnabled.value_or_default()); + + float contrast = Config::Instance()->Contrast.value_or_default(); + if (ImGui::SliderFloat("Contrast", &contrast, 0.0f, 2.0f, "%.2f")) + Config::Instance()->Contrast = contrast; + + ShowHelpMarker("Higher values increases sharpness at high contrast areas.\n" + "High values might cause graphical GLITCHES \n" + "when used with high sharpness values !!!"); + + ImGui::EndDisabled(); + + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Motion Adaptive Sharpness##2")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + if (bool overrideMotionSharpness = + Config::Instance()->MotionSharpnessEnabled.value_or_default(); + ImGui::Checkbox("Motion Adaptive Sharpness", &overrideMotionSharpness)) + Config::Instance()->MotionSharpnessEnabled = overrideMotionSharpness; + ShowHelpMarker("Applies more sharpness to things in motion"); + + ImGui::BeginDisabled(!Config::Instance()->MotionSharpnessEnabled.value_or_default()); + + ImGui::SameLine(0.0f, 6.0f); + + if (bool overrideMSDebug = Config::Instance()->MotionSharpnessDebug.value_or_default(); + ImGui::Checkbox("MAS Debug", &overrideMSDebug)) + Config::Instance()->MotionSharpnessDebug = overrideMSDebug; + ShowHelpMarker("Areas that are more red will have more sharpness applied\n" + "Green areas will get reduced sharpness"); + + float motionSharpness = Config::Instance()->MotionSharpness.value_or_default(); + ImGui::SliderFloat("MotionSharpness", &motionSharpness, -1.3f, 1.3f, "%.3f"); + Config::Instance()->MotionSharpness = motionSharpness; + + float motionThreshod = Config::Instance()->MotionThreshold.value_or_default(); + ImGui::SliderFloat("MotionThreshod", &motionThreshod, 0.0f, 100.0f, "%.2f"); + Config::Instance()->MotionThreshold = motionThreshod; + + float motionScale = Config::Instance()->MotionScaleLimit.value_or_default(); + ImGui::SliderFloat("MotionRange", &motionScale, 0.01f, 100.0f, "%.2f"); + Config::Instance()->MotionScaleLimit = motionScale; + + ImGui::EndDisabled(); + + ImGui::Spacing(); + ImGui::Spacing(); + } + + ImGui::EndDisabled(); + } + // UPSCALE RATIO OVERRIDE ----------------- auto minSliderLimit = Config::Instance()->ExtendedLimits.value_or_default() ? 0.1f : 1.0f; auto maxSliderLimit = Config::Instance()->ExtendedLimits.value_or_default() ? 6.0f : 3.0f; - ImGui::SeparatorText("Upscale Ratio"); + ImGui::SeparatorText("Upscale Ratio Override"); + if (bool upOverride = Config::Instance()->UpscaleRatioOverrideEnabled.value_or_default(); - ImGui::Checkbox("Ratio Override", &upOverride)) + ImGui::Checkbox("Override all", &upOverride)) + { Config::Instance()->UpscaleRatioOverrideEnabled = upOverride; + + if (upOverride) + Config::Instance()->QualityRatioOverrideEnabled = false; + } ShowHelpMarker("Let's you override every upscaler preset\n" "with a value set below\n\n" "1.5x on a 1080p screen means internal resolution of 720p\n" "1080 / 1.5 = 720"); - ImGui::BeginDisabled(!Config::Instance()->UpscaleRatioOverrideEnabled.value_or_default()); - - float urOverride = Config::Instance()->UpscaleRatioOverrideValue.value_or_default(); - ImGui::SliderFloat("Override Ratio", &urOverride, minSliderLimit, maxSliderLimit, "%.3f"); - Config::Instance()->UpscaleRatioOverrideValue = urOverride; - - ImGui::EndDisabled(); - - // QUALITY OVERRIDES ----------------------------- - ImGui::SeparatorText("Quality Overrides"); - if (bool qOverride = Config::Instance()->QualityRatioOverrideEnabled.value_or_default(); - ImGui::Checkbox("Quality Override", &qOverride)) + ImGui::Checkbox("Override per quality preset", &qOverride)) + { Config::Instance()->QualityRatioOverrideEnabled = qOverride; + + if (qOverride) + Config::Instance()->UpscaleRatioOverrideEnabled = false; + } + ShowHelpMarker("Let's you override each preset's ratio individually\n" "Note that not every game supports every quality preset\n\n" "1.5x on a 1080p screen means internal resolution of 720p\n" "1080 / 1.5 = 720"); - ImGui::BeginDisabled(!Config::Instance()->QualityRatioOverrideEnabled.value_or_default()); - - float qDlaa = Config::Instance()->QualityRatio_DLAA.value_or_default(); - if (ImGui::SliderFloat("DLAA", &qDlaa, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_DLAA = qDlaa; - - float qUq = Config::Instance()->QualityRatio_UltraQuality.value_or_default(); - if (ImGui::SliderFloat("Ultra Quality", &qUq, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_UltraQuality = qUq; - - float qQ = Config::Instance()->QualityRatio_Quality.value_or_default(); - if (ImGui::SliderFloat("Quality", &qQ, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_Quality = qQ; - - float qB = Config::Instance()->QualityRatio_Balanced.value_or_default(); - if (ImGui::SliderFloat("Balanced", &qB, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_Balanced = qB; - - float qP = Config::Instance()->QualityRatio_Performance.value_or_default(); - if (ImGui::SliderFloat("Performance", &qP, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_Performance = qP; - - float qUp = Config::Instance()->QualityRatio_UltraPerformance.value_or_default(); - if (ImGui::SliderFloat("Ultra Performance", &qUp, minSliderLimit, maxSliderLimit, "%.3f")) - Config::Instance()->QualityRatio_UltraPerformance = qUp; - - ImGui::EndDisabled(); - - // DRS ----------------------------- - ImGui::SeparatorText("DRS (Dynamic Resolution Scaling)"); - if (ImGui::BeginTable("drs", 2, ImGuiTableFlags_SizingStretchSame)) + if (Config::Instance()->UpscaleRatioOverrideEnabled.value_or_default()) { - ImGui::TableNextColumn(); - if (bool drsMin = Config::Instance()->DrsMinOverrideEnabled.value_or_default(); - ImGui::Checkbox("Override Minimum", &drsMin)) - Config::Instance()->DrsMinOverrideEnabled = drsMin; - ShowHelpMarker("Fix for games ignoring official DRS limits"); + float urOverride = Config::Instance()->UpscaleRatioOverrideValue.value_or_default(); + ImGui::SliderFloat("All Ratios", &urOverride, minSliderLimit, maxSliderLimit, "%.3f"); + Config::Instance()->UpscaleRatioOverrideValue = urOverride; + } - ImGui::TableNextColumn(); - if (bool drsMax = Config::Instance()->DrsMaxOverrideEnabled.value_or_default(); - ImGui::Checkbox("Override Maximum", &drsMax)) - Config::Instance()->DrsMaxOverrideEnabled = drsMax; - ShowHelpMarker("Fix for games ignoring official DRS limits"); + if (Config::Instance()->QualityRatioOverrideEnabled.value_or_default()) + { + float qDlaa = Config::Instance()->QualityRatio_DLAA.value_or_default(); + if (ImGui::SliderFloat("DLAA", &qDlaa, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_DLAA = qDlaa; - ImGui::EndTable(); + float qUq = Config::Instance()->QualityRatio_UltraQuality.value_or_default(); + if (ImGui::SliderFloat("Ultra Quality", &qUq, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_UltraQuality = qUq; + + float qQ = Config::Instance()->QualityRatio_Quality.value_or_default(); + if (ImGui::SliderFloat("Quality", &qQ, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_Quality = qQ; + + float qB = Config::Instance()->QualityRatio_Balanced.value_or_default(); + if (ImGui::SliderFloat("Balanced", &qB, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_Balanced = qB; + + float qP = Config::Instance()->QualityRatio_Performance.value_or_default(); + if (ImGui::SliderFloat("Performance", &qP, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_Performance = qP; + + float qUp = Config::Instance()->QualityRatio_UltraPerformance.value_or_default(); + if (ImGui::SliderFloat("Ultra Performance", &qUp, minSliderLimit, maxSliderLimit, "%.3f")) + Config::Instance()->QualityRatio_UltraPerformance = qUp; + } + + if (currentFeature != nullptr && !currentFeature->IsFrozen()) + { + // OUTPUT SCALING ----------------------------- + if (State::Instance().api == DX12 || State::Instance().api == DX11) + { + // if motion vectors are not display size + ImGui::BeginDisabled(!currentFeature->LowResMV()); + + ImGui::SeparatorText("Output Scaling"); + + float defaultRatio = 1.5f; + + if (_ssRatio == 0.0f) + { + _ssRatio = Config::Instance()->OutputScalingMultiplier.value_or(defaultRatio); + _ssEnabled = Config::Instance()->OutputScalingEnabled.value_or_default(); + _ssUseFsr = Config::Instance()->OutputScalingUseFsr.value_or_default(); + _ssDownsampler = Config::Instance()->OutputScalingDownscaler.value_or_default(); + } + + ImGui::BeginDisabled((currentBackend == "xess" || currentBackend == "dlss") && + State::Instance().currentFeature->RenderWidth() > + State::Instance().currentFeature->DisplayWidth()); + ImGui::Checkbox("Enable", &_ssEnabled); + ImGui::EndDisabled(); + + ShowHelpMarker("Upscales the image internally to a selected resolution\n" + "Then scales it to your resolution\n\n" + "Values <1.0 might make the upscaler cheaper\n" + "Values >1.0 might make image sharper at the cost of performance\n\n" + "You can see each step at the bottom of this menu"); + + ImGui::SameLine(0.0f, 6.0f); + + ImGui::BeginDisabled(!_ssEnabled); + { + ImGui::Checkbox("Use FSR 1", &_ssUseFsr); + ShowHelpMarker("Use FSR 1 for scaling"); + + ImGui::SameLine(0.0f, 6.0f); + + ImGui::BeginDisabled(_ssUseFsr || _ssRatio < 1.0f); + { + const char* ds_modes[] = { "Bicubic", "Lanczos", "Catmull-Rom", "MAGC" }; + const std::string ds_modesDesc[] = { "", "", "", "" }; + + ImGui::PushItemWidth(75.0f * Config::Instance()->MenuScale.value()); + PopulateCombo("Downscaler", &Config::Instance()->OutputScalingDownscaler, ds_modes, + ds_modesDesc, 4); + ImGui::PopItemWidth(); + } + ImGui::EndDisabled(); + } + ImGui::EndDisabled(); + + bool applyEnabled = + _ssEnabled != Config::Instance()->OutputScalingEnabled.value_or_default() || + _ssRatio != Config::Instance()->OutputScalingMultiplier.value_or(defaultRatio) || + _ssUseFsr != Config::Instance()->OutputScalingUseFsr.value_or_default() || + (_ssRatio > 1.0f && + _ssDownsampler != Config::Instance()->OutputScalingDownscaler.value_or_default()); + + ImGui::BeginDisabled(!applyEnabled); + if (ImGui::Button("Apply Change")) + { + Config::Instance()->OutputScalingEnabled = _ssEnabled; + Config::Instance()->OutputScalingMultiplier = _ssRatio; + Config::Instance()->OutputScalingUseFsr = _ssUseFsr; + _ssDownsampler = Config::Instance()->OutputScalingDownscaler.value_or_default(); + + if (State::Instance().currentFeature->Name() == "DLSSD") + State::Instance().newBackend = "dlssd"; + else + State::Instance().newBackend = currentBackend; + + MARK_ALL_BACKENDS_CHANGED(); + } + ImGui::EndDisabled(); + + ImGui::BeginDisabled(!_ssEnabled || State::Instance().currentFeature->RenderWidth() > + State::Instance().currentFeature->DisplayWidth()); + ImGui::SliderFloat("Ratio", &_ssRatio, 0.5f, 3.0f, "%.2f"); + ImGui::EndDisabled(); + + if (currentFeature != nullptr && !currentFeature->IsFrozen()) + { + ImGui::Text("Output Scaling is %s, Target Res: %dx%d\nJitter Count: %d", + Config::Instance()->OutputScalingEnabled.value_or_default() ? "ENABLED" + : "DISABLED", + (uint32_t) (currentFeature->DisplayWidth() * _ssRatio), + (uint32_t) (currentFeature->DisplayHeight() * _ssRatio), + currentFeature->JitterCount()); + } + + ImGui::EndDisabled(); + } } // INIT ----------------------------- ImGui::SeparatorText("Init Flags"); - if (ImGui::BeginTable("init", 2, ImGuiTableFlags_SizingStretchSame)) + if (ImGui::BeginTable("init", 2, ImGuiTableFlags_SizingStretchProp)) { ImGui::TableNextColumn(); if (bool autoExposure = currentFeature->AutoExposure(); @@ -3338,8 +3403,7 @@ bool MenuCommon::RenderMenu() if (currentBackend == "xess") { State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; + MARK_ALL_BACKENDS_CHANGED(); } } @@ -3359,7 +3423,8 @@ bool MenuCommon::RenderMenu() { ScopedIndent indent {}; ImGui::Spacing(); - if (ImGui::BeginTable("init2", 2, ImGuiTableFlags_SizingStretchSame)) + + if (ImGui::BeginTable("init2", 2, ImGuiTableFlags_SizingStretchProp)) { ImGui::TableNextColumn(); if (bool depth = currentFeature->DepthInverted(); @@ -3448,52 +3513,13 @@ bool MenuCommon::RenderMenu() } } - // FAKENVAPI --------------------------- - if (fakenvapi::isUsingFakenvapi()) - { - ImGui::SeparatorText("fakenvapi"); - - if (bool logs = Config::Instance()->FN_EnableLogs.value_or_default(); - ImGui::Checkbox("Enable Logs", &logs)) - Config::Instance()->FN_EnableLogs = logs; - - ImGui::SameLine(0.0f, 6.0f); - if (bool traceLogs = Config::Instance()->FN_EnableTraceLogs.value_or_default(); - ImGui::Checkbox("Enable Trace Logs", &traceLogs)) - Config::Instance()->FN_EnableTraceLogs = traceLogs; - - if (bool forceLFX = Config::Instance()->FN_ForceLatencyFlex.value_or_default(); - ImGui::Checkbox("Force LatencyFlex", &forceLFX)) - Config::Instance()->FN_ForceLatencyFlex = forceLFX; - ShowHelpMarker("When possible AntiLag 2 is used, this setting let's you force LatencyFlex instead"); - - const char* lfx_modes[] = { "Conservative", "Aggressive", "Reflex ID" }; - const std::string lfx_modesDesc[] = { - "The safest but might not reduce latency well", - "Improves latency but in some cases will lower fps more than expected", - "Best when can be used, some games are not compatible (i.e. cyberpunk) and will fallback to " - "aggressive" - }; - - PopulateCombo("LatencyFlex mode", &Config::Instance()->FN_LatencyFlexMode, lfx_modes, lfx_modesDesc, - 3); - - const char* rfx_modes[] = { "Follow in-game", "Force Disable", "Force Enable" }; - const std::string rfx_modesDesc[] = { "", "", "" }; - - PopulateCombo("Force Reflex", &Config::Instance()->FN_ForceReflex, rfx_modes, rfx_modesDesc, 3); - - if (ImGui::Button("Apply##2")) - { - Config::Instance()->SaveFakenvapiIni(); - } - } - + // ADVANCED SETTINGS ----------------------------- ImGui::Spacing(); if (ImGui::CollapsingHeader("Advanced Settings")) { ScopedIndent indent {}; ImGui::Spacing(); + if (currentFeature != nullptr && !currentFeature->IsFrozen()) { bool extendedLimits = Config::Instance()->ExtendedLimits.value_or_default(); @@ -3510,8 +3536,64 @@ bool MenuCommon::RenderMenu() { Config::Instance()->UsePrecompiledShaders = pcShaders; State::Instance().newBackend = currentBackend; - for (auto& singleChangeBackend : State::Instance().changeBackend) - singleChangeBackend.second = true; + MARK_ALL_BACKENDS_CHANGED(); + } + + // DRS + ImGui::SeparatorText("DRS (Dynamic Resolution Scaling)"); + if (ImGui::BeginTable("drs", 2, ImGuiTableFlags_SizingStretchProp)) + { + ImGui::TableNextColumn(); + if (bool drsMin = Config::Instance()->DrsMinOverrideEnabled.value_or_default(); + ImGui::Checkbox("Override Minimum", &drsMin)) + Config::Instance()->DrsMinOverrideEnabled = drsMin; + ShowHelpMarker("Fix for games ignoring official DRS limits"); + + ImGui::TableNextColumn(); + if (bool drsMax = Config::Instance()->DrsMaxOverrideEnabled.value_or_default(); + ImGui::Checkbox("Override Maximum", &drsMax)) + Config::Instance()->DrsMaxOverrideEnabled = drsMax; + ShowHelpMarker("Fix for games ignoring official DRS limits"); + + ImGui::EndTable(); + } + + // Non-DLSS hotfixes ----------------------------- + if (currentFeature != nullptr && !currentFeature->IsFrozen() && currentBackend != "dlss") + { + // BARRIERS ----------------------------- + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Resource Barriers")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + AddResourceBarrier("Color", &Config::Instance()->ColorResourceBarrier); + AddResourceBarrier("Depth", &Config::Instance()->DepthResourceBarrier); + AddResourceBarrier("Motion", &Config::Instance()->MVResourceBarrier); + AddResourceBarrier("Exposure", &Config::Instance()->ExposureResourceBarrier); + AddResourceBarrier("Mask", &Config::Instance()->MaskResourceBarrier); + AddResourceBarrier("Output", &Config::Instance()->OutputResourceBarrier); + } + + // HOTFIXES ----------------------------- + if (State::Instance().api == DX12) + { + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Root Signatures")) + { + ScopedIndent indent {}; + ImGui::Spacing(); + + if (bool crs = Config::Instance()->RestoreComputeSignature.value_or_default(); + ImGui::Checkbox("Restore Compute Root Signature", &crs)) + Config::Instance()->RestoreComputeSignature = crs; + + if (bool grs = Config::Instance()->RestoreGraphicSignature.value_or_default(); + ImGui::Checkbox("Restore Graphic Root Signature", &grs)) + Config::Instance()->RestoreGraphicSignature = grs; + } + } } } @@ -3521,6 +3603,7 @@ bool MenuCommon::RenderMenu() { ScopedIndent indent {}; ImGui::Spacing(); + if (Config::Instance()->LogToConsole.value_or_default() || Config::Instance()->LogToFile.value_or_default() || Config::Instance()->LogToNGX.value_or_default()) @@ -3569,6 +3652,7 @@ bool MenuCommon::RenderMenu() { ScopedIndent indent {}; ImGui::Spacing(); + bool fpsEnabled = Config::Instance()->ShowFps.value_or_default(); if (ImGui::Checkbox("FPS Overlay Enabled", &fpsEnabled)) Config::Instance()->ShowFps = fpsEnabled; @@ -3619,7 +3703,8 @@ bool MenuCommon::RenderMenu() float values[] = { 0.0f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.6f, 1.7f, 1.8f, 1.9f, 2.0f }; - if (ImGui::SliderInt("Scale", ¤tIndex, 0, IM_ARRAYSIZE(options) - 1, options[currentIndex])) + if (ImGui::SliderInt("Scale", ¤tIndex, 0, IM_ARRAYSIZE(options) - 1, options[currentIndex], + ImGuiSliderFlags_ClampOnInput)) { if (currentIndex == 0) { @@ -3632,7 +3717,7 @@ bool MenuCommon::RenderMenu() } } - // ADVANCED SETTINGS ----------------------------- + // UPSCALER INPUTS ----------------------------- ImGui::Spacing(); auto uiStateOpen = currentFeature == nullptr || currentFeature->IsFrozen(); if (ImGui::CollapsingHeader("Upscaler Inputs", uiStateOpen ? ImGuiTreeNodeFlags_DefaultOpen : 0)) @@ -3843,53 +3928,14 @@ bool MenuCommon::RenderMenu() ImGui::Text("Will be applied after RESOLUTION/PRESET change !!!"); } - - if (currentFeature != nullptr && !currentFeature->IsFrozen()) - { - // Non-DLSS hotfixes ----------------------------- - if (currentBackend != "dlss") - { - // BARRIERS ----------------------------- - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Resource Barriers")) - { - ScopedIndent indent {}; - ImGui::Spacing(); - AddResourceBarrier("Color", &Config::Instance()->ColorResourceBarrier); - AddResourceBarrier("Depth", &Config::Instance()->DepthResourceBarrier); - AddResourceBarrier("Motion", &Config::Instance()->MVResourceBarrier); - AddResourceBarrier("Exposure", &Config::Instance()->ExposureResourceBarrier); - AddResourceBarrier("Mask", &Config::Instance()->MaskResourceBarrier); - AddResourceBarrier("Output", &Config::Instance()->OutputResourceBarrier); - } - - // HOTFIXES ----------------------------- - if (State::Instance().api == DX12) - { - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Root Signatures")) - { - ScopedIndent indent {}; - ImGui::Spacing(); - if (bool crs = Config::Instance()->RestoreComputeSignature.value_or_default(); - ImGui::Checkbox("Restore Compute Root Signature", &crs)) - Config::Instance()->RestoreComputeSignature = crs; - - if (bool grs = Config::Instance()->RestoreGraphicSignature.value_or_default(); - ImGui::Checkbox("Restore Graphic Root Signature", &grs)) - Config::Instance()->RestoreGraphicSignature = grs; - } - } - } - } } ImGui::Spacing(); if (ImGui::CollapsingHeader("Keybinds")) { ScopedIndent indent {}; - ImGui::Spacing(); + ImGui::Text("Key combinations are currently NOT supported!"); ImGui::Text("Escape to cancel, Backspace to unbind"); ImGui::Spacing(); From 6144d8868a38008ab30fc1ba0f28a28a08fd2935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Lewandowski?= <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:50:07 +0200 Subject: [PATCH 08/10] FSR 4 model selection (#546) * FSR 4 model selection * Fix Lunyx * Clamp the config value --- OptiScaler.ini | 5 ++++ OptiScaler/Config.cpp | 5 ++++ OptiScaler/Config.h | 1 + OptiScaler/FSR4Upgrade.h | 51 +++++++++++++++++++++++++++++++++ OptiScaler/State.h | 1 + OptiScaler/menu/menu_common.cpp | 47 ++++++++++++++++++++++++++++++ OptiScaler/scanner/scanner.cpp | 4 ++- OptiScaler/scanner/scanner.h | 1 + 8 files changed, 114 insertions(+), 1 deletion(-) diff --git a/OptiScaler.ini b/OptiScaler.ini index 61ad442b..0ef20099 100644 --- a/OptiScaler.ini +++ b/OptiScaler.ini @@ -327,6 +327,11 @@ DlssReactiveMaskBias=auto ; true or false - Default (auto) is depends on GPU Fsr4Update=auto +; Select FSR4 model to use +; 0 = model used for FSR AA/Quality, 5 = model used for FSR Ultra Performance +; From 0 to 5 - Default (auto) is game's default +Fsr4Model=auto + ; Indicates input color resource contains perceptual sRGB colors ; Might improve IQ of FSR4 ; true or false - Default (auto) is false diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index 37e52bd8..3d330d8c 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -127,6 +127,10 @@ bool Config::Reload(std::filesystem::path iniPath) FsrUseMaskForTransparency.set_from_config(readBool("FSR", "UseReactiveMaskForTransparency")); DlssReactiveMaskBias.set_from_config(readFloat("FSR", "DlssReactiveMaskBias")); Fsr4Update.set_from_config(readBool("FSR", "Fsr4Update")); + + if (auto setting = readInt("FSR", "Fsr4Model"); setting.has_value() && setting >= 0 && setting <= 5) + Fsr4Model.set_from_config(setting); + FsrNonLinearPQ.set_from_config(readBool("FSR", "FsrNonLinearPQ")); FsrNonLinearSRGB.set_from_config(readBool("FSR", "FsrNonLinearSRGB")); FsrAgilitySDKUpgrade.set_from_config(readBool("FSR", "FsrAgilitySDKUpgrade")); @@ -693,6 +697,7 @@ bool Config::SaveIni() ini.SetValue("FSR", "DlssReactiveMaskBias", GetFloatValue(Instance()->DlssReactiveMaskBias.value_for_config()).c_str()); ini.SetValue("FSR", "Fsr4Update", GetBoolValue(Instance()->Fsr4Update.value_for_config()).c_str()); + ini.SetValue("FSR", "Fsr4Model", GetIntValue(Instance()->Fsr4Model.value_for_config()).c_str()); ini.SetValue("FSR", "FsrNonLinearPQ", GetBoolValue(Instance()->FsrNonLinearPQ.value_for_config()).c_str()); ini.SetValue("FSR", "FsrNonLinearSRGB", GetBoolValue(Instance()->FsrNonLinearSRGB.value_for_config()).c_str()); ini.SetValue("FSR", "FsrAgilitySDKUpgrade", diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index 370ef72e..6fa00ada 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -292,6 +292,7 @@ class Config CustomOptional Fsr3xIndex { 0 }; CustomOptional FsrUseMaskForTransparency { true }; CustomOptional Fsr4Update { false }; + CustomOptional Fsr4Model; CustomOptional FsrNonLinearSRGB { false }; CustomOptional FsrNonLinearPQ { false }; CustomOptional FsrAgilitySDKUpgrade { false }; diff --git a/OptiScaler/FSR4Upgrade.h b/OptiScaler/FSR4Upgrade.h index a236a47d..53c78878 100644 --- a/OptiScaler/FSR4Upgrade.h +++ b/OptiScaler/FSR4Upgrade.h @@ -9,11 +9,14 @@ #include #include +#include typedef HRESULT(__cdecl* PFN_AmdExtD3DCreateInterface)(IUnknown* pOuter, REFIID riid, void** ppvObject); +typedef uint64_t (*PFN_getModelBlob)(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size); static HMODULE moduleAmdxc64 = nullptr; static HMODULE fsr4Module = nullptr; +static PFN_getModelBlob o_getModelBlob = nullptr; #pragma region GDI32 @@ -145,6 +148,22 @@ inline static std::vector GetDriverStore() #pragma endregion +uint64_t hkgetModelBlob(uint32_t preset, uint64_t unknown, uint64_t* source, uint64_t* size) +{ + LOG_FUNC(); + + if (Config::Instance()->Fsr4Model.has_value()) + { + preset = Config::Instance()->Fsr4Model.value(); + } + + State::Instance().currentFsr4Model = preset; + + auto result = o_getModelBlob(preset, unknown, source, size); + + return result; +} + /* Potato_of_Doom's Implementation */ #pragma region IAmdExtFfxApi @@ -200,6 +219,38 @@ struct AmdExtFfxApi : public IAmdExtFfxApi return E_NOINTERFACE; } + { + const char* pattern = "83 F9 05 0F 87 ? ? ? ?"; + + auto fsr4ModulePtr = (uintptr_t) fsr4Module; + + const uintptr_t moduleEnd = [&]() + { + auto ntHeaders = reinterpret_cast( + fsr4ModulePtr + reinterpret_cast(fsr4ModulePtr)->e_lfanew); + return static_cast(fsr4ModulePtr + ntHeaders->OptionalHeader.SizeOfImage); + }(); + + o_getModelBlob = + (PFN_getModelBlob) scanner::FindPattern(fsr4ModulePtr, moduleEnd - fsr4ModulePtr, pattern); + } + + if (o_getModelBlob) + { + LOG_DEBUG("Hooking model selection"); + + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + DetourAttach(&(PVOID&) o_getModelBlob, hkgetModelBlob); + + DetourTransactionCommit(); + } + else + { + LOG_ERROR("Couldn't hook model selection"); + } + o_UpdateFfxApiProvider = (PFN_UpdateFfxApiProvider) KernelBaseProxy::GetProcAddress_()(fsr4Module, "UpdateFfxApiProvider"); diff --git a/OptiScaler/State.h b/OptiScaler/State.h index 32e5e302..0a36eca1 100644 --- a/OptiScaler/State.h +++ b/OptiScaler/State.h @@ -130,6 +130,7 @@ class State // FSR3.x std::vector fsr3xVersionNames {}; std::vector fsr3xVersionIds {}; + uint32_t currentFsr4Model {}; // Linux check bool isRunningOnLinux = false; diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index c3608e4c..70c5a8a3 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -2028,6 +2028,53 @@ bool MenuCommon::RenderMenu() ImGui::EndTable(); } + + std::array models = { "Default", "Model 0", "Model 1", "Model 2", + "Model 3", "Model 4", "Model 5" }; + + // Conversion from 0 -> 6 into nullopt + 0 -> 5 is required + uint32_t configModes = 0; + + if (Config::Instance()->Fsr4Model.has_value()) + configModes = Config::Instance()->Fsr4Model.value_or(0) + 1; + + if (configModes < 0 || configModes >= models.size()) + configModes = 0; + + const char* selectedModel = models[configModes]; + + if (ImGui::BeginCombo("Models", selectedModel)) + { + for (int n = 0; n < models.size(); n++) + { + uint32_t selection = 0; + + if (Config::Instance()->Fsr4Model.has_value()) + selection = Config::Instance()->Fsr4Model.value_or(0) + 1; + + if (ImGui::Selectable(models[n], selection == n)) + { + if (n < 1) + Config::Instance()->Fsr4Model.reset(); + else + Config::Instance()->Fsr4Model = n - 1; + + State::Instance().newBackend = currentBackend; + MARK_ALL_BACKENDS_CHANGED(); + } + } + + ImGui::EndCombo(); + } + ShowHelpMarker("Model 0 is meant for FSR AA/Ultra Quality\n" + "Model 1 is meant for Quality\n" + "Model 2 is meant for Balanced\n" + "Model 3 is meant for Performance\n" + "Model 5 is meant for Ultra Performance"); + + ImGui::Spacing(); + ImGui::Text("Current model: %d", State::Instance().currentFsr4Model); + ImGui::Spacing(); } if (majorFsrVersion == 3) diff --git a/OptiScaler/scanner/scanner.cpp b/OptiScaler/scanner/scanner.cpp index 4fff1e19..94723268 100644 --- a/OptiScaler/scanner/scanner.cpp +++ b/OptiScaler/scanner/scanner.cpp @@ -16,7 +16,7 @@ std::pair GetModule(const std::wstring_view moduleName) return { moduleBase, moduleEnd }; } -uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask) +uintptr_t scanner::FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask) { std::vector> pattern; @@ -47,6 +47,7 @@ uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mas return std::distance(dataStart, sig) + startAddress; } +// Has some issues with DLLs on Linux uintptr_t scanner::GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset, uintptr_t startAddress) { @@ -58,6 +59,7 @@ uintptr_t scanner::GetAddress(const std::wstring_view moduleName, const std::str address = FindPattern(GetModule(moduleName.data()).first, GetModule(moduleName.data()).second - GetModule(moduleName.data()).first, pattern.data()); + // Use KernelBaseProxy::GetModuleHandleW_() ? if ((GetModuleHandleW(moduleName.data()) != nullptr) && (address != NULL)) { return (address + offset); diff --git a/OptiScaler/scanner/scanner.h b/OptiScaler/scanner/scanner.h index 5a32cf95..a7dac057 100644 --- a/OptiScaler/scanner/scanner.h +++ b/OptiScaler/scanner/scanner.h @@ -4,6 +4,7 @@ namespace scanner { +uintptr_t FindPattern(uintptr_t startAddress, uintptr_t maxSize, const char* mask); uintptr_t GetAddress(const std::wstring_view moduleName, const std::string_view pattern, ptrdiff_t offset = 0, uintptr_t startAddress = 0); uintptr_t GetOffsetFromInstruction(const std::wstring_view moduleName, const std::string_view pattern, From 72c10661000e7ceeb7b7347aab07cd9ef259880b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Lewandowski?= <49685661+FakeMichau@users.noreply.github.com> Date: Tue, 24 Jun 2025 20:02:11 +0200 Subject: [PATCH 09/10] Implement jitter scale for XeSS inputs (#547) --- OptiScaler/inputs/XeSS_Base.cpp | 3 ++- OptiScaler/inputs/XeSS_Base.h | 7 ++++--- OptiScaler/inputs/XeSS_Common.cpp | 12 ++++++++++-- OptiScaler/inputs/XeSS_Dx12.cpp | 14 ++++++++++++-- OptiScaler/inputs/XeSS_Vulkan.cpp | 14 ++++++++++++-- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/OptiScaler/inputs/XeSS_Base.cpp b/OptiScaler/inputs/XeSS_Base.cpp index 6db42b30..8cea21ff 100644 --- a/OptiScaler/inputs/XeSS_Base.cpp +++ b/OptiScaler/inputs/XeSS_Base.cpp @@ -2,6 +2,7 @@ std::map _nvParams; std::map _contexts; -std::map _motionScales; +std::map _motionScales; +std::map _jitterScales; std::map _d3d12InitParams; std::map _vkInitParams; diff --git a/OptiScaler/inputs/XeSS_Base.h b/OptiScaler/inputs/XeSS_Base.h index f6ef1536..b16ed574 100644 --- a/OptiScaler/inputs/XeSS_Base.h +++ b/OptiScaler/inputs/XeSS_Base.h @@ -6,14 +6,15 @@ #include #include -typedef struct MotionScale +typedef struct Scale { float x; float y; -} motion_scale; +} scale; extern std::map _nvParams; extern std::map _contexts; -extern std::map _motionScales; +extern std::map _motionScales; +extern std::map _jitterScales; extern std::map _d3d12InitParams; extern std::map _vkInitParams; diff --git a/OptiScaler/inputs/XeSS_Common.cpp b/OptiScaler/inputs/XeSS_Common.cpp index 294ec0dd..fb6c3b0a 100644 --- a/OptiScaler/inputs/XeSS_Common.cpp +++ b/OptiScaler/inputs/XeSS_Common.cpp @@ -256,8 +256,13 @@ xess_result_t hk_xessGetJitterScale(xess_context_handle_t hContext, float* pX, f { LOG_DEBUG(""); - *pX = 1.0f; - *pY = 1.0f; + if (!_jitterScales.contains(hContext)) + return XESS_RESULT_ERROR_INVALID_CONTEXT; + + auto scales = &_jitterScales[hContext]; + + *pX = scales->x; + *pY = scales->y; return XESS_RESULT_SUCCESS; } @@ -369,6 +374,9 @@ xess_result_t hk_xessGetVelocityScale(xess_context_handle_t hContext, float* pX, xess_result_t hk_xessSetJitterScale(xess_context_handle_t hContext, float x, float y) { LOG_DEBUG("x: {}, y: {}", x, y); + + _jitterScales[hContext] = { x, y }; + return XESS_RESULT_SUCCESS; } diff --git a/OptiScaler/inputs/XeSS_Dx12.cpp b/OptiScaler/inputs/XeSS_Dx12.cpp index 0ed0cfce..b90d68e1 100644 --- a/OptiScaler/inputs/XeSS_Dx12.cpp +++ b/OptiScaler/inputs/XeSS_Dx12.cpp @@ -224,8 +224,18 @@ xess_result_t hk_xessD3D12Execute(xess_context_handle_t hContext, ID3D12Graphics } } - params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX); - params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY); + float jitterScaleX = 1.0f; + float jitterScaleY = 1.0f; + + if (_jitterScales.contains(hContext)) + { + auto scales = &_jitterScales[hContext]; + jitterScaleX = scales->x; + jitterScaleY = scales->y; + } + + params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX * jitterScaleX); + params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY * jitterScaleY); params->Set(NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pExecParams->exposureScale); params->Set(NVSDK_NGX_Parameter_Reset, pExecParams->resetHistory); params->Set(NVSDK_NGX_Parameter_Width, pExecParams->inputWidth); diff --git a/OptiScaler/inputs/XeSS_Vulkan.cpp b/OptiScaler/inputs/XeSS_Vulkan.cpp index 4407b874..18b82b71 100644 --- a/OptiScaler/inputs/XeSS_Vulkan.cpp +++ b/OptiScaler/inputs/XeSS_Vulkan.cpp @@ -254,8 +254,18 @@ xess_result_t hk_xessVKExecute(xess_context_handle_t hContext, VkCommandBuffer c } } - params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX); - params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY); + float jitterScaleX = 1.0f; + float jitterScaleY = 1.0f; + + if (_jitterScales.contains(hContext)) + { + auto scales = &_jitterScales[hContext]; + jitterScaleX = scales->x; + jitterScaleY = scales->y; + } + + params->Set(NVSDK_NGX_Parameter_Jitter_Offset_X, pExecParams->jitterOffsetX * jitterScaleX); + params->Set(NVSDK_NGX_Parameter_Jitter_Offset_Y, pExecParams->jitterOffsetY * jitterScaleY); params->Set(NVSDK_NGX_Parameter_DLSS_Exposure_Scale, pExecParams->exposureScale); params->Set(NVSDK_NGX_Parameter_Reset, pExecParams->resetHistory); params->Set(NVSDK_NGX_Parameter_Width, pExecParams->inputWidth); From 301f86f590e7e16859f03e3fdc6f129fcdd80bef Mon Sep 17 00:00:00 2001 From: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com> Date: Tue, 24 Jun 2025 17:05:58 -0400 Subject: [PATCH 10/10] feat: Linux installer/uninstaller script (#544) * feat: add .sh setup for linux systems * fix: mention launch option requirements, automate where able * fix: rm .bat file in uninstaller * fix: check for nvidia and rm unneeded echos * fix: clean up nested logic * fix: rm extract marker from script dir not from wd --- optiscaler_setup.sh | 325 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100755 optiscaler_setup.sh diff --git a/optiscaler_setup.sh b/optiscaler_setup.sh new file mode 100755 index 00000000..ad45b276 --- /dev/null +++ b/optiscaler_setup.sh @@ -0,0 +1,325 @@ +#!/bin/bash + +# Setup OptiScaler for your game (Linux version) +clear + +echo " :::::::: ::::::::: ::::::::::: ::::::::::: :::::::: :::::::: ::: ::: :::::::::: ::::::::: " +echo ":+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: " +echo "#+: +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ " +echo "+#+ +:+ +#++:++#+ +#+ +#+ +#++:++#++ +#+ +#++:++#++: +#+ +#++:++# +#++:++#: " +echo "+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ " +echo "#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# " +echo " ######## ### ### ########### ######## ######## ### ### ########## ########## ### ### " +echo "" +echo "Coping is strong with this one..." +echo "" + +# Remove extraction marker file if it exists +rm -f "$SCRIPT_DIR/!! EXTRACT ALL FILES TO GAME FOLDER !!" 2>/dev/null + +# Get the script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +GAME_PATH="$SCRIPT_DIR" +OPTISCALER_FILE="$GAME_PATH/OptiScaler.dll" +SETUP_SUCCESS=false + +# Check if OptiScaler.dll exists +if [ ! -f "OptiScaler.dll" ]; then + echo "OptiScaler \"OptiScaler.dll\" file is not found!" + echo "Please make sure you extracted all OptiScaler files to the game folder." + echo "" + echo "For Unreal Engine games, look for the game executable in:" + echo "- /Game-or-Project-name/Binaries/Win64/" + echo "- Ignore the Engine folder" + echo "" + read -p "Press Enter to exit..." + exit 1 +fi + +# Check if the Engine folder exists (Unreal Engine detection) +if [ -d "$GAME_PATH/Engine" ]; then + echo "Found Engine folder, if this is an Unreal Engine game then please extract OptiScaler to #CODENAME#/Binaries/Win64" + echo "" + + while true; do + read -p "Continue installation to current folder? [y/n]: " continue_choice + continue_choice=$(echo "$continue_choice" | tr -d ' ') + + if [ "$continue_choice" = "y" ] || [ "$continue_choice" = "Y" ]; then + break + elif [ "$continue_choice" = "n" ] || [ "$continue_choice" = "N" ]; then + echo "Installation cancelled." + read -p "Press Enter to exit..." + exit 0 + fi + done +fi + +# Function to select filename +select_filename() { + while true; do + echo "" + echo "Choose a filename for OptiScaler (default is dxgi.dll):" + echo " [1] dxgi.dll" + echo " [2] winmm.dll" + echo " [3] version.dll" + echo " [4] dbghelp.dll" + echo " [5] d3d12.dll" + echo " [6] wininet.dll" + echo " [7] winhttp.dll" + echo " [8] OptiScaler.asi" + + read -p "Enter 1-8 (or press Enter for default): " filename_choice + + case "$filename_choice" in + ""|"1") + selected_filename="dxgi.dll" + ;; + "2") + selected_filename="winmm.dll" + ;; + "3") + selected_filename="version.dll" + ;; + "4") + selected_filename="dbghelp.dll" + ;; + "5") + selected_filename="d3d12.dll" + ;; + "6") + selected_filename="wininet.dll" + ;; + "7") + selected_filename="winhttp.dll" + ;; + "8") + selected_filename="OptiScaler.asi" + ;; + *) + echo "Invalid choice. Please select a valid option." + echo "" + continue + ;; + esac + + # Check if file already exists + if [ -f "$selected_filename" ]; then + echo "" + echo "WARNING: $selected_filename already exists in the current folder." + echo "" + + while true; do + read -p "Do you want to overwrite $selected_filename? [y/n]: " overwrite_choice + overwrite_choice=$(echo "$overwrite_choice" | tr -d ' ') + + if [ "$overwrite_choice" = "y" ] || [ "$overwrite_choice" = "Y" ]; then + break 2 # Break out of both loops + elif [ "$overwrite_choice" = "n" ] || [ "$overwrite_choice" = "N" ]; then + break # Break inner loop, continue filename selection + fi + done + else + break # File doesn't exist, proceed + fi + done +} + +# Call filename selection function +select_filename + +echo "" + +# Try to detect GPU type +NVIDIA_DETECTED=false +if command -v nvidia-smi >/dev/null 2>&1; then + if nvidia-smi >/dev/null 2>&1; then + NVIDIA_DETECTED=true + echo "Nvidia GPU detected." + fi +elif [ -d "/proc/driver/nvidia" ] || lspci 2>/dev/null | grep -i nvidia >/dev/null 2>&1; then + NVIDIA_DETECTED=true + echo "Nvidia GPU detected." +fi + +# GPU type detection and configuration +echo "" +echo "Are you using an Nvidia GPU or AMD/Intel GPU?" +echo "[1] AMD/Intel" +echo "[2] Nvidia" + +while true; do + if [ "$NVIDIA_DETECTED" = true ]; then + read -p "Enter 1 or 2 (or press Enter for Nvidia): " gpu_choice + else + read -p "Enter 1 or 2 (or press Enter for AMD/Intel): " gpu_choice + fi + + case "$gpu_choice" in + ""|"1") + # Default logic: if Nvidia detected, skip AMD/Intel unless explicitly chosen + if [ "$gpu_choice" = "1" ] || [ "$NVIDIA_DETECTED" = false ]; then + # AMD/Intel GPU - ask about DLSS usage + echo "" + echo "Will you try to use DLSS inputs? (enables spoofing, required for DLSS FG, Reflex->AL2)" + echo "[1] Yes" + echo "[2] No" + + while true; do + read -p "Enter 1 or 2 (or press Enter for Yes): " enabling_spoofing + + case "$enabling_spoofing" in + ""|"1") + # Keep spoofing enabled (default) + break + ;; + "2") + # Disable spoofing + config_file="OptiScaler.ini" + if [ ! -f "$config_file" ]; then + echo "Config file not found: $config_file" + read -p "Press Enter to continue..." + else + # Use sed to replace Dxgi=auto with Dxgi=false + sed -i 's/Dxgi=auto/Dxgi=false/g' "$config_file" + echo "Spoofing disabled in configuration." + fi + break + ;; + *) + echo "Invalid choice. Please enter 1 or 2." + continue + ;; + esac + done + fi + break + ;; + "2") + # Nvidia GPU - skip spoofing configuration + break + ;; + *) + echo "Invalid choice. Please enter 1 or 2." + continue + ;; + esac +done + +# Complete setup - rename OptiScaler file +echo "" +if [ "$overwrite_choice" = "y" ] || [ "$overwrite_choice" = "Y" ]; then + echo "Removing previous $selected_filename..." + rm -f "$selected_filename" +fi + +echo "Renaming OptiScaler file to $selected_filename..." +if ! mv "$OPTISCALER_FILE" "$selected_filename"; then + echo "" + echo "ERROR: Failed to rename OptiScaler file to $selected_filename." + echo "Please check file permissions and try again." + read -p "Press Enter to exit..." + exit 1 +fi + +# Create uninstaller +create_uninstaller() { + cat > "remove_optiscaler.sh" << 'EOF' +#!/bin/bash + +clear +echo " :::::::: ::::::::: ::::::::::: ::::::::::: :::::::: :::::::: ::: ::: :::::::::: ::::::::: " +echo ":+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: :+: " +echo "#+: +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ " +echo "+#+ +:+ +#++:++#+ +#+ +#+ +#++:++#++ +#+ +#++:++#++: +#+ +#++:++# +#++:++#: " +echo "+#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ " +echo "#+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# #+# " +echo " ######## ### ### ########### ######## ######## ### ### ########## ########## ### ### " +echo "" +echo "Coping is strong with this one..." +echo "" + +read -p "Do you want to remove OptiScaler? [y/n]: " remove_choice + +if [ "$remove_choice" = "y" ] || [ "$remove_choice" = "Y" ]; then + echo "" + echo "Removing OptiScaler files..." + + # Remove OptiScaler files + rm -f OptiScaler.log + rm -f OptiScaler.ini + rm -f "OptiScaler Setup.bat" + rm -f SELECTED_FILENAME_PLACEHOLDER + + # Remove directories + rm -rf D3D12_Optiscaler + rm -rf DlssOverrides + rm -rf Licenses + + echo "" + echo "OptiScaler removed!" + echo "" + + # Remove this uninstaller + rm -f "$0" +else + echo "" + echo "Operation cancelled." + echo "" +fi + +read -p "Press Enter to exit..." +EOF + + # Replace the placeholder with the actual selected filename + sed -i "s/SELECTED_FILENAME_PLACEHOLDER/$selected_filename/g" "remove_optiscaler.sh" + + # Make the uninstaller executable + chmod +x "remove_optiscaler.sh" + + echo "" + echo "Uninstaller created: remove_optiscaler.sh" + echo "" +} + +# Create the uninstaller +create_uninstaller + +# Success message +clear +echo " OptiScaler setup completed successfully..." +echo "" +echo " ___ " +echo " (_ ' " +echo " /__ /) / () (/ " +echo " _/ / " +echo "" + +# Display Wine DLL override information +echo "IMPORTANT FOR LINUX/WINE USERS:" +echo "You need to add the renamed DLL to Wine overrides:" +echo "" +echo "WINEDLLOVERRIDES=$selected_filename=n,b %COMMAND%" +echo "" +echo "For example, if using Steam, add this to launch options:" +echo "WINEDLLOVERRIDES=$selected_filename=n,b %command%" +echo "" +echo "Remember: Insert key opens OptiScaler overlay, Page Up/Down for performance stats" +echo "" +echo "Note: If you need to send log files for support, set LogLevel=0 and" +echo "LogToFile=true in OptiScaler.ini (forced debugging is disabled since 0.7.7-Pre8)" +echo "" +echo "IMPORTANT: Do not rename OptiScaler.ini - it must stay as OptiScaler.ini" +echo "" + +SETUP_SUCCESS=true + +# Cleanup - remove setup script +read -p "Press Enter to exit..." + +if [ "$SETUP_SUCCESS" = true ]; then + # Remove this setup script + rm -f "$0" +fi + +exit 0