diff --git a/OptiScaler/hooks/LibraryLoad_Hooks.cpp b/OptiScaler/hooks/LibraryLoad_Hooks.cpp index 1a1ed38d..6c3f022a 100644 --- a/OptiScaler/hooks/LibraryLoad_Hooks.cpp +++ b/OptiScaler/hooks/LibraryLoad_Hooks.cpp @@ -167,14 +167,17 @@ HMODULE LibraryLoadHooks::LoadLibraryCheckW(std::wstring libName, LPCWSTR lpLibF } // sl.dlss_g.dll - if (hookOptiDlls && (CheckDllNameW(&libName, &slDlssgNamesW) || - (normalizedPath.contains(L"\\versions\\") && normalizedPath.contains(L"\\sl_dlss_g_")))) + if ((CheckDllNameW(&libName, &slDlssgNamesW) || + (normalizedPath.contains(L"\\versions\\") && normalizedPath.contains(L"\\sl_dlss_g_")))) { auto dlssgModule = NtdllProxy::LoadLibraryExW_Ldr(lpLibFullPath, NULL, 0); - if (dlssgModule != nullptr && dlssgModule != State::Instance().optiSlDLSSG) + if (dlssgModule != nullptr) { - StreamlineHooks::hookDlssg(dlssgModule); + if (!normalizedPath.contains(L"\\opti_dlls") && dlssgModule != State::Instance().optiSlDLSSG) + StreamlineHooks::hookDlssg(dlssgModule); + else + StreamlineHooks::hookLocalDlssg(dlssgModule); } else { diff --git a/OptiScaler/hooks/Streamline_Hooks.cpp b/OptiScaler/hooks/Streamline_Hooks.cpp index ff2bcffe..fb97ba2d 100644 --- a/OptiScaler/hooks/Streamline_Hooks.cpp +++ b/OptiScaler/hooks/Streamline_Hooks.cpp @@ -48,6 +48,10 @@ StreamlineHooks::PFN_slOnPluginLoad StreamlineHooks::o_dlssg_slOnPluginLoad = nu decltype(&slDLSSGSetOptions) StreamlineHooks::o_slDLSSGSetOptions = nullptr; decltype(&slDLSSGGetState) StreamlineHooks::o_slDLSSGGetState = nullptr; +// Local DLSSG +StreamlineHooks::PFN_slGetPluginFunction StreamlineHooks::o_local_dlssg_slGetPluginFunction = nullptr; +StreamlineHooks::PFN_slOnPluginLoad StreamlineHooks::o_local_dlssg_slOnPluginLoad = nullptr; + // Reflex StreamlineHooks::PFN_slGetPluginFunction StreamlineHooks::o_reflex_slGetPluginFunction = nullptr; StreamlineHooks::PFN_slSetConstants_sl1 StreamlineHooks::o_reflex_slSetConstants_sl1 = nullptr; @@ -409,7 +413,7 @@ void StreamlineHooks::hookSystemCaps(sl::param::IParameters* params) } } -uint32_t StreamlineHooks::getSystemCapsArch() +uint32_t StreamlineHooks::getSystemCapsArch(SystemCaps* altSystemCaps) { uint32_t highestArch = 0; @@ -418,9 +422,10 @@ uint32_t StreamlineHooks::getSystemCapsArch() { if (State::Instance().streamlineVersion.major > 1) { - if (systemCaps) + auto caps = altSystemCaps != nullptr ? altSystemCaps : systemCaps; + if (caps) { - for (auto& adapter : systemCaps->adapters) + for (auto& adapter : caps->adapters) { if (adapter.architecture > highestArch) highestArch = adapter.architecture; @@ -448,23 +453,25 @@ uint32_t StreamlineHooks::getSystemCapsArch() return highestArch; } -void StreamlineHooks::setArch(uint32_t arch) +void StreamlineHooks::setArch(uint32_t arch, SystemCaps* altSystemCaps) { static auto primaryGpu = IdentifyGpu::getPrimaryGpu(); if (State::Instance().streamlineVersion.major > 1) { - if (systemCaps) + // Assumes that altCaps are always for SL2+ + auto caps = altSystemCaps != nullptr ? altSystemCaps : systemCaps; + if (caps) { - for (uint32_t i = 0; i < systemCaps->gpuCount; i++) + for (uint32_t i = 0; i < caps->gpuCount; i++) { - systemCaps->adapters[i].architecture = arch; - systemCaps->adapters[i].vendor = VendorId::Nvidia; + caps->adapters[i].architecture = arch; + caps->adapters[i].vendor = VendorId::Nvidia; } if (fakenvapi::isUsingAsMainNvapi() || primaryGpu.vendorId != VendorId::Nvidia) - systemCaps->driverVersionMajor = 999; + caps->driverVersionMajor = 999; - systemCaps->hwsSupported = true; + caps->hwsSupported = true; } } else if (State::Instance().streamlineVersion.major == 1) @@ -483,7 +490,7 @@ void StreamlineHooks::setArch(uint32_t arch) } // Spoof arch based on feature and current arch -void StreamlineHooks::spoofArch(uint32_t currentArch, sl::Feature feature) +void StreamlineHooks::spoofArch(uint32_t currentArch, sl::Feature feature, SystemCaps* altSystemCaps) { constexpr uint32_t maxArch = 0xFFFFFFFF; @@ -491,7 +498,7 @@ void StreamlineHooks::spoofArch(uint32_t currentArch, sl::Feature feature) if (feature == sl::kFeatureDLSS) { if (currentArch < NV_GPU_ARCHITECTURE_TU100) - return setArch(maxArch); + return setArch(maxArch, altSystemCaps); } // Don't spoof DLSSD at all @@ -504,13 +511,13 @@ void StreamlineHooks::spoofArch(uint32_t currentArch, sl::Feature feature) else if (feature == sl::kFeatureDLSS_G) { if (currentArch < NV_GPU_ARCHITECTURE_AD100) - return setArch(maxArch); + return setArch(maxArch, altSystemCaps); } else if (feature == sl::kFeatureReflex || feature == sl::kFeaturePCL) { if (fakenvapi::isUsingAsMainNvapi()) - return setArch(maxArch); + return setArch(maxArch, altSystemCaps); } } @@ -643,6 +650,55 @@ bool StreamlineHooks::hkdlssg_slOnPluginLoad(sl::param::IParameters* params, con return result; } +bool StreamlineHooks::hklocal_dlssg_slOnPluginLoad(sl::param::IParameters* params, const char* loaderJSON, + const char** pluginJSON) +{ + LOG_FUNC(); + + // TODO: do it better than "static" and hoping for the best + static std::string config; + + bool shouldSpoofArch = Config::Instance()->StreamlineSpoofing.value_or_default(); + + uint32_t currentArch = 0; + SystemCaps* localSystemCaps = nullptr; + if (shouldSpoofArch) + { + sl::param::getPointerParam(params, sl::param::common::kSystemCaps, &localSystemCaps); + + if (localSystemCaps) + { + currentArch = getSystemCapsArch(localSystemCaps); + spoofArch(currentArch, sl::kFeatureDLSS_G, localSystemCaps); + } + } + + auto result = o_local_dlssg_slOnPluginLoad(params, loaderJSON, pluginJSON); + + if (shouldSpoofArch && localSystemCaps) + setArch(currentArch, localSystemCaps); + + nlohmann::json configJson = nlohmann::json::parse(*pluginJSON); + + if (configJson.contains("/external/hws/required"_json_pointer)) + configJson["external"]["hws"]["required"] = false; // disable eHardwareSchedulingRequired + + if (Config::Instance()->VulkanExtensionSpoofing.value_or_default()) + { + if (configJson.contains("/external/vk/instance/extensions"_json_pointer)) + configJson["external"]["vk"]["instance"]["extensions"].clear(); + + if (configJson.contains("/external/vk/device/extensions"_json_pointer)) + configJson["external"]["vk"]["device"]["extensions"].clear(); + } + + config = configJson.dump(); + + *pluginJSON = config.c_str(); + + return result; +} + sl::Result StreamlineHooks::hkslSetConstants(const sl::Constants& values, const sl::FrameToken& frame, const sl::ViewportHandle& viewport) { @@ -941,6 +997,19 @@ void* StreamlineHooks::hkdlssg_slGetPluginFunction(const char* functionName) return o_dlssg_slGetPluginFunction(functionName); } +void* StreamlineHooks::hklocal_dlssg_slGetPluginFunction(const char* functionName) +{ + // LOG_DEBUG("{}", functionName); + + if (strcmp(functionName, "slOnPluginLoad") == 0 && Config::Instance()->FGOutput == FGOutput::DLSSGWithNukems) + { + o_local_dlssg_slOnPluginLoad = (PFN_slOnPluginLoad) o_local_dlssg_slGetPluginFunction(functionName); + return &hklocal_dlssg_slOnPluginLoad; + } + + return o_local_dlssg_slGetPluginFunction(functionName); +} + bool StreamlineHooks::hkreflex_slSetConstants_sl1(const void* data, uint32_t frameIndex, uint32_t id) { // Streamline v1's version of slReflexSetOptions + slPCLSetMarker @@ -1404,6 +1473,52 @@ void StreamlineHooks::hookDlssg(HMODULE slDlssg) } } +// Local SL DLSSG + +void StreamlineHooks::unhookLocalDlssg() +{ + LOG_FUNC(); + + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + if (o_local_dlssg_slGetPluginFunction) + { + DetourDetach(&(PVOID&) o_local_dlssg_slGetPluginFunction, hklocal_dlssg_slGetPluginFunction); + o_local_dlssg_slGetPluginFunction = nullptr; + } + + DetourTransactionCommit(); +} + +void StreamlineHooks::hookLocalDlssg(HMODULE slDlssg) +{ + LOG_FUNC(); + + if (!slDlssg) + { + LOG_WARN("Dlssg module in NULL"); + return; + } + + if (o_local_dlssg_slGetPluginFunction) + unhookLocalDlssg(); + + o_local_dlssg_slGetPluginFunction = + reinterpret_cast(KernelBaseProxy::GetProcAddress_()(slDlssg, "slGetPluginFunction")); + + if (o_local_dlssg_slGetPluginFunction != nullptr) + { + LOG_TRACE("Hooking slGetPluginFunction in local sl.dlssg"); + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + + DetourAttach(&(PVOID&) o_local_dlssg_slGetPluginFunction, hklocal_dlssg_slGetPluginFunction); + + DetourTransactionCommit(); + } +} + // SL REFLEX void StreamlineHooks::unhookReflex() diff --git a/OptiScaler/hooks/Streamline_Hooks.h b/OptiScaler/hooks/Streamline_Hooks.h index fb5192d4..6eed5a0f 100644 --- a/OptiScaler/hooks/Streamline_Hooks.h +++ b/OptiScaler/hooks/Streamline_Hooks.h @@ -148,6 +148,9 @@ class StreamlineHooks static void unhookDlssg(); static void hookDlssg(HMODULE slDlssg); + static void unhookLocalDlssg(); + static void hookLocalDlssg(HMODULE slDlssg); + static void unhookReflex(); static void hookReflex(HMODULE slReflex); @@ -172,9 +175,9 @@ class StreamlineHooks static SystemCaps* systemCaps; static SystemCapsSl15* systemCapsSl15; static void hookSystemCaps(sl::param::IParameters* params); - static uint32_t getSystemCapsArch(); - static void setArch(uint32_t arch); - static void spoofArch(uint32_t currentArch, sl::Feature feature); + static uint32_t getSystemCapsArch(SystemCaps* altSystemCaps = nullptr); + static void setArch(uint32_t arch, SystemCaps* altSystemCaps = nullptr); + static void spoofArch(uint32_t currentArch, sl::Feature feature, SystemCaps* altSystemCaps = nullptr); // Interposer static decltype(&slInit) o_slInit; @@ -233,6 +236,14 @@ class StreamlineHooks const sl::DLSSGOptions* options); static void* hkdlssg_slGetPluginFunction(const char* functionName); + // Local DLSSG + static PFN_slGetPluginFunction o_local_dlssg_slGetPluginFunction; + static PFN_slOnPluginLoad o_local_dlssg_slOnPluginLoad; + + static bool hklocal_dlssg_slOnPluginLoad(sl::param::IParameters* params, const char* loaderJSON, + const char** pluginJSON); + static void* hklocal_dlssg_slGetPluginFunction(const char* functionName); + // Reflex static sl::ReflexMode reflexGamesLastMode; static PFN_slGetPluginFunction o_reflex_slGetPluginFunction; diff --git a/OptiScaler/proxies/Streamline_Proxy.h b/OptiScaler/proxies/Streamline_Proxy.h index 2112b2ac..63616e71 100644 --- a/OptiScaler/proxies/Streamline_Proxy.h +++ b/OptiScaler/proxies/Streamline_Proxy.h @@ -7,6 +7,7 @@ #include #include +#include #include #include