Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed regression in video rendering framerates on Nvidia #552

Merged
merged 1 commit into from
Mar 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 75 additions & 22 deletions extlibs/nvapi/nvapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ));
Expand All @@ -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;
}
Expand All @@ -64,38 +66,68 @@ 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);
NvAPI_DRS_SetSetting = (NvAPI_DRS_SetSetting_t) (*NvAPI_QueryInterface)(0x577DD202);
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;
NvAPI_Status status;

// 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 );

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 );

Expand All @@ -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 )
Expand Down Expand Up @@ -145,23 +170,51 @@ namespace {
}

// Set Triple Buffering
if ( enableTripleBuffering )
if ( disableTripleBuffering )
{
setting.version = NVDRS_SETTING_VER;
setting.settingId = OGL_TRIPLE_BUFFER_ID;
setting.settingType = NVDRS_DWORD_TYPE;
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;
Expand All @@ -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;
}
}
19 changes: 17 additions & 2 deletions extlibs/nvapi/nvapi_definitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -290,13 +299,16 @@ 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);
typedef NvAPI_Status (*NvAPI_DRS_SetSetting_t)(NvDRSSessionHandle hSession, NvDRSProfileHandle hProfile, NVDRS_SETTING *pSetting);
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
Expand All @@ -305,13 +317,16 @@ 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;
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;

}
4 changes: 3 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down