Platform SDK: DirectX

Selecting an Enumerated Device

[C++]

In C++, Direct3D invokes the D3DEnumDevicesCallback7 function provided by the caller for each Direct3D device installed on the system. When it is called, its first and second parameters are strings that describe the device and provide the user-friendly device name.

The third parameter is a pointer to a D3DDEVICEDESC7 structure containing information about the hardware capabilities of the device. Even if the device being enumerated is a HAL device, the particular hardware may not support all the capabilities that Direct3D allows. The last parameter is a programmer-defined value. Your application passes this value to the IDirect3D7::EnumDevices method. It in turn passes this value to the D3DEnumDevicesCallback7 function.

The following code fragment illustrates how to create a D3DEnumDevicesCallback7 function. In this example, the application-supplied callback function is named EnumDeviceCallback. The EnumDeviceCallback function uses the following algorithm to choose an appropriate Direct3D device.

  1. Discard any devices that don't match the current display depth.
  2. Discard any devices that can't do Gouraud-shaded triangles.
  3. If a hardware device is found that passes the tests in points 1 and 2, use it. However, if the application is running in debug mode, it does not use the hardware device.

The code for the EnumDeviceCallback function is shown in the following example.

// This function is written with the assumption that the following
// global variables are declared in the program.
// DWORD                   g_dwDeviceBitDepth          = 0; 
// GUID                    g_guidDevice; 
// char                    g_szDeviceName[MAX_PATH]; 
// char                    g_szDeviceDesc[MAX_PATH]; 
// D3DDEVICEDESC7          g_d3dDeviceDesc; 
 
static HRESULT WINAPI 
EnumDeviceCallback(LPSTR            lpszDeviceDesc, 
                   LPSTR            lpszDeviceName, 
                   LPD3DDEVICEDESC7 lpd3dEnumDeviceDesc, 
                   LPVOID           lpUserArg) 
{ 
    BOOL fIsHardware = FALSE;

    fIsHardware = (lpd3dEnumDeviceDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION); 

    // Does the device render at the depth we want? 
    if ((lpd3dEnumDeviceDesc->dwDeviceRenderBitDepth & g_dwDeviceBitDepth) == 0) 
    { 
        // If not, skip this device. 
 
        return D3DENUMRET_OK; 
    } 
 
    // The device must support Gouraud-shaded triangles. 
    if (!(lpd3dEnumDeviceDesc->dpcTriCaps.dwShadeCaps & 
          D3DPSHADECAPS_COLORGOURAUDRGB)) 
    { 
        // No Gouraud shading. Skip this device. 
 
        return D3DENUMRET_OK; 
    } 
  
    //
    // This device has the necessary capabilities. Save the details. 
    //
    *(BOOL*)lpUserArg = TRUE; 
    CopyMemory(&g_guidDevice, &lpd3dEnumDeviceDesc->deviceGUID, sizeof(GUID)); 
    strcpy(g_szDeviceDesc, lpszDeviceDesc); 
    strcpy(g_szDeviceName, lpszDeviceName); 
    CopyMemory(&g_d3dDeviceDesc, lpd3dEnumDeviceDesc, 
               sizeof(D3DDEVICEDESC7)); 
 
    // If this is a hardware device, it has 
    // the necessary capabilities. 
    if (fIsHardware) 
        return D3DENUMRET_CANCEL; 
 
    // Otherwise, keep looking. 
 
    return D3DENUMRET_OK; 
} 
[Visual Basic]

In Visual Basic, the Direct3DEnumDevices class enumerates the Direct3D devices installed on the system. Retrieve information about each device by querying the class, identifying devices enumerated within the class by their index. The first device is at index 1, the second is at 2, and so on. The Direct3DEnumDevices.GetCount method reports the number of enumerated devices and, therefore, the highest allowable index value.

Call the Direct3DEnumDevices.GetGuid method to retrieve the GUID for an enumerated device as a text string. The string differs from one device to another.

Call the Direct3DEnumDevices.GetName and Direct3DEnumDevices.GetDescription methods to retrieve text strings that contain the name and user-friendly description of the device.

Call the Direct3DEnumDevices.GetDesc methods to retrieve a description of the capabilities of the device, in the form of the D3DDEVICEDESC7 type. Even if the device being enumerated is a hardware device, the particular hardware might not support all of the capabilities that the Direct3D API allows.

The following code fragment illustrates how to create a function that calls the methods of the Direct3DEnumDevices class to determine device capabilities. In this example, the application-defined function uses the following algorithm to choose an appropriate Direct3D device.

  1. Discard any devices that don't match the current display depth.
  2. Discard any devices that can't do Gouraud-shaded triangles.
  3. If a hardware device is found that passes the tests in points 1 and 2, use it.
Private Sub EnumerateDevices(d3denum As Direct3DEnumDevices)
' For this example, the following global variables are assumed to be defined:
    '   g_lDeviceBitDepth is the desired bit depth (combination of CONST_DDBITDEPTHFLAGS constants).
    '   g_DeviceDesc contains the D3DDEVICEDESC7 for device capabilities.
    '   g_strDeviceGUID contains the GUID string for the device.
    '   g_strDeviceDescription contains the string for the device description text.
    '   g_strDeviceName contains the string for the device name.
    
    ' Local variables used to enumerate devices.
    Dim iDevice As Integer
    Dim DevDesc As D3DDEVICEDESC7
    Dim bIsHardware As Boolean
    
    ' Begin enumerating the devices.
    For iDevice = 1 To d3denum.GetCount
        Dim checkDesc As D3DDEVICEDESC7
        Call d3denum.GetDesc(iDevice, DevDesc)
        
        ' If there is no hardware support for this device
        bIsHardware = (DevDesc.lDevCaps Or D3DDEVCAPS_HWRASTERIZATION)
        
        ' Does the device render at the depth you want? If not, stop
        ' checking, and get the next device.
        If checkDesc.lDeviceRenderBitDepth And Not g_lDeviceBitDepth Then
            GoTo NEXT_DEVICE
        End If
        
        ' The device must support Gouraud-shaded triangles.
        If (Not checkDesc.dpcTriCaps.lShadeCaps And D3DPSHADECAPS_COLORGOURAUDRGB) Then
            ' No Gouraud shading in RGB mode. Skip this device.
            GoTo NEXT_DEVICE
        End If
        
        '
        ' By the time you get here, you know that this is a device you
        ' are interested in. Place the results in the global variables.
        '
        g_strDeviceGUID = d3denum.GetGuid(iDevice)
        g_strDeviceDescription = d3denum.GetDescription(iDevice)
        g_strDeviceName = d3denum.GetName(iDevice)
        g_DeviceDesc = DevDesc
                
        ' If this current device is hardware accelerated,
        ' you have found what you are looking for.
        If bIsHardware = True Then Exit For
        
        ' Otherwise, keep looking.
NEXT_DEVICE:
    Next iDevice
End Sub ' EnumerateDevices