Move DLSS/Novideo checks to the new thingy

This commit is contained in:
FakeMichau
2026-03-01 14:40:47 +01:00
parent be8b0530f2
commit 07a5286eeb
13 changed files with 60 additions and 119 deletions
+3 -8
View File
@@ -6,6 +6,7 @@
#include "nvapi/fakenvapi.h"
#include <hooks/Streamline_Hooks.h>
#include <misc/IdentifyGpu.h>
#include <SimpleIni.h>
@@ -1007,7 +1008,7 @@ bool Config::SaveIni()
// Menu
{
ini.SetValue("Menu", "Scale", GetFloatValue(Instance()->MenuScale.value_for_config(true)).c_str());
ini.SetValue("Menu", "Scale", GetFloatValue(Instance()->MenuScale.value_for_config()).c_str());
ini.SetValue("Menu", "OverlayMenu", GetBoolValue(Instance()->OverlayMenu.value_for_config()).c_str());
auto setting = Instance()->ShortcutKey.value_for_config();
@@ -1213,13 +1214,7 @@ bool Config::SaveIni()
// Spoofing
{
// Save Dxgi spoofing value only if it differs from the current GPU vendor
bool forceSaveDxgi = Instance()->DxgiSpoofing.has_value() &&
((State::Instance().isRunningOnNvidia && Instance()->DxgiSpoofing.value()) ||
(!State::Instance().isRunningOnNvidia && !Instance()->DxgiSpoofing.value()));
ini.SetValue("Spoofing", "Dxgi",
GetBoolValue(Instance()->DxgiSpoofing.value_for_config(forceSaveDxgi)).c_str());
ini.SetValue("Spoofing", "Dxgi", GetBoolValue(Instance()->DxgiSpoofing.value_for_config()).c_str());
ini.SetValue("Spoofing", "DxgiFactoryWrapping",
GetBoolValue(Instance()->DxgiFactoryWrapping.value_for_config()).c_str());
ini.SetValue("Spoofing", "DxgiBlacklist", Instance()->DxgiBlacklist.value_for_config_or("auto").c_str());
+3 -3
View File
@@ -104,7 +104,7 @@ template <class T, HasDefaultValue defaultState = WithDefault> class CustomOptio
return this->has_value() ? std::move(this->value()) : std::move(_defaultValue);
}
constexpr std::optional<T> value_for_config(bool forceSave = false)
constexpr std::optional<T> value_for_config()
requires(defaultState == WithDefault)
{
if (_volatile)
@@ -115,7 +115,7 @@ template <class T, HasDefaultValue defaultState = WithDefault> class CustomOptio
return std::nullopt;
}
if (!this->has_value() || (!forceSave && *this == _defaultValue))
if (!this->has_value() || *this == _defaultValue)
return std::nullopt;
return this->value();
@@ -246,7 +246,7 @@ class Config
CustomOptional<float> Contrast { 0.0f };
// Menu
CustomOptional<float> MenuScale { 1.0f };
CustomOptional<float, SoftDefault> MenuScale { 1.0f };
CustomOptional<bool> OverlayMenu { true };
CustomOptional<int> ShortcutKey { VK_INSERT };
CustomOptional<bool> ExtendedLimits { false };
+3 -1
View File
@@ -4,6 +4,7 @@
#include "Config.h"
#include <ankerl/unordered_dense.h>
#include <misc/IdentifyGpu.h>
// Use real NVNGX params encapsulated in custom one
// Which is not working correctly
@@ -483,7 +484,8 @@ inline static void InitNGXParameters(NVSDK_NGX_Parameter* InParams)
InParams->Set(NVSDK_NGX_Parameter_DLSS_Enable_Output_Subrects, 1);
InParams->Set(NVSDK_NGX_Parameter_RTXValue, 0);
if (!State::Instance().isRunningOnNvidia)
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (!primaryGpu.dlssCapable)
{
InParams->Set("SuperSamplingDenoising.NeedsUpdatedDriver", 0);
-1
View File
@@ -196,7 +196,6 @@ class State
bool isRunningOnLinux = false;
// Other checks
bool isRunningOnNvidia = false;
std::optional<bool> isRunningOnRDNA4;
bool isPascalOrOlder = false;
bool isDxgiMode = false;
+14 -85
View File
@@ -1311,6 +1311,7 @@ static void CheckQuirks()
auto quirks = getQuirksForExe(exePathFilename);
auto state = &State::Instance();
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
// Apply config-level quirks
if (quirks & GameQuirk::DisableHudfix && Config::Instance()->FGInput.value_or_default() == FGInput::Upscaler)
@@ -1328,14 +1329,14 @@ static void CheckQuirks()
if (quirks & GameQuirk::DisableDxgiSpoofing && !Config::Instance()->DxgiSpoofing.has_value())
Config::Instance()->DxgiSpoofing.set_volatile_value(false);
if (quirks & GameQuirk::RestoreComputeSigOnNonNvidia && !State::Instance().isRunningOnNvidia &&
if (quirks & GameQuirk::RestoreComputeSigOnNonNvidia && primaryGpu.vendorId != VendorId::Nvidia &&
!Config::Instance()->DxgiSpoofing.value_or_default() &&
!Config::Instance()->RestoreComputeSignature.has_value())
{
Config::Instance()->RestoreComputeSignature.set_volatile_value(true);
}
if (quirks & GameQuirk::RestoreComputeSigOnNvidia && State::Instance().isRunningOnNvidia &&
if (quirks & GameQuirk::RestoreComputeSigOnNvidia && primaryGpu.vendorId == VendorId::Nvidia &&
!Config::Instance()->RestoreComputeSignature.has_value())
{
Config::Instance()->RestoreComputeSignature.set_volatile_value(true);
@@ -1350,13 +1351,13 @@ static void CheckQuirks()
if (quirks & GameQuirk::DisableUseFsrInputValues)
Config::Instance()->FsrUseFsrInputValues.set_volatile_value(false);
if (quirks & GameQuirk::EnableVulkanSpoofing && !State::Instance().isRunningOnNvidia &&
if (quirks & GameQuirk::EnableVulkanSpoofing && primaryGpu.vendorId != VendorId::Nvidia &&
!Config::Instance()->VulkanSpoofing.has_value())
{
Config::Instance()->VulkanSpoofing.set_volatile_value(true);
}
if (quirks & GameQuirk::EnableVulkanExtensionSpoofing && !State::Instance().isRunningOnNvidia &&
if (quirks & GameQuirk::EnableVulkanExtensionSpoofing && primaryGpu.vendorId != VendorId::Nvidia &&
!Config::Instance()->VulkanExtensionSpoofing.has_value())
{
Config::Instance()->VulkanExtensionSpoofing.set_volatile_value(true);
@@ -1551,78 +1552,6 @@ static void CheckQuirks()
printQuirks(quirks);
}
bool isNvidia()
{
bool nvidiaDetected = false;
bool loadedHere = false;
auto nvapiModule = GetDllNameWModule(&nvapiNamesW);
if (!nvapiModule)
{
nvapiModule = NtdllProxy::LoadLibraryExW_Ldr(L"nvapi64.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
loadedHere = true;
}
// No nvapi, should not be nvidia
if (!nvapiModule)
{
LOG_DEBUG("Detected: {}", nvidiaDetected);
return nvidiaDetected;
}
if (auto o_NvAPI_QueryInterface =
(PFN_NvApi_QueryInterface) KernelBaseProxy::GetProcAddress_()(nvapiModule, "nvapi_QueryInterface"))
{
// dxvk-nvapi calls CreateDxgiFactory which we can't do because we are inside DLL_PROCESS_ATTACH
NvAPI_ShortString desc;
auto* getVersion = GET_INTERFACE(NvAPI_GetInterfaceVersionString, o_NvAPI_QueryInterface);
if (getVersion && getVersion(desc) == NVAPI_OK &&
(std::string_view(desc) == std::string_view("NVAPI Open Source Interface (DXVK-NVAPI)") ||
std::string_view(desc) == std::string_view("DXVK_NVAPI")))
{
LOG_DEBUG("Using dxvk-nvapi");
DISPLAY_DEVICEA dd = {};
dd.cb = sizeof(dd);
int deviceIndex = 0;
while (EnumDisplayDevicesA(nullptr, deviceIndex, &dd, 0))
{
if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE && std::string_view(dd.DeviceID).contains("VEN_10DE"))
{
// Having any Nvidia GPU active will take precedence
nvidiaDetected = true;
}
deviceIndex++;
}
}
else if (o_NvAPI_QueryInterface(GET_ID(Fake_InformFGState)))
{
// Check for fakenvapi in system32, assume it's not nvidia if found
LOG_DEBUG("Using fakenvapi");
nvidiaDetected = false;
}
else
{
LOG_DEBUG("Using Nvidia's nvapi");
auto init = GET_INTERFACE(NvAPI_Initialize, o_NvAPI_QueryInterface);
if (init && init() == NVAPI_OK)
{
nvidiaDetected = true;
if (auto unload = GET_INTERFACE(NvAPI_Unload, o_NvAPI_QueryInterface))
unload();
}
}
}
if (loadedHere)
NtdllProxy::FreeLibrary_Ldr(nvapiModule);
LOG_DEBUG("Detected: {}", nvidiaDetected);
return nvidiaDetected;
}
void CheckForExcludedProcess()
{
std::wstring exeLower = Util::ExePath().filename().wstring();
@@ -1749,11 +1678,10 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
if (Config::Instance()->DLSSEnabled.value_or_default())
{
spdlog::info("");
State::Instance().isRunningOnNvidia = isNvidia();
if (State::Instance().isRunningOnNvidia)
if (primaryGpu.dlssCapable)
{
spdlog::info("Running on Nvidia");
spdlog::info("Running on DLSS capable GPU");
auto exePath = Util::ExePath().remove_filename();
State::Instance().NVNGX_DLSS_Path = Util::FindFilePath(exePath, "nvngx_dlss.dll");
@@ -1771,6 +1699,7 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
Config::Instance()->DLSSEnabled.set_volatile_value(false);
}
// Assumes that dxgi spoofing is only used to enable DLSS
if (!Config::Instance()->DxgiSpoofing.has_value())
{
spdlog::info("Disabling DxgiSpoofing");
@@ -1783,13 +1712,13 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
}
else
{
spdlog::info("Not running on Nvidia, disabling DLSS");
spdlog::info("Running on non-\"DLSS capable\" GPU, disabling DLSS");
Config::Instance()->DLSSEnabled.set_volatile_value(false);
}
}
else
{
spdlog::info("Not running on Nvidia, disabling DLSS");
spdlog::info("Running on non-\"DLSS capable\" GPU, disabling DLSS");
Config::Instance()->DLSSEnabled.set_volatile_value(false);
}
@@ -1852,12 +1781,12 @@ DWORD WINAPI InitThread(LPVOID hModuleVoid)
if (!Config::Instance()->OverrideNvapiDll.has_value())
{
spdlog::info("OverrideNvapiDll not set, setting it to: {}",
!State::Instance().isRunningOnNvidia ? "true" : "false");
Config::Instance()->OverrideNvapiDll.set_volatile_value(!State::Instance().isRunningOnNvidia);
bool nvidia = primaryGpu.vendorId == VendorId::Nvidia;
spdlog::info("OverrideNvapiDll not set, setting it to: {}", !nvidia ? "true" : "false");
Config::Instance()->OverrideNvapiDll.set_volatile_value(!nvidia);
// Try to load fakenvapi.dll as the main nvapi if not on Nvidia
if (!State::Instance().isRunningOnNvidia && !Config::Instance()->NvapiDllPath.has_value())
if (!nvidia && !Config::Instance()->NvapiDllPath.has_value())
Config::Instance()->NvapiDllPath.set_volatile_value(L"fakenvapi.dll");
}
+10 -5
View File
@@ -13,6 +13,7 @@
#include <magic_enum.hpp>
#include <sl1_reflex.h>
#include <nvapi/fakenvapi.h>
#include <misc/IdentifyGpu.h>
sl::RenderAPI StreamlineHooks::renderApi = sl::RenderAPI::eCount;
std::mutex StreamlineHooks::setConstantsMutex {};
@@ -355,7 +356,8 @@ uint32_t StreamlineHooks::getSystemCapsArch()
{
uint32_t highestArch = 0;
if (!fakenvapi::isUsingFakenvapi() && State::Instance().isRunningOnNvidia)
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (!fakenvapi::isUsingFakenvapi() && primaryGpu.vendorId == VendorId::Nvidia)
{
if (State::Instance().streamlineVersion.major > 1)
{
@@ -391,6 +393,7 @@ uint32_t StreamlineHooks::getSystemCapsArch()
void StreamlineHooks::setArch(uint32_t arch)
{
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (State::Instance().streamlineVersion.major > 1)
{
if (systemCaps)
@@ -401,7 +404,7 @@ void StreamlineHooks::setArch(uint32_t arch)
systemCaps->adapters[i].vendor = VendorId::Nvidia;
}
if (fakenvapi::isUsingFakenvapi() || !State::Instance().isRunningOnNvidia)
if (fakenvapi::isUsingFakenvapi() || primaryGpu.vendorId != VendorId::Nvidia)
systemCaps->driverVersionMajor = 999;
systemCaps->hwsSupported = true;
@@ -414,7 +417,7 @@ void StreamlineHooks::setArch(uint32_t arch)
for (uint32_t i = 0; i < systemCapsSl15->gpuCount; i++)
systemCapsSl15->architecture[i] = arch;
if (fakenvapi::isUsingFakenvapi() || !State::Instance().isRunningOnNvidia)
if (fakenvapi::isUsingFakenvapi() || primaryGpu.vendorId != VendorId::Nvidia)
systemCapsSl15->driverVersionMajor = 999;
systemCapsSl15->hwSchedulingEnabled = true;
@@ -476,7 +479,8 @@ bool StreamlineHooks::hkdlss_slOnPluginLoad(void* params, const char* loaderJSON
nlohmann::json configJson = nlohmann::json::parse(*pluginJSON);
if (!State::Instance().isRunningOnNvidia || State::Instance().isPascalOrOlder)
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (primaryGpu.vendorId != VendorId::Nvidia || !primaryGpu.dlssCapable)
{
if (Config::Instance()->VulkanExtensionSpoofing.value_or_default())
{
@@ -702,7 +706,8 @@ bool StreamlineHooks::hkreflex_slOnPluginLoad(void* params, const char* loaderJS
nlohmann::json configJson = nlohmann::json::parse(*pluginJSON);
if (!State::Instance().isRunningOnNvidia && Config::Instance()->VulkanExtensionSpoofing.value_or_default())
if (IdentifyGpu::getPrimaryGpu().vendorId != VendorId::Nvidia &&
Config::Instance()->VulkanExtensionSpoofing.value_or_default())
{
if (configJson.contains("/external/vk/instance/extensions"_json_pointer))
configJson["external"]["vk"]["instance"]["extensions"].clear();
+3 -1
View File
@@ -10,6 +10,7 @@
#include <detours/detours.h>
#include <vulkan/vulkan_core.h>
#include <misc/IdentifyGpu.h>
typedef VkResult (*PFN_vkQueueSubmitL)(VkQueue queue, uint32_t submitCount, VkSubmitInfo* pSubmits, VkFence fence);
typedef VkResult (*PFN_vkQueueSubmit2L)(VkQueue queue, uint32_t submitCount, VkSubmitInfo2* pSubmits, VkFence fence);
@@ -1058,8 +1059,9 @@ void Vulkan_wDx12::hk_vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipe
uint32_t imageMemoryBarrierCount,
const VkImageMemoryBarrier* pImageMemoryBarriers)
{
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (State::Instance().gameQuirks & GameQuirk::VulkanDLSSBarrierFixup &&
(!State::Instance().isRunningOnNvidia || State::Instance().isPascalOrOlder))
(primaryGpu.vendorId != VendorId::Nvidia || !primaryGpu.dlssCapable))
{
// AMD drivers on the cards around RDNA2 didn't treat VK_IMAGE_LAYOUT_UNDEFINED in the same way Nvidia does.
// Doesn't seem like a bug, just a different way of handling an UB but we need to adjust.
+6 -8
View File
@@ -2267,6 +2267,8 @@ bool MenuCommon::RenderMenu()
}
}
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
// No active upscaler message
if (currentFeature == nullptr || !currentFeature->IsInited())
{
@@ -2287,7 +2289,7 @@ bool MenuCommon::RenderMenu()
if (state.fsrHooks)
upscalers.push_back("FSR");
if (state.nvngxExists || state.nvngxReplacement.has_value() || state.isRunningOnNvidia)
if (state.nvngxExists || state.nvngxReplacement.has_value() || primaryGpu.dlssCapable)
upscalers.push_back("DLSS");
if (state.libxessExists || XeSSProxy::Module() != nullptr)
@@ -2308,12 +2310,7 @@ bool MenuCommon::RenderMenu()
ImGui::Spacing();
if (!state.isRunningOnNvidia)
{
ImGui::Text("nvngx.dll: %s", state.nvngxExists ? "Exists" : "Doesn't Exist");
}
if (state.isRunningOnNvidia)
if (primaryGpu.dlssCapable)
{
ImGui::Text("nvngx_dlss : %s", state.NVNGX_DLSS_Path.has_value() ? "Exists" : "Doesn't Exist");
ImGui::SameLine(0.0f, 16.0f);
@@ -2322,6 +2319,7 @@ bool MenuCommon::RenderMenu()
}
else
{
ImGui::Text("nvngx.dll: %s", state.nvngxExists ? "Exists" : "Doesn't Exist");
ImGui::SameLine(0.0f, 16.0f);
ImGui::Text("nvngx replacement: %s",
state.nvngxReplacement.has_value() ? "Exists" : "Doesn't Exist");
@@ -2489,7 +2487,7 @@ bool MenuCommon::RenderMenu()
ImGui::EndDisabled();
}
if (state.isRunningOnNvidia && !state.NVNGX_DLSS_Path.has_value())
if (primaryGpu.dlssCapable && !state.NVNGX_DLSS_Path.has_value())
{
ImGui::Spacing();
ImGui::TextColored(ImVec4(1.f, 0.8f, 0.f, 1.f), "nvngx_dlss.dll not found, DLSS disabled!");
+1
View File
@@ -70,6 +70,7 @@ void IdentifyGpu::checkGpuInfo()
GpuInformation gpuInfo;
gpuInfo.luid = adapterDesc.AdapterLuid;
gpuInfo.vendorId = (VendorId::Value) adapterDesc.VendorId;
gpuInfo.deviceId = adapterDesc.DeviceId;
gpuInfo.dedicatedVramInBytes = adapterDesc.DedicatedVideoMemory;
std::wstring szName(adapterDesc.Description);
+2 -1
View File
@@ -43,6 +43,7 @@ struct GpuInformation
LUID luid {}; // Unique id to be able to reference the exact GPU, VkPhysicalDeviceIDProperties
std::string name {};
VendorId::Value vendorId = VendorId::Invalid;
uint32_t deviceId = 0x0;
size_t dedicatedVramInBytes = 0;
bool usesDxvk = false;
bool usesVkd3dProton = false;
@@ -50,7 +51,7 @@ struct GpuInformation
bool fsr4Capable = false;
ID3D12Device* d3d12device = nullptr;
bool dlssCapable = false;
bool dlssCapable = false; // assumes GTX16xx to be capable due to our spoofing
NV_GPU_ARCH_INFO nvidiaArchInfo {};
};
+4 -1
View File
@@ -8,6 +8,7 @@
#include <proxies/KernelBase_Proxy.h>
#include <detours/detours.h>
#include <misc/IdentifyGpu.h>
NvAPI_Status __stdcall NvApiHooks::hkNvAPI_GPU_GetArchInfo(NvPhysicalGpuHandle hPhysicalGpu,
NV_GPU_ARCH_INFO* pGpuArchInfo)
@@ -87,9 +88,11 @@ void* __stdcall NvApiHooks::hkNvAPI_QueryInterface(unsigned int InterfaceId)
if (!o_NvAPI_QueryInterface)
return nullptr;
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
// Disable flip metering
if (InterfaceId == 0xF3148C42 &&
Config::Instance()->DisableFlipMetering.value_or(!State::Instance().isRunningOnNvidia))
Config::Instance()->DisableFlipMetering.value_or(primaryGpu.vendorId != VendorId::Nvidia))
{
LOG_INFO("FlipMetering is disabled!");
return nullptr;
+4 -1
View File
@@ -1,6 +1,7 @@
#include "pch.h"
#include "fakenvapi.h"
#include "proxies/FfxApi_Proxy.h"
#include <misc/IdentifyGpu.h>
void fakenvapi::Init(PFN_NvApi_QueryInterface& queryInterface)
{
@@ -152,7 +153,9 @@ bool fakenvapi::setModeAndContext(void* context, Mode mode)
bool fakenvapi::loadForNvidia()
{
if (!State::Instance().isRunningOnNvidia)
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (primaryGpu.vendorId != VendorId::Nvidia)
return false;
if (_dllForNvidia != nullptr)
+7 -4
View File
@@ -12,6 +12,7 @@
#include <detours/detours.h>
#include <vulkan/vulkan_core.h>
#include <misc/IdentifyGpu.h>
static std::map<std::string, bool> vkDeviceExtensions;
static std::map<std::string, bool> vkInstanceExtensions;
@@ -274,7 +275,8 @@ VkResult VulkanSpoofing::hkvkCreateInstance(VkInstanceCreateInfo* pCreateInfo, c
newExtensionList.push_back(pCreateInfo->ppEnabledExtensionNames[i]);
}
if (State::Instance().isRunningOnNvidia && Config::Instance()->DLSSEnabled.value_or_default())
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
if (primaryGpu.dlssCapable && Config::Instance()->DLSSEnabled.value_or_default())
{
LOG_INFO("Adding NVNGX Vulkan extensions");
if (vkInstanceExtensions.size() == 0 ||
@@ -374,12 +376,13 @@ VkResult VulkanSpoofing::hkvkCreateDevice(VkPhysicalDevice physicalDevice, VkDev
static std::vector<const char*> newExtensionList;
newExtensionList.clear();
auto primaryGpu = IdentifyGpu::getPrimaryGpu();
LOG_DEBUG("Checking extensions and removing Streamline ones");
for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++)
{
auto extName = pCreateInfo->ppEnabledExtensionNames[i];
if (Config::Instance()->VulkanExtensionSpoofing.value_or_default() && !State::Instance().isRunningOnNvidia)
if (Config::Instance()->VulkanExtensionSpoofing.value_or_default() && primaryGpu.vendorId != VendorId::Nvidia)
{
auto binaryImport = std::strcmp(extName, VK_NVX_BINARY_IMPORT_EXTENSION_NAME) == 0;
auto imgViewHandle = std::strcmp(extName, VK_NVX_IMAGE_VIEW_HANDLE_EXTENSION_NAME) == 0;
@@ -402,7 +405,7 @@ VkResult VulkanSpoofing::hkvkCreateDevice(VkPhysicalDevice physicalDevice, VkDev
}
const bool isPascalOrOlder = State::Instance().isPascalOrOlder;
if (State::Instance().isRunningOnNvidia)
if (primaryGpu.vendorId == VendorId::Nvidia)
{
LOG_INFO("Adding NVNGX Vulkan extensions");
if (vkDeviceExtensions.size() == 0 ||
@@ -433,7 +436,7 @@ VkResult VulkanSpoofing::hkvkCreateDevice(VkPhysicalDevice physicalDevice, VkDev
newExtensionList.push_back(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
}
if (!isPascalOrOlder)
if (!primaryGpu.dlssCapable)
{
if (vkDeviceExtensions.size() == 0 ||
vkDeviceExtensions.contains(std::string(VK_NVX_BINARY_IMPORT_EXTENSION_NAME)))