c++nvapi

How to use NvAPI_DISP_GetDisplayConfig?


When using the NVAPI I'm having problems with NvAPI_DISP_GetDisplayConfig. I get an AppCrash on the second call to NvAPI_DISP_GetDisplayConfig. Can't seem to figure out why.

NvU32 count = 0;
status = NvAPI_DISP_GetDisplayConfig(&count, NULL);
if (status != NVAPI_OK) 
    PrintError(status);
printf("Configs: %i\n", count);
NV_DISPLAYCONFIG_PATH_INFO *configinfos = new NV_DISPLAYCONFIG_PATH_INFO[count];
configinfos[0].version = NV_DISPLAYCONFIG_PATH_INFO_VER;
status = NvAPI_DISP_GetDisplayConfig(&count, configinfos);
if (status != NVAPI_OK) 
    PrintError(status);

On my system, count = 2 after the first call. The notes on NvAPI_DISP_GetDisplayConfig say:

NVAPI_INTERFACE NvAPI_DISP_GetDisplayConfig(
__inout NvU32 * pathInfoCount,
__out_ecount_full_opt *pathInfoCount NV_DISPLAYCONFIG_PATH_INFO * pathInfo
)

DESCRIPTION: This API lets caller retrieve the current global display
configuration.
USAGE: The caller might have to call this three times to fetch all the required
configuration details as follows:
First Pass: Caller should Call NvAPI_DISP_GetDisplayConfig() with pathInfo set
to NULL to fetch pathInfoCount.
Second Pass: Allocate memory for pathInfo with respect to the number of
pathInfoCount(from First Pass) to fetch //! //! targetInfoCount. If
sourceModeInfo is needed allocate memory or it can be initialized to NULL.
Third Pass(Optional, only required if target information is required): Allocate
memory for targetInfo with respect to number of
targetInfoCount(from Second Pass). SUPPORTED OS: Windows Vista and higher

Thanks.

Edit: I've also tried to set configinfos[0].sourceModeInfo = NULL to no avail. I've also tried to iterate over the array to set all .version and .sourceModeInfo to no avail (an example in the docs I saw only set version on the first item in the array)


Solution

  • This should work for you:

    NvAPI_Status status = NVAPI_OK;
    NvU32 deviceCount = 0;
    NV_DISPLAYCONFIG_PATH_INFO_V2 *  pathInfo = NULL;
    
    status = NvAPI_Initialize();
    if (status == NVAPI_OK) {
        status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
        if ((status == NVAPI_OK) && (deviceCount > 0)) {
            pathInfo = new NV_DISPLAYCONFIG_PATH_INFO_V2[deviceCount];
            for (int i = 0; i < deviceCount; i++)
            {
                pathInfo[i].targetInfo = 0;
                pathInfo[i].targetInfoCount = 0;
                pathInfo[i].version = NV_DISPLAYCONFIG_PATH_INFO_VER2;
                pathInfo[i].sourceModeInfo = 0;
                pathInfo[i].reserved = 0;
            }
    
            status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
    
            if (status == NVAPI_OK) {
                for (int i = 0; i < deviceCount; i++)
                {
                    pathInfo[i].sourceModeInfo = new NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1;
                    pathInfo[i].sourceModeInfo->reserved = 0;
                    pathInfo[i].targetInfo = new NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2[pathInfo[i].targetInfoCount];
                    for (int j = 0; j < pathInfo[i].targetInfoCount; j++) {
                        pathInfo[i].targetInfo[j].details = 0;
                    }
                }
            }
    
            status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
    
            for (int i = 0; i < deviceCount; i++)
            {
                if (pathInfo[i].sourceModeInfo) delete pathInfo[i].sourceModeInfo;
                if (pathInfo[i].targetInfo) delete [] pathInfo[i].targetInfo;
            }
            delete[] pathInfo;
        }
    }