diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index 30f1fd3a..681c5cc4 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -369,6 +369,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
@@ -508,6 +509,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
diff --git a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp
index 224a72ac..30e3d507 100644
--- a/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp
+++ b/OptiScaler/inputs/NVNGX_DLSS_Dx12.cpp
@@ -1,19 +1,14 @@
-#include "Config.h"
#include "Util.h"
+#include "Config.h"
#include "DLSSG_Mod.h"
#include "NVNGX_DLSS.h"
#include "NVNGX_Parameter.h"
#include "proxies/NVNGX_Proxy.h"
-#include "FG/Upscaler_Inputs_Dx12.h"
+#include
-#include "upscalers/dlss/DLSSFeature_Dx12.h"
-#include "upscalers/dlssd/DLSSDFeature_Dx12.h"
-#include "upscalers/fsr2/FSR2Feature_Dx12.h"
-#include "upscalers/fsr2_212/FSR2Feature_Dx12_212.h"
-#include "upscalers/fsr31/FSR31Feature_Dx12.h"
-#include "upscalers/xess/XeSSFeature_Dx12.h"
+#include "FG/Upscaler_Inputs_Dx12.h"
#include "hooks/HooksDx.h"
@@ -455,17 +450,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void)
shutdown = true;
State::Instance().NvngxDx12Inited = false;
- // if (Dx12Contexts.size() > 0)
- //{
- // for (auto const& [key, val] : Dx12Contexts) {
- // if (val.feature)
- // NVSDK_NGX_D3D12_ReleaseFeature(val.feature->Handle());
- // }
-
- //}
-
- // Dx12Contexts.clear();
-
D3D12Device = nullptr;
State::Instance().currentFeature = nullptr;
@@ -474,8 +458,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void)
// Disabled for now to check if it cause any issues
// UnhookAll();
- DLSSFeatureDx12::Shutdown(D3D12Device);
-
// Added `&& !State::Instance().isShuttingDown` hack for crash on exit
if (Config::Instance()->DLSSEnabled.value_or_default() && NVNGXProxy::IsDx12Inited() &&
NVNGXProxy::D3D12_Shutdown() != nullptr && !State::Instance().isShuttingDown)
@@ -682,14 +664,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
auto handleId = IFeature::GetNextHandleId();
LOG_INFO("HandleId: {0}", handleId);
- // nvsdk logging - ini first
- if (!Config::Instance()->LogToNGX.has_value())
- {
- int nvsdkLogging = 0;
- InParameters->Get("DLSSEnabler.Logging", &nvsdkLogging);
- Config::Instance()->LogToNGX.set_volatile_value(nvsdkLogging > 0);
- }
-
// Root signature restore
if (Config::Instance()->RestoreComputeSignature.value_or_default() ||
Config::Instance()->RestoreGraphicSignature.value_or_default())
@@ -697,134 +671,36 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
if (InFeatureID == NVSDK_NGX_Feature_SuperSampling)
{
- // backend selection
- // 0 : XeSS
- // 1 : FSR2.2
- // 2 : FSR2.1
- // 3 : DLSS
- // 4 : FSR3.1
-
- int upscalerChoice = 0; // Default XeSS
+ std::string upscalerChoice = "xess"; // Default XeSS
// If original NVNGX available use DLSS as base upscaler
- if (NVNGXProxy::IsDx12Inited())
- upscalerChoice = 3;
+ if (Config::Instance()->DLSSEnabled.value_or_default() && NVNGXProxy::IsDx12Inited())
+ upscalerChoice = "dlss";
- // if Enabler does not set any upscaler
- if (InParameters->Get("DLSSEnabler.Dx12Backend", &upscalerChoice) != NVSDK_NGX_Result_Success)
+ if (Config::Instance()->Dx12Upscaler.has_value())
+ upscalerChoice = Config::Instance()->Dx12Upscaler.value();
+
+ LOG_INFO("Creating new {} upscaler", upscalerChoice);
+
+ Dx12Contexts[handleId] = {};
+
+ if (!FeatureProvider_Dx12::GetFeature(upscalerChoice, handleId, InParameters, &Dx12Contexts[handleId].feature))
{
-
- if (Config::Instance()->Dx12Upscaler.has_value())
- {
- LOG_INFO("DLSS Enabler does not set any upscaler using ini: {0}",
- Config::Instance()->Dx12Upscaler.value());
-
- if (Config::Instance()->Dx12Upscaler.value() == "xess")
- upscalerChoice = 0;
- else if (Config::Instance()->Dx12Upscaler.value() == "fsr22")
- upscalerChoice = 1;
- else if (Config::Instance()->Dx12Upscaler.value() == "fsr21")
- upscalerChoice = 2;
- else if (Config::Instance()->Dx12Upscaler.value() == "dlss" &&
- Config::Instance()->DLSSEnabled.value_or_default())
- upscalerChoice = 3;
- else if (Config::Instance()->Dx12Upscaler.value() == "fsr31")
- upscalerChoice = 4;
- }
-
- LOG_INFO("upscalerChoice: {0}", upscalerChoice);
+ LOG_ERROR("Upscaler can't created");
+ return NVSDK_NGX_Result_Fail;
}
- else
- {
- LOG_INFO("DLSS Enabler upscalerChoice: {0}", upscalerChoice);
- }
-
- if (upscalerChoice == 3)
- {
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!Dx12Contexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new DLSS feature, fallback to XeSS!");
-
- Dx12Contexts[handleId].feature.reset();
- Dx12Contexts[handleId].feature = nullptr;
- // auto it = std::find_if(Dx12Contexts.begin(), Dx12Contexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); Dx12Contexts.erase(it);
-
- upscalerChoice = 0;
- }
- else
- {
- Config::Instance()->Dx12Upscaler = "dlss";
- LOG_INFO("creating new DLSS feature");
- }
- }
-
- if (upscalerChoice == 0)
- {
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!Dx12Contexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new XeSS feature, Fallback to FSR2.1!");
-
- Dx12Contexts[handleId].feature.reset();
- Dx12Contexts[handleId].feature = nullptr;
- // auto it = std::find_if(Dx12Contexts.begin(), Dx12Contexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); Dx12Contexts.erase(it);
-
- upscalerChoice = 2;
- }
- else
- {
- Config::Instance()->Dx12Upscaler = "xess";
- LOG_INFO("creating new XeSS feature");
- }
- }
-
- if (upscalerChoice == 4)
- {
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!Dx12Contexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new FSR 3.X feature, Fallback to FSR2.1!");
-
- Dx12Contexts[handleId].feature.reset();
- auto it = std::find_if(Dx12Contexts.begin(), Dx12Contexts.end(),
- [&handleId](const auto& p) { return p.first == handleId; });
- Dx12Contexts.erase(it);
-
- upscalerChoice = 2;
- }
- else
- {
- Config::Instance()->Dx12Upscaler = "fsr31";
- LOG_INFO("creating new FSR 3.X feature");
- }
- }
-
- if (upscalerChoice == 1)
- {
- Config::Instance()->Dx12Upscaler = "fsr22";
- LOG_INFO("creating new FSR 2.2.1 feature");
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
- }
- else if (upscalerChoice == 2)
- {
- Config::Instance()->Dx12Upscaler = "fsr21";
- LOG_INFO("creating new FSR 2.1.2 feature");
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
- }
-
- // write back finel selected upscaler
- InParameters->Set("DLSSEnabler.Dx12Backend", upscalerChoice);
}
- else
+ else if (InFeatureID == NVSDK_NGX_Feature_RayReconstruction)
{
LOG_INFO("creating new DLSSD feature");
- Dx12Contexts[handleId].feature = std::make_unique(handleId, InParameters);
+
+ Dx12Contexts[handleId] = {};
+
+ if (!FeatureProvider_Dx12::GetFeature("dlssd", handleId, InParameters, &Dx12Contexts[handleId].feature))
+ {
+ LOG_ERROR("DLSSD can't created");
+ return NVSDK_NGX_Result_Fail;
+ }
}
auto deviceContext = Dx12Contexts[handleId].feature.get();
@@ -1179,210 +1055,15 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
// Change backend
if (State::Instance().changeBackend[handleId])
{
- if (State::Instance().newBackend == "" ||
- (!Config::Instance()->DLSSEnabled.value_or_default() && State::Instance().newBackend == "dlss"))
- State::Instance().newBackend = Config::Instance()->Dx12Upscaler.value_or_default();
+ UpscalerInputsDx12::Reset();
+ contextRendering = false;
- deviceContext->changeBackendCounter++;
+ FeatureProvider_Dx12::ChangeFeature(State::Instance().newBackend, D3D12Device, InCmdList, handleId,
+ InParameters, deviceContext);
- LOG_INFO("changeBackend is true, counter: {0}", deviceContext->changeBackendCounter);
-
- // first release everything
- if (deviceContext->changeBackendCounter == 1)
- {
- if (State::Instance().currentFG != nullptr && State::Instance().currentFG->IsActive() &&
- State::Instance().activeFgInput == FGInput::Upscaler)
- {
- State::Instance().currentFG->DestroyFGContext();
- UpscalerInputsDx12::Reset();
- State::Instance().FGchanged = true;
- State::Instance().ClearCapturedHudlesses = true;
- }
-
- if (Dx12Contexts.contains(handleId) && deviceContext->feature != nullptr)
- {
- LOG_INFO("changing backend to {0}", State::Instance().newBackend);
-
- auto dc = deviceContext->feature.get();
-
- if (State::Instance().newBackend != "dlssd" && State::Instance().newBackend != "dlss")
- deviceContext->createParams = GetNGXParameters("OptiDx12");
- else
- deviceContext->createParams = InParameters;
-
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, dc->GetFeatureFlags());
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_Width, dc->RenderWidth());
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_Height, dc->RenderHeight());
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_OutWidth, dc->DisplayWidth());
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_OutHeight, dc->DisplayHeight());
- deviceContext->createParams->Set(NVSDK_NGX_Parameter_PerfQualityValue, dc->PerfQualityValue());
-
- dc = nullptr;
-
- if (State::Instance().gameQuirks & GameQuirk::FastFeatureReset)
- {
- LOG_DEBUG("sleeping before reset of current feature for 100ms (Fast Feature Reset)");
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
- }
- else
- {
- LOG_DEBUG("sleeping before reset of current feature for 1000ms");
- std::this_thread::sleep_for(std::chrono::milliseconds(1000));
- }
-
- deviceContext->feature.reset();
- deviceContext->feature = nullptr;
- // auto it = std::find_if(Dx12Contexts.begin(), Dx12Contexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); Dx12Contexts.erase(it);
-
- State::Instance().currentFeature = nullptr;
-
- contextRendering = false;
- }
- else
- {
- LOG_ERROR("can't find handle {0} in Dx12Contexts!", handleId);
-
- State::Instance().newBackend = "";
- State::Instance().changeBackend[handleId] = false;
-
- if (deviceContext->createParams != nullptr)
- {
- free(deviceContext->createParams);
- deviceContext->createParams = nullptr;
- }
-
- deviceContext->changeBackendCounter = 0;
- }
-
- return NVSDK_NGX_Result_Success;
- }
-
- // create new feature
- if (deviceContext->changeBackendCounter == 2)
- {
- // backend selection
- // 0 : XeSS
- // 1 : FSR2.2
- // 2 : FSR2.1
- // 3 : DLSS
- // 4 : FSR3.1
- int upscalerChoice = -1;
-
- // prepare new upscaler
- if (State::Instance().newBackend == "fsr22")
- {
- Config::Instance()->Dx12Upscaler = "fsr22";
- LOG_INFO("creating new FSR 2.2.1 feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- upscalerChoice = 1;
- }
- else if (State::Instance().newBackend == "fsr21")
- {
- Config::Instance()->Dx12Upscaler = "fsr21";
- LOG_INFO("creating new FSR 2.1.2 feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- upscalerChoice = 2;
- }
- else if (State::Instance().newBackend == "dlss")
- {
- Config::Instance()->Dx12Upscaler = "dlss";
- LOG_INFO("creating new DLSS feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- upscalerChoice = 3;
- }
- else if (State::Instance().newBackend == "dlssd")
- {
- LOG_INFO("creating new DLSSD feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- }
- else if (State::Instance().newBackend == "fsr31")
- {
- Config::Instance()->Dx12Upscaler = "fsr31";
- LOG_INFO("creating new FSR 3.X feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- upscalerChoice = 4;
- }
- else
- {
- Config::Instance()->Dx12Upscaler = "xess";
- LOG_INFO("creating new XeSS feature");
- deviceContext->feature = std::make_unique(handleId, deviceContext->createParams);
- upscalerChoice = 0;
- }
-
- if (upscalerChoice >= 0)
- InParameters->Set("DLSSEnabler.Dx12Backend", upscalerChoice);
-
- return NVSDK_NGX_Result_Success;
- }
-
- // init feature
- if (deviceContext->changeBackendCounter == 3)
- {
- auto initResult = deviceContext->feature->Init(D3D12Device, InCmdList, deviceContext->createParams);
-
- deviceContext->changeBackendCounter = 0;
-
- if (!initResult)
- {
- LOG_ERROR("init failed with {0} feature", State::Instance().newBackend);
-
- if (State::Instance().newBackend != "dlssd")
- {
- if (Config::Instance()->Dx12Upscaler == "dlss")
- {
- State::Instance().newBackend = "xess";
- InParameters->Set("DLSSEnabler.Dx12Backend", 0);
- }
- else
- {
- State::Instance().newBackend = "fsr21";
- InParameters->Set("DLSSEnabler.Dx12Backend", 2);
- }
- }
- else
- {
- // Retry DLSSD
- State::Instance().newBackend = "dlssd";
- }
-
- State::Instance().changeBackend[handleId] = true;
- return NVSDK_NGX_Result_Success;
- }
- else
- {
- LOG_INFO("init successful for {0}, upscaler changed", State::Instance().newBackend);
-
- State::Instance().newBackend = "";
- State::Instance().changeBackend[handleId] = false;
- evalCounter = 0;
- }
-
- // if opti nvparam release it
- int optiParam = 0;
- if (deviceContext->createParams->Get("OptiScaler", &optiParam) == NVSDK_NGX_Result_Success &&
- optiParam == 1)
- {
- free(deviceContext->createParams);
- deviceContext->createParams = nullptr;
- }
- }
-
- // if initial feature can't be inited
- State::Instance().currentFeature = deviceContext->feature.get();
- if (State::Instance().currentFG != nullptr && State::Instance().activeFgInput == FGInput::Upscaler)
- State::Instance().currentFG->UpdateTarget();
-
- // return NVSDK_NGX_Result_Success;
+ return NVSDK_NGX_Result_Success;
}
- // if (deviceContext == nullptr)
- //{
- // LOG_DEBUG("trying to use released handle, returning NVSDK_NGX_Result_Success");
- // return NVSDK_NGX_Result_Success;
- // }
-
if (!deviceContext->feature->IsInited() && Config::Instance()->Dx12Upscaler.value_or_default() != "fsr21")
{
LOG_WARN("InCmdList {0} is not inited, falling back to FSR 2.1.2", deviceContext->feature->Name());
diff --git a/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp b/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
index 6e39885b..e1899136 100644
--- a/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
+++ b/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
@@ -689,34 +689,26 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice
upscalerChoice = 2;
// if Enabler does not set any upscaler
- if (InParameters->Get("DLSSEnabler.VkBackend", &upscalerChoice) != NVSDK_NGX_Result_Success)
+ if (Config::Instance()->VulkanUpscaler.has_value())
{
+ LOG_INFO("DLSS Enabler does not set any upscaler using ini: {0}",
+ Config::Instance()->VulkanUpscaler.value());
- if (Config::Instance()->VulkanUpscaler.has_value())
- {
- LOG_INFO("DLSS Enabler does not set any upscaler using ini: {0}",
- Config::Instance()->VulkanUpscaler.value());
-
- if (Config::Instance()->VulkanUpscaler.value() == "fsr21")
- upscalerChoice = 0;
- else if (Config::Instance()->VulkanUpscaler.value() == "fsr22")
- upscalerChoice = 1;
- else if (Config::Instance()->VulkanUpscaler.value() == "dlss" &&
- Config::Instance()->DLSSEnabled.value_or_default())
- upscalerChoice = 2;
- else if (Config::Instance()->VulkanUpscaler.value() == "fsr31")
- upscalerChoice = 3;
- else if (Config::Instance()->VulkanUpscaler.value() == "xess")
- upscalerChoice = 4;
- }
-
- LOG_INFO("upscalerChoice: {0}", upscalerChoice);
- }
- else
- {
- LOG_INFO("DLSS Enabler upscalerChoice: {0}", upscalerChoice);
+ if (Config::Instance()->VulkanUpscaler.value() == "fsr21")
+ upscalerChoice = 0;
+ else if (Config::Instance()->VulkanUpscaler.value() == "fsr22")
+ upscalerChoice = 1;
+ else if (Config::Instance()->VulkanUpscaler.value() == "dlss" &&
+ Config::Instance()->DLSSEnabled.value_or_default())
+ upscalerChoice = 2;
+ else if (Config::Instance()->VulkanUpscaler.value() == "fsr31")
+ upscalerChoice = 3;
+ else if (Config::Instance()->VulkanUpscaler.value() == "xess")
+ upscalerChoice = 4;
}
+ LOG_INFO("upscalerChoice: {0}", upscalerChoice);
+
if (upscalerChoice == 2)
{
VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
@@ -795,9 +787,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice
LOG_INFO("creating new FSR 2.2.1 feature");
VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
}
-
- // write back finel selected upscaler
- InParameters->Set("DLSSEnabler.VkBackend", upscalerChoice);
}
else
{
@@ -1137,9 +1126,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
upscalerChoice = 0;
}
- if (upscalerChoice >= 0)
- InParameters->Set("DLSSEnabler.VkBackend", upscalerChoice);
-
return NVSDK_NGX_Result_Success;
}
diff --git a/OptiScaler/upscalers/FeatureProvider_Dx12.cpp b/OptiScaler/upscalers/FeatureProvider_Dx12.cpp
new file mode 100644
index 00000000..374cbd5b
--- /dev/null
+++ b/OptiScaler/upscalers/FeatureProvider_Dx12.cpp
@@ -0,0 +1,225 @@
+#include "FeatureProvider_Dx12.h"
+
+#include "Util.h"
+#include "Config.h"
+
+#include "NVNGX_Parameter.h"
+
+#include "upscalers/dlss/DLSSFeature_Dx12.h"
+#include "upscalers/dlssd/DLSSDFeature_Dx12.h"
+#include "upscalers/fsr2/FSR2Feature_Dx12.h"
+#include "upscalers/fsr2_212/FSR2Feature_Dx12_212.h"
+#include "upscalers/fsr31/FSR31Feature_Dx12.h"
+#include "upscalers/xess/XeSSFeature_Dx12.h"
+
+bool FeatureProvider_Dx12::GetFeature(std::string upscalerName, UINT handleId, NVSDK_NGX_Parameter* parameters,
+ std::unique_ptr* feature)
+{
+ do
+ {
+ if (upscalerName == "xess")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+ else if (upscalerName == "fsr21")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+ else if (upscalerName == "fsr22")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+ else if (upscalerName == "fsr31")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+
+ if (Config::Instance()->DLSSEnabled.value_or_default())
+ {
+ if (upscalerName == "dlss")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+ else if (upscalerName == "dlssd")
+ {
+ *feature = std::make_unique(handleId, parameters);
+ break;
+ }
+ }
+
+ } while (false);
+
+ if (!(*feature)->ModuleLoaded())
+ {
+ (*feature).reset();
+ *feature = std::make_unique(handleId, parameters);
+ upscalerName = "fsr21";
+ }
+
+ auto result = (*feature)->ModuleLoaded();
+
+ if (result)
+ {
+ if (upscalerName == "dlssd")
+ upscalerName = "dlss";
+
+ Config::Instance()->Dx12Upscaler = upscalerName;
+ }
+
+ return result;
+}
+
+bool FeatureProvider_Dx12::ChangeFeature(std::string upscalerName, ID3D12Device* device,
+ ID3D12GraphicsCommandList* cmdList, UINT handleId,
+ NVSDK_NGX_Parameter* parameters, ContextData* contextData)
+{
+ if (State::Instance().changeBackend[handleId])
+ {
+ if (State::Instance().newBackend == "" ||
+ (!Config::Instance()->DLSSEnabled.value_or_default() && State::Instance().newBackend == "dlss"))
+ State::Instance().newBackend = Config::Instance()->Dx12Upscaler.value_or_default();
+
+ contextData->changeBackendCounter++;
+
+ LOG_INFO("changeBackend is true, counter: {0}", contextData->changeBackendCounter);
+
+ // first release everything
+ if (contextData->changeBackendCounter == 1)
+ {
+ if (State::Instance().currentFG != nullptr && State::Instance().currentFG->IsActive() &&
+ State::Instance().activeFgInput == FGInput::Upscaler)
+ {
+ State::Instance().currentFG->DestroyFGContext();
+ State::Instance().FGchanged = true;
+ State::Instance().ClearCapturedHudlesses = true;
+ }
+
+ if (contextData->feature != nullptr)
+ {
+ LOG_INFO("changing backend to {}", State::Instance().newBackend);
+
+ auto dc = contextData->feature.get();
+
+ if (State::Instance().newBackend != "dlssd" && State::Instance().newBackend != "dlss")
+ contextData->createParams = GetNGXParameters("OptiDx12");
+ else
+ contextData->createParams = parameters;
+
+ contextData->createParams->Set(NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags, dc->GetFeatureFlags());
+ contextData->createParams->Set(NVSDK_NGX_Parameter_Width, dc->RenderWidth());
+ contextData->createParams->Set(NVSDK_NGX_Parameter_Height, dc->RenderHeight());
+ contextData->createParams->Set(NVSDK_NGX_Parameter_OutWidth, dc->DisplayWidth());
+ contextData->createParams->Set(NVSDK_NGX_Parameter_OutHeight, dc->DisplayHeight());
+ contextData->createParams->Set(NVSDK_NGX_Parameter_PerfQualityValue, dc->PerfQualityValue());
+
+ dc = nullptr;
+
+ if (State::Instance().gameQuirks & GameQuirk::FastFeatureReset)
+ {
+ LOG_DEBUG("sleeping before reset of current feature for 100ms (Fast Feature Reset)");
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+ else
+ {
+ LOG_DEBUG("sleeping before reset of current feature for 1000ms");
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+ }
+
+ contextData->feature.reset();
+ contextData->feature = nullptr;
+
+ State::Instance().currentFeature = nullptr;
+ }
+ else
+ {
+ LOG_ERROR("can't find handle {0} in Dx12Contexts!", handleId);
+
+ State::Instance().newBackend = "";
+ State::Instance().changeBackend[handleId] = false;
+
+ if (contextData->createParams != nullptr)
+ {
+ free(contextData->createParams);
+ contextData->createParams = nullptr;
+ }
+
+ contextData->changeBackendCounter = 0;
+ }
+
+ return NVSDK_NGX_Result_Success;
+ }
+
+ // create new feature
+ if (contextData->changeBackendCounter == 2)
+ {
+ LOG_INFO("Creating new {} upscaler", State::Instance().newBackend);
+
+ contextData->feature.reset();
+
+ if (!FeatureProvider_Dx12::GetFeature(State::Instance().newBackend, handleId, parameters,
+ &contextData->feature))
+ {
+ LOG_ERROR("Upscaler can't created");
+ return NVSDK_NGX_Result_Fail;
+ }
+
+ return NVSDK_NGX_Result_Success;
+ }
+
+ // init feature
+ if (contextData->changeBackendCounter == 3)
+ {
+ auto initResult = contextData->feature->Init(device, cmdList, contextData->createParams);
+
+ contextData->changeBackendCounter = 0;
+
+ if (!initResult)
+ {
+ LOG_ERROR("init failed with {0} feature", State::Instance().newBackend);
+
+ if (State::Instance().newBackend != "dlssd")
+ {
+ if (Config::Instance()->Dx12Upscaler == "dlss")
+ State::Instance().newBackend = "xess";
+ else
+ State::Instance().newBackend = "fsr21";
+ }
+ else
+ {
+ // Retry DLSSD
+ State::Instance().newBackend = "dlssd";
+ }
+
+ State::Instance().changeBackend[handleId] = true;
+ return NVSDK_NGX_Result_Success;
+ }
+ else
+ {
+ LOG_INFO("init successful for {0}, upscaler changed", State::Instance().newBackend);
+
+ State::Instance().newBackend = "";
+ State::Instance().changeBackend[handleId] = false;
+ }
+
+ // if opti nvparam release it
+ int optiParam = 0;
+ if (contextData->createParams->Get("OptiScaler", &optiParam) == NVSDK_NGX_Result_Success && optiParam == 1)
+ {
+ free(contextData->createParams);
+ contextData->createParams = nullptr;
+ }
+ }
+
+ // if initial feature can't be inited
+ State::Instance().currentFeature = contextData->feature.get();
+ if (State::Instance().currentFG != nullptr && State::Instance().activeFgInput == FGInput::Upscaler)
+ State::Instance().currentFG->UpdateTarget();
+
+ return true;
+ }
+}
diff --git a/OptiScaler/upscalers/FeatureProvider_Dx12.h b/OptiScaler/upscalers/FeatureProvider_Dx12.h
new file mode 100644
index 00000000..68b7accb
--- /dev/null
+++ b/OptiScaler/upscalers/FeatureProvider_Dx12.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include
+
+#include "IFeature_Dx12.h"
+
+#include
+
+class FeatureProvider_Dx12
+{
+ public:
+ static bool GetFeature(std::string upscalerName, UINT handleId, NVSDK_NGX_Parameter* parameters,
+ std::unique_ptr* feature);
+
+ static bool ChangeFeature(std::string upscalerName, ID3D12Device* device, ID3D12GraphicsCommandList* cmdList, UINT handleId, NVSDK_NGX_Parameter* parameters,
+ ContextData* contextData);
+};