diff --git a/OptiScaler/NVNGX_DLSS_Vk.cpp b/OptiScaler/NVNGX_DLSS_Vk.cpp
index 6e45d9d3..961e0ae5 100644
--- a/OptiScaler/NVNGX_DLSS_Vk.cpp
+++ b/OptiScaler/NVNGX_DLSS_Vk.cpp
@@ -276,7 +276,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequi
}
}
- if (FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_SuperSampling)
+ if (FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_SuperSampling || FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_FrameGeneration)
{
if (NVNGXProxy::NVNGXModule() != nullptr)
{
@@ -338,14 +338,14 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequire
}
}
- if (FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_SuperSampling)
+ if (FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_SuperSampling || FeatureDiscoveryInfo->FeatureID == NVSDK_NGX_Feature_FrameGeneration)
{
if (OutExtensionProperties == nullptr)
{
LOG_INFO("returning no extensions are needed!");
*OutExtensionCount = 0;
}
-
+
// Only Nvidia hardware should reach here, so in any case returning known extensions for DLSS
//if (OutExtensionProperties == nullptr)
//{
@@ -733,7 +733,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
if (Config::Instance()->OverlayMenu.value_or(true) && Config::Instance()->CurrentFeature != nullptr && !ImGuiOverlayVk::IsInitedVk() &&
Config::Instance()->CurrentFeature->FrameCount() > Config::Instance()->MenuInitDelay.value_or(75))
{
- ImGuiOverlayDx12::ShutdownDx12();
+ if (ImGuiOverlayDx12::IsInitedDx12())
+ ImGuiOverlayDx12::ShutdownDx12();
+
auto hwnd = Util::GetProcessWindow();
ImGuiOverlayVk::InitVk(hwnd, vkDevice, vkInstance, vkPD);
}
@@ -757,7 +759,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
Config::Instance()->newBackend = Config::Instance()->VulkanUpscaler.value_or("fsr21");
changeBackendCounter++;
-
+
LOG_INFO("changeBackend is true, counter: {0}", changeBackendCounter);
// first release everything
diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index 261cb411..4b0b86ed 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -82,7 +82,7 @@
$(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(IncludePath)
$(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(LibraryPath)
dlss-enabler-upscaler
- D:\Folders\Games\Banishers Ghosts of New Eden\NWD\Binaries\Win64\
+ D:\Folders\Games\Streamline_Sample\_bin\
.\x64\Debug
diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp
index f9debc1b..b9e1a791 100644
--- a/OptiScaler/dllmain.cpp
+++ b/OptiScaler/dllmain.cpp
@@ -7,6 +7,7 @@
#include "NVNGX_Proxy.h"
#include "imgui/imgui_overlay_dx12.h"
+#include "imgui/imgui_overlay_vk.h"
#include
@@ -1465,6 +1466,7 @@ static void CheckWorkingMode()
if ((!isNvngxMode || isWorkingWithEnabler) && !Config::Instance()->DisableEarlyHooking.value_or(false) && Config::Instance()->OverlayMenu.value_or(true))
{
ImGuiOverlayDx12::Dx12Bind();
+ ImGuiOverlayVk::HookVK();
//ImGuiOverlayDx12::FSR3Bind();
}
diff --git a/OptiScaler/imgui/imgui_overlay_vk.cpp b/OptiScaler/imgui/imgui_overlay_vk.cpp
index 1afd738a..dcceddcc 100644
--- a/OptiScaler/imgui/imgui_overlay_vk.cpp
+++ b/OptiScaler/imgui/imgui_overlay_vk.cpp
@@ -30,6 +30,19 @@ struct ImGui_ImplVulkan_InitInfo g_ImVulkan_Info = { };
struct ImGui_ImplVulkanH_Frame* g_ImVulkan_Frames = NULL;
static VkSemaphore* g_ImVulkan_Semaphores = NULL;
+typedef VkResult(__fastcall* PFN_QueuePresentKHR)(VkQueue, const VkPresentInfoKHR*);
+typedef VkResult(__fastcall* PFN_CreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*);
+
+PFN_vkCreateDevice o_vkCreateDevice = nullptr;
+PFN_vkCreateInstance o_vkCreateInstance = nullptr;
+PFN_vkCreateDevice o_SL_vkCreateDevice = nullptr;
+PFN_QueuePresentKHR oQueuePresentKHR = nullptr;
+PFN_CreateSwapchainKHR oCreateSwapchainKHR = nullptr;
+
+static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
+static VkResult VKAPI_CALL hkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
+static VkResult VKAPI_CALL hkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
+
static int createCounter = 0;
static void DestroyVulkanObjects(bool shutdown)
@@ -73,7 +86,12 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
{
if (g_bInitialized)
{
+ if (ImGui::GetIO().BackendRendererUserData != nullptr)
+ ImGui_ImplVulkan_Shutdown();
+
DestroyVulkanObjects(false);
+
+ g_bInitialized = false;
}
// Initialize ImGui for IO.
@@ -118,6 +136,7 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, NULL);
VkQueueFamilyProperties queues[8];
vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, queues);
+
for (uint32_t i = 0; i < count; i++)
{
if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
@@ -341,43 +360,65 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
g_bEnabled = true;
}
-typedef VkResult(__fastcall* PFN_AcquireNextImageKHR)(VkDevice, VkSwapchainKHR, uint64_t, VkSemaphore, VkFence, uint32_t*);
-PFN_AcquireNextImageKHR oAcquireNextImageKHR = nullptr;
-static VkResult VKAPI_CALL hkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore,
- VkFence fence, uint32_t* pImageIndex)
+static void HookDevice(VkDevice InDevice)
{
- return oAcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+ if (oCreateSwapchainKHR != nullptr)
+ return;
+
+ oQueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR"));
+ oCreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR"));
+
+ if (oCreateSwapchainKHR)
+ {
+ // Hook
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+
+ DetourAttach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR);
+ DetourAttach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR);
+
+ DetourTransactionCommit();
+ }
}
-typedef VkResult(__fastcall* PFN_AcquireNextImage2KHR)(VkDevice, const VkAcquireNextImageInfoKHR*, uint32_t*);
-PFN_AcquireNextImage2KHR oAcquireNextImage2KHR = nullptr;
-static VkResult VKAPI_CALL hkAcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)
+static VkResult hkvkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
{
- return oAcquireNextImage2KHR(device, pAcquireInfo, pImageIndex);
+ auto result = o_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
+
+ if (result == VK_SUCCESS)
+ _instance = *pInstance;
+
+ return result;
+}
+
+static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
+{
+ auto result = o_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
+
+ if (result == VK_SUCCESS)
+ {
+ _PD = physicalDevice;
+ _device = *pDevice;
+ HookDevice(_device);
+ }
+
+
+ return result;
}
-typedef VkResult(__fastcall* PFN_QueuePresentKHR)(VkQueue, const VkPresentInfoKHR*);
-PFN_QueuePresentKHR oQueuePresentKHR = nullptr;
static VkResult VKAPI_CALL hkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
{
if (!g_bInitialized)
{
- if (createCounter == 0)
+ if (pPresentInfo->swapchainCount > 0)
{
- createCounter++;
- return VK_ERROR_OUT_OF_DATE_KHR;
+ auto sc = pPresentInfo->pSwapchains[0];
+ CreateVulkanObjects(_device, nullptr, &sc);
}
else
{
- if (pPresentInfo->swapchainCount > 0)
- {
- auto sc = pPresentInfo->pSwapchains[0];
- CreateVulkanObjects(_device, nullptr, &sc);
- }
- else
- {
- createCounter = 0;
- }
+ return oQueuePresentKHR(queue, pPresentInfo);
}
}
@@ -458,9 +499,6 @@ static VkResult VKAPI_CALL hkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pP
return oQueuePresentKHR(queue, pPresentInfo);
}
-typedef VkResult(__fastcall* PFN_CreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*);
-PFN_CreateSwapchainKHR oCreateSwapchainKHR = nullptr;
-
static VkResult VKAPI_CALL hkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator,
VkSwapchainKHR* pSwapchain)
{
@@ -488,30 +526,39 @@ HWND ImGuiOverlayVk::Handle()
void ImGuiOverlayVk::InitVk(HWND InHwnd, VkDevice InDevice, VkInstance InInstance, VkPhysicalDevice InPD)
{
_hwnd = InHwnd;
- _device = InDevice;
- _instance = InInstance;
- _PD = InPD;
- oAcquireNextImageKHR = (PFN_AcquireNextImageKHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImageKHR"));
- oAcquireNextImage2KHR = (PFN_AcquireNextImage2KHR)(vkGetDeviceProcAddr(InDevice, "vkAcquireNextImage2KHR"));
- oQueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR"));
- oCreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR"));
+ if (_instance == nullptr)
+ _instance = InInstance;
- if (oAcquireNextImageKHR)
- {
- // Hook
- DetourTransactionBegin();
- DetourUpdateThread(GetCurrentThread());
+ if (_device == nullptr)
+ _device = InDevice;
- DetourAttach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR);
- DetourAttach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR);
- DetourAttach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR);
- DetourAttach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR);
+ if (_PD == nullptr)
+ _PD = InPD;
- DetourTransactionCommit();
+ HookDevice(InDevice);
- _isInited = true;
- }
+ _isInited = true;
+}
+
+void ImGuiOverlayVk::HookVK()
+{
+ if (o_vkCreateDevice != nullptr)
+ return;
+
+ o_vkCreateDevice = (PFN_vkCreateDevice)DetourFindFunction("vulkan-1.dll", "vkCreateDevice");
+ o_vkCreateInstance = (PFN_vkCreateInstance)DetourFindFunction("vulkan-1.dll", "vkCreateInstance");
+
+ DetourTransactionBegin();
+ DetourUpdateThread(GetCurrentThread());
+
+ if (o_vkCreateDevice != nullptr)
+ DetourAttach(&(PVOID&)o_vkCreateDevice, hkvkCreateDevice);
+
+ if (o_vkCreateInstance != nullptr)
+ DetourAttach(&(PVOID&)o_vkCreateInstance, hkvkCreateInstance);
+
+ DetourTransactionCommit();
}
void ImGuiOverlayVk::ShutdownVk()
@@ -529,8 +576,6 @@ void ImGuiOverlayVk::ShutdownVk()
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
- DetourDetach(&(PVOID&)oAcquireNextImageKHR, hkAcquireNextImageKHR);
- DetourDetach(&(PVOID&)oAcquireNextImage2KHR, hkAcquireNextImage2KHR);
DetourDetach(&(PVOID&)oQueuePresentKHR, hkQueuePresentKHR);
DetourDetach(&(PVOID&)oCreateSwapchainKHR, hkCreateSwapchainKHR);
diff --git a/OptiScaler/imgui/imgui_overlay_vk.h b/OptiScaler/imgui/imgui_overlay_vk.h
index 2cf88786..52983603 100644
--- a/OptiScaler/imgui/imgui_overlay_vk.h
+++ b/OptiScaler/imgui/imgui_overlay_vk.h
@@ -9,6 +9,7 @@ namespace ImGuiOverlayVk
HWND Handle();
void InitVk(HWND InHwnd, VkDevice InDevice, VkInstance InInstance, VkPhysicalDevice InPD);
+ void HookVK();
void ShutdownVk();
void ReInitVk(HWND InNewHwnd);
}