Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Biggles

Help with Device Enumeration

This topic is 6081 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Does anyone know of any tutorials available that explain finding out which devices are available on a system and what modes and stuff they support? I think that it''s called Device Enumeration but I''m not sure. I''ve tried going through the code in the d3dapp.cpp file and I understand some of it, but there is much that I don''t understand, especially about multiple devices, etc. If there arn''t any tutorials, could someone explain the concept here please? -------------------- Never eat anything bigger than your own head.

Share this post


Link to post
Share on other sites
Advertisement
Sorry to Biggles if you''ve got e-mail notification of a reply and come here hoping for an answer, but I''d just like to say that I''m curious about this too. Most D3D tutorials don''t go into device enumeration too much and I''ve yet to find a decent book that explains it properly.

RM.



Tron Software

-=Kicking Butt and Writing Code=-

Share this post


Link to post
Share on other sites
I must have missed that when I did my search. It''s quite a good article, but some of the function calls and methods for doing things appear to have changed between 7 and 8. Does anyone know of a similar article based on DirectX 8?


--------------------

Never eat anything bigger than your own head.

Share this post


Link to post
Share on other sites
I find that the DirectX SDK help file is very adequate for this. It provides complete descriptions of the necessary functions, structures and expected behaviors. I'll post some code that I wrote just from dealing with it (I ripped it out of my own code and cleaned it up a little so it's easier to understand):

    
// Direct3D8 "Device Enumeration"

static LPDIRECT3D8 lp_D3D = NULL;
static LPDIRECT3DDEVICE8 lp_D3DDevice = NULL;
static unsigned int s_nAdapters;
//...

static vector<string> s_vecDeviceNames;
static vector<string> s_vecDriverNames;
static vector<int> s_vecAdapterModes;
//...

s_nAdapters = lp_D3D->GetAdapterCount();
//...

for(int n = 0; n < s_nAdapters; ++n)
{
D3DADAPTER_IDENTIFIER8 id;
lp_D3D->GetAdapterIdentifier(n, D3DENUM_NO_WHQL_LEVEL, &id);
s_vecDeviceNames.push_back(id.Description);
s_vecDriverNames.push_back(id.Driver);

s_vecAdapterModes.push_back(lp_D3D->GetAdapterModeCount(n));
}
//...

for(int n = 0; n < s_nAdapters; ++n)
{
cout << s_vecDeviceNames[n] << endl;
cout << s_vecDriverNames[n] << endl;
for(int m = 0; m < s_vecAdapterModes[n]; ++m)
{
lp_D3D->EnumAdapterModes(n, m, &d3ddm);
cout << d3ddm.Width << 'x'
<< d3ddm.Height << 'x'
<< d3ddm.Format << '@'
<< d3ddm.RefreshRate << endl;
}
}


  
// DirectInput Device Enumeration

static LPDIRECTINPUT8 lp_DI = NULL;
//...

static vector<string> s_vecDeviceNames;
static vector<DIDEVICEINSTANCE> s_vecDevices;
static vector<DIDEVICEOBJECTINSTANCE> s_vecDeviceObjects;
//...

HRESULT EnumDevices(DWORD dwDevType, DWORD dwFlags)
{
// currently I pass nothing to the callback

// I can pass data through the void *

int nDevice = 0;
return lp_DI->EnumDevices(dwDevType, EnumDevicesCallback,
(void *)&nDevice, dwFlags);
}
//...

BOOL CALLBACK EnumDevicesCallback(LPCDIDEVICEINSTANCE lpddi, void *pvRef)
{
s_vecDeviceNames.push_back(lpddi->tszProductName);
// just to show how the passed data can be used, I'll

// increment the passed integer

int i = (int)*pvRef;
++i;
return DIENUM_CONTINUE;
}


I hope you find that useful.
[Edit:] formatting.

Edited by - Oluseyi on November 18, 2001 1:34:03 PM

Share this post


Link to post
Share on other sites
Thanks, that''s very helpful. I know it sounds stupid, but where in the help files is the stuff about D3D enumeration? I looked around but couldn''t find anything, and when I tried doing a search I found lots for things like DirectPlay and Input, but nothing for D3D.

