Skip to content

Instantly share code, notes, and snippets.

@rickbrew
Last active March 17, 2024 12:34
Show Gist options
  • Save rickbrew/10e5c0fa3593ceb6f03766914f43a0c6 to your computer and use it in GitHub Desktop.
Save rickbrew/10e5c0fa3593ceb6f03766914f43a0c6 to your computer and use it in GitHub Desktop.
NVAPI establish application profile that disables GSync, FXAA, and sharpening
// This goes in the header file, which probably isn't necessary unless you're exporting the function from a DLL
__declspec(dllexport) NvAPI_Status (__stdcall EstablishNvApiApplicationProfile)(
const wchar_t* wszProfileName, // "Paint.NET"
const wchar_t* wszAppName, // EXE file path, or Package Family Name
const wchar_t* wszUserFriendlyName // EXE file name, or Package Family Name
);
// CPP file
#include "nvapi/nvapi.h"
#include "nvapi/NvApiDriverSettings.h"
#pragma comment(lib, "nvapi64.lib")
static void SetNVUString(NvAPI_UnicodeString& nvStr, const wchar_t* wcStr)
{
memset(nvStr, 0, sizeof(NvU16) * NVAPI_UNICODE_STRING_MAX);
wcscpy_s(reinterpret_cast<wchar_t*>(nvStr), NVAPI_UNICODE_STRING_MAX, wcStr);
}
static NvAPI_Status SetSimpleNvDRSSetting(
NvDRSSessionHandle hSession,
NvDRSProfileHandle hProfile,
NvU32 settingId,
NVDRS_SETTING_TYPE settingType,
NvU32 u32CurrentValue)
{
NVDRS_SETTING nvSetting = { 0 };
nvSetting.version = NVDRS_SETTING_VER;
nvSetting.settingId = settingId;
nvSetting.settingType = settingType;
nvSetting.u32CurrentValue = u32CurrentValue;
return NvAPI_DRS_SetSetting(hSession, hProfile, &nvSetting);
}
NvAPI_Status (__stdcall EstablishNvApiApplicationProfile)(
const wchar_t* wszProfileName,
const wchar_t* wszAppName,
const wchar_t* wszUserFriendlyName)
{
if (wszProfileName == NULL || wszAppName == NULL || wszUserFriendlyName == NULL)
{
return NVAPI_INVALID_POINTER;
}
NvAPI_Status status = NVAPI_OK;
bool initialized = false;
if (NV_SUCCEEDED(status))
{
status = NvAPI_Initialize();
if (NV_SUCCEEDED(status))
{
initialized = true;
}
}
NvDRSSessionHandle hSession = 0;
if (NV_SUCCEEDED(status))
{
status = NvAPI_DRS_CreateSession(&hSession);
}
if (NV_SUCCEEDED(status))
{
status = NvAPI_DRS_LoadSettings(hSession);
}
// Find or create the profile
NvDRSProfileHandle hProfile = 0;
if (NV_SUCCEEDED(status))
{
NVDRS_APPLICATION nvApplication = { 0 };
nvApplication.version = NVDRS_APPLICATION_VER;
NvAPI_UnicodeString nvsAppName;
SetNVUString(nvsAppName, wszAppName);
// try to look up the profile by appName (path to EXE)
status = NvAPI_DRS_FindApplicationByName(
hSession,
nvsAppName,
&hProfile,
&nvApplication);
if (NV_FAILED(status))
{
NvAPI_UnicodeString nvsProfileName;
SetNVUString(nvsProfileName, wszProfileName);
// try to look up profile by the profile's name ("Paint.NET")
status = NvAPI_DRS_FindProfileByName(
hSession,
nvsProfileName,
&hProfile);
if (NV_FAILED(status))
{
NVDRS_PROFILE nvProfile = { 0 };
nvProfile.version = NVDRS_PROFILE_VER;
nvProfile.isPredefined = 0;
SetNVUString(nvProfile.profileName, wszProfileName);
// create a new profile
status = NvAPI_DRS_CreateProfile(
hSession,
&nvProfile,
&hProfile);
}
// add our EXE to whichever profile we've got
if (NV_SUCCEEDED(status))
{
NVDRS_APPLICATION nvApplication2 = { 0 };
nvApplication2.version = NVDRS_APPLICATION_VER;
nvApplication2.isPredefined = 0;
SetNVUString(nvApplication2.appName, wszAppName);
SetNVUString(nvApplication2.userFriendlyName, wszUserFriendlyName);
SetNVUString(nvApplication2.launcher, L"");
SetNVUString(nvApplication2.fileInFolder, L"");
status = NvAPI_DRS_CreateApplication(
hSession,
hProfile,
&nvApplication2);
}
}
}
// This is out here for easier debugging. Errors while setting individual settings are
// ignored in order to avoid derailing the whole process.
NvAPI_Status setSettingStatus = NVAPI_OK;
// Turn off "image sharpening" in the profile. This setting really messes up how the UI looks.
// TODO: did this change in the latest driver versions? removed or renamed? (dec 2020)
if (NV_SUCCEEDED(status))
{
setSettingStatus = SetSimpleNvDRSSetting(
hSession,
hProfile,
0x00598928,
NVDRS_DWORD_TYPE,
0);
}
// Turn off GSYNC, which doesn't work well for windowed applications
// "GSYNC - Application State" set to "Force Off"
// In the NVCPL, the "Monitor Technology" setting will then be greyed out and say "Not supported for this application".
// This is the same profile that Microsoft Visual Studio uses, and it's a WPF app that would also have problems with
// GSYNC. WPA (Windows Performance Analyzer), another WPF app, has the same problems if you don't modify its NVCP settings.
if (NV_SUCCEEDED(status))
{
setSettingStatus = SetSimpleNvDRSSetting(
hSession,
hProfile,
VRR_APP_OVERRIDE_ID,
NVDRS_DWORD_TYPE,
VRR_APP_OVERRIDE_FORCE_OFF);
}
// Disallow FXAA
if (NV_SUCCEEDED(status))
{
setSettingStatus = SetSimpleNvDRSSetting(
hSession,
hProfile,
FXAA_ALLOW_ID,
NVDRS_DWORD_TYPE,
FXAA_ALLOW_DISALLOWED);
}
if (NV_SUCCEEDED(status))
{
status = NvAPI_DRS_SaveSettings(hSession);
}
if (hSession != NULL)
{
status = NvAPI_DRS_DestroySession(hSession);
hSession = NULL;
}
if (initialized)
{
(void)NvAPI_Unload();
}
return status;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment