MAINT-1841 Use NVAPI to force NVIDIA GPU power management mode to prefer max performance

Reviewed by Simon.
master
Dave Parks 2012-11-19 17:40:43 -06:00
parent a1d60fc219
commit 7491fbd677
4 changed files with 166 additions and 0 deletions

View File

@ -1463,6 +1463,30 @@
</map>
</map>
</map>
<key>nvapi</key>
<map>
<key>license</key>
<string>NVAPI</string>
<key>license_file</key>
<string>LICENSES/NVAPI_SDK_License_Agreement.pdf</string>
<key>name</key>
<string>nvapi</string>
<key>platforms</key>
<map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>baf519d36dffe4e4a59471450e391d01</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-nvapi/rev/267102/arch/CYGWIN/installer/nvapi-304-windows-20121116.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
</map>
</map>
<key>ogg-vorbis</key>
<map>
<key>license</key>

17
indra/cmake/NVAPI.cmake Normal file
View File

@ -0,0 +1,17 @@
# -*- cmake -*-
include(Prebuilt)
set(NVAPI ON CACHE BOOL "Use NVAPI.")
if (NVAPI)
use_prebuilt_binary(nvapi)
if (WINDOWS)
set(NVAPI_LIBRARY nvapi)
else (WINDOWS)
set(NVAPI_LIBRARY "")
endif (WINDOWS)
else (NVAPI)
set(NVAPI_LIBRARY "")
endif (NVAPI)

View File

@ -34,6 +34,7 @@ include(LLXML)
include(LScript)
include(Linking)
include(NDOF)
include(NVAPI)
include(GooglePerfTools)
include(TemplateCheck)
include(UI)
@ -1812,6 +1813,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLMATH_LIBRARIES}
${LLCOMMON_LIBRARIES}
${NDOF_LIBRARY}
${NVAPI_LIBRARY}
${HUNSPELL_LIBRARY}
${viewer_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}

View File

@ -46,6 +46,11 @@
#include "llviewercontrol.h"
#include "lldxhardware.h"
#include "nvapi/nvapi.h"
#include "nvapi/NvApiDriverSettings.h"
#include <stdlib.h>
#include "llweb.h"
#include "llsecondlifeurls.h"
@ -60,6 +65,7 @@
#include "llwindebug.h"
#endif
// *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib
// The lib was compiled under VS2005 - in VS2003 we need to remap assert
#ifdef LL_DEBUG
@ -75,6 +81,20 @@ extern "C" {
const std::string LLAppViewerWin32::sWindowClass = "Second Life";
/*
This function is used to print to the command line a text message
describing the nvapi error and quits
*/
void nvapi_error(NvAPI_Status status)
{
NvAPI_ShortString szDesc = {0};
NvAPI_GetErrorMessage(status, szDesc);
llwarns << szDesc << llendl;
//should always trigger when asserts are enabled
llassert(status == NVAPI_OK);
}
// Create app mutex creates a unique global windows object.
// If the object can be created it returns true, otherwise
// it returns false. The false result can be used to determine
@ -96,6 +116,79 @@ bool create_app_mutex()
return result;
}
void ll_nvapi_init(NvDRSSessionHandle hSession)
{
// (2) load all the system settings into the session
NvAPI_Status status = NvAPI_DRS_LoadSettings(hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
NvAPI_UnicodeString profile_name;
std::string app_name = LLTrans::getString("APP_NAME");
llutf16string w_app_name = utf8str_to_utf16str(app_name);
wsprintf(profile_name, L"%s", w_app_name.c_str());
status = NvAPI_DRS_SetCurrentGlobalProfile(hSession, profile_name);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
// (3) Obtain the current profile.
NvDRSProfileHandle hProfile = 0;
status = NvAPI_DRS_GetCurrentGlobalProfile(hSession, &hProfile);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
// load settings for querying
status = NvAPI_DRS_LoadSettings(hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
//get the preferred power management mode for Second Life
NVDRS_SETTING drsSetting = {0};
drsSetting.version = NVDRS_SETTING_VER;
status = NvAPI_DRS_GetSetting(hSession, hProfile, PREFERRED_PSTATE_ID, &drsSetting);
if (status == NVAPI_SETTING_NOT_FOUND)
{ //only override if the user hasn't specifically set this setting
// (4) Specify that we want the VSYNC disabled setting
// first we fill the NVDRS_SETTING struct, then we call the function
drsSetting.version = NVDRS_SETTING_VER;
drsSetting.settingId = PREFERRED_PSTATE_ID;
drsSetting.settingType = NVDRS_DWORD_TYPE;
drsSetting.u32CurrentValue = PREFERRED_PSTATE_PREFER_MAX;
status = NvAPI_DRS_SetSetting(hSession, hProfile, &drsSetting);
if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
}
else if (status != NVAPI_OK)
{
nvapi_error(status);
return;
}
// (5) Now we apply (or save) our changes to the system
status = NvAPI_DRS_SaveSettings(hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
}
}
//#define DEBUGGING_SEH_FILTER 1
#if DEBUGGING_SEH_FILTER
# define WINMAIN DebuggingWinMain
@ -165,6 +258,27 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
return -1;
}
NvAPI_Status status;
// Initialize NVAPI
status = NvAPI_Initialize();
NvDRSSessionHandle hSession = 0;
if (status == NVAPI_OK)
{
// Create the session handle to access driver settings
status = NvAPI_DRS_CreateSession(&hSession);
if (status != NVAPI_OK)
{
nvapi_error(status);
}
else
{
//override driver setting as needed
ll_nvapi_init(hSession);
}
}
// Have to wait until after logging is initialized to display LFH info
if (num_heaps > 0)
{
@ -232,6 +346,15 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
LLAppViewer::sUpdaterInfo = NULL ;
}
// (NVAPI) (6) We clean up. This is analogous to doing a free()
if (hSession)
{
NvAPI_DRS_DestroySession(hSession);
hSession = 0;
}
return 0;
}