beeradmoore/dlss-swapper · error · Exception

Failed to load DLL

Error message

Failed to load DLL

What it means

FSR31Helper.GetVersions loads the AMD FidelityFX API DLL via LoadLibrary to call its ffxQuery export and query FSR 3.1 driver/runtime versions. When LoadLibrary returns IntPtr.Zero the DLL could not be loaded, so the helper throws 'Failed to load DLL'. This is a native interop failure: the module never made it into the process address space.

Solutions

  1. Verify the file exists at dllPath (File.Exists) and that its bitness matches the process (x64 DLL in a 64-bit process) before calling LoadLibrary.
  2. Update AMD Radeon/Adrenalin drivers (or install the FidelityFX API redistributable) so the DLL and its dependencies exist.
  3. Run dependency inspection (Dependencies/dumpbin /dependents) to find missing dependent DLLs and install the VC++ redistributables.
  4. Unblock the file (file Properties > Unblock, or remove the Zone.Identifier ADS) if Mark-of-the-Web is blocking it.
  5. Check antivirus quarantine logs and whitelist the DLL if it was removed.

Example fix

// before
var hModule = LoadLibrary(dllPath);
if (hModule == IntPtr.Zero)
    throw new Exception("Failed to load DLL");
// after
var hModule = LoadLibrary(dllPath);
if (hModule == IntPtr.Zero)
{
    var err = Marshal.GetLastWin32Error();
    throw new Exception($"Failed to load DLL '{dllPath}' (Win32Error={err}, exists={File.Exists(dllPath)})");
}
Defensive patterns

Strategy: validation

Validate before calling

if (!File.Exists(dllPath))
    throw new FileNotFoundException($"FidelityFX DLL not found: {dllPath}");
// optional: verify bitness matches the process before LoadLibrary

Type guard

static bool CanLoadLibrary(string dllPath)
{
    var h = LoadLibrary(dllPath);
    if (h != IntPtr.Zero) { FreeLibrary(h); return true; }
    return false;
}

Try / catch

try
{
    var versions = FSR31Helper.GetVersions();
}
catch (Exception ex) when (ex.Message == "Failed to load DLL")
{
    Logger.Warn(ex, $"Could not load {dllPath}; FSR 3.1 version info unavailable. Check drivers and bitness.");
}

Prevention

When it happens

Trigger: Calling GetVersions when the DLL at dllPath is missing, is blocked (downloaded file with Mark-of-the-Web, antivirus quarantine), has unsatisfied native dependencies (missing VC++ runtime, driver DLLs), or the architecture (x86/x64/ARM64) does not match the process. Also when amdxc64.dll / the FidelityFX API is absent because GPU drivers are outdated or non-AMD GPUs are present.

Common situations: Users without current AMD drivers or with NVIDIA-only systems; x86 process trying to load an x64 DLL; DLL shipped without its dependency chain; SmartScreen/AV blocking unsigned DLLs in temp folders.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15). Data as JSON: /api/errors/9a72ef1ebe47f50c. Report an issue: GitHub.

Appendix: source

Thrown at src/Helpers/FSR31/FSR31Helper.cs:35

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool FreeLibrary(IntPtr hModule);

    // Define a delegate for the ffxQuery function
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    private delegate FfxApiReturnCodes ffxQueryDelegate(IntPtr context, ref QueryDescGetVersions header);

    public static List<string?> GetVersions(string dllPath)
    {
        if (Path.Exists(dllPath) == false)
        {
            return new List<string?>();
        }
        Logger.Info($"AMDFidelityFXAPI - Loading {dllPath}");
        var hModule = LoadLibrary(dllPath);
        if (hModule == IntPtr.Zero)
        {
            throw new Exception("Failed to load DLL");
        }

        try
        {
            var pAddressOfFunctionToCall = GetProcAddress(hModule, "ffxQuery");
            if (pAddressOfFunctionToCall == IntPtr.Zero)
            {
                throw new Exception("Failed to get function address");
            }

            var ffxQuery = Marshal.GetDelegateForFunctionPointer(pAddressOfFunctionToCall, typeof(ffxQueryDelegate)) as ffxQueryDelegate;
            if (ffxQuery is null)
            {
                throw new Exception("Failed to get function delegate");
            }

            var versionQuery = new QueryDescGetVersions();

View on GitHub (pinned to ab9b1e2d4b)