The adapter name

Started by Evil-Devil, July 21, 2006, 10:31:48

Previous topic - Next topic

Evil-Devil

Hi,
as of the getAdapter() method most time returns the graphics card driver name it should be changed. I don't know if this behavior is even on linux and mac os, but I allways want to know exactly which hardware the user is running without the need to create a OGL display first and asking OGL for the renderer.

So I looked through the ati and nvidia pages and found their DeviceID tools and the needed sourcecode. Its only code for windows, but on linux and mac os might exists familar functions. Or not?

Ok, here is the code which do the magic, I am sure you c/c++ gurus can do something with it, my c/c++ knowledge isn't that big.

ATI DeviceID
//-----------------------------------------------------------------------------
// File: DeviceID.cpp
// Copyright (c) 2006 ATI Technologies Inc. All rights reserved.
//-----------------------------------------------------------------------------



#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hThisIns, HINSTANCE hLastIns, LPSTR lpszCmdLine, int nCmdShow){
	char string[1024];

	DISPLAY_DEVICE dev;
	dev.cb = sizeof(DISPLAY_DEVICE);
	int i = 0;
	while (EnumDisplayDevices(NULL, i, &dev, 0)){
		if (dev.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE){
			char *str = string + sprintf(string, "%s\n\n", dev.DeviceString);

			char *vendorID = strstr(dev.DeviceID, "VEN_");
			char *deviceID = strstr(dev.DeviceID, "DEV_");

			char *st = dev.DeviceID;
			while ((st = strchr(st, '&')) != NULL){
				*st = '\0';
				st++;
			}

			if (vendorID) str += sprintf(str, "VendorID: 0x%s\n", vendorID + 4);
			if (deviceID) str += sprintf(str, "DeviceID: 0x%s\n", deviceID + 4);

			MessageBox(NULL, string, "Device", MB_OK | MB_ICONINFORMATION);
			return 0;
		}
		i++;
	}

	MessageBox(NULL, "No primary device found", "Error", MB_OK | MB_ICONERROR);
	return -1;
}


Nvidia DeviceID
// Example code to retrieve vendor and device ID's for the primary display
// device.
//
// NOTE: Visual Studio 6 does not ship with a winuser.h that defines the
//       EnumDisplayDevices function so in order to compile this code, you'll 
//       need to install the Platform SDK. 

#include <windows.h>

#include <string>
#include <iostream>

using namespace std;

bool GetDeviceIdentification(string &vendorID, string &deviceID)
{
    DISPLAY_DEVICE dd;
    dd.cb = sizeof(DISPLAY_DEVICE);

    int i = 0;
    string id;

    // locate primary display device
    while (EnumDisplayDevices(NULL, i, &dd, 0))
    {
        if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
        {
            id = dd.DeviceID;
            break;
        }

        i++;
    }

    if (id == "") return false;

    // get vendor ID
    vendorID = id.substr(8, 4);

    // get device ID
    deviceID = id.substr(17, 4);

    return true;
}

int main(void)
{
    string vendorID;
    string deviceID;

    if (GetDeviceIdentification(vendorID, deviceID))
    {
        cout << "Vendor ID: " << vendorID << endl;
        cout << "Device ID: " << deviceID << endl;
    }
    else
        cout << "Unable to locate device information" << endl;

    return 0;
}


Would be really cool if we could use it. Maybe in another method like "getDeviceID(),getVendorID()" or with a single method "getAdapterIDs()" that return a two dimensional array.

The Lists with the IDs for the deviced where available from the vendor pages.

ATI Vendor ID List
NVidia Vendor ID List

Evil

Matzon

why do you need the info before creation? - bug reports ?

Evil-Devil

Quote from: "Matzon"why do you need the info before creation? - bug reports ?
Yea and because I know enough people who like to setup some settings before they start the game. And some people aren't sure about what card they really have. Thus plus info would be a great deal :)

BTW: The creation of the wiki layout is doing well. It might be finished next month. I will pm you, when I am finsihed with it.

spasi

I would create a headless context (a simple pbuffer), grab whatever info I need and immediately destroy it.

There's no need for the (probably not robust/cross-platform) solution you're suggesting. To identify the GPU vendor or even its specific generation (e.g. is it an NV30 or an NV40? an R300 or an R520?) is far simpler and safer using extension availability from the pbuffer's context.

Evil-Devil

And which extension should be used for that way? By using glGetString(GL_RENDERER) it returns for my graphics card "Radeon 9600XT, MMX, 3DNow" and some other buzz words

spasi

Based on the availability of certain extensions you can assert which GPU you have. Some examples:

NV_register_combiners
    NVIDIA GeForce+ (NV10)
NV10 && NV_register_combiners2
    NVIDIA GeForce 3+ (NV20)
NV20 && NV_fragment_program
    NVIDIA GeForce FX+ (NV30)
NV30 && NV_fragment_program2
    NVIDIA GeForce 6+ (NV40)
(afaik, there's not yet an extension to identify a GeForce 7)

ATI_fragment_shader
    ATI 8500+ (R200)
R200 && ARB_fragment_program
    ATI 9500+ (R300)
R300 && ATI_texture_compression_3dc
    ATI Xx00+ (R420)
R420 && ATI_shader_texture_lod
    ATI 1x00+ (R520)