DXUTenum.cpp
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:32k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // File: DXUTEnum.cpp
  3. //
  4. // Enumerates D3D adapters, devices, modes, etc.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #undef min // use __min instead
  10. #undef max // use __max instead
  11. //--------------------------------------------------------------------------------------
  12. // Forward declarations
  13. //--------------------------------------------------------------------------------------
  14. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 );
  15. UINT DXUTStencilBits( D3DFORMAT fmt );
  16. UINT DXUTDepthBits( D3DFORMAT fmt );
  17. UINT DXUTAlphaChannelBits( D3DFORMAT fmt );
  18. UINT DXUTColorChannelBits( D3DFORMAT fmt );
  19. CD3DEnumeration* DXUTGetEnumeration()
  20. {
  21.     // Using an accessor function gives control of the construction order
  22.     static CD3DEnumeration d3denum;
  23.     return &d3denum;
  24. }
  25. //--------------------------------------------------------------------------------------
  26. CD3DEnumeration::CD3DEnumeration()
  27. {
  28.     m_pD3D = NULL;
  29.     m_IsDeviceAcceptableFunc = NULL;
  30.     m_pIsDeviceAcceptableFuncUserContext = NULL;
  31.     m_bRequirePostPixelShaderBlending = true;
  32.     m_nMinWidth = 640;
  33.     m_nMinHeight = 480;
  34.     m_nMaxWidth = UINT_MAX;
  35.     m_nMaxHeight = UINT_MAX;
  36.     m_nRefreshMin = 0;
  37.     m_nRefreshMax = UINT_MAX;
  38.     m_nMultisampleQualityMax = 0xFFFF;
  39.     ResetPossibleDepthStencilFormats();
  40.     ResetPossibleMultisampleTypeList();                                   
  41.     ResetPossiblePresentIntervalList();
  42.     SetPossibleVertexProcessingList( true, true, true, false );
  43. }
  44. //--------------------------------------------------------------------------------------
  45. CD3DEnumeration::~CD3DEnumeration()
  46. {
  47.     ClearAdapterInfoList();
  48. }
  49. //--------------------------------------------------------------------------------------
  50. // Enumerates available D3D adapters, devices, modes, etc.
  51. //--------------------------------------------------------------------------------------
  52. HRESULT CD3DEnumeration::Enumerate( IDirect3D9* pD3D,
  53.                                     LPDXUTCALLBACKISDEVICEACCEPTABLE IsDeviceAcceptableFunc,
  54.                                     void* pIsDeviceAcceptableFuncUserContext )
  55. {
  56.     if( pD3D == NULL )
  57.     {
  58.         pD3D = DXUTGetD3DObject();
  59.         if( pD3D == NULL )
  60.             return DXUTERR_NODIRECT3D;
  61.     }
  62.     m_pD3D = pD3D;
  63.     m_IsDeviceAcceptableFunc = IsDeviceAcceptableFunc;
  64.     m_pIsDeviceAcceptableFuncUserContext = pIsDeviceAcceptableFuncUserContext;
  65.     HRESULT hr;
  66.     ClearAdapterInfoList();
  67.     CGrowableArray<D3DFORMAT> adapterFormatList;
  68.     const D3DFORMAT allowedAdapterFormatArray[] = 
  69.     {   
  70.         D3DFMT_X8R8G8B8, 
  71.         D3DFMT_X1R5G5B5, 
  72.         D3DFMT_R5G6B5, 
  73.         D3DFMT_A2R10G10B10
  74.     };
  75.     const UINT allowedAdapterFormatArrayCount  = sizeof(allowedAdapterFormatArray) / sizeof(allowedAdapterFormatArray[0]);
  76.     UINT numAdapters = pD3D->GetAdapterCount();
  77.     for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
  78.     {
  79.         CD3DEnumAdapterInfo* pAdapterInfo = new CD3DEnumAdapterInfo;
  80.         if( pAdapterInfo == NULL )
  81.             return E_OUTOFMEMORY;
  82.         pAdapterInfo->AdapterOrdinal = adapterOrdinal;
  83.         pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
  84.         // Get list of all display modes on this adapter.  
  85.         // Also build a temporary list of all display adapter formats.
  86.         adapterFormatList.RemoveAll();
  87.         for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ )
  88.         {
  89.             D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList];
  90.             UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
  91.             for (UINT mode = 0; mode < numAdapterModes; mode++)
  92.             {
  93.                 D3DDISPLAYMODE displayMode;
  94.                 pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
  95.                 if( displayMode.Width < m_nMinWidth ||
  96.                     displayMode.Height < m_nMinHeight || 
  97.                     displayMode.Width > m_nMaxWidth ||
  98.                     displayMode.Height > m_nMaxHeight || 
  99.                     displayMode.RefreshRate < m_nRefreshMin ||
  100.                     displayMode.RefreshRate > m_nRefreshMax )
  101.                 {
  102.                     continue;
  103.                 }
  104.                 pAdapterInfo->displayModeList.Add( displayMode );
  105.                 
  106.                 if( !adapterFormatList.Contains(displayMode.Format) )
  107.                     adapterFormatList.Add( displayMode.Format );
  108.             }
  109.         }
  110.         D3DDISPLAYMODE displayMode;
  111.         pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode );
  112.         if( !adapterFormatList.Contains(displayMode.Format) )
  113.             adapterFormatList.Add( displayMode.Format );
  114.         // Sort displaymode list
  115.         ::qsort( pAdapterInfo->displayModeList.GetData(), 
  116.                pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ),
  117.                SortModesCallback );
  118.         // Get info for each device on this adapter
  119.         if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
  120.         {
  121.             delete pAdapterInfo;
  122.             continue;
  123.         }
  124.         // If at least one device on this adapter is available and compatible
  125.         // with the app, add the adapterInfo to the list
  126.         if( pAdapterInfo->deviceInfoList.GetSize() > 0 )
  127.         {
  128.             hr = m_AdapterInfoList.Add( pAdapterInfo );
  129.             if( FAILED(hr) )
  130.                 return hr;
  131.         } else
  132.             delete pAdapterInfo;
  133.     }
  134.     bool bUniqueDesc = true;
  135.     CD3DEnumAdapterInfo* pAdapterInfo;
  136.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  137.     {
  138.         CD3DEnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt(i);
  139.         for( int j=i+1; j<m_AdapterInfoList.GetSize(); j++ )
  140.         {
  141.             CD3DEnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt(j);
  142.             if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description, 
  143.                           pAdapterInfo2->AdapterIdentifier.Description ) == 0 )
  144.             {
  145.                 bUniqueDesc = false;
  146.                 break;
  147.             }
  148.         }
  149.         if( !bUniqueDesc )
  150.             break;
  151.     }
  152.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  153.     {
  154.         pAdapterInfo = m_AdapterInfoList.GetAt(i);
  155.         MultiByteToWideChar( CP_ACP, 0, 
  156.                              pAdapterInfo->AdapterIdentifier.Description, -1, 
  157.                              pAdapterInfo->szUniqueDescription, 100 );
  158.         pAdapterInfo->szUniqueDescription[100] = 0;
  159.         if( !bUniqueDesc )
  160.         {
  161.             WCHAR sz[100];
  162.             StringCchPrintf( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal );
  163.             StringCchCat( pAdapterInfo->szUniqueDescription, 256, sz );
  164.         }
  165.     }
  166.     return S_OK;
  167. }
  168. //--------------------------------------------------------------------------------------
  169. // Enumerates D3D devices for a particular adapter.
  170. //--------------------------------------------------------------------------------------
  171. HRESULT CD3DEnumeration::EnumerateDevices( CD3DEnumAdapterInfo* pAdapterInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
  172. {
  173.     HRESULT hr;
  174.     const D3DDEVTYPE devTypeArray[] = 
  175.     { 
  176.         D3DDEVTYPE_HAL, 
  177.         D3DDEVTYPE_SW, 
  178.         D3DDEVTYPE_REF 
  179.     };
  180.     const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
  181.     // Enumerate each Direct3D device type
  182.     for( UINT iDeviceType = 0; iDeviceType < devTypeArrayCount; iDeviceType++ )
  183.     {
  184.         CD3DEnumDeviceInfo* pDeviceInfo = new CD3DEnumDeviceInfo;
  185.         if( pDeviceInfo == NULL )
  186.             return E_OUTOFMEMORY;
  187.         // Fill struct w/ AdapterOrdinal and D3DDEVTYPE
  188.         pDeviceInfo->DeviceType = devTypeArray[iDeviceType];
  189.         // Store device caps
  190.         if( FAILED( hr = m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, 
  191.                                                 &pDeviceInfo->Caps ) ) )
  192.         {
  193.             delete pDeviceInfo;
  194.             continue;
  195.         }
  196.         // Create a temp device to verify that it is really possible to create a REF device 
  197.         // [the developer DirectX redist has to be installed]
  198.         D3DDISPLAYMODE Mode;
  199.         m_pD3D->GetAdapterDisplayMode(0, &Mode);
  200.         D3DPRESENT_PARAMETERS pp;
  201.         ZeroMemory( &pp, sizeof(D3DPRESENT_PARAMETERS) );
  202.         pp.BackBufferWidth  = 1;
  203.         pp.BackBufferHeight = 1;
  204.         pp.BackBufferFormat = Mode.Format;
  205.         pp.BackBufferCount  = 1;
  206.         pp.SwapEffect       = D3DSWAPEFFECT_COPY;
  207.         pp.Windowed         = TRUE;
  208.         pp.hDeviceWindow    = DXUTGetHWNDFocus();
  209.         IDirect3DDevice9 *pDevice = NULL;
  210.         if( FAILED( hr = m_pD3D->CreateDevice( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, DXUTGetHWNDFocus(),
  211.                                           D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &pDevice ) ) )
  212.         {
  213.             if( hr == D3DERR_NOTAVAILABLE )
  214.             {
  215.                 delete pDeviceInfo;
  216.                 continue;
  217.             }
  218.         }
  219.         SAFE_RELEASE( pDevice );
  220.         // Get info for each devicecombo on this device
  221.         if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo, pDeviceInfo, pAdapterFormatList ) ) )
  222.         {
  223.             delete pDeviceInfo;
  224.             continue;
  225.         }
  226.         // If at least one devicecombo for this device is found, 
  227.         // add the deviceInfo to the list
  228.         if (pDeviceInfo->deviceSettingsComboList.GetSize() > 0 )
  229.             pAdapterInfo->deviceInfoList.Add( pDeviceInfo );
  230.         else
  231.             delete pDeviceInfo;
  232.     }
  233.     return S_OK;
  234. }
  235. //--------------------------------------------------------------------------------------
  236. // Enumerates DeviceCombos for a particular device.
  237. //--------------------------------------------------------------------------------------
  238. HRESULT CD3DEnumeration::EnumerateDeviceCombos( CD3DEnumAdapterInfo* pAdapterInfo, CD3DEnumDeviceInfo* pDeviceInfo, CGrowableArray<D3DFORMAT>* pAdapterFormatList )
  239. {
  240.     const D3DFORMAT backBufferFormatArray[] = 
  241.     {   
  242.         D3DFMT_A8R8G8B8, 
  243.         D3DFMT_X8R8G8B8, 
  244.         D3DFMT_A2R10G10B10, 
  245.         D3DFMT_R5G6B5, 
  246.         D3DFMT_A1R5G5B5, 
  247.         D3DFMT_X1R5G5B5 
  248.     };
  249.     const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
  250.     // See which adapter formats are supported by this device
  251.     for( int iFormat=0; iFormat<pAdapterFormatList->GetSize(); iFormat++ )
  252.     {
  253.         D3DFORMAT adapterFormat = pAdapterFormatList->GetAt(iFormat);
  254.         for( UINT iBackBufferFormat = 0; iBackBufferFormat < backBufferFormatArrayCount; iBackBufferFormat++ )
  255.         {
  256.             D3DFORMAT backBufferFormat = backBufferFormatArray[iBackBufferFormat];
  257.             for( int nWindowed = 0; nWindowed < 2; nWindowed++)
  258.             {
  259.                 if( !nWindowed && pAdapterInfo->displayModeList.GetSize() == 0 )
  260.                     continue;
  261.                 if (FAILED( m_pD3D->CheckDeviceType( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType, 
  262.                                                      adapterFormat, backBufferFormat, nWindowed )))
  263.                 {
  264.                     continue;
  265.                 }
  266.                 if( m_bRequirePostPixelShaderBlending )
  267.                 {
  268.                     // If the backbuffer format doesn't support D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
  269.                     // then alpha test, pixel fog, render-target blending, color write enable, and dithering. 
  270.                     // are not supported.
  271.                     if( FAILED( m_pD3D->CheckDeviceFormat( pAdapterInfo->AdapterOrdinal, pDeviceInfo->DeviceType,
  272.                                                            adapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
  273.                                                            D3DRTYPE_TEXTURE, backBufferFormat ) ) )
  274.                     {
  275.                         continue;
  276.                     }
  277.                 }
  278.                 // If an application callback function has been provided, make sure this device
  279.                 // is acceptable to the app.
  280.                 if( m_IsDeviceAcceptableFunc != NULL )
  281.                 {
  282.                     if( !m_IsDeviceAcceptableFunc( &pDeviceInfo->Caps, adapterFormat, backBufferFormat, FALSE != nWindowed, m_pIsDeviceAcceptableFuncUserContext ) )
  283.                         continue;
  284.                 }
  285.                 
  286.                 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
  287.                 // DeviceCombo that is supported by the system and acceptable to the app. We still 
  288.                 // need to find one or more suitable depth/stencil buffer format,
  289.                 // multisample type, and present interval.
  290.                 CD3DEnumDeviceSettingsCombo* pDeviceCombo = new CD3DEnumDeviceSettingsCombo;
  291.                 if( pDeviceCombo == NULL )
  292.                     return E_OUTOFMEMORY;
  293.                 pDeviceCombo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
  294.                 pDeviceCombo->DeviceType = pDeviceInfo->DeviceType;
  295.                 pDeviceCombo->AdapterFormat = adapterFormat;
  296.                 pDeviceCombo->BackBufferFormat = backBufferFormat;
  297.                 pDeviceCombo->Windowed = (nWindowed != 0);
  298.                
  299.                 BuildDepthStencilFormatList( pDeviceCombo );
  300.                 BuildMultiSampleTypeList( pDeviceCombo );
  301.                 if (pDeviceCombo->multiSampleTypeList.GetSize() == 0)
  302.                 {
  303.                     delete pDeviceCombo;
  304.                     continue;
  305.                 }
  306.                 BuildDSMSConflictList( pDeviceCombo );
  307.                 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo );
  308.                 pDeviceCombo->pAdapterInfo = pAdapterInfo;
  309.                 pDeviceCombo->pDeviceInfo = pDeviceInfo;
  310.                 pDeviceInfo->deviceSettingsComboList.Add( pDeviceCombo );
  311.             
  312.             }
  313.         }
  314.     }
  315.     return S_OK;
  316. }
  317. //--------------------------------------------------------------------------------------
  318. // Adds all depth/stencil formats that are compatible with the device 
  319. //       and app to the given D3DDeviceCombo.
  320. //--------------------------------------------------------------------------------------
  321. void CD3DEnumeration::BuildDepthStencilFormatList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  322. {
  323.     D3DFORMAT depthStencilFmt;
  324.     for( int idsf = 0; idsf < m_DepthStecilPossibleList.GetSize(); idsf++ )
  325.     {
  326.         depthStencilFmt = m_DepthStecilPossibleList.GetAt(idsf);
  327.         if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal, 
  328.                 pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, 
  329.                 D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
  330.         {
  331.             if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal, 
  332.                     pDeviceCombo->DeviceType, pDeviceCombo->AdapterFormat, 
  333.                     pDeviceCombo->BackBufferFormat, depthStencilFmt)))
  334.             {
  335.                 pDeviceCombo->depthStencilFormatList.Add( depthStencilFmt );
  336.             }
  337.         }
  338.     }
  339. }
  340. //--------------------------------------------------------------------------------------
  341. // Adds all multisample types that are compatible with the device and app to
  342. //       the given D3DDeviceCombo.
  343. //--------------------------------------------------------------------------------------
  344. void CD3DEnumeration::BuildMultiSampleTypeList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  345. {
  346.     D3DMULTISAMPLE_TYPE msType;
  347.     DWORD msQuality;
  348.     for( int imst = 0; imst < m_MultiSampleTypeList.GetSize(); imst++ )
  349.     {
  350.         msType = m_MultiSampleTypeList.GetAt(imst);
  351.         if( SUCCEEDED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, 
  352.                 pDeviceCombo->DeviceType, pDeviceCombo->BackBufferFormat, 
  353.                 pDeviceCombo->Windowed, msType, &msQuality ) ) )
  354.         {
  355.             pDeviceCombo->multiSampleTypeList.Add( msType );
  356.             if( msQuality > m_nMultisampleQualityMax+1 )
  357.                 msQuality = m_nMultisampleQualityMax+1;
  358.             pDeviceCombo->multiSampleQualityList.Add( msQuality );
  359.         }
  360.     }
  361. }
  362. //--------------------------------------------------------------------------------------
  363. // Find any conflicts between the available depth/stencil formats and
  364. //       multisample types.
  365. //--------------------------------------------------------------------------------------
  366. void CD3DEnumeration::BuildDSMSConflictList( CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  367. {
  368.     CD3DEnumDSMSConflict DSMSConflict;
  369.     for( int iDS=0; iDS<pDeviceCombo->depthStencilFormatList.GetSize(); iDS++ )
  370.     {
  371.         D3DFORMAT dsFmt = pDeviceCombo->depthStencilFormatList.GetAt(iDS);
  372.         for( int iMS=0; iMS<pDeviceCombo->multiSampleTypeList.GetSize(); iMS++ )
  373.         {
  374.             D3DMULTISAMPLE_TYPE msType = pDeviceCombo->multiSampleTypeList.GetAt(iMS);
  375.             if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DeviceType,
  376.                                                             dsFmt, pDeviceCombo->Windowed, msType, NULL ) ) )
  377.             {
  378.                 DSMSConflict.DSFormat = dsFmt;
  379.                 DSMSConflict.MSType = msType;
  380.                 pDeviceCombo->DSMSConflictList.Add( DSMSConflict );
  381.             }
  382.         }
  383.     }
  384. }
  385. //--------------------------------------------------------------------------------------
  386. // Adds all present intervals that are compatible with the device and app 
  387. //       to the given D3DDeviceCombo.
  388. //--------------------------------------------------------------------------------------
  389. void CD3DEnumeration::BuildPresentIntervalList( CD3DEnumDeviceInfo* pDeviceInfo, 
  390.                                                 CD3DEnumDeviceSettingsCombo* pDeviceCombo )
  391. {
  392.     UINT pi;
  393.     for( int ipi = 0; ipi < m_PresentIntervalList.GetSize(); ipi++ )
  394.     {
  395.         pi = m_PresentIntervalList.GetAt(ipi);
  396.         if( pDeviceCombo->Windowed )
  397.         {
  398.             if( pi == D3DPRESENT_INTERVAL_TWO ||
  399.                 pi == D3DPRESENT_INTERVAL_THREE ||
  400.                 pi == D3DPRESENT_INTERVAL_FOUR )
  401.             {
  402.                 // These intervals are not supported in windowed mode.
  403.                 continue;
  404.             }
  405.         }
  406.         // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
  407.         // can't do a caps check for it -- it is always available.
  408.         if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
  409.             (pDeviceInfo->Caps.PresentationIntervals & pi) )
  410.         {
  411.             pDeviceCombo->presentIntervalList.Add( pi );
  412.         }
  413.     }
  414. }
  415. //--------------------------------------------------------------------------------------
  416. // Release all the allocated CD3DEnumAdapterInfo objects and empty the list
  417. //--------------------------------------------------------------------------------------
  418. void CD3DEnumeration::ClearAdapterInfoList()
  419. {
  420.     CD3DEnumAdapterInfo* pAdapterInfo;
  421.     for( int i=0; i<m_AdapterInfoList.GetSize(); i++ )
  422.     {
  423.         pAdapterInfo = m_AdapterInfoList.GetAt(i);
  424.         delete pAdapterInfo;
  425.     }
  426.     m_AdapterInfoList.RemoveAll();
  427. }
  428. //--------------------------------------------------------------------------------------
  429. // Call GetAdapterInfoList() after Enumerate() to get a STL vector of 
  430. //       CD3DEnumAdapterInfo* 
  431. //--------------------------------------------------------------------------------------
  432. CGrowableArray<CD3DEnumAdapterInfo*>* CD3DEnumeration::GetAdapterInfoList()
  433. {
  434.     return &m_AdapterInfoList;
  435. }
  436. //--------------------------------------------------------------------------------------
  437. CD3DEnumAdapterInfo* CD3DEnumeration::GetAdapterInfo( UINT AdapterOrdinal )
  438. {
  439.     for( int iAdapter=0; iAdapter<m_AdapterInfoList.GetSize(); iAdapter++ )
  440.     {
  441.         CD3DEnumAdapterInfo* pAdapterInfo = m_AdapterInfoList.GetAt(iAdapter);
  442.         if( pAdapterInfo->AdapterOrdinal == AdapterOrdinal )
  443.             return pAdapterInfo;
  444.     }
  445.     return NULL;
  446. }
  447. //--------------------------------------------------------------------------------------
  448. CD3DEnumDeviceInfo* CD3DEnumeration::GetDeviceInfo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType )
  449. {
  450.     CD3DEnumAdapterInfo* pAdapterInfo = GetAdapterInfo( AdapterOrdinal );
  451.     if( pAdapterInfo )
  452.     {
  453.         for( int iDeviceInfo=0; iDeviceInfo<pAdapterInfo->deviceInfoList.GetSize(); iDeviceInfo++ )
  454.         {
  455.             CD3DEnumDeviceInfo* pDeviceInfo = pAdapterInfo->deviceInfoList.GetAt(iDeviceInfo);
  456.             if( pDeviceInfo->DeviceType == DeviceType )
  457.                 return pDeviceInfo;
  458.         }
  459.     }
  460.     return NULL;
  461. }
  462. //--------------------------------------------------------------------------------------
  463. // 
  464. //--------------------------------------------------------------------------------------
  465. CD3DEnumDeviceSettingsCombo* CD3DEnumeration::GetDeviceSettingsCombo( UINT AdapterOrdinal, D3DDEVTYPE DeviceType, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, BOOL bWindowed )
  466. {
  467.     CD3DEnumDeviceInfo* pDeviceInfo = GetDeviceInfo( AdapterOrdinal, DeviceType );
  468.     if( pDeviceInfo )
  469.     {
  470.         for( int iDeviceCombo=0; iDeviceCombo<pDeviceInfo->deviceSettingsComboList.GetSize(); iDeviceCombo++ )
  471.         {
  472.             CD3DEnumDeviceSettingsCombo* pDeviceSettingsCombo = pDeviceInfo->deviceSettingsComboList.GetAt(iDeviceCombo);
  473.             if( pDeviceSettingsCombo->AdapterFormat == AdapterFormat &&
  474.                 pDeviceSettingsCombo->BackBufferFormat == BackBufferFormat &&
  475.                 pDeviceSettingsCombo->Windowed == bWindowed )
  476.                 return pDeviceSettingsCombo;
  477.         }
  478.     }
  479.     return NULL;
  480. }
  481. //--------------------------------------------------------------------------------------
  482. // Returns the number of color channel bits in the specified D3DFORMAT
  483. //--------------------------------------------------------------------------------------
  484. UINT DXUTColorChannelBits( D3DFORMAT fmt )
  485. {
  486.     switch( fmt )
  487.     {
  488.         case D3DFMT_R8G8B8:
  489.             return 8;
  490.         case D3DFMT_A8R8G8B8:
  491.             return 8;
  492.         case D3DFMT_X8R8G8B8:
  493.             return 8;
  494.         case D3DFMT_R5G6B5:
  495.             return 5;
  496.         case D3DFMT_X1R5G5B5:
  497.             return 5;
  498.         case D3DFMT_A1R5G5B5:
  499.             return 5;
  500.         case D3DFMT_A4R4G4B4:
  501.             return 4;
  502.         case D3DFMT_R3G3B2:
  503.             return 2;
  504.         case D3DFMT_A8R3G3B2:
  505.             return 2;
  506.         case D3DFMT_X4R4G4B4:
  507.             return 4;
  508.         case D3DFMT_A2B10G10R10:
  509.             return 10;
  510.         case D3DFMT_A8B8G8R8:
  511.             return 8;
  512.         case D3DFMT_A2R10G10B10:
  513.             return 10;
  514.         case D3DFMT_A16B16G16R16:
  515.             return 16;
  516.         default:
  517.             return 0;
  518.     }
  519. }
  520. //--------------------------------------------------------------------------------------
  521. // Returns the number of alpha channel bits in the specified D3DFORMAT
  522. //--------------------------------------------------------------------------------------
  523. UINT DXUTAlphaChannelBits( D3DFORMAT fmt )
  524. {
  525.     switch( fmt )
  526.     {
  527.         case D3DFMT_R8G8B8:
  528.             return 0;
  529.         case D3DFMT_A8R8G8B8:
  530.             return 8;
  531.         case D3DFMT_X8R8G8B8:
  532.             return 0;
  533.         case D3DFMT_R5G6B5:
  534.             return 0;
  535.         case D3DFMT_X1R5G5B5:
  536.             return 0;
  537.         case D3DFMT_A1R5G5B5:
  538.             return 1;
  539.         case D3DFMT_A4R4G4B4:
  540.             return 4;
  541.         case D3DFMT_R3G3B2:
  542.             return 0;
  543.         case D3DFMT_A8R3G3B2:
  544.             return 8;
  545.         case D3DFMT_X4R4G4B4:
  546.             return 0;
  547.         case D3DFMT_A2B10G10R10:
  548.             return 2;
  549.         case D3DFMT_A8B8G8R8:
  550.             return 8;
  551.         case D3DFMT_A2R10G10B10:
  552.             return 2;
  553.         case D3DFMT_A16B16G16R16:
  554.             return 16;
  555.         default:
  556.             return 0;
  557.     }
  558. }
  559. //--------------------------------------------------------------------------------------
  560. // Returns the number of depth bits in the specified D3DFORMAT
  561. //--------------------------------------------------------------------------------------
  562. UINT DXUTDepthBits( D3DFORMAT fmt )
  563. {
  564.     switch( fmt )
  565.     {
  566.         case D3DFMT_D32F_LOCKABLE:
  567.         case D3DFMT_D32:
  568.             return 32;
  569.         case D3DFMT_D24X8:
  570.         case D3DFMT_D24S8:
  571.         case D3DFMT_D24X4S4:
  572.         case D3DFMT_D24FS8:
  573.             return 24;
  574.         case D3DFMT_D16_LOCKABLE:
  575.         case D3DFMT_D16:
  576.             return 16;
  577.         case D3DFMT_D15S1:
  578.             return 15;
  579.         default:
  580.             return 0;
  581.     }
  582. }
  583. //--------------------------------------------------------------------------------------
  584. // Returns the number of stencil bits in the specified D3DFORMAT
  585. //--------------------------------------------------------------------------------------
  586. UINT DXUTStencilBits( D3DFORMAT fmt )
  587. {
  588.     switch( fmt )
  589.     {
  590.         case D3DFMT_D16_LOCKABLE:
  591.         case D3DFMT_D16:
  592.         case D3DFMT_D32F_LOCKABLE:
  593.         case D3DFMT_D32:
  594.         case D3DFMT_D24X8:
  595.             return 0;
  596.         case D3DFMT_D15S1:
  597.             return 1;
  598.         case D3DFMT_D24X4S4:
  599.             return 4;
  600.         case D3DFMT_D24S8:
  601.         case D3DFMT_D24FS8:
  602.             return 8;
  603.         default:
  604.             return 0;
  605.     }
  606. }
  607. //--------------------------------------------------------------------------------------
  608. // Used to sort D3DDISPLAYMODEs
  609. //--------------------------------------------------------------------------------------
  610. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
  611. {
  612.     D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
  613.     D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
  614.     if (pdm1->Width > pdm2->Width)
  615.         return 1;
  616.     if (pdm1->Width < pdm2->Width)
  617.         return -1;
  618.     if (pdm1->Height > pdm2->Height)
  619.         return 1;
  620.     if (pdm1->Height < pdm2->Height)
  621.         return -1;
  622.     if (pdm1->Format > pdm2->Format)
  623.         return 1;
  624.     if (pdm1->Format < pdm2->Format)
  625.         return -1;
  626.     if (pdm1->RefreshRate > pdm2->RefreshRate)
  627.         return 1;
  628.     if (pdm1->RefreshRate < pdm2->RefreshRate)
  629.         return -1;
  630.     return 0;
  631. }
  632. //--------------------------------------------------------------------------------------
  633. CD3DEnumAdapterInfo::~CD3DEnumAdapterInfo( void )
  634. {
  635.     CD3DEnumDeviceInfo* pDeviceInfo;
  636.     for( int i=0; i<deviceInfoList.GetSize(); i++ )
  637.     {
  638.         pDeviceInfo = deviceInfoList.GetAt(i);
  639.         delete pDeviceInfo;
  640.     }
  641.     deviceInfoList.RemoveAll();
  642. }
  643. //--------------------------------------------------------------------------------------
  644. CD3DEnumDeviceInfo::~CD3DEnumDeviceInfo( void )
  645. {
  646.     CD3DEnumDeviceSettingsCombo* pDeviceCombo;
  647.     for( int i=0; i<deviceSettingsComboList.GetSize(); i++ )
  648.     {
  649.         pDeviceCombo = deviceSettingsComboList.GetAt(i);
  650.         delete pDeviceCombo;
  651.     }
  652.     deviceSettingsComboList.RemoveAll();
  653. }
  654. //--------------------------------------------------------------------------------------
  655. void CD3DEnumeration::ResetPossibleDepthStencilFormats()
  656. {
  657.     m_DepthStecilPossibleList.RemoveAll();
  658.     m_DepthStecilPossibleList.Add( D3DFMT_D16 );
  659.     m_DepthStecilPossibleList.Add( D3DFMT_D15S1 );
  660.     m_DepthStecilPossibleList.Add( D3DFMT_D24X8 );
  661.     m_DepthStecilPossibleList.Add( D3DFMT_D24S8 );
  662.     m_DepthStecilPossibleList.Add( D3DFMT_D24X4S4 );
  663.     m_DepthStecilPossibleList.Add( D3DFMT_D32 );
  664. }
  665. //--------------------------------------------------------------------------------------
  666. CGrowableArray<D3DFORMAT>* CD3DEnumeration::GetPossibleDepthStencilFormatList() 
  667. {
  668.     return &m_DepthStecilPossibleList;
  669. }
  670. //--------------------------------------------------------------------------------------
  671. CGrowableArray<D3DMULTISAMPLE_TYPE>* CD3DEnumeration::GetPossibleMultisampleTypeList()
  672. {
  673.     return &m_MultiSampleTypeList;
  674. }
  675. //--------------------------------------------------------------------------------------
  676. void CD3DEnumeration::ResetPossibleMultisampleTypeList()
  677. {
  678.     m_MultiSampleTypeList.RemoveAll();
  679.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONE );
  680.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_NONMASKABLE );
  681.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_2_SAMPLES );
  682.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_3_SAMPLES );
  683.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_4_SAMPLES );
  684.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_5_SAMPLES );
  685.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_6_SAMPLES );
  686.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_7_SAMPLES );
  687.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_8_SAMPLES );
  688.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_9_SAMPLES );
  689.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_10_SAMPLES );
  690.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_11_SAMPLES );
  691.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_12_SAMPLES );
  692.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_13_SAMPLES );
  693.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_14_SAMPLES );
  694.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_15_SAMPLES );
  695.     m_MultiSampleTypeList.Add( D3DMULTISAMPLE_16_SAMPLES );
  696. }
  697. //--------------------------------------------------------------------------------------
  698. void CD3DEnumeration::GetPossibleVertexProcessingList( bool* pbSoftwareVP, bool* pbHardwareVP, bool* pbPureHarewareVP, bool* pbMixedVP )
  699. {
  700.     *pbSoftwareVP = m_bSoftwareVP;
  701.     *pbHardwareVP = m_bHardwareVP;
  702.     *pbPureHarewareVP = m_bPureHarewareVP;
  703.     *pbMixedVP = m_bMixedVP;
  704. }
  705. //--------------------------------------------------------------------------------------
  706. void CD3DEnumeration::SetPossibleVertexProcessingList( bool bSoftwareVP, bool bHardwareVP, bool bPureHarewareVP, bool bMixedVP )
  707. {
  708.     m_bSoftwareVP = bSoftwareVP;
  709.     m_bHardwareVP = bHardwareVP;
  710.     m_bPureHarewareVP = bPureHarewareVP;
  711.     m_bMixedVP = bMixedVP;
  712. }
  713. //--------------------------------------------------------------------------------------
  714. CGrowableArray<UINT>* CD3DEnumeration::GetPossiblePresentIntervalList()
  715. {
  716.     return &m_PresentIntervalList;
  717. }
  718. //--------------------------------------------------------------------------------------
  719. void CD3DEnumeration::ResetPossiblePresentIntervalList()
  720. {
  721.     m_PresentIntervalList.RemoveAll();
  722.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_IMMEDIATE );
  723.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_DEFAULT );
  724.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_ONE );
  725.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_TWO );
  726.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_THREE );
  727.     m_PresentIntervalList.Add( D3DPRESENT_INTERVAL_FOUR );
  728. }
  729. //--------------------------------------------------------------------------------------
  730. void CD3DEnumeration::SetResolutionMinMax( UINT nMinWidth, UINT nMinHeight, 
  731.                                            UINT nMaxWidth, UINT nMaxHeight )
  732. {
  733.     m_nMinWidth = nMinWidth;
  734.     m_nMinHeight = nMinHeight;
  735.     m_nMaxWidth = nMaxWidth;
  736.     m_nMaxHeight = nMaxHeight;
  737. }
  738. //--------------------------------------------------------------------------------------
  739. void CD3DEnumeration::SetRefreshMinMax( UINT nMin, UINT nMax )
  740. {
  741.     m_nRefreshMin = nMin;
  742.     m_nRefreshMax = nMax;
  743. }
  744. //--------------------------------------------------------------------------------------
  745. void CD3DEnumeration::SetMultisampleQualityMax( UINT nMax )
  746. {
  747.     if( nMax > 0xFFFF )
  748.         nMax = 0xFFFF;
  749.     m_nMultisampleQualityMax = nMax;
  750. }