Programmatically determine if system has switchable graphics

848 Views Asked by At

We are struggling with the following problem on laptops with switchable graphics (AMD Radeon 7670M + Intel 4000) in our WPF application:

The D3DImage we use to display some video only shows a black frame. This only happens when the discrete graphics (AMD) is active for the application (mode set to high performance). With the Intel graphics active (mode set to power saving) it works. It looks like we are not alone with this issue. A search on google revealed the following posts in the AMD forums:

I have found a workaround using D3DImage.CopyBackBuffer - it looks like the backbuffer does indeed contain the right frame - so I will try to display that instead.

But in order to only apply this workaround when it is necessary, this brings me to the subject of this question: How do I find out if the system actually has switchable graphics?
I suppose there might be some ways using WMI or looking through the registry, but I would be so glad if someone could point me in the right direction or might even have an example how to do so.

Update:

I have tried EnumDisplayDevices and System.Management.ManagementObjectSearcher. The first not returning all devices while the latter does. But perhaps there is still a better way?

3

There are 3 best solutions below

0
On

May be searching for driver name is another answer. But is not completely correct. Because it is possible to driver updated. So I prefer using using System.Management.ManagementObjectSearcher.

0
On

Combining this question and this one the solution would be to use System.Management like this:

internal class Program
{
    private static void Main(string[] args)
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
        var mos = searcher.Get();
        foreach (ManagementObject mo in mos)
        {
            foreach (PropertyData property in mo.Properties)
            {
                if (property.Name == "Description")
                {
                    Console.WriteLine(property.Value);
                }
            }
        }
        Console.ReadKey();
    }
}

My hardware is:

enter image description here

And the result is:

enter image description here

Since I have a not-really-hardware device called "DameWare Development Mirror" you can also look at VideoProcessor property. For NVidea and Intel they will have its value, for non-existing device there will be null.

if (property.Name == "Description")
   Console.WriteLine(property.Value);
if (property.Name == "VideoProcessor")
   Console.WriteLine(property.Value);

enter image description here

And to determine active videocard you can check if "CurrentBitsPerPixel" property has value

0
On

With some of luck you can use WMI queries to get that information with System.Management.ManagementObjectSearcher, but it could be very tighly coupled to Windows and drivers versions.

I think that your real problem is you are missing the key event when hardware device is lost and hardware related resources (surfaces and VRAM allocated memory) are dumped. Try subscribe to events like this https://msdn.microsoft.com/en-us/library/system.windows.interop.d3dimage.isfrontbufferavailablechanged.aspx in order to catch the switching and rebuild your hardware surfaces to the new graphics context.