diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index 6bbac5ca..b1fcb45c 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -372,6 +372,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
@@ -514,6 +515,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
+
diff --git a/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp b/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
index ebfef234..3abd5037 100644
--- a/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
+++ b/OptiScaler/inputs/NVNGX_DLSS_Vk.cpp
@@ -8,12 +8,7 @@
#include "NVNGX_Parameter.h"
#include "proxies/NVNGX_Proxy.h"
-#include "upscalers/fsr2/FSR2Feature_Vk.h"
-#include "upscalers/dlss/DLSSFeature_Vk.h"
-#include "upscalers/dlssd/DLSSDFeature_Vk.h"
-#include "upscalers/fsr2_212/FSR2Feature_Vk_212.h"
-#include "upscalers/fsr31/FSR31Feature_Vk.h"
-#include "upscalers/xess/XeSSFeature_Vk.h"
+#include "upscalers/FeatureProvider_Vk.h"
#include "hooks/HooksVk.h"
@@ -30,42 +25,6 @@ static ankerl::unordered_dense::map> VkCo
static inline int evalCounter = 0;
static inline bool shutdown = false;
-NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext(unsigned long long InApplicationId,
- const wchar_t* InApplicationDataPath, VkInstance InInstance,
- VkPhysicalDevice InPD, VkDevice InDevice,
- NVSDK_NGX_Version InSDKVersion,
- const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
-{
- LOG_FUNC();
-
- if (Config::Instance()->DLSSEnabled.value_or_default() && !NVNGXProxy::IsVulkanInited())
- {
- if (Config::Instance()->UseGenericAppIdWithDlss.value_or_default())
- InApplicationId = app_id_override;
-
- if (NVNGXProxy::NVNGXModule() == nullptr)
- NVNGXProxy::InitNVNGX();
-
- if (NVNGXProxy::NVNGXModule() != nullptr && NVNGXProxy::VULKAN_Init_Ext() != nullptr)
- {
- LOG_INFO("calling NVNGXProxy::VULKAN_Init_Ext");
- auto result = NVNGXProxy::VULKAN_Init_Ext()(InApplicationId, InApplicationDataPath, InInstance, InPD,
- InDevice, InSDKVersion, InFeatureInfo);
- LOG_INFO("NVNGXProxy::VULKAN_Init_Ext result: {0:X}", (UINT) result);
-
- if (result == NVSDK_NGX_Result_Success)
- NVNGXProxy::SetVulkanInited(true);
- }
- }
-
- DLSSGMod::InitDLSSGMod_Vulkan();
- DLSSGMod::VULKAN_Init_Ext(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice, InSDKVersion,
- InFeatureInfo);
-
- return NVSDK_NGX_VULKAN_Init_Ext2(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice,
- vkGetInstanceProcAddr, vkGetDeviceProcAddr, InSDKVersion, InFeatureInfo);
-}
-
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(
unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, VkInstance InInstance,
VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA,
@@ -194,6 +153,42 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(
return NVSDK_NGX_Result_Success;
}
+NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext(unsigned long long InApplicationId,
+ const wchar_t* InApplicationDataPath, VkInstance InInstance,
+ VkPhysicalDevice InPD, VkDevice InDevice,
+ NVSDK_NGX_Version InSDKVersion,
+ const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo)
+{
+ LOG_FUNC();
+
+ if (Config::Instance()->DLSSEnabled.value_or_default() && !NVNGXProxy::IsVulkanInited())
+ {
+ if (Config::Instance()->UseGenericAppIdWithDlss.value_or_default())
+ InApplicationId = app_id_override;
+
+ if (NVNGXProxy::NVNGXModule() == nullptr)
+ NVNGXProxy::InitNVNGX();
+
+ if (NVNGXProxy::NVNGXModule() != nullptr && NVNGXProxy::VULKAN_Init_Ext() != nullptr)
+ {
+ LOG_INFO("calling NVNGXProxy::VULKAN_Init_Ext");
+ auto result = NVNGXProxy::VULKAN_Init_Ext()(InApplicationId, InApplicationDataPath, InInstance, InPD,
+ InDevice, InSDKVersion, InFeatureInfo);
+ LOG_INFO("NVNGXProxy::VULKAN_Init_Ext result: {0:X}", (UINT) result);
+
+ if (result == NVSDK_NGX_Result_Success)
+ NVNGXProxy::SetVulkanInited(true);
+ }
+ }
+
+ DLSSGMod::InitDLSSGMod_Vulkan();
+ DLSSGMod::VULKAN_Init_Ext(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice, InSDKVersion,
+ InFeatureInfo);
+
+ return NVSDK_NGX_VULKAN_Init_Ext2(InApplicationId, InApplicationDataPath, InInstance, InPD, InDevice,
+ vkGetInstanceProcAddr, vkGetDeviceProcAddr, InSDKVersion, InFeatureInfo);
+}
+
NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_ProjectID_Ext(
const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion,
const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice,
@@ -676,122 +671,36 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice
if (InFeatureID == NVSDK_NGX_Feature_SuperSampling)
{
- // backend selection
- // 0 : FSR2.1
- // 1 : FSR2.2
- // 2 : DLSS
- // 3 : FSR3.1
- // 4 : XeSS
- int upscalerChoice = 0; // Default FSR2.1
+ std::string upscalerChoice = "fsr22"; // Default XeSS
// If original NVNGX available use DLSS as base upscaler
- if (NVNGXProxy::IsVulkanInited())
- upscalerChoice = 2;
+ if (Config::Instance()->DLSSEnabled.value_or_default() && NVNGXProxy::IsDx12Inited())
+ upscalerChoice = "dlss";
- // if Enabler does not set any upscaler
- if (Config::Instance()->VulkanUpscaler.has_value())
+ if (Config::Instance()->Dx12Upscaler.has_value())
+ upscalerChoice = Config::Instance()->VulkanUpscaler.value();
+
+ LOG_INFO("Creating new {} upscaler", upscalerChoice);
+
+ VkContexts[handleId] = {};
+
+ if (!FeatureProvider_Vk::GetFeature(upscalerChoice, handleId, InParameters, &VkContexts[handleId].feature))
{
- 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);
-
- if (upscalerChoice == 2)
- {
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!VkContexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new DLSS feature, fallback to XeSS!");
-
- VkContexts[handleId].feature.reset();
- VkContexts[handleId].feature = nullptr;
- // auto it = std::find_if(VkContexts.begin(), VkContexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); VkContexts.erase(it);
-
- upscalerChoice = 0;
- }
- else
- {
- Config::Instance()->VulkanUpscaler = "dlss";
- LOG_INFO("creating new DLSS feature");
- }
- }
-
- if (upscalerChoice == 3)
- {
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!VkContexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new FSR 3.X feature, Fallback to FSR2.1!");
-
- VkContexts[handleId].feature.reset();
- VkContexts[handleId].feature = nullptr;
- // auto it = std::find_if(VkContexts.begin(), VkContexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); VkContexts.erase(it);
-
- upscalerChoice = 0;
- }
- else
- {
- Config::Instance()->VulkanUpscaler = "fsr31";
- LOG_INFO("creating new FSR 3.X feature");
- }
- }
-
- if (upscalerChoice == 4)
- {
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
-
- if (!VkContexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("can't create new XeSS feature, Fallback to FSR2.1!");
-
- VkContexts[handleId].feature.reset();
- VkContexts[handleId].feature = nullptr;
- // auto it = std::find_if(VkContexts.begin(), VkContexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); VkContexts.erase(it);
-
- upscalerChoice = 0;
- }
- else
- {
- Config::Instance()->VulkanUpscaler = "xess";
- LOG_INFO("creating new XeSS feature");
- }
- }
-
- if (upscalerChoice == 0)
- {
- Config::Instance()->VulkanUpscaler = "fsr21";
- LOG_INFO("creating new FSR 2.1.2 feature");
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
- }
- else if (upscalerChoice == 1)
- {
- Config::Instance()->VulkanUpscaler = "fsr22";
- LOG_INFO("creating new FSR 2.2.1 feature");
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
+ LOG_ERROR("Upscaler can't created");
+ return NVSDK_NGX_Result_Fail;
}
}
- else
+ else if (InFeatureID == NVSDK_NGX_Feature_RayReconstruction)
{
LOG_INFO("creating new DLSSD feature");
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
+
+ VkContexts[handleId] = {};
+
+ if (!FeatureProvider_Vk::GetFeature("dlssd", handleId, InParameters, &VkContexts[handleId].feature))
+ {
+ LOG_ERROR("DLSSD can't created");
+ return NVSDK_NGX_Result_Fail;
+ }
}
auto deviceContext = VkContexts[handleId].feature.get();
@@ -964,181 +873,13 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
LOG_WARN("callback exist");
IFeature_Vk* deviceContext = nullptr;
+ auto contextData = &VkContexts[handleId];
if (State::Instance().changeBackend[handleId])
{
- if (State::Instance().newBackend == "" ||
- (!Config::Instance()->DLSSEnabled.value_or_default() && State::Instance().newBackend == "dlss"))
- State::Instance().newBackend = Config::Instance()->VulkanUpscaler.value_or_default();
-
- VkContexts[handleId].changeBackendCounter++;
-
- LOG_INFO("changeBackend is true, counter: {0}", VkContexts[handleId].changeBackendCounter);
-
- // first release everything
- if (VkContexts[handleId].changeBackendCounter == 1)
- {
- if (VkContexts.contains(handleId) && VkContexts[handleId].feature != nullptr)
- {
- LOG_INFO("changing backend to {0}", State::Instance().newBackend);
-
- auto dc = VkContexts[handleId].feature.get();
-
- if (State::Instance().newBackend != "dlssd" && State::Instance().newBackend != "dlss")
- VkContexts[handleId].createParams = GetNGXParameters("OptiVk");
- else
- VkContexts[handleId].createParams = InParameters;
-
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_DLSS_Feature_Create_Flags,
- dc->GetFeatureFlags());
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_Width, dc->RenderWidth());
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_Height, dc->RenderHeight());
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_OutWidth, dc->DisplayWidth());
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_OutHeight, dc->DisplayHeight());
- VkContexts[handleId].createParams->Set(NVSDK_NGX_Parameter_PerfQualityValue, dc->PerfQualityValue());
-
- dc = nullptr;
-
- LOG_DEBUG("sleeping before reset of current feature for 1000ms");
- std::this_thread::sleep_for(std::chrono::milliseconds(1000));
-
- VkContexts[handleId].feature.reset();
- VkContexts[handleId].feature = nullptr;
- // auto it = std::find_if(VkContexts.begin(), VkContexts.end(), [&handleId](const auto& p) { return
- // p.first == handleId; }); VkContexts.erase(it);
-
- State::Instance().currentFeature = nullptr;
- }
- else
- {
- LOG_ERROR("can't find handle {0} in VkContexts!", handleId);
-
- State::Instance().newBackend = "";
- State::Instance().changeBackend[handleId] = false;
-
- if (VkContexts[handleId].createParams != nullptr)
- {
- free(VkContexts[handleId].createParams);
- VkContexts[handleId].createParams = nullptr;
- }
-
- VkContexts[handleId].changeBackendCounter = 0;
- }
-
- return NVSDK_NGX_Result_Success;
- }
-
- if (VkContexts[handleId].changeBackendCounter == 2)
- {
- // backend selection
- // 0 : FSR2.1
- // 1 : FSR2.2
- // 2 : DLSS
- // 3 : FSR3.1
- // 4 : XeSS
- int upscalerChoice = -1; // Default FSR2.1
-
- // prepare new upscaler
- if (State::Instance().newBackend == "fsr22")
- {
- Config::Instance()->VulkanUpscaler = "fsr22";
- LOG_INFO("creating new FSR 2.2.1 feature");
- VkContexts[handleId].feature =
- std::make_unique(handleId, VkContexts[handleId].createParams);
- upscalerChoice = 1;
- }
- else if (State::Instance().newBackend == "dlss")
- {
- Config::Instance()->VulkanUpscaler = "dlss";
- LOG_INFO("creating new DLSS feature");
- VkContexts[handleId].feature =
- std::make_unique(handleId, VkContexts[handleId].createParams);
- upscalerChoice = 2;
- }
- else if (State::Instance().newBackend == "fsr31")
- {
- Config::Instance()->VulkanUpscaler = "fsr31";
- LOG_INFO("creating new FSR 3.X feature");
- VkContexts[handleId].feature =
- std::make_unique(handleId, VkContexts[handleId].createParams);
- upscalerChoice = 3;
- }
- else if (State::Instance().newBackend == "dlssd")
- {
- LOG_INFO("creating new DLSSD feature");
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
- }
- else if (State::Instance().newBackend == "xess")
- {
- Config::Instance()->VulkanUpscaler = "xess";
- LOG_INFO("creating new XeSS feature");
- VkContexts[handleId].feature = std::make_unique(handleId, InParameters);
- }
- else
- {
- Config::Instance()->VulkanUpscaler = "fsr21";
- LOG_INFO("creating new FSR 2.1.2 feature");
- VkContexts[handleId].feature =
- std::make_unique(handleId, VkContexts[handleId].createParams);
- upscalerChoice = 0;
- }
-
- return NVSDK_NGX_Result_Success;
- }
-
- if (VkContexts[handleId].changeBackendCounter == 3)
- {
- // next frame create context
- auto initResult = VkContexts[handleId].feature->Init(vkInstance, vkPD, vkDevice, InCmdList, vkGIPA, vkGDPA,
- VkContexts[handleId].createParams);
-
- VkContexts[handleId].changeBackendCounter = 0;
-
- if (!initResult || !VkContexts[handleId].feature->ModuleLoaded())
- {
- LOG_ERROR("init failed with {0} feature", State::Instance().newBackend);
-
- if (State::Instance().newBackend != "dlssd")
- {
- if (Config::Instance()->VulkanUpscaler == "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;
- evalCounter = 0;
- }
-
- // if opti nvparam release it
- int optiParam = 0;
- if (VkContexts[handleId].createParams->Get("OptiScaler", &optiParam) == NVSDK_NGX_Result_Success &&
- optiParam == 1)
- {
- free(VkContexts[handleId].createParams);
- VkContexts[handleId].createParams = nullptr;
- }
- }
-
- // if initial feature can't be inited
- State::Instance().currentFeature = VkContexts[handleId].feature.get();
+ FeatureProvider_Vk::ChangeFeature(State::Instance().newBackend, vkInstance, vkPD, vkDevice, InCmdList, vkGIPA,
+ vkGDPA, handleId, InParameters, contextData);
+ evalCounter = 0;
return NVSDK_NGX_Result_Success;
}
@@ -1146,9 +887,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
deviceContext = VkContexts[handleId].feature.get();
State::Instance().currentFeature = deviceContext;
- if (!deviceContext->IsInited() && Config::Instance()->VulkanUpscaler.value_or_default() != "fsr21")
+ if (!deviceContext->IsInited() && Config::Instance()->VulkanUpscaler.value_or_default() != "fsr22")
{
- State::Instance().newBackend = "fsr21";
+ State::Instance().newBackend = "fsr22";
State::Instance().changeBackend[handleId] = true;
return NVSDK_NGX_Result_Success;
}
@@ -1182,8 +923,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Shutdown(void)
State::Instance().currentFeature = nullptr;
- DLSSFeatureVk::Shutdown(vkDevice);
-
if (Config::Instance()->DLSSEnabled.value_or_default() && NVNGXProxy::IsVulkanInited() &&
NVNGXProxy::VULKAN_Shutdown() != nullptr)
{
diff --git a/OptiScaler/upscalers/FeatureProvider_Dx11.cpp b/OptiScaler/upscalers/FeatureProvider_Dx11.cpp
index 85e81a46..46426912 100644
--- a/OptiScaler/upscalers/FeatureProvider_Dx11.cpp
+++ b/OptiScaler/upscalers/FeatureProvider_Dx11.cpp
@@ -147,7 +147,7 @@ bool FeatureProvider_Dx11::ChangeFeature(std::string upscalerName, ID3D11Device*
contextData->changeBackendCounter = 0;
}
- return NVSDK_NGX_Result_Success;
+ return true;
}
if (contextData->changeBackendCounter == 2)
@@ -159,10 +159,10 @@ bool FeatureProvider_Dx11::ChangeFeature(std::string upscalerName, ID3D11Device*
if (!GetFeature(State::Instance().newBackend, handleId, parameters, &contextData->feature))
{
LOG_ERROR("Upscaler can't created");
- return NVSDK_NGX_Result_Fail;
+ return false;
}
- return NVSDK_NGX_Result_Success;
+ return true;
}
if (contextData->changeBackendCounter == 3)
diff --git a/OptiScaler/upscalers/FeatureProvider_Dx12.cpp b/OptiScaler/upscalers/FeatureProvider_Dx12.cpp
index cb5228d4..0f1a0775 100644
--- a/OptiScaler/upscalers/FeatureProvider_Dx12.cpp
+++ b/OptiScaler/upscalers/FeatureProvider_Dx12.cpp
@@ -152,7 +152,7 @@ bool FeatureProvider_Dx12::ChangeFeature(std::string upscalerName, ID3D12Device*
contextData->changeBackendCounter = 0;
}
- return NVSDK_NGX_Result_Success;
+ return true;
}
// create new feature
@@ -165,10 +165,10 @@ bool FeatureProvider_Dx12::ChangeFeature(std::string upscalerName, ID3D12Device*
if (!GetFeature(State::Instance().newBackend, handleId, parameters, &contextData->feature))
{
LOG_ERROR("Upscaler can't created");
- return NVSDK_NGX_Result_Fail;
+ return false;
}
- return NVSDK_NGX_Result_Success;
+ return true;
}
// init feature
diff --git a/OptiScaler/upscalers/FeatureProvider_Vk.cpp b/OptiScaler/upscalers/FeatureProvider_Vk.cpp
new file mode 100644
index 00000000..ce5e76df
--- /dev/null
+++ b/OptiScaler/upscalers/FeatureProvider_Vk.cpp
@@ -0,0 +1,208 @@
+#include "FeatureProvider_Vk.h"
+
+#include "Util.h"
+#include "Config.h"
+
+#include "NVNGX_Parameter.h"
+
+#include "upscalers/fsr2/FSR2Feature_Vk.h"
+#include "upscalers/dlss/DLSSFeature_Vk.h"
+#include "upscalers/dlssd/DLSSDFeature_Vk.h"
+#include "upscalers/fsr2_212/FSR2Feature_Vk_212.h"
+#include "upscalers/fsr31/FSR31Feature_Vk.h"
+#include "upscalers/xess/XeSSFeature_Vk.h"
+
+bool FeatureProvider_Vk::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 = "fsr22";
+ }
+
+ auto result = (*feature)->ModuleLoaded();
+
+ if (result)
+ {
+ if (upscalerName == "dlssd")
+ upscalerName = "dlss";
+
+ Config::Instance()->VulkanUpscaler = upscalerName;
+ }
+
+ return result;
+}
+
+bool FeatureProvider_Vk::ChangeFeature(std::string upscalerName, VkInstance instance, VkPhysicalDevice pd,
+ VkDevice device, VkCommandBuffer cmdBuffer, PFN_vkGetInstanceProcAddr gipa,
+ PFN_vkGetDeviceProcAddr gdpa, UINT handleId, NVSDK_NGX_Parameter* parameters,
+ ContextData* contextData)
+{
+ if (State::Instance().newBackend == "" ||
+ (!Config::Instance()->DLSSEnabled.value_or_default() && State::Instance().newBackend == "dlss"))
+ State::Instance().newBackend = Config::Instance()->VulkanUpscaler.value_or_default();
+
+ contextData->changeBackendCounter++;
+
+ LOG_INFO("changeBackend is true, counter: {0}", contextData->changeBackendCounter);
+
+ // first release everything
+ if (contextData->changeBackendCounter == 1)
+ {
+ if (contextData->feature != nullptr)
+ {
+ LOG_INFO("changing backend to {0}", State::Instance().newBackend);
+
+ auto dc = contextData->feature.get();
+
+ if (State::Instance().newBackend != "dlssd" && State::Instance().newBackend != "dlss")
+ contextData->createParams = GetNGXParameters("OptiVk");
+ 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;
+
+ 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 VkContexts!", 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;
+ }
+
+ if (contextData->changeBackendCounter == 2)
+ {
+ LOG_INFO("Creating new {} upscaler", State::Instance().newBackend);
+
+ contextData->feature.reset();
+
+ if (!GetFeature(State::Instance().newBackend, handleId, parameters, &contextData->feature))
+ {
+ LOG_ERROR("Upscaler can't created");
+ return false;
+ }
+
+ return true;
+ }
+
+ if (contextData->changeBackendCounter == 3)
+ {
+ // next frame create context
+ auto initResult =
+ contextData->feature->Init(instance, pd, device, cmdBuffer, gipa, gdpa, contextData->createParams);
+
+ contextData->changeBackendCounter = 0;
+
+ if (!initResult || !contextData->feature->ModuleLoaded())
+ {
+ LOG_ERROR("init failed with {0} feature", State::Instance().newBackend);
+
+ if (State::Instance().newBackend != "dlssd")
+ {
+ if (Config::Instance()->VulkanUpscaler == "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();
+
+ return true;
+}
diff --git a/OptiScaler/upscalers/FeatureProvider_Vk.h b/OptiScaler/upscalers/FeatureProvider_Vk.h
new file mode 100644
index 00000000..86a6c097
--- /dev/null
+++ b/OptiScaler/upscalers/FeatureProvider_Vk.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+
+#include "IFeature_Vk.h"
+
+#include
+
+class FeatureProvider_Vk
+{
+ public:
+ static bool GetFeature(std::string upscalerName, UINT handleId, NVSDK_NGX_Parameter* parameters,
+ std::unique_ptr* feature);
+
+ static bool ChangeFeature(std::string upscalerName, VkInstance instance, VkPhysicalDevice pd, VkDevice device,
+ VkCommandBuffer cmdBuffer, PFN_vkGetInstanceProcAddr gipa, PFN_vkGetDeviceProcAddr gdpa,
+ UINT handleId, NVSDK_NGX_Parameter* parameters, ContextData* contextData);
+};