Add native K/M/RR inference engines, HIP kernels, replay and validation harnesses, and Windows DLSS setup and runtime support. Include GPU profiling tools, build and packaging scripts, platform integration patches, and implementation documentation.
82 lines
3.0 KiB
C
82 lines
3.0 KiB
C
// Opt-in NVAPI identity bridge for OptiScaler's NVIDIA-only DLSS backend.
|
|
// All NVAPI interfaces except the version string are forwarded to the
|
|
// prefix-local DXVK-NVAPI DLL. The underlying GPU and DLSS execution remain
|
|
// AMD/ZLUDA; this only lets OptiScaler select its official-DLSS route.
|
|
#include <windows.h>
|
|
#include <string.h>
|
|
|
|
#define NVAPI_GET_INTERFACE_VERSION_STRING 0x01053fa5u
|
|
#define NVAPI_INITIALIZE 0x0150e828u
|
|
#define NVAPI_UNLOAD 0xd22bdd7eu
|
|
|
|
typedef void *(__cdecl *NvapiQueryInterface)(unsigned int);
|
|
static NvapiQueryInterface real_query;
|
|
static volatile LONG spoof_probe_armed;
|
|
static volatile LONG spoof_probe_used;
|
|
static volatile LONG spoof_unload_armed;
|
|
|
|
static NvapiQueryInterface load_real_query(void)
|
|
{
|
|
if (real_query != NULL)
|
|
return real_query;
|
|
|
|
wchar_t path[MAX_PATH];
|
|
UINT length = GetSystemDirectoryW(path, MAX_PATH);
|
|
static const wchar_t suffix[] = L"\\d4r_nvapi64_real.dll";
|
|
if (length == 0 || length + (sizeof(suffix) / sizeof(suffix[0])) > MAX_PATH)
|
|
return NULL;
|
|
memcpy(path + length, suffix, sizeof(suffix));
|
|
|
|
HMODULE module = LoadLibraryW(path);
|
|
if (module == NULL)
|
|
return NULL;
|
|
FARPROC symbol = GetProcAddress(module, "nvapi_QueryInterface");
|
|
memcpy(&real_query, &symbol, sizeof(real_query));
|
|
return real_query;
|
|
}
|
|
|
|
static int __cdecl d4r_get_interface_version_string(char *description)
|
|
{
|
|
if (description == NULL)
|
|
return -5; // NVAPI_INVALID_ARGUMENT
|
|
// OptiScaler takes the real-NVIDIA branch for any non-DXVK version string.
|
|
// NVAPI's short string has 64 bytes.
|
|
static const char identity[] = "NVIDIA NVAPI (d4r compatibility)";
|
|
memcpy(description, identity, sizeof(identity));
|
|
if (InterlockedCompareExchange(&spoof_probe_used, 0, 0) == 0)
|
|
InterlockedExchange(&spoof_probe_armed, 1);
|
|
return 0; // NVAPI_OK
|
|
}
|
|
|
|
static int __cdecl d4r_initialize_identity_probe(void)
|
|
{
|
|
// OptiScaler calls this inside DLL_PROCESS_ATTACH when it believes it is
|
|
// loading NVIDIA's own NVAPI. DXVK-NVAPI initializes DXGI here, which is
|
|
// unsafe under the loader lock. The later, ordinary init calls are passed
|
|
// through to DXVK-NVAPI.
|
|
InterlockedExchange(&spoof_probe_used, 1);
|
|
InterlockedExchange(&spoof_unload_armed, 1);
|
|
return 0;
|
|
}
|
|
|
|
static int __cdecl d4r_unload_identity_probe(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
__declspec(dllexport) void *__cdecl nvapi_QueryInterface(unsigned int interface_id)
|
|
{
|
|
NvapiQueryInterface query = load_real_query();
|
|
if (query == NULL)
|
|
return NULL;
|
|
if (interface_id == NVAPI_GET_INTERFACE_VERSION_STRING)
|
|
return (void *)&d4r_get_interface_version_string;
|
|
if (interface_id == NVAPI_INITIALIZE &&
|
|
InterlockedCompareExchange(&spoof_probe_armed, 0, 1) == 1)
|
|
return (void *)&d4r_initialize_identity_probe;
|
|
if (interface_id == NVAPI_UNLOAD &&
|
|
InterlockedCompareExchange(&spoof_unload_armed, 0, 1) == 1)
|
|
return (void *)&d4r_unload_identity_probe;
|
|
return query(interface_id);
|
|
}
|