locked
QueryDisplayConfig not returning source mode for iGPU monitor RRS feed

  • Question

  • On a desktop system that uses a dedicated and an integrated GPU, QueryDisplayConfig (QDC_DATABASE_CURRENT) often fails to return the source mode information for the monitor connected to the iGPU. Using extended desktop mode and having one monitor on the dGPU and one on the iGPU, only 3 modes are returned instead of the expected 4. DISPLAYCONFIG_PATH_SOURCE_INFO::modeInfoIdx and DISPLAYCONFIG_PATH_SOURCE_INFO::sourceModeInfoIdx are both set to 0xFFFFFFFF for the respective path that represents the monitor on the iGPU.

    How do I get the source mode of this monitor?

    Using an alternative API (EnumDisplayDevices, EnumDisplayMonitors) is not an option. They have different bugs for a small number of my users, like monitor names being swapped at random, which is unacceptable because I require consistent identification of monitors between system restarts.





    • Edited by Biohazard90 Tuesday, July 18, 2017 7:18 PM
    • Moved by Hart Wang Monday, July 24, 2017 9:19 AM
    Tuesday, July 18, 2017 3:13 PM

All replies

  • Hi,

    Thank you for posting here.

    The QueryDisplayConfig is returning every possible combination of source and target on my machine, even pairing monitors with sources they are not actually connected to.

    Here is a similar solution that use the GdiDeviceName, you could ChangeDisplaySettingsEx to make it the primary monitor.

    DisplayConfigGetDeviceInfo can get you the friendly name for a target too. If you scanned all the targets for one matching your attached display.

    I hope that the similar solution would be helpful.

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 19, 2017 3:02 AM
  • Hello Hart,

    Thank you so much for your prompt reply!

    My problem is actually that I would just like to list all active monitors and somehow identify them uniquely between system restarts or system sleep states. I don't need to enable or disable any monitors or generally change anything about the current configuration. Maybe my mistake was using QDC_DATABASE_CURRENT instead of QDC_ONLY_ACTIVE_PATHS, although I was already filtering for DISPLAYCONFIG_PATH_ACTIVE anyway.

    A few of my users have reported that QueryDisplayConfig (with QDC_DATABASE_CURRENT) does not return the source mode of the monitor from the iGPU even though it is active already. Using EnumDisplayMonitors in this case does work, however. I believe the affected users are all using Windows 10, so I have looked around and found the (undocumented?) flag QDC_VIRTUAL_MODE_AWARE which I am now using for Windows 10 and handle sourceModeInfoIdx accordingly. Although I don't have an understanding yet of what this virtual mode is about (virtual resolution perhaps?).

    Just for additional information:
    I would be happy with EnumDisplayMonitors, but yet another subset of my customers report their monitor names being swapped after sleeping or restarting this way (same when I use the GDI source name from QueryDisplayConfig). Checking Google, the issue of names being swapped seems to have been reported by other developers in the past, so likely EnumDisplayMonitors is not intended to be used with these expectations.

    Please let me know if there is anything else I could further clarify about my issue. I have also not been able to reproduce this problem on my own machine, but I presume I must be doing something wrong or missing something in my implementation.

    (Confusingly enough, some users reported the source mode containing the wrong position or size without QDC_VIRTUAL_MODE_AWARE. Which makes me think I am referencing the source mode incorrectly. Only one has reported back so far, but their issue got fixed when I added QDC_VIRTUAL_MODE_AWARE.)

    This is a condensed version of what I am currently doing:

    uint32 pathInfoCount = 0;
    uint32 modeInfoCount = 0;
    uint32 queryMode = IsWindows10OrGreater() ? QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE : QDC_ONLY_ACTIVE_PATHS;
    
    result = GetDisplayConfigBufferSizes(queryMode, &pathInfoCount, &modeInfoCount);
    
    if (result != ERROR_SUCCESS)
    {
    	return false;
    }
    
    pathInfoCount = MAX(1, pathInfoCount + 16);
    modeInfoCount = MAX(1, modeInfoCount + 16);
    
    DISPLAYCONFIG_PATH_INFO *pathInfo = new DISPLAYCONFIG_PATH_INFO[pathInfoCount];
    DISPLAYCONFIG_MODE_INFO *modeInfo = new DISPLAYCONFIG_MODE_INFO[modeInfoCount];
    
    result = QueryDisplayConfig(queryMode, &pathInfoCount, pathInfo, &modeInfoCount, modeInfo, nullptr);
    
    if (result != ERROR_SUCCESS)
    {
    	delete[] pathInfo;
    	delete[] modeInfo;
    	return false;
    }
    
    unordered_set<uint32> knownSourceIndices;
    
    for (int p = 0; p < pathInfoCount; ++p)
    {
    	DISPLAYCONFIG_PATH_INFO &path = pathInfo[p];
    	if ((path.flags & DISPLAYCONFIG_PATH_ACTIVE) == 0)
    	{
    		continue;
    	}
    
    	DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceDeviceName;
    	sourceDeviceName.header.adapterId = path.sourceInfo.adapterId;
    	sourceDeviceName.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME);
    	sourceDeviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
    	sourceDeviceName.header.id = path.sourceInfo.id;
    
    	result = DisplayConfigGetDeviceInfo((DISPLAYCONFIG_DEVICE_INFO_HEADER*) &sourceDeviceName);
    	if (result != ERROR_SUCCESS)
    	{
    		continue;
    	}
    
    	DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName;
    	deviceName.header.adapterId = path.targetInfo.adapterId;
    	deviceName.header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
    	deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
    	deviceName.header.id = path.targetInfo.id;
    
    	result = DisplayConfigGetDeviceInfo((DISPLAYCONFIG_DEVICE_INFO_HEADER*) &deviceName);
    	if (result != ERROR_SUCCESS)
    	{
    		*deviceName.monitorDevicePath = 0;
    		*deviceName.monitorFriendlyDeviceName = 0;
    	}
    
    	const bool usingVirtualMode = (path.flags & DISPLAYCONFIG_PATH_SUPPORT_VIRTUAL_MODE) != 0;
    	const uint32 sourceModeIndex = usingVirtualMode ? path.sourceInfo.sourceModeInfoIdx : path.sourceInfo.modeInfoIdx;
    
    	if (usingVirtualMode ?
    		path.sourceInfo.sourceModeInfoIdx == DISPLAYCONFIG_PATH_SOURCE_MODE_IDX_INVALID :
    		path.sourceInfo.modeInfoIdx == DISPLAYCONFIG_PATH_MODE_IDX_INVALID)
    	{
    		continue;
    	}
    
    	// Ignore cloned sources
    	if (knownSourceIndices.find(sourceModeIndex) != knownSourceIndices.end())
    	{
    		continue;
    	}
    	knownSourceIndices.insert(sourceModeIndex);
    
    	MonitorInfo::Monitor monitor;
    	monitor.friendlyName = UTF8CONVERT().to_bytes(deviceName.monitorFriendlyDeviceName);
    	monitor.deviceName = UTF8CONVERT().to_bytes(sourceDeviceName.viewGdiDeviceName);
    
    	const DISPLAYCONFIG_SOURCE_MODE &srcMode = modeInfo[sourceModeIndex].sourceMode;
    	const DISPLAYCONFIG_ROTATION rotation = path.targetInfo.rotation;
    
    	if (rotation == DISPLAYCONFIG_ROTATION_IDENTITY || rotation == DISPLAYCONFIG_ROTATION_ROTATE180)
    	{
    		monitor.w = srcMode.width;
    		monitor.h = srcMode.height;
    	}
    	else
    	{
    		monitor.w = srcMode.height;
    		monitor.h = srcMode.width;
    	}
    
    	monitor.x = srcMode.position.x;
    	monitor.y = srcMode.position.y;
    
    	RECT monitorRect;
    	monitorRect.left = monitor.x;
    	monitorRect.right = monitor.x + monitor.w;
    	monitorRect.top = monitor.y;
    	monitorRect.bottom = monitor.y + monitor.h;
    	monitor.handle = MonitorFromRect(&monitorRect, MONITOR_DEFAULTTONEAREST);
    
    	if (monitor.handle == nullptr)
    	{
    		continue;
    	}
    	data.monitors->push_back(monitor);
    }
    
    delete[] pathInfo;
    delete[] modeInfo;




    • Edited by Biohazard90 Wednesday, July 19, 2017 5:36 PM
    Wednesday, July 19, 2017 5:31 PM
  • Hi,

    Thank you for your feedback.

    Based on my search, i think that your issue is related to Intel programming, you could post the issue on here.

    Since your issue is related to GPU model. the current forum just discuss about general development software on desktop. 

    i will move the case to off-topic forum.

    Best Regards,

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, July 21, 2017 8:11 AM