Getting GPU vendor ID

Started by
5 comments, last by IrYoKu1 10 years, 7 months ago

Hi,

I'm trying to use this code for getting the vendor ID:


    IDXGIDevice *dxgiDevice;
    V(device->QueryInterface(__uuidof(IDXGIDevice), (void **) &dxgiDevice));


    IDXGIAdapter *dxgiAdapter;
    V(dxgiDevice->GetAdapter(&dxgiAdapter));

    DXGI_ADAPTER_DESC adapterDesc;
    dxgiAdapter->GetDesc(&adapterDesc);

    SAFE_RELEASE(dxgiAdapter);
    SAFE_RELEASE(dxgiDevice);

    return adapterDesc.VendorId;
And is working well in most cases, but it's failing on my multi-GPU laptop. It always return the vendor ID of the integrated Intel GPU, even if the NVIDIA one is being currently used.
Someone knows where can be the problem?
Thanks!
Advertisement
According to MSDN there's IDXGIFactory::EnumAdapters to get a IDXGIAdapter for every graphics card you have.
I wouldn't waste time with tricks and experiments to initialize your device variable in a way that associates it with the graphic card you are interested in; it might turn out to be impossible or too inconvenient.

Omae Wa Mou Shindeiru

The problem is how I can tell which one is the one currently being used, when using EnumAdapters?

The code I posted came from this page:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb174526(v=vs.85).aspx

I wonder if it's a bug.

Probably isn't available, the driver takes care of that. I'm not sure exactly how that technology works, but I think that the NVidia GPU just renders the image and sends it to the Intel one for display, so from the application perspective it's always Intel. Probably the underlying GPU that renders your image can even change without recreating the adapter, if you pull the power coord and your laptop throttles down to save battery or whatever.

It seems you are right; in fact I think the way this is implemented is bogus.

I tried to get the first adapter available:


factory->EnumAdapters(0, &adapter)

Hoping it would always yield the GPU actually used. Doing it right in the beginning of the app worked out, but after DXUT initialization it was failing. I tracked down the problem and found this:


factory->EnumAdapters(0, &adapter); // Returns the adapter for the Intel card
D3D10CreateDevice(...); // Seems to be the first one in the app, when DXUT creates dummy devices for testing compatibility
factory->EnumAdapters(0, &adapter); // Returns the adapter for the NVIDIA card

So, doing it as I wrote in my first post (getting the adapter from the device) is not reliable, and trying to do in this other way (directly from first adapter ordinal) is also bogus. Unless this is done before device creation, you cannot rely on what you get from EnumAdapters.

You don't know what order the EnumAdapters results come out, but the results are valid and presumably repeatable for a given computer. What do you need the Nvidia IDXGIAdapter for? If it's for advanced capabilities, you can and should query whether they are available, classifying each adapter as "good enough", "not good enough" or "untested" for your purposes. If multiple adapters seem good enough, you can use the first one you find, ask the user, or apply heuristics (e.g Nvidia or AMD/ATI vendor over Intel vendor if and only if Windows power management reports "plugged in")

Omae Wa Mou Shindeiru

I think in general it should be repeatable, but in laptops with multi-GPUs this is hacked, and seems to be bogus (after creating a device, the adapter order changes).

I think what is happening under the hood is that the driver is exposing the selected GPU as first adapter; but somehow, after device creation this hacked order is being reverted (probably to the real one, putting the NVIDIA GPU first).

If I enum the adapters, I'll always only get only one; it seems the driver again hides the second one (in this particular case). I was searching for doing special things depending on the vendor, as some optimizations that improve things in some vendor, make things worse in others.

This topic is closed to new replies.

Advertisement