Share this post


Link to post
Share on other sites
If you think about it, you''re not really enumerating devices under D3D (which is why I wrote "device enumeration" in quotes). You query the interface for the number of available adaptors and then query those for their capabilities.

In the Contents panel:
DirectX 8.1 (I''ve migrated)
->DirectX Graphics
->Programmer''s Guide
->Using Direct3D
->About Devices
->Using Devices
->Determining Hardware Support
->Selecting a Device

Share this post


Link to post
Share on other sites
OK, the next thing I''m confused about is where to do this and where to store the info I get out. If I have a D3DDevice class, should I store the info in there? That makes sense to me since a d3ddevice should know what adapters, devices and modes it has available to it. Once I know where, when should it be done? I would assume it should be done before or while creating the device. And finally, how is the info used to select a good default adapter, and what is the best way to save the information needed to select a customised configuration in a config file so that it will load with the user''s preffered option the next time the game loads?


--------------------

Never eat anything bigger than your own head.

Share this post


Link to post
Share on other sites
In our (DX8) engine we have an array of D3DAdapterInfo structures. One for each graphics card found in the system. A direct cut & paste:

  
typedef struct
{
bool bValid; // is this device valid for Paradox use


UINT uiAdapterOrdinal; // required to create device under DX8

D3DADAPTER_IDENTIFIER8 identifier; // nice name and driver information

D3DCAPS8 caps; // capabilities of this device


long lRating; // how good is device (score can be -ve)


HMONITOR hMonitor; // which monitor is this connected to

UINT uiModeCount; // number of valid modes in the array

UINT uiDefaultMode; // initial default mode

UINT uiCurrentMode; // current mode for this screen

D3DDISPLAYMODE* modes; // list of usable modes for device


DWORD dwShaderVPUsage; // usage flags for shader vertex processing ops

DWORD dwFixedVPUsage; // usage flags for fixed vertex processing ops

DWORD dwCreationFlags; // flags for the creation of this adapter

}
D3DAdapterInfo;



Depending on the application we either automatically choose a device to start the application with (usually based on it''s rating field *). Or we bring up a dialog box where the user can choose which device and mode to use.

The selection which the user makes is best stored into the registry. The best location will be under HKEY_CURRENT_USER, *NOT* HKEY_LOCAL_MACHINE (remember the computer may have multiple users, each may want to play your game at different resolutions, on a different adapter etc. This is also the reason you shouldn''t just save the settings to a file).

A few hints about storing device selections to the registry:

a. Save the selection just before the application is about to exit, DON''T save it just after the selection has been made. If the setting someone chose crashed your game before it started, the settings won''t get saved so the user will be given the choice again (the correct way).

b. Always have a command line switch or some other method to ignore the settings in the registry and go back to the configuration screen. We do this by installing an extra shortcut which has a command line of -config.

c. When storing selections to the registry, also store some sort of check to see which devices are installed and how many there are (we take a checksum (CRC32) of all their device identifiers and store that), if the checksum doesn''t match what you enumerate at startup, you bring up the settings dialog. This way if the user installs a new graphics card, removes a graphics card, updates their drivers etc they get a new settings dialog.


* We work out a rating for each device when enumerating. Essentially we check all the device caps which affect our engine and add a score to the rating for them. Any caps which indicate problematic cards or functionality we have a negative score for (i.e. subtract from the rating). Other factors such as whether the driver is WHQL certified, which modes and texture formats are available etc are also taken into account. We use the rating to decide which adapter is chosed as default. In situations where there''s a tie, we pick the adapter with the lowest ordinal (since it''s likely to be the primary AGP adapter).
In an ideal world we''d also include some sort of runtime profiling of each device in the rating, but in practice the above seems ok in all the situations it''s been tested in).


--
Simon O''''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
I think I may be missing something in the heirarchy here. Correct me if I''m wrong, but is it:

Adapters -> (many) Devices -> (many) Display modes

So for each adapter you find out which devices it has, and for each device which compatible display modes it can run it? Then you let the user choose which adapter to use, which device on that adapter, and which display mode?


--------------------

Never eat anything bigger than your own head.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!