diff --git a/extlibs/nvapi/nvapi.hpp b/extlibs/nvapi/nvapi.hpp index 957041a2e..4259a11c9 100644 --- a/extlibs/nvapi/nvapi.hpp +++ b/extlibs/nvapi/nvapi.hpp @@ -33,12 +33,15 @@ namespace { int nvapi_init() { const bool disableThreadedOptimizations = true; - const bool maximumPerformance = true; - const bool enableTripleBuffering = true; + const bool setMaximumPerformance = true; + const bool disableTripleBuffering = true; + const bool setPrerenderedFrames = true; - const wchar_t* profileName = L"Attract Mode2"; + const wchar_t* profileName = L"Attract Mode"; const wchar_t* appName = L""; + int return_code = 0; + std::wstring file_name; wchar_t result[MAX_PATH]; file_name = std::wstring( result, GetModuleFileNameW( NULL, result, MAX_PATH )); @@ -49,7 +52,6 @@ namespace { HMODULE hmod = LoadLibrary( NVAPI_DLL ); if ( hmod == NULL ) { - //FeLog remove FeDebug() << "NvAPI: " << NVAPI_DLL << " not found" << std::endl; return 0; } @@ -64,6 +66,7 @@ namespace { NvAPI_EnumPhysicalGPUs = (NvAPI_EnumPhysicalGPUs_t) (*NvAPI_QueryInterface)(0xE5AC921F); NvAPI_GPU_GetUsages = (NvAPI_GPU_GetUsages_t) (*NvAPI_QueryInterface)(0x189A1FDF); NvAPI_DRS_CreateProfile = (NvAPI_DRS_CreateProfile_t) (*NvAPI_QueryInterface)(0xCC176068); + NvAPI_DRS_DeleteProfile = (NvAPI_DRS_DeleteProfile_t) (*NvAPI_QueryInterface)(0x17093206); NvAPI_DRS_CreateSession = (NvAPI_DRS_CreateSession_t) (*NvAPI_QueryInterface)(0x0694D52E); NvAPI_DRS_LoadSettings = (NvAPI_DRS_LoadSettings_t) (*NvAPI_QueryInterface)(0x375DBD6B); NvAPI_DRS_CreateApplication = (NvAPI_DRS_CreateApplication_t) (*NvAPI_QueryInterface)(0x4347A9DE); @@ -71,6 +74,8 @@ namespace { NvAPI_DRS_SaveSettings = (NvAPI_DRS_SaveSettings_t) (*NvAPI_QueryInterface)(0xFCBC7E14); NvAPI_DRS_DestroySession = (NvAPI_DRS_DestroySession_t) (*NvAPI_QueryInterface)(0x0DAD9CFF8); NvAPI_DRS_FindProfileByName = (NvAPI_DRS_FindProfileByName_t) (*NvAPI_QueryInterface)(0x7E4A9A0B); + NvAPI_DRS_FindApplicationByName = (NvAPI_DRS_FindApplicationByName_t) (*NvAPI_QueryInterface)(0xEEE566B2); + NvAPI_DRS_GetProfileInfo = (NvAPI_DRS_GetProfileInfo_t) (*NvAPI_QueryInterface)(0x61CD6FD6); NvAPI_GetErrorMessage = (NvAPI_GetErrorMessage_t) (*NvAPI_QueryInterface)(0x6C2D048C); NvDRSSessionHandle hSession; @@ -78,9 +83,9 @@ namespace { // Initialize NvAPI status = NvAPI_Initialize(); - FeDebug() << "NvAPI: Initialize: " << nvapi_get_error_msg( status ); - if ( status != NVAPI_OK ) - return 0; + FeDebug() << "NvAPI: Initialize: " << nvapi_get_error_msg( status ); + if ( status != NVAPI_OK ) + return 0; status = NvAPI_DRS_CreateSession( &hSession ); FeDebug() << "NvAPI: CreateSession: " << nvapi_get_error_msg( status ); @@ -88,14 +93,41 @@ namespace { status = NvAPI_DRS_LoadSettings( hSession ); FeDebug() << "NvAPI: LoadSettings: " << nvapi_get_error_msg( status ); - // Fill profile info + // Fill application info + NVDRS_APPLICATION app; + app.version = NVDRS_APPLICATION_VER; + app.isPredefined = 0; + nvapi_set_ustring( app.appName, appName ); + nvapi_set_ustring( app.launcher, L"" ); + + NvDRSProfileHandle hProfile; + + status = NvAPI_DRS_FindApplicationByName(hSession, app.appName, &hProfile, &app); + if ( status != NVAPI_OK ) + return_code = 1; + NVDRS_PROFILE profileInfo; profileInfo.version = NVDRS_PROFILE_VER; profileInfo.isPredefined = 0; + + NvAPI_DRS_GetProfileInfo(hSession, hProfile, &profileInfo); + + if ( status == NVAPI_OK ) + { + if ( std::wcscmp((wchar_t*)profileInfo.profileName, profileName) != 0 ) + { + FeDebug() << "NvAPI: " << nowide::narrow( file_name ) << " is already assigned in profile " << + nowide::narrow((wchar_t*)profileInfo.profileName) << std::endl; + status = NvAPI_DRS_DeleteProfile( hSession, hProfile ); + FeDebug() << "NvAPI: Deleting Nvidia profile: " << nvapi_get_error_msg( status ); + return_code = 1; + } + } + + // Fill profile info nvapi_set_ustring( profileInfo.profileName, profileName ); // Open profile or create if not found - NvDRSProfileHandle hProfile; status = NvAPI_DRS_FindProfileByName( hSession, profileInfo.profileName, &hProfile ); FeDebug() << "NvAPI: FindProfileByName: " << nvapi_get_error_msg( status ); @@ -105,13 +137,6 @@ namespace { FeDebug() << "NvAPI: CreateProfile: " << nvapi_get_error_msg( status ); } - // Fill application info - NVDRS_APPLICATION app; - app.version = NVDRS_APPLICATION_VER; - app.isPredefined = 0; - nvapi_set_ustring( app.appName, appName ); - nvapi_set_ustring( app.launcher, L"" ); - // Create application status = NvAPI_DRS_CreateApplication( hSession, hProfile, &app ); if ( status != NVAPI_ERROR ) @@ -145,7 +170,7 @@ namespace { } // Set Triple Buffering - if ( enableTripleBuffering ) + if ( disableTripleBuffering ) { setting.version = NVDRS_SETTING_VER; setting.settingId = OGL_TRIPLE_BUFFER_ID; @@ -153,15 +178,43 @@ namespace { setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION; setting.isCurrentPredefined = 0; setting.isPredefinedValid = 0; - setting.u32CurrentValue = OGL_TRIPLE_BUFFER_ENABLED; - setting.u32PredefinedValue = OGL_TRIPLE_BUFFER_ENABLED; + setting.u32CurrentValue = OGL_TRIPLE_BUFFER_DISABLED; + setting.u32PredefinedValue = OGL_TRIPLE_BUFFER_DISABLED; + + status = NvAPI_DRS_SetSetting( hSession, hProfile, &setting ); + FeDebug() << "NvAPI: Triple Buffering OFF: " << nvapi_get_error_msg( status ); + } + + // Set Prerendered Frames + if ( setPrerenderedFrames ) + { + setting.version = NVDRS_SETTING_VER; + setting.settingId = PRERENDERLIMIT_ID; + setting.settingType = NVDRS_DWORD_TYPE; + setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION; + setting.isCurrentPredefined = 0; + setting.isPredefinedValid = 0; + setting.u32CurrentValue = 0x04; + setting.u32PredefinedValue = 0x04; + + status = NvAPI_DRS_SetSetting( hSession, hProfile, &setting ); + FeDebug() << "NvAPI: Prendered Frames set to 4: " << nvapi_get_error_msg( status ); + + setting.version = NVDRS_SETTING_VER; + setting.settingId = OGL_MAX_FRAMES_ALLOWED_ID; + setting.settingType = NVDRS_DWORD_TYPE; + setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION; + setting.isCurrentPredefined = 0; + setting.isPredefinedValid = 0; + setting.u32CurrentValue = 0x04; + setting.u32PredefinedValue = 0x04; status = NvAPI_DRS_SetSetting( hSession, hProfile, &setting ); - FeDebug() << "NvAPI: Triple Buffering ON: " << nvapi_get_error_msg( status ); + FeDebug() << "NvAPI: Maximum frames allowed set to 4: " << nvapi_get_error_msg( status ); } // Set Power State - if ( maximumPerformance ) + if ( setMaximumPerformance ) { setting.version = NVDRS_SETTING_VER; setting.settingId = PREFERRED_PSTATE_ID; @@ -184,6 +237,6 @@ namespace { status = NvAPI_DRS_DestroySession( hSession ); FeDebug() << "NvAPI: Closing Nvidia session: " << nvapi_get_error_msg( status ); - return 0; + return return_code; } } diff --git a/extlibs/nvapi/nvapi_definitions.hpp b/extlibs/nvapi/nvapi_definitions.hpp index c4419a94d..ca7219cd8 100644 --- a/extlibs/nvapi/nvapi_definitions.hpp +++ b/extlibs/nvapi/nvapi_definitions.hpp @@ -9,8 +9,9 @@ namespace { enum Esetting { OGL_THREAD_CONTROL_ID = 0x20C1221E, OGL_TRIPLE_BUFFER_ID = 0x20FDD1F9, - PREFERRED_PSTATE_ID = 0x1057EB71 - + PREFERRED_PSTATE_ID = 0x1057EB71, + PRERENDERLIMIT_ID = 0x007BA09E, + OGL_MAX_FRAMES_ALLOWED_ID = 0x208E55E3 }; enum EValues_OGL_THREAD_CONTROL { @@ -40,6 +41,14 @@ enum EValues_PREFERRED_PSTATE { PREFERRED_PSTATE_DEFAULT = PREFERRED_PSTATE_OPTIMAL_POWER }; +enum EValues_PRERENDERLIMIT { + PRERENDERLIMIT_MIN = 0x00, + PRERENDERLIMIT_MAX = 0xff, + PRERENDERLIMIT_APP_CONTROLLED = 0x00, + PRERENDERLIMIT_NUM_VALUES = 3, + PRERENDERLIMIT_DEFAULT = PRERENDERLIMIT_APP_CONTROLLED +}; + typedef enum _NvAPI_Status { NVAPI_OK = 0, //!< Success. Request is completed. @@ -290,6 +299,7 @@ typedef NvAPI_Status (*NvAPI_Initialize_t)(); typedef NvAPI_Status (*NvAPI_EnumPhysicalGPUs_t)(int **handles, int *count); typedef NvAPI_Status (*NvAPI_GPU_GetUsages_t)(int *handle, unsigned int *usages); typedef NvAPI_Status (*NvAPI_DRS_CreateProfile_t)(NvDRSSessionHandle hSession, NVDRS_PROFILE *pProfileInfo, NvDRSProfileHandle *phProfile); +typedef NvAPI_Status (*NvAPI_DRS_DeleteProfile_t)(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile); typedef NvAPI_Status (*NvAPI_DRS_CreateSession_t)(NvDRSSessionHandle *phSession); typedef NvAPI_Status (*NvAPI_DRS_LoadSettings_t)(NvDRSSessionHandle hSession); typedef NvAPI_Status (*NvAPI_DRS_CreateApplication_t)(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile, NVDRS_APPLICATION *pApplication); @@ -297,6 +307,8 @@ typedef NvAPI_Status (*NvAPI_DRS_SetSetting_t)(NvDRSSessionHandle hSession, NvDR typedef NvAPI_Status (*NvAPI_DRS_SaveSettings_t)(NvDRSSessionHandle hSession); typedef NvAPI_Status (*NvAPI_DRS_DestroySession_t)(NvDRSSessionHandle hSession); typedef NvAPI_Status (*NvAPI_DRS_FindProfileByName_t)(NvDRSSessionHandle hSession, NvAPI_UnicodeString profileName, NvDRSProfileHandle* phProfile); +typedef NvAPI_Status (*NvAPI_DRS_FindApplicationByName_t)(NvDRSSessionHandle hSession, NvAPI_UnicodeString appName, NvDRSProfileHandle* phProfile, NVDRS_APPLICATION* pApplication); +typedef NvAPI_Status (*NvAPI_DRS_GetProfileInfo_t)(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile, NVDRS_PROFILE* pProfileInfo); typedef NvAPI_Status (*NvAPI_GetErrorMessage_t)(NvAPI_Status nr,NvAPI_ShortString szDesc); // nvapi.dll internal function pointers @@ -305,6 +317,7 @@ NvAPI_Initialize_t NvAPI_Initialize = NULL; NvAPI_EnumPhysicalGPUs_t NvAPI_EnumPhysicalGPUs = NULL; NvAPI_GPU_GetUsages_t NvAPI_GPU_GetUsages = NULL; NvAPI_DRS_CreateProfile_t NvAPI_DRS_CreateProfile = NULL; +NvAPI_DRS_DeleteProfile_t NvAPI_DRS_DeleteProfile = NULL; NvAPI_DRS_CreateSession_t NvAPI_DRS_CreateSession = NULL; NvAPI_DRS_LoadSettings_t NvAPI_DRS_LoadSettings = NULL; NvAPI_DRS_CreateApplication_t NvAPI_DRS_CreateApplication = NULL; @@ -312,6 +325,8 @@ NvAPI_DRS_SetSetting_t NvAPI_DRS_SetSetting = NULL; NvAPI_DRS_SaveSettings_t NvAPI_DRS_SaveSettings = NULL; NvAPI_DRS_DestroySession_t NvAPI_DRS_DestroySession = NULL; NvAPI_DRS_FindProfileByName_t NvAPI_DRS_FindProfileByName = NULL; +NvAPI_DRS_FindApplicationByName_t NvAPI_DRS_FindApplicationByName = NULL; +NvAPI_DRS_GetProfileInfo_t NvAPI_DRS_GetProfileInfo = NULL; NvAPI_GetErrorMessage_t NvAPI_GetErrorMessage = NULL; } diff --git a/src/main.cpp b/src/main.cpp index f446b5cc7..e2682ece4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -112,7 +112,9 @@ int main(int argc, char *argv[]) #ifdef SFML_SYSTEM_WINDOWS // Detect an nvidia card and if it's found create an nvidia profile // for Attract Mode with optimizations - nvapi_init(); + if ( nvapi_init() > 0 ) + FeLog() << "Nvidia GPU detected. Attract Mode profile was not found so it has been created.\n" + << "In order for the changes to take effect, please restart Attract Mode\n" << std::endl; FeDebug() << std::endl; #endif