This commit is contained in:
FakeMichau
2024-09-25 20:39:06 +02:00
8 changed files with 85 additions and 89 deletions
+43 -60
View File
@@ -2,36 +2,36 @@
namespace nvd {
NvAPI_Status __cdecl NvAPI_Initialize() {
if (!deviceId) {
IDXGIFactory1* pFactory = nullptr;
if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory))) {
if (!device_id) {
IDXGIFactory1* factory = nullptr;
if (FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory))) {
spdlog::error("Failed to create DXGI Factory");
return ERROR();
}
IDXGIAdapter1* pAdapter = nullptr;
if (FAILED(pFactory->EnumAdapters1(0, &pAdapter))) {
IDXGIAdapter1* adapter = nullptr;
if (FAILED(factory->EnumAdapters1(0, &adapter))) {
spdlog::error("Failed to enumerate adapters");
pFactory->Release();
factory->Release();
return ERROR();
}
DXGI_ADAPTER_DESC1 adapterDesc;
if (FAILED(pAdapter->GetDesc1(&adapterDesc))) {
DXGI_ADAPTER_DESC1 adapter_desc;
if (FAILED(adapter->GetDesc1(&adapter_desc))) {
spdlog::error("Failed to get adapter description");
pAdapter->Release();
pFactory->Release();
adapter->Release();
factory->Release();
return ERROR();
}
luid = adapterDesc.AdapterLuid;
deviceId = adapterDesc.DeviceId;
vendorId = adapterDesc.VendorId;
subSysId = adapterDesc.SubSysId;
revisionId = adapterDesc.Revision;
luid = adapter_desc.AdapterLuid;
device_id = adapter_desc.DeviceId;
vendor_id = adapter_desc.VendorId;
subsystem_id = adapter_desc.SubSysId;
revision_id = adapter_desc.Revision;
pAdapter->Release();
pFactory->Release();
adapter->Release();
factory->Release();
lowlatency_ctx.init_lfx();
}
@@ -60,7 +60,7 @@ namespace nvd {
if (displayId == 0) {
return OK();
}
return ERROR(NVAPI_END_ENUMERATION);
return ERROR_VALUE(NVAPI_END_ENUMERATION);
}
NvAPI_Status __cdecl NvAPI_GetLogicalGPUFromPhysicalGPU(NvPhysicalGpuHandle physicalHandle, NvLogicalGpuHandle* logicalHandle) {
@@ -94,17 +94,17 @@ namespace nvd {
}
NvAPI_Status __cdecl NvAPI_GetErrorMessage(NvAPI_Status status, NvAPI_ShortString szMsg) {
std::string error = fromErrorNr(status);
std::string error = from_error_nr(status);
spdlog::error("NvAPI_GetErrorMessage gave this error: {}", error);
tonvss(szMsg, error);
return OK();
}
NvAPI_Status __cdecl NvAPI_GPU_CudaEnumComputeCapableGpus(NV_COMPUTE_GPU_TOPOLOGY* pComputeTopo) {
auto pComputeTopoV1 = reinterpret_cast<NV_COMPUTE_GPU_TOPOLOGY_V1*>(pComputeTopo);
pComputeTopoV1->gpuCount = 1;
pComputeTopoV1->computeGpus[0].hPhysicalGpu = nullptr;
pComputeTopoV1->computeGpus[0].flags = NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_CAPABLE | NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_ENABLE | NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_RECOMMENDED;
auto compute_topoV1 = reinterpret_cast<NV_COMPUTE_GPU_TOPOLOGY_V1*>(pComputeTopo);
compute_topoV1->gpuCount = 1;
compute_topoV1->computeGpus[0].hPhysicalGpu = nullptr;
compute_topoV1->computeGpus[0].flags = NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_CAPABLE | NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_ENABLE | NV_COMPUTE_GPU_TOPOLOGY_PHYSICS_RECOMMENDED;
return OK();
}
@@ -133,10 +133,10 @@ namespace nvd {
}
NvAPI_Status __cdecl NvAPI_GPU_GetPCIIdentifiers(NvPhysicalGpuHandle hPhysicalGpu, NvU32* pDeviceId, NvU32* pSubSystemId, NvU32* pRevisionId, NvU32* pExtDeviceId) {
*pDeviceId = (deviceId << 16) | vendorId;
*pSubSystemId = subSysId;
*pRevisionId = revisionId;
*pExtDeviceId = deviceId;
*pDeviceId = (device_id << 16) | vendor_id;
*pSubSystemId = subsystem_id;
*pRevisionId = revision_id;
*pExtDeviceId = device_id;
return OK();
}
@@ -152,13 +152,13 @@ namespace nvd {
NvAPI_Status __cdecl NvAPI_GPU_GetAllClockFrequencies(NvPhysicalGpuHandle hPhysicalGPU, NV_GPU_CLOCK_FREQUENCIES* pClkFreqs) {
if (pClkFreqs == nullptr)
return ERROR(NVAPI_INVALID_ARGUMENT);
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
if (pClkFreqs->version != NV_GPU_CLOCK_FREQUENCIES_VER_1 && pClkFreqs->version != NV_GPU_CLOCK_FREQUENCIES_VER_2 && pClkFreqs->version != NV_GPU_CLOCK_FREQUENCIES_VER_3)
return ERROR(NVAPI_INCOMPATIBLE_STRUCT_VERSION);
return ERROR_VALUE(NVAPI_INCOMPATIBLE_STRUCT_VERSION);
if (pClkFreqs->ClockType != static_cast<unsigned int>(NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ)) {
return ERROR(NVAPI_NOT_SUPPORTED);
return ERROR_VALUE(NVAPI_NOT_SUPPORTED);
}
// Reset all clock data for all domains
@@ -218,25 +218,8 @@ namespace nvd {
pPstatesInfo->pstates[0].baseVoltages[0].voltDelta_uV.valueRange.max = 0;
// Fill mock data for P-state 1
memcpy(&pPstatesInfo->pstates[1], &pPstatesInfo->pstates[0], sizeof(pPstatesInfo->pstates[0]));
pPstatesInfo->pstates[1].pstateId = NVAPI_GPU_PERF_PSTATE_P1;
pPstatesInfo->pstates[1].bIsEditable = false;
pPstatesInfo->pstates[1].clocks[0].domainId = NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS;
pPstatesInfo->pstates[1].clocks[0].freqDelta_kHz.value = 1000; // 1 MHz
pPstatesInfo->pstates[1].clocks[0].freqDelta_kHz.valueRange.min = 800;
pPstatesInfo->pstates[1].clocks[0].freqDelta_kHz.valueRange.max = 1200;
pPstatesInfo->pstates[1].clocks[1].domainId = NVAPI_GPU_PUBLIC_CLOCK_MEMORY;
pPstatesInfo->pstates[1].clocks[1].freqDelta_kHz.value = 1000; // 1 MHz
pPstatesInfo->pstates[1].clocks[1].freqDelta_kHz.valueRange.min = 800;
pPstatesInfo->pstates[1].clocks[1].freqDelta_kHz.valueRange.max = 1200;
pPstatesInfo->pstates[1].clocks[2].domainId = NVAPI_GPU_PUBLIC_CLOCK_VIDEO;
pPstatesInfo->pstates[1].clocks[2].freqDelta_kHz.value = 1000; // 1 MHz
pPstatesInfo->pstates[1].clocks[2].freqDelta_kHz.valueRange.min = 800;
pPstatesInfo->pstates[1].clocks[2].freqDelta_kHz.valueRange.max = 1200;
pPstatesInfo->pstates[1].baseVoltages[0].volt_uV = 1000000; // 1V
pPstatesInfo->pstates[1].baseVoltages[0].bIsEditable = false;
pPstatesInfo->pstates[1].baseVoltages[0].voltDelta_uV.value = 1000;
pPstatesInfo->pstates[1].baseVoltages[0].voltDelta_uV.valueRange.min = 0;
pPstatesInfo->pstates[1].baseVoltages[0].voltDelta_uV.valueRange.max = 0;
return OK();
}
@@ -314,7 +297,7 @@ namespace nvd {
}
NvAPI_Status __cdecl NvAPI_D3D_SetResourceHint() {
return ERROR(NVAPI_NO_IMPLEMENTATION);
return ERROR_VALUE(NVAPI_NO_IMPLEMENTATION);
}
NvAPI_Status __cdecl NvAPI_D3D_GetSleepStatus(IUnknown* pDevice, NV_GET_SLEEP_STATUS_PARAMS* pGetSleepStatusParams) {
@@ -431,12 +414,12 @@ namespace nvd {
NvAPI_Status __cdecl NvAPI_D3D12_GetRaytracingCaps(IUnknown* invalid, NVAPI_D3D12_RAYTRACING_CAPS_TYPE type, void* pData, size_t dataSize) {
if (pData == nullptr)
return ERROR(NVAPI_INVALID_POINTER);
return ERROR_VALUE(NVAPI_INVALID_POINTER);
switch (type) {
case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_THREAD_REORDERING:
if (dataSize != sizeof(NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS))
return ERROR(NVAPI_INVALID_ARGUMENT);
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
// let's hope that NvAPI_D3D12_IsNvShaderExtnOpCodeSupported returning false is enough to discourage games from attempting to use Shader Execution Reordering
*(NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAPS*)pData = NVAPI_D3D12_RAYTRACING_THREAD_REORDERING_CAP_NONE;
@@ -444,20 +427,20 @@ namespace nvd {
case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_OPACITY_MICROMAP:
if (dataSize != sizeof(NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS))
return ERROR(NVAPI_INVALID_POINTER);
return ERROR_VALUE(NVAPI_INVALID_POINTER);
*(NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAPS*)pData = NVAPI_D3D12_RAYTRACING_OPACITY_MICROMAP_CAP_NONE;
break;
case NVAPI_D3D12_RAYTRACING_CAPS_TYPE_DISPLACEMENT_MICROMAP:
if (dataSize != sizeof(NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAPS))
return ERROR(NVAPI_INVALID_POINTER);
return ERROR_VALUE(NVAPI_INVALID_POINTER);
*(NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAPS*)pData = NVAPI_D3D12_RAYTRACING_DISPLACEMENT_MICROMAP_CAP_NONE;
break;
default:
return ERROR(NVAPI_INVALID_POINTER);
return ERROR_VALUE(NVAPI_INVALID_POINTER);
}
return OK();
@@ -533,7 +516,7 @@ namespace nvd {
D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS desc{};
if (!ConvertBuildRaytracingAccelerationStructureInputs(pParams->pDesc, geometryDescs, &desc))
return ERROR(NVAPI_INVALID_ARGUMENT);
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
pDevice->GetRaytracingAccelerationStructurePrebuildInfo(&desc, pParams->pInfo);
return OK();
@@ -549,7 +532,7 @@ namespace nvd {
};
if (!ConvertBuildRaytracingAccelerationStructureInputs(&pParams->pDesc->inputs, geometryDescs, &desc.Inputs))
return ERROR(NVAPI_INVALID_ARGUMENT);
return ERROR_VALUE(NVAPI_INVALID_ARGUMENT);
pCommandList->BuildRaytracingAccelerationStructure(&desc, pParams->numPostbuildInfoDescs, pParams->pPostbuildInfoDescs);
static bool logged = false;
@@ -596,7 +579,7 @@ namespace nvd {
}
NvAPI_Status __cdecl NvAPI_DRS_CreateSession(NvDRSSessionHandle* session) {
*session = drsSession;
*session = drs_session;
return OK();
}
@@ -609,7 +592,7 @@ namespace nvd {
}
NvAPI_Status __cdecl NvAPI_DRS_GetBaseProfile(NvDRSSessionHandle session, NvDRSProfileHandle* profile) {
*profile = drsProfile;
*profile = drs_profile;
return OK();
}
@@ -662,9 +645,9 @@ namespace nvd {
}
NvAPI_Status __cdecl Dummy_GetLatency(uint64_t* call_spot, uint64_t* target, uint64_t* latency, uint64_t* frame_time) {
if (!call_spot || !target || !latency || !frame_time) return ERROR(NVAPI_INVALID_POINTER);
if (!call_spot || !target || !latency || !frame_time) return ERROR_VALUE(NVAPI_INVALID_POINTER);
if (lowlatency_ctx.get_mode() != LatencyFlex) return ERROR(NVAPI_DATA_NOT_FOUND);
if (lowlatency_ctx.get_mode() != LatencyFlex) return ERROR_VALUE(NVAPI_DATA_NOT_FOUND);
*call_spot = (uint64_t)lowlatency_ctx.call_spot;
*target = lowlatency_ctx.lfx_stats.target;
+6 -6
View File
@@ -16,14 +16,14 @@
namespace nvd {
static auto drs = 1U;
static auto drsSession = reinterpret_cast<NvDRSSessionHandle>(&drs);
static auto drsProfile = reinterpret_cast<NvDRSProfileHandle>(&drs);
static auto drs_session = reinterpret_cast<NvDRSSessionHandle>(&drs);
static auto drs_profile = reinterpret_cast<NvDRSProfileHandle>(&drs);
static LUID luid = {};
static UINT deviceId = {};
static UINT vendorId = {};
static UINT subSysId = {};
static UINT revisionId = {};
static UINT device_id = {};
static UINT vendor_id = {};
static UINT subsystem_id = {};
static UINT revision_id = {};
static LowLatency lowlatency_ctx;
+3 -3
View File
@@ -6,11 +6,11 @@ NvAPI_Status Ok(const char* function_name) {
}
NvAPI_Status Error(const char* function_name, NvAPI_Status status) {
spdlog::trace("{}: {}", function_name, fromErrorNr(status));
spdlog::trace("{}: {}", function_name, from_error_nr(status));
return status;
}
void prepareLogging(spdlog::level::level_enum level) {
void prepare_logging(spdlog::level::level_enum level) {
try {
if (level != spdlog::level::off) {
auto logger = spdlog::basic_logger_mt("basic_logger", "fakenvapi.log", true);
@@ -27,7 +27,7 @@ void prepareLogging(spdlog::level::level_enum level) {
}
}
void closeLogging() {
void close_logging() {
spdlog::default_logger()->flush();
spdlog::shutdown();
}
+4 -3
View File
@@ -7,9 +7,10 @@
#define OK() Ok(__func__)
#undef ERROR
#define ERROR(...) Error(__func__, ##__VA_ARGS__)
#define ERROR() Error(__func__)
#define ERROR_VALUE(status) Error(__func__, status)
NvAPI_Status Ok(const char* function_name);
NvAPI_Status Error(const char* function_name, NvAPI_Status status = NVAPI_ERROR);
void prepareLogging(spdlog::level::level_enum level);
void closeLogging();
void prepare_logging(spdlog::level::level_enum level);
void close_logging();
+16 -6
View File
@@ -71,18 +71,18 @@ class LowLatency {
// https://learn.microsoft.com/en-us/windows/win32/sync/using-waitable-timer-objects
static inline int timer_sleep(int64_t hundred_ns){
static HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
LARGE_INTEGER liDueTime;
static HANDLE timer = CreateWaitableTimer(NULL, TRUE, NULL);
LARGE_INTEGER due_time;
liDueTime.QuadPart = -hundred_ns;
due_time.QuadPart = -hundred_ns;
if(!hTimer)
if(!timer)
return 1;
if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0))
if (!SetWaitableTimer(timer, &due_time, 0, NULL, NULL, 0))
return 2;
if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
if (WaitForSingleObject(timer, INFINITE) != WAIT_OBJECT_0)
return 3;
return 0;
@@ -154,6 +154,16 @@ public:
spdlog::info("LatencyFleX initialized");
}
void deinit() {
#if _MSC_VER && _WIN64
if (context_dx12.m_pAntiLagAPI)
AMD::AntiLag2DX12::DeInitialize(&context_dx12);
if (context_dx11.m_pAntiLagAPI)
AMD::AntiLag2DX11::DeInitialize(&context_dx11);
#endif
free(lf);
}
inline HRESULT update() {
if (force_reflex == ForceDisable || (force_reflex == InGame && !active)) return S_FALSE;
+5 -4
View File
@@ -19,15 +19,16 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
case DLL_PROCESS_ATTACH:
if (get_config(L"fakenvapi", L"enable_logs", true))
if (get_config(L"fakenvapi", L"enable_trace_logs", false))
prepareLogging(spdlog::level::trace);
prepare_logging(spdlog::level::trace);
else
prepareLogging(spdlog::level::info);
prepare_logging(spdlog::level::info);
else
prepareLogging(spdlog::level::off);
prepare_logging(spdlog::level::off);
spdlog::critical("fakenvapi version: {}", FAKENVAPI_VERSION);
break;
case DLL_PROCESS_DETACH:
closeLogging();
close_logging();
nvd::lowlatency_ctx.deinit();
break;
}
return TRUE;
+5 -5
View File
@@ -6,11 +6,11 @@ void tonvss(NvAPI_ShortString nvss, std::string str) {
}
static void get_ini_path(wchar_t* path) {
HMODULE hModule = GetModuleHandle(NULL);
GetModuleFileNameW(hModule, path, MAX_PATH);
wchar_t* lastSlash = wcsrchr(path, L'\\');
if (lastSlash != nullptr) {
*lastSlash = L'\0';
HMODULE module = GetModuleHandle(NULL);
GetModuleFileNameW(module, path, MAX_PATH);
wchar_t* last_slash = wcsrchr(path, L'\\');
if (last_slash != nullptr) {
*last_slash = L'\0';
}
wcscat(path, L"\\fakenvapi.ini");
}
+3 -2
View File
@@ -2,6 +2,7 @@
#include "../external/nvapi.h"
#include <string>
#include <map>
#include <cstdint>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -13,7 +14,7 @@ int get_config(const wchar_t* section, const wchar_t* key, int default_value);
return registry.insert({id, (void *)method}).first->second;
// function taken from jp7677's dxvk-nvapi project licensed under MIT
inline std::string fromErrorNr(const int16_t errorNr) {
inline std::string from_error_nr(const int16_t error_nr) {
static const std::map<int16_t, std::string> errors{
{-1, "NVAPI_ERROR"},
{-2, "NVAPI_LIBRARY_NOT_FOUND"},
@@ -156,6 +157,6 @@ inline std::string fromErrorNr(const int16_t errorNr) {
{-223, "NVAPI_REQUIRE_FURTHER_HDCP_ACTION"},
{-224, "NVAPI_DISPLAY_MUX_TRANSITION_FAILED"} };
auto it = errors.find(errorNr);
auto it = errors.find(error_nr);
return it != errors.end() ? it->second : "UNKNOWN_ERROR";
}