Enumerating Your System s Adapters

Enumerating Your System's Adapters

Many systems today can support multiple monitors per machine. While it hasn't quite hit the "mainstream," having multiple monitors (multimon for short) can be quite useful, and is rapidly becoming more popular. With the higher-end graphics card supporting multimon natively, you can expect this feature to be used more exclusively. The latest cards from ATI, nVidia, and Matrox all have dual head support, which can allow multiple monitors to be attached to a single graphics card.

Direct3D devices are specified per adapter. In this case, you can think of an "adapter" as the actual graphics hardware that connects to the monitor. While the ATI Radeon 9700 is only one "physical" adapter, it has two monitor hookups (DVI and VGA), and thus has two adapters in Direct3D. You may not know which, or even how many, devices are on a system your game will be running on, so how can you detect them and pick the right one?

There is a static class in the Direct3D assemblies called "Manager" that can easily be used to enumerate adapters and device information, as well as retrieving the capabilities of the devices available on the system.

The very first property in the Manager class is the list of adapters in your system. This property can be used in multiple ways. It stores a "count" member that will tell you the total number of adapters on the system. Each adapter can be indexed directly (for example, Manager.Adapters[0]), and it can also be used to enumerate through each of the adapters on your system.

To demonstrate these features, a simple application will be written that will create a tree view of the current adapters on your system and the supported display modes that adapter can use. Load Visual Studio and follow these steps:

  1. Create a new C# Windows Forms Project. You can name it anything you want; the sample code provided was named "Enumeration".

  2. Add a reference to the Microsoft.DirectX.Direct3D and Microsoft.DirectX assemblies. Add using clauses for these assemblies as well.

  3. In design view for the created windows form, add a TreeView control to your application. You will find the TreeView control in the toolbox.

  4. Select the TreeView control on your form, and hit the F4 key (or right-click and choose Properties). In the properties of your TreeView, set the "Dock" parameter to "Fill". This will cause your TreeView to always fill up the entire window, even if it is resized.

Now, you should add a function that will scan through every adapter on the system, and provide a little information on the modes each one can support. The following function will do this work, so add it somewhere in your class:

 /// <summary> /// We will fill our tree view here /// </summary> public void LoadGraphics() {     foreach(AdapterInformation ai in Manager.Adapters)     {         TreeNode root = new TreeNode(ai.Information.Description);         TreeNode driverInfo = new TreeNode(string.Format             ("Driver information: {0} - {1}",             ai.Information.DriverName,             ai.Information.DriverVersion) );         // Add the driver information to the root node         root.Nodes.Add(driverInfo);         // Get each display mode supported         TreeNode displayMode = new TreeNode(string.Format             ("Current Display Mode: {0}x{1}x{2}",             ai.CurrentDisplayMode.Width,             ai.CurrentDisplayMode.Height,             ai.CurrentDisplayMode.Format));         foreach(DisplayMode dm in ai.SupportedDisplayModes)         {             TreeNode supportedNode = new TreeNode(string.Format                 ("Supported: {0}x{1}x{2}",                 dm.Width, dm.Height, dm.Format));             displayMode.Nodes.Add(supportedNode);         }         // Add the display modes         root.Nodes.Add(displayMode);         // Add the root node         treeView1.Nodes.Add(root);     } } 

While this may look like quite a bit of code, in reality what it's doing is quite simple. We can break it down to see exactly what's going on. First, we begin our enumeration of the adapters in the system. The foreach mechanism used in C# makes this loop amazingly simple. For each adapter in the system, this loop will run one time, and fill out the AdapterInformation structure for the given adapter.

Looking at the AdapterInformation structure itself, you will see that it has several members:

 public struct AdapterInformation { int Adapter; DisplayMode CurrentDisplayMode; AdapterDetails Information; AdapterDetails GetWhqlInformation(); DisplayModeEnumerator SupportedDisplayModes; } 

The adapter member refers to the adapter ordinal that you use when creating the device. The ordinal will be a zero-based index with the number of ordinals being equal to the number of adapters in your system. The two members of this structure that return AdapterDetails structures both return identical results, with one exception. In the "Information" member, Windows Hardware Quality Labs (WHQL) information isn't returned with the details, while it is in the GetWhqlInformation function. Retrieving this information can be quite expensive and take some time, thus the need to separate it out.

The AdapterDetails structure contains much information about the adapter itself, including its description and driver information. Applications can use this structure to make decisions based on certain hardware types, although this shouldn't ever be necessary.

The last two members of this structure return DisplayMode structures. These structures can be used to determine various types of display modes, and include the width and height of the display mode, as well as the refresh rate and the format being used. The CurrentDisplayMode member will return the information about the display mode currently in use on the adapter, while the SupportedDisplayModes will return a list of all of the display modes supported by this adapter.

So, we use the description of the device retrieved by the Information property to form our root node in our tree view. We then add a node that will contain the driver name and version number (also retrieved from the Information property) as a child of this root node. We also add a child containing the current display mode properties for the adapter.

We then add child nodes for every supported display mode for this adapter under the current display mode. Now, we just need to call this function during application startup, and we can run it. Modify the main function as follows:

 using (Form1 frm = new Form1()) {     frm.LoadGraphics();     Application.Run(frm); } 

When running this application, you should see a window much like you see in Figure 2.1.

Figure 2.1. A treeview of adapter modes.

graphics/02fig01.gif

As you can see, this list contains a list of formats supported by the device. These formats can be used as a valid back buffer format when filling out your present parameter's structure. The format enumeration follows a pattern when naming the various formats supported. The pattern is a single letter followed by a number. The letter represents the type of data; the number is the number of bits of data being held. Some of the letters can be as follows:

  • A alpha

  • X unused

  • R red

  • G green

  • B blue

  • L luminance

  • P palette

The total sum of all the bits in the format determines the total size of the format. For example, a format that is X8R8G8B8 (as listed in Figure 2.1) would be a 32-bit format with 8 bits used in each red, green, and blue, with the remaining 8 bits unused.

VALID FORMATS FOR BACK BUFFERS AND DISPLAYS

While the list of formats is quite large, there are only a few that are valid and can be used as a back buffer or display format. The valid formats for a back buffer are

  • A2R10G10B10

  • A8R8G8B8

  • X8R8G8B8

  • A1R5G5B5

  • X1R5G5B5

  • R5G6B5

Display formats can be the same as the back buffer formats, with the exception of those that contain an alpha component. The only format that can be used for a display with alpha is A2R10G10B10, and even then that's only in full-screen mode.

Note that just because these formats are supported by Direct3D as valid back buffer formats, your adapter may not support them. In our sample, the only supported formats we received were X8R8G8B8 and R5G6B5.

So thus far, we've gathered enough information to get the adapter ordinal for the device we want to create, as well as the back buffer format we want to support. What about the other options in the device constructor? Well, luckily, the Manager class has all we need.



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net