NvDisplayHandle EnumNvidiaDisplayHandles(VOID) { NvPhysicalGpuHandle szGPUHandle[NVAPI_MAX_PHYSICAL_GPUS] = { 0 }; NvU32 gpuCount = 0; ULONG i = 0; NvStatus status = NvAPI_EnumPhysicalGPUs(szGPUHandle, &gpuCount); if (NV_SUCCESS(status)) { for (i = 0; i < gpuCount; i++) { NvDisplayHandle zero = 0; if (NV_SUCCESS(NvAPI_EnumNvidiaDisplayHandle(i, &zero))) { return zero; } } } else { LogEvent(L"gfxinfo: (EnumNvidiaDisplayHandles) NvAPI_EnumPhysicalGPUs failed (%s)", status); } return NULL; }
PStateNV::PStateNV(void) { NvAPI_Status status = NvAPI_Initialize(); if(status != NVAPI_OK) throw "NVAPI cannot be initialized!"; NvAPI_EnumPhysicalGPUs(m_hPhysicalGPU, &m_gpuCount); m_DynamicPStateInfo.version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER; m_nNumPState = 0; GetPStateInfo(); }
VOID NvGpuEnumPhysicalHandles(VOID) { NvU32 gpuCount = 0; NvPhysicalGpuHandle gpuHandles[NVAPI_MAX_PHYSICAL_GPUS]; memset(gpuHandles, 0, sizeof(gpuHandles)); if (NvAPI_EnumPhysicalGPUs && NvAPI_EnumPhysicalGPUs(gpuHandles, &gpuCount) == NVAPI_OK) { PhAddItemsList(NvGpuPhysicalHandleList, gpuHandles, gpuCount); } }
void MemoryMonitor::Init() { NvAPI_Status Status = NvAPI_Initialize(); assert(Status == NVAPI_OK); NvPhysicalGpuHandle NvGpuHandles[NVAPI_MAX_PHYSICAL_GPUS] = { 0 }; NvU32 NvGpuCount = 0; Status = NvAPI_EnumPhysicalGPUs(NvGpuHandles, &NvGpuCount); assert(Status == NVAPI_OK); assert(NvGpuCount != 0); m_GpuHandle = NvGpuHandles[0]; }
////////////////////////////////////////////////////////// // // NvOptimusDetect // // Try detecting optimus via NvAPI // ////////////////////////////////////////////////////////// bool NvOptimusDetect( void ) { if( NvAPI_Initialize() != NVAPI_OK ) { return false; } // Get and log driver info NvAPI_ShortString szDesc = "-"; NvU32 uiDriverVersion = -1; NvAPI_ShortString szBuildBranchString = "-"; NvAPI_GetInterfaceVersionString( szDesc ); NvAPI_SYS_GetDriverAndBranchVersion( &uiDriverVersion, szBuildBranchString ); WriteDebugEventAndReport( 7460, SString( "NvAPI - InterfaceVersion:'%s' DriverVersion:%d.%d Branch:'%s'", szDesc, uiDriverVersion / 100, uiDriverVersion % 100, szBuildBranchString ) ); // Get all the Physical GPU Handles NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS] = {0}; NvU32 uiGpuCount = 0; if( NvAPI_EnumPhysicalGPUs( nvGPUHandle, &uiGpuCount ) != NVAPI_OK ) { return false; } bool bFoundOptimus = false; for( NvU32 i = 0; i < uiGpuCount; i++ ) { NV_SYSTEM_TYPE SystemType = (NV_SYSTEM_TYPE)-1; // 1-Laptop 2-Desktop NV_GPU_TYPE GpuType = (NV_GPU_TYPE)-1; // 1-Integrated 2-Discrete NvAPI_ShortString szName = "-"; NvAPI_GPU_GetSystemType( nvGPUHandle[i], &SystemType ); NvAPI_GPU_GetGPUType( nvGPUHandle[i], &GpuType ); NvAPI_GPU_GetFullName( nvGPUHandle[i], szName ); SString strStatus( "NvAPI - GPU %d/%d - SystemType:%d GpuType:%d (%s)", i, uiGpuCount, SystemType, GpuType, szName ); if ( SystemType == NV_SYSTEM_TYPE_LAPTOP && GpuType == NV_SYSTEM_TYPE_DGPU ) { bFoundOptimus = true; strStatus += " FoundOptimus"; } WriteDebugEventAndReport( 7461, strStatus ); } return bFoundOptimus; }
CNvidia::CNvidia(void) { // NVAPI initialize NvAPI_Status nvResult = NVAPI_OK; nvResult = NvAPI_Initialize(); if (nvResult != NVAPI_OK) AfxMessageBox(_T("Error Initialize NVAPI.")); // Physical gpu enumeration nvResult = NvAPI_EnumPhysicalGPUs(&m_nvGPUHandle, &m_gpuCount); if (nvResult != NVAPI_OK) AfxMessageBox(_T("Error Get PhysicalGPU.")); // version m_settings.version = NV_GPU_THERMAL_SETTINGS_VER_1; m_clkFreqs.version = NV_GPU_CLOCK_FREQUENCIES_VER; m_clkFreqs.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ; }
NvPhysicalGpuHandle EnumNvidiaGpuHandles(VOID) { NvPhysicalGpuHandle szGPUHandle[NVAPI_MAX_PHYSICAL_GPUS] = { 0 }; NvU32 gpuCount = 0; ULONG i = 0; NvStatus status = NvAPI_EnumPhysicalGPUs(szGPUHandle, &gpuCount); if (NV_SUCCESS(status)) { for (i = 0; i < gpuCount; i++) { NvDisplayHandle zero = 0; if (NV_SUCCESS(NvAPI_EnumNvidiaDisplayHandle(i, &zero))) { NvU32 num3; NvPhysicalGpuHandle gpuHandles2[0x40]; if (NV_SUCCESS(NvAPI_GetPhysicalGPUsFromDisplay(zero, gpuHandles2, &num3))) { ULONG gpuCount2; for (gpuCount2 = 0; gpuCount2 < num3; gpuCount2++) { //if (!NVidiaGPUs.ContainsKey(gpuCount2)) // NVidiaGPUs.Add(gpuCount2, new NvidiaGPU(i, gpuHandles2[gpuCount2], zero)); return gpuHandles2[gpuCount2]; } } } } } else { LogEvent(L"gfxinfo: (EnumNvidiaGpuHandles) NvAPI_EnumPhysicalGPUs failed (%s)", status); } return szGPUHandle[0]; }
void NvidiaGPUService::ObtainGPUs() { NvPhysicalGpuHandle hPhysicalGpu[NVAPI_MAX_PHYSICAL_GPUS]; NvU32 physicalGpuCount = 0; NvAPI_Status ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu, &physicalGpuCount); m_GPUs.New(physicalGpuCount); for (NvU32 i = 0; i < physicalGpuCount; ++i) { m_GPUs[i].m_AvailableValues.Resize(9); for(auto j = 0; j < m_GPUs[i].m_AvailableValues.Count(); ++j) { m_GPUs[i].m_AvailableValues(j) = false; } m_GPUs[i].m_MaxValues.Resize(9); m_GPUs[i].m_MinValues.Resize(9); m_GPUs[i].m_Values.Resize(9); m_GPUs[i].m_AdapterId = hPhysicalGpu[i]; m_GPUs[i].m_AvailableValues(GPUService::FanSpeedPercentage) = false; m_GPUs[i].m_MaxValues(GPUService::FanSpeedPercentage) = 1; m_GPUs[i].m_MinValues(GPUService::FanSpeedPercentage) = 0; NvU32 tach = 0; if(NvAPI_GPU_GetTachReading(m_GPUs[i].m_AdapterId, &tach) == NVAPI_OK) { m_GPUs[i].m_AvailableValues(GPUService::FanSpeedRPM) = true; m_GPUs[i].m_MaxValues(GPUService::FanSpeedRPM) = 1; m_GPUs[i].m_MinValues(GPUService::FanSpeedRPM) = 0; } NV_GPU_THERMAL_SETTINGS thermal = {0}; thermal.version = NV_GPU_THERMAL_SETTINGS_VER; thermal.sensor[0].target = NVAPI_THERMAL_TARGET_GPU; thermal.sensor[0].controller = NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL; if(NvAPI_GPU_GetThermalSettings(m_GPUs[i].m_AdapterId, NVAPI_THERMAL_TARGET_NONE, &thermal) == NVAPI_OK) { m_GPUs[i].m_AvailableValues(GPUService::GPUTemperature) = true; m_GPUs[i].m_MaxValues(GPUService::GPUTemperature) = thermal.sensor[0].defaultMaxTemp; m_GPUs[i].m_MinValues(GPUService::GPUTemperature) = thermal.sensor[0].defaultMinTemp; } NvU32 lanes; if(NvAPI_GPU_GetCurrentPCIEDownstreamWidth(m_GPUs[i].m_AdapterId, &lanes) == NVAPI_OK) { m_GPUs[i].m_AvailableValues(GPUService::Lanes) = true; m_GPUs[i].m_MaxValues(GPUService::Lanes) = 16; m_GPUs[i].m_MinValues(GPUService::Lanes) = 0; m_GPUs[i].m_Values(GPUService::Lanes) = lanes; } NV_GPU_CLOCK_FREQUENCIES_V2 clkFreq = {0}; clkFreq.ClockType = NV_GPU_CLOCK_FREQUENCIES_CURRENT_FREQ; clkFreq.version = NV_GPU_CLOCK_FREQUENCIES_VER; if(NvAPI_GPU_GetAllClockFrequencies(m_GPUs[i].m_AdapterId, &clkFreq) == NVAPI_OK) { m_GPUs[i].m_AvailableValues(GPUService::MemoryClock) = clkFreq.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY].bIsPresent; m_GPUs[i].m_MaxValues(GPUService::MemoryClock) = 1; m_GPUs[i].m_MinValues(GPUService::MemoryClock) = 0; m_GPUs[i].m_AvailableValues(GPUService::CoreClock) = clkFreq.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS].bIsPresent; m_GPUs[i].m_MaxValues(GPUService::CoreClock) = 1; m_GPUs[i].m_MinValues(GPUService::CoreClock) = 0; } NV_GPU_DYNAMIC_PSTATES_INFO_EX states = {0}; states.version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER; if(NvAPI_GPU_GetDynamicPstatesInfoEx(m_GPUs[i].m_AdapterId, &states) == NVAPI_OK) { m_GPUs[i].m_AvailableValues(GPUService::GPUActivity) = states.utilization[0].bIsPresent; m_GPUs[i].m_MaxValues(GPUService::GPUActivity) = 1; m_GPUs[i].m_MinValues(GPUService::GPUActivity) = 0; } m_GPUs[i].m_AvailableValues(GPUService::BusSpeed) = false; m_GPUs[i].m_MaxValues(GPUService::BusSpeed) = 1; m_GPUs[i].m_MinValues(GPUService::BusSpeed) = 0; } }
HRESULT CGPUUsage::Init(CString DeviceName) { Clean(); { // ATI OverDrive ATIData.hAtiADL = LoadLibrary(L"atiadlxx.dll"); if (ATIData.hAtiADL == NULL) { ATIData.hAtiADL = LoadLibrary(L"atiadlxy.dll"); } if (ATIData.hAtiADL) { ADL_MAIN_CONTROL_CREATE ADL_Main_Control_Create; ADL_ADAPTER_NUMBEROFADAPTERS_GET ADL_Adapter_NumberOfAdapters_Get; ADL_ADAPTER_ADAPTERINFO_GET ADL_Adapter_AdapterInfo_Get; ADL_ADAPTER_ACTIVE_GET ADL_Adapter_Active_Get; ADL_OVERDRIVE_CAPS ADL_Overdrive_Caps; ADL_Main_Control_Create = (ADL_MAIN_CONTROL_CREATE)GetProcAddress(ATIData.hAtiADL,"ADL_Main_Control_Create"); ATIData.ADL_Main_Control_Destroy = (ADL_MAIN_CONTROL_DESTROY)GetProcAddress(ATIData.hAtiADL,"ADL_Main_Control_Destroy"); ADL_Adapter_NumberOfAdapters_Get = (ADL_ADAPTER_NUMBEROFADAPTERS_GET)GetProcAddress(ATIData.hAtiADL,"ADL_Adapter_NumberOfAdapters_Get"); ADL_Adapter_AdapterInfo_Get = (ADL_ADAPTER_ADAPTERINFO_GET)GetProcAddress(ATIData.hAtiADL,"ADL_Adapter_AdapterInfo_Get"); ADL_Adapter_Active_Get = (ADL_ADAPTER_ACTIVE_GET)GetProcAddress(ATIData.hAtiADL, "ADL_Adapter_Active_Get"); ADL_Overdrive_Caps = (ADL_OVERDRIVE_CAPS)GetProcAddress(ATIData.hAtiADL, "ADL_Overdrive_Caps"); if (NULL == ADL_Main_Control_Create || NULL == ATIData.ADL_Main_Control_Destroy || NULL == ADL_Adapter_NumberOfAdapters_Get || NULL == ADL_Adapter_AdapterInfo_Get || NULL == ADL_Adapter_Active_Get || NULL == ADL_Overdrive_Caps) { Clean(); } if (ATIData.hAtiADL) { int iNumberAdapters = 0; if (ADL_OK == ADL_Main_Control_Create(ADL_Main_Memory_Alloc, 1) && ADL_OK == ADL_Adapter_NumberOfAdapters_Get(&iNumberAdapters) && iNumberAdapters) { LPAdapterInfo lpAdapterInfo = DNew AdapterInfo[iNumberAdapters]; if (lpAdapterInfo) { memset(lpAdapterInfo, 0, sizeof(AdapterInfo) * iNumberAdapters); // Get the AdapterInfo structure for all adapters in the system ADL_Adapter_AdapterInfo_Get(lpAdapterInfo, sizeof(AdapterInfo) * iNumberAdapters); for (int i = 0; i < iNumberAdapters; i++ ) { int adapterActive = 0; AdapterInfo adapterInfo = lpAdapterInfo[i]; ADL_Adapter_Active_Get(adapterInfo.iAdapterIndex, &adapterActive); if (adapterActive && adapterInfo.iAdapterIndex >= 0 && adapterInfo.iVendorID == 1002) { if (DeviceName.GetLength() && DeviceName != CString(adapterInfo.strDisplayName)) { continue; } int iOverdriveSupported = 0; int iOverdriveEnabled = 0; if (ADL_OK != ADL_Overdrive_Caps(adapterInfo.iAdapterIndex, &iOverdriveSupported, &iOverdriveEnabled, &ATIData.iOverdriveVersion) || !iOverdriveSupported) { break; } if (ATIData.iOverdriveVersion == 5) { ADL_OVERDRIVE5_ODPARAMETERS_GET ADL_Overdrive5_ODParameters_Get; ADL_Overdrive5_ODParameters_Get = (ADL_OVERDRIVE5_ODPARAMETERS_GET)GetProcAddress(ATIData.hAtiADL, "ADL_Overdrive5_ODParameters_Get"); ATIData.ADL_Overdrive5_CurrentActivity_Get = (ADL_OVERDRIVE5_CURRENTACTIVITY_GET)GetProcAddress(ATIData.hAtiADL, "ADL_Overdrive5_CurrentActivity_Get"); if (NULL == ADL_Overdrive5_ODParameters_Get || NULL == ATIData.ADL_Overdrive5_CurrentActivity_Get) { break; } ADLODParameters overdriveParameters = {0}; overdriveParameters.iSize = sizeof (ADLODParameters); if (ADL_OK != ADL_Overdrive5_ODParameters_Get(adapterInfo.iAdapterIndex, &overdriveParameters) || !overdriveParameters.iActivityReportingSupported) { break; } ATIData.iAdapterId = adapterInfo.iAdapterIndex; } else if (ATIData.iOverdriveVersion == 6) { ADL_OVERDRIVE6_CAPABILITIES_GET ADL_Overdrive6_Capabilities_Get; ADL_Overdrive6_Capabilities_Get = (ADL_OVERDRIVE6_CAPABILITIES_GET)GetProcAddress(ATIData.hAtiADL, "ADL_Overdrive6_Capabilities_Get"); ATIData.ADL_Overdrive6_CurrentStatus_Get = (ADL_OVERDRIVE6_CURRENTSTATUS_GET)GetProcAddress(ATIData.hAtiADL, "ADL_Overdrive6_CurrentStatus_Get"); if (NULL == ADL_Overdrive6_Capabilities_Get || NULL == ATIData.ADL_Overdrive6_CurrentStatus_Get) { break; } ADLOD6Capabilities od6Capabilities = {0}; if (ADL_OK != ADL_Overdrive6_Capabilities_Get(adapterInfo.iAdapterIndex, &od6Capabilities) || (od6Capabilities.iCapabilities & ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR) != ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR) { break; } ATIData.iAdapterId = adapterInfo.iAdapterIndex; } break; } } delete [] lpAdapterInfo; } } } } if (ATIData.iAdapterId == -1 && ATIData.hAtiADL) { Clean(); } if (ATIData.iAdapterId >= 0 && ATIData.hAtiADL) { m_GPUType = ATI_GPU; } } if (m_GPUType == UNKNOWN_GPU) { // NVApi NVData.hNVApi = LoadLibrary(L"nvapi64.dll"); if (NVData.hNVApi == NULL) { NVData.hNVApi = LoadLibrary(L"nvapi.dll"); } if (NVData.hNVApi) { NvAPI_QueryInterface_t NvAPI_QueryInterface = (NvAPI_QueryInterface_t)GetProcAddress(NVData.hNVApi, "nvapi_QueryInterface"); NvAPI_Initialize_t NvAPI_Initialize = NULL; NvAPI_EnumPhysicalGPUs_t NvAPI_EnumPhysicalGPUs = NULL; if (NvAPI_QueryInterface) { NvAPI_Initialize = (NvAPI_Initialize_t)(NvAPI_QueryInterface)(0x0150E828); NvAPI_EnumPhysicalGPUs = (NvAPI_EnumPhysicalGPUs_t)(NvAPI_QueryInterface)(0xE5AC921F); NVData.NvAPI_GPU_GetUsages = (NvAPI_GPU_GetUsages_t)(NvAPI_QueryInterface)(0x189A1FDF); } if (NULL == NvAPI_QueryInterface || NULL == NvAPI_Initialize || NULL == NvAPI_EnumPhysicalGPUs || NULL == NVData.NvAPI_GPU_GetUsages) { Clean(); } if (NVData.hNVApi) { NvAPI_Initialize(); int gpuCount = 0; NvAPI_EnumPhysicalGPUs(NVData.gpuHandles, &gpuCount); if (!gpuCount) { Clean(); } } } if (NVData.hNVApi && NVData.NvAPI_GPU_GetUsages) { m_GPUType = NVIDIA_GPU; } } return m_GPUType == UNKNOWN_GPU ? E_FAIL : S_OK; }
int main() { if (NvAPI_Initialize() != NVAPI_OK) throw std::runtime_error("NVIDIA Api not initialized"); if (NvAPI_DRS_CreateSession(&_session) != NVAPI_OK) throw std::runtime_error("can't create session"); if (NvAPI_DRS_LoadSettings(_session) != NVAPI_OK) throw std::runtime_error("can't load system settings"); if (NvAPI_DRS_GetCurrentGlobalProfile(_session, &_profile) != NVAPI_OK) throw std::runtime_error("can't get current global profile"); NvPhysicalGpuHandle nvGPUHandle[NVAPI_MAX_PHYSICAL_GPUS]; NvAPI_Status status; NvU32 GpuCount; NvU32 DeviceId; NvU32 SubSystemId; NvU32 RevisionId; NvU32 ExtDeviceId; NvU32 BusId; NvU32 BiosRevision; NvU32 BiosRevisionOEM; NV_BOARD_INFO BoardInfo; BoardInfo.version = NV_BOARD_INFO_VER; NvU32 ConfiguredFeatureMask; NvU32 ConsistentFeatureMask; NvU32 CoreCount; NvAPI_EnumPhysicalGPUs(nvGPUHandle, &GpuCount); NvAPI_ShortString str; NvAPI_GPU_GetFullName(nvGPUHandle[0], str); NvAPI_GPU_GetPCIIdentifiers(nvGPUHandle[0], &DeviceId, &SubSystemId, &RevisionId, &ExtDeviceId); NvAPI_GPU_GetBusId(nvGPUHandle[0], &BusId); NvAPI_GPU_GetVbiosRevision(nvGPUHandle[0], &BiosRevision); NvAPI_GPU_GetVbiosOEMRevision(nvGPUHandle[0], &BiosRevisionOEM); NvAPI_GPU_GetVbiosVersionString(nvGPUHandle[0], str); status = NvAPI_GPU_GetBoardInfo(nvGPUHandle[0], &BoardInfo); status = NvAPI_GPU_WorkstationFeatureQuery(nvGPUHandle[0], &ConfiguredFeatureMask, &ConsistentFeatureMask); status = NvAPI_GPU_GetGpuCoreCount(nvGPUHandle[0], &CoreCount); NV_CHIPSET_INFO info; info.version = NV_CHIPSET_INFO_VER_4; status =NvAPI_SYS_GetChipSetInfo(&info); NvAPI_GetInterfaceVersionString(str); unsigned int test= (unsigned int) -0x68; unsigned int index = 0; while ((status = NvAPI_DRS_EnumProfiles(_session, index, &_profile)) == NVAPI_OK) { _profInfo.version = NVDRS_PROFILE_VER; if (NvAPI_DRS_GetProfileInfo(_session, _profile, &_profInfo) != NVAPI_OK) throw std::runtime_error("can't get current global profile info"); index++; } EnumerateProfilesOnSystem(); NvAPI_DRS_DestroySession(_session); return 0; }
// This function actually sets the possible display configurations on the multi-monitor setup NvAPI_Status SetMode(void) { NvU32 totalTargets = 0; NvAPI_Status ret = NVAPI_OK; NvU32 DisplayID = 0; NvU32 pathCount = 0; NV_DISPLAYCONFIG_PATH_INFO *pathInfo = NULL; NvDisplayHandle *pNvDispHandle = NULL; //Retrieve the display path information ShowCurrentDisplayConfig(); ret = AllocateAndGetDisplayConfig(&pathCount, &pathInfo); if (ret != NVAPI_OK) return ret; if( pathCount == 1 ) { totalTargets += pathInfo[0].targetInfoCount; if(pathInfo[0].targetInfoCount > 1) DisplayID = pathInfo[0].targetInfo[1].displayId; // Store displayId to use later } else { for (NvU32 i = 0; i < pathCount; i++) { totalTargets += pathInfo[i].targetInfoCount; // Count all targets DisplayID = pathInfo[i].targetInfo[0].displayId; // Store displayId to use later } } // Activate and Set 2 targets in Clone mode; pathCount >= 1 and targetInfoCount > 1 if (totalTargets > 1) { printf("\nActivating clone mode display on system"); pathInfo[0].targetInfoCount = 2; NV_DISPLAYCONFIG_PATH_TARGET_INFO* primary = (NV_DISPLAYCONFIG_PATH_TARGET_INFO*) malloc(pathInfo[0].targetInfoCount * sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO)); printf("."); memset(primary, 0, pathInfo[0].targetInfoCount * sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO)); primary->displayId = pathInfo[0].targetInfo[0].displayId; printf("."); delete pathInfo[0].targetInfo; pathInfo[0].targetInfo = primary; pathInfo[0].targetInfo[1].displayId = DisplayID; pathInfo[0].sourceModeInfo[0].bGDIPrimary = 1; // Decide the primary display ret = NvAPI_DISP_SetDisplayConfig(1, pathInfo, 0); printf(".\n"); NvU32 tempPathCount = 0; NV_DISPLAYCONFIG_PATH_INFO *tempPathInfo = NULL; if (ret == NVAPI_OK) { //Validation of set ret = AllocateAndGetDisplayConfig(&tempPathCount, &tempPathInfo); if (ret != NVAPI_OK) { ret = NVAPI_ERROR; return ret; } else { (tempPathCount == 1 && pathInfo[0].targetInfoCount == tempPathInfo[0].targetInfoCount) ? ret = NVAPI_OK : ret = NVAPI_ERROR; } } if (ret != NVAPI_OK) return ret; printf("Clone mode set!\n"); printf("\nPress any key to continue..."); getchar(); } // Activate and Set 2 targets in Extended mode; pathCount > 1 and targetInfoCount = 1 if (totalTargets > 1) { printf("\nActivating extended mode display on system"); NV_DISPLAYCONFIG_PATH_INFO *pathInfo1 = NULL; NvU32 nDisplayIds = 0; NvU32 physicalGpuCount = 0; NV_GPU_DISPLAYIDS* pDisplayIds = NULL; NvPhysicalGpuHandle hPhysicalGpu[NVAPI_MAX_PHYSICAL_GPUS]; for (NvU32 i = 0; i<NVAPI_MAX_PHYSICAL_GPUS; i++) { hPhysicalGpu[i] = 0; } // Enumerate the physical GPU handle ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu, &physicalGpuCount); printf("."); // GPUs enumerated // get the display ids of connected displays NvU32 DisplayGpuIndex = 0; for(DisplayGpuIndex = 0; DisplayGpuIndex < physicalGpuCount; DisplayGpuIndex++) { ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[DisplayGpuIndex], pDisplayIds, &nDisplayIds, 0); if(nDisplayIds)break; else continue; } printf(".");//Located the GPU on which active display is present if ((ret == NVAPI_OK) && (nDisplayIds)) { pDisplayIds = (NV_GPU_DISPLAYIDS*)malloc(nDisplayIds * sizeof(NV_GPU_DISPLAYIDS)); if (pDisplayIds) { memset(pDisplayIds, 0, nDisplayIds * sizeof(NV_GPU_DISPLAYIDS)); pDisplayIds[0].version = NV_GPU_DISPLAYIDS_VER; ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[DisplayGpuIndex], pDisplayIds, &nDisplayIds, 0); } } pathInfo1 = (NV_DISPLAYCONFIG_PATH_INFO*) malloc(nDisplayIds * sizeof(NV_DISPLAYCONFIG_PATH_INFO)); if (!pathInfo1) { return NVAPI_OUT_OF_MEMORY; } memset(pathInfo1, 0, nDisplayIds * sizeof(NV_DISPLAYCONFIG_PATH_INFO)); for (NvU32 i = 0; i < nDisplayIds; i++) { pathInfo1[i].version = NV_DISPLAYCONFIG_PATH_INFO_VER; pathInfo1[i].targetInfoCount = 1; // extended mode pathInfo1[i].targetInfo = (NV_DISPLAYCONFIG_PATH_TARGET_INFO*) malloc(sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO)); memset(pathInfo1[i].targetInfo, 0,sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO)); pathInfo1[i].targetInfo->displayId = pDisplayIds[i].displayId; } ret = NvAPI_DISP_SetDisplayConfig(nDisplayIds, pathInfo1, 0); printf(".\n");//Display config set to extended mode NvU32 tempPathCount = 0; NV_DISPLAYCONFIG_PATH_INFO *tempPathInfo = NULL; if (ret == NVAPI_OK) { //Validation of set ret = AllocateAndGetDisplayConfig(&tempPathCount, &tempPathInfo); if (ret != NVAPI_OK) { ret = NVAPI_ERROR; } else { (tempPathCount == nDisplayIds) ? ret = NVAPI_OK : ret = NVAPI_ERROR; } } if (ret != NVAPI_OK) return ret; printf("Extended mode set!\n"); } return ret; }
// This function is used to display the current GPU configuration and the connected displays void ShowCurrentDisplayConfig(void) { NvAPI_Status ret = NVAPI_OK; NV_DISPLAYCONFIG_PATH_INFO *pathInfo = NULL; NvU32 pathCount = 0; NV_DISPLAYCONFIG_PATH_INFO *pathInfo1 = NULL; NvU32 nDisplayIds = 0; NvU32 physicalGpuCount = 0; NV_GPU_DISPLAYIDS* pDisplayIds = NULL; NvPhysicalGpuHandle hPhysicalGpu[NVAPI_MAX_PHYSICAL_GPUS]; for (NvU32 PhysicalGpuIndex = 0; PhysicalGpuIndex < NVAPI_MAX_PHYSICAL_GPUS; PhysicalGpuIndex++) { hPhysicalGpu[PhysicalGpuIndex]=0; } printf("\nThe currently running display configuration is as follows:\n"); for(NvU32 count = 0; count < 60; count++) printf("#"); printf("\nGPU index\tGPU ID\t\tDisplayIDs of displays\n"); // Enumerate the physical GPU handle ret = NvAPI_EnumPhysicalGPUs(hPhysicalGpu, &physicalGpuCount); if(ret != NVAPI_OK) { printf("Cannot enumerate GPUs in the system...\n"); getchar(); exit(1); } // get the display ids of connected displays NvU32 DisplayGpuIndex = 0; for(NvU32 GpuIndex = 0; GpuIndex < physicalGpuCount; GpuIndex++) { ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[GpuIndex], pDisplayIds, &nDisplayIds, 0); if((ret == NVAPI_OK) && nDisplayIds) { DisplayGpuIndex = GpuIndex; pDisplayIds = (NV_GPU_DISPLAYIDS*)malloc(nDisplayIds * sizeof(NV_GPU_DISPLAYIDS)); if (pDisplayIds) { memset(pDisplayIds, 0, nDisplayIds * sizeof(NV_GPU_DISPLAYIDS)); pDisplayIds[GpuIndex].version = NV_GPU_DISPLAYIDS_VER; ret = NvAPI_GPU_GetConnectedDisplayIds(hPhysicalGpu[DisplayGpuIndex], pDisplayIds, &nDisplayIds, 0); for(NvU32 DisplayIdIndex = 0; DisplayIdIndex < nDisplayIds; DisplayIdIndex++) { printf("%2d\t\t0x%x\t0x%x", GpuIndex, hPhysicalGpu[DisplayGpuIndex], pDisplayIds[DisplayIdIndex].displayId); if(!pDisplayIds[DisplayIdIndex].displayId)printf("(NONE)"); printf("\n"); } } } else printf("%2d\t\t0x%x\n", GpuIndex, hPhysicalGpu[GpuIndex]); } for(NvU32 count = 0; count < 60; count++)printf("#"); printf("\n"); ret = AllocateAndGetDisplayConfig(&pathCount, &pathInfo); if (ret != NVAPI_OK) { printf("AllocateAndGetDisplayConfig failed!\n"); getchar(); exit(1); } if( pathCount == 1 ) { if( pathInfo[0].targetInfoCount == 1 ) // if pathCount = 1 and targetInfoCount =1 it is Single Mode printf("Single MODE\n"); else if( pathInfo[0].targetInfoCount > 1) // if pathCount >= 1 and targetInfoCount >1 it is Clone Mode printf("Monitors in Clone MODE\n"); } else { for (NvU32 PathIndex = 0; PathIndex < pathCount; PathIndex++) { if(pathInfo[PathIndex].targetInfoCount == 1) { printf("Monitor with Display Id 0x%x is in Extended MODE\n",pathInfo[PathIndex].targetInfo->displayId); // if pathCount > 1 and targetInfoCount =1 it is Extended Mode } else if( pathInfo[PathIndex].targetInfoCount > 1) { for (NvU32 TargetIndex = 0; TargetIndex < pathInfo[PathIndex].targetInfoCount; TargetIndex++) { // if pathCount >= 1 and targetInfoCount > 1 it is Clone Mode printf("Monitors with Display Id 0x%x are in Clone MODE\n",pathInfo[PathIndex].targetInfo[TargetIndex].displayId); } } } } }