d3denumeration.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:26k
源码类别:

游戏

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. // File: D3DEnumeration.cpp
  3. //
  4. // Desc: Enumerates D3D adapters, devices, modes, etc.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. //-----------------------------------------------------------------------------
  10. // Name: ColorChannelBits
  11. // Desc: Returns the number of color channel bits in the specified D3DFORMAT
  12. //-----------------------------------------------------------------------------
  13. static UINT ColorChannelBits( D3DFORMAT fmt )
  14. {
  15.     switch( fmt )
  16.     {
  17.         case D3DFMT_R8G8B8:
  18.             return 8;
  19.         case D3DFMT_A8R8G8B8:
  20.             return 8;
  21.         case D3DFMT_X8R8G8B8:
  22.             return 8;
  23.         case D3DFMT_R5G6B5:
  24.             return 5;
  25.         case D3DFMT_X1R5G5B5:
  26.             return 5;
  27.         case D3DFMT_A1R5G5B5:
  28.             return 5;
  29.         case D3DFMT_A4R4G4B4:
  30.             return 4;
  31.         case D3DFMT_R3G3B2:
  32.             return 2;
  33.         case D3DFMT_A8R3G3B2:
  34.             return 2;
  35.         case D3DFMT_X4R4G4B4:
  36.             return 4;
  37.         case D3DFMT_A2B10G10R10:
  38.             return 10;
  39.         case D3DFMT_A2R10G10B10:
  40.             return 10;
  41.         default:
  42.             return 0;
  43.     }
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Name: AlphaChannelBits
  47. // Desc: Returns the number of alpha channel bits in the specified D3DFORMAT
  48. //-----------------------------------------------------------------------------
  49. static UINT AlphaChannelBits( D3DFORMAT fmt )
  50. {
  51.     switch( fmt )
  52.     {
  53.         case D3DFMT_R8G8B8:
  54.             return 0;
  55.         case D3DFMT_A8R8G8B8:
  56.             return 8;
  57.         case D3DFMT_X8R8G8B8:
  58.             return 0;
  59.         case D3DFMT_R5G6B5:
  60.             return 0;
  61.         case D3DFMT_X1R5G5B5:
  62.             return 0;
  63.         case D3DFMT_A1R5G5B5:
  64.             return 1;
  65.         case D3DFMT_A4R4G4B4:
  66.             return 4;
  67.         case D3DFMT_R3G3B2:
  68.             return 0;
  69.         case D3DFMT_A8R3G3B2:
  70.             return 8;
  71.         case D3DFMT_X4R4G4B4:
  72.             return 0;
  73.         case D3DFMT_A2B10G10R10:
  74.             return 2;
  75.         case D3DFMT_A2R10G10B10:
  76.             return 2;
  77.         default:
  78.             return 0;
  79.     }
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Name: DepthBits
  83. // Desc: Returns the number of depth bits in the specified D3DFORMAT
  84. //-----------------------------------------------------------------------------
  85. static UINT DepthBits( D3DFORMAT fmt )
  86. {
  87.     switch( fmt )
  88.     {
  89.         case D3DFMT_D16:
  90.             return 16;
  91.         case D3DFMT_D15S1:
  92.             return 15;
  93.         case D3DFMT_D24X8:
  94.             return 24;
  95.         case D3DFMT_D24S8:
  96.             return 24;
  97.         case D3DFMT_D24X4S4:
  98.             return 24;
  99.         case D3DFMT_D32:
  100.             return 32;
  101.         default:
  102.             return 0;
  103.     }
  104. }
  105. //-----------------------------------------------------------------------------
  106. // Name: StencilBits
  107. // Desc: Returns the number of stencil bits in the specified D3DFORMAT
  108. //-----------------------------------------------------------------------------
  109. static UINT StencilBits( D3DFORMAT fmt )
  110. {
  111.     switch( fmt )
  112.     {
  113.         case D3DFMT_D16:
  114.             return 0;
  115.         case D3DFMT_D15S1:
  116.             return 1;
  117.         case D3DFMT_D24X8:
  118.             return 0;
  119.         case D3DFMT_D24S8:
  120.             return 8;
  121.         case D3DFMT_D24X4S4:
  122.             return 4;
  123.         case D3DFMT_D32:
  124.             return 0;
  125.         default:
  126.             return 0;
  127.     }
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Name: D3DAdapterInfo destructor
  131. // Desc: 
  132. //-----------------------------------------------------------------------------
  133. D3DAdapterInfo::~D3DAdapterInfo( void )
  134. {
  135.     if( pDisplayModeList != NULL )
  136.         delete pDisplayModeList;
  137.     if( pDeviceInfoList != NULL )
  138.     {
  139.         for( UINT idi = 0; idi < pDeviceInfoList->Count(); idi++ )
  140.             delete (D3DDeviceInfo*)pDeviceInfoList->GetPtr(idi);
  141.         delete pDeviceInfoList;
  142.     }
  143. }
  144. //-----------------------------------------------------------------------------
  145. // Name: D3DDeviceInfo destructor
  146. // Desc: 
  147. //-----------------------------------------------------------------------------
  148. D3DDeviceInfo::~D3DDeviceInfo( void )
  149. {
  150.     if( pDeviceComboList != NULL )
  151.     {
  152.         for( UINT idc = 0; idc < pDeviceComboList->Count(); idc++ )
  153.             delete (D3DDeviceCombo*)pDeviceComboList->GetPtr(idc);
  154.         delete pDeviceComboList;
  155.     }
  156. }
  157. //-----------------------------------------------------------------------------
  158. // Name: D3DDeviceCombo destructor
  159. // Desc: 
  160. //-----------------------------------------------------------------------------
  161. D3DDeviceCombo::~D3DDeviceCombo( void )
  162. {
  163.     if( pDepthStencilFormatList != NULL )
  164.         delete pDepthStencilFormatList;
  165.     if( pMultiSampleTypeList != NULL )
  166.         delete pMultiSampleTypeList;
  167.     if( pMultiSampleQualityList != NULL )
  168.         delete pMultiSampleQualityList;
  169.     if( pDSMSConflictList != NULL )
  170.         delete pDSMSConflictList;
  171.     if( pVertexProcessingTypeList != NULL )
  172.         delete pVertexProcessingTypeList;
  173.     if( pPresentIntervalList != NULL )
  174.         delete pPresentIntervalList;
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Name: CD3DEnumeration constructor
  178. // Desc: 
  179. //-----------------------------------------------------------------------------
  180. CD3DEnumeration::CD3DEnumeration()
  181. {
  182.     m_pAdapterInfoList = NULL;
  183.     m_pAllowedAdapterFormatList = NULL;
  184.     AppMinFullscreenWidth = 640;
  185.     AppMinFullscreenHeight = 480;
  186.     AppMinColorChannelBits = 5;
  187.     AppMinAlphaChannelBits = 0;
  188.     AppMinDepthBits = 15;
  189.     AppMinStencilBits = 0;
  190.     AppUsesDepthBuffer = false;
  191.     AppUsesMixedVP = false;
  192.     AppRequiresWindowed = false;
  193.     AppRequiresFullscreen = false;
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Name: CD3DEnumeration destructor
  197. // Desc: 
  198. //-----------------------------------------------------------------------------
  199. CD3DEnumeration::~CD3DEnumeration()
  200. {
  201.     if( m_pAdapterInfoList != NULL )
  202.     {
  203.         for( UINT iai = 0; iai < m_pAdapterInfoList->Count(); iai++ )
  204.             delete (D3DAdapterInfo*)m_pAdapterInfoList->GetPtr(iai);
  205.         delete m_pAdapterInfoList;
  206.     }
  207.     SAFE_DELETE( m_pAllowedAdapterFormatList );
  208. }
  209. //-----------------------------------------------------------------------------
  210. // Name: SortModesCallback
  211. // Desc: Used to sort D3DDISPLAYMODEs
  212. //-----------------------------------------------------------------------------
  213. static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
  214. {
  215.     D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
  216.     D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
  217.     if (pdm1->Width > pdm2->Width)
  218.         return 1;
  219.     if (pdm1->Width < pdm2->Width)
  220.         return -1;
  221.     if (pdm1->Height > pdm2->Height)
  222.         return 1;
  223.     if (pdm1->Height < pdm2->Height)
  224.         return -1;
  225.     if (pdm1->Format > pdm2->Format)
  226.         return 1;
  227.     if (pdm1->Format < pdm2->Format)
  228.         return -1;
  229.     if (pdm1->RefreshRate > pdm2->RefreshRate)
  230.         return 1;
  231.     if (pdm1->RefreshRate < pdm2->RefreshRate)
  232.         return -1;
  233.     return 0;
  234. }
  235. //-----------------------------------------------------------------------------
  236. // Name: Enumerate
  237. // Desc: Enumerates available D3D adapters, devices, modes, etc.
  238. //-----------------------------------------------------------------------------
  239. HRESULT CD3DEnumeration::Enumerate()
  240. {
  241.     HRESULT hr;
  242.     CArrayList adapterFormatList( AL_VALUE, sizeof(D3DFORMAT) );
  243.     if( m_pD3D == NULL )
  244.         return E_FAIL;
  245.     m_pAdapterInfoList = new CArrayList( AL_REFERENCE );
  246.     if( m_pAdapterInfoList == NULL )
  247.         return E_OUTOFMEMORY;
  248.     m_pAllowedAdapterFormatList = new CArrayList( AL_VALUE, sizeof(D3DFORMAT) );
  249.     if( m_pAllowedAdapterFormatList == NULL )
  250.         return E_OUTOFMEMORY;
  251.     D3DFORMAT fmt;
  252.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X8R8G8B8 ) ) ) )
  253.         return hr;
  254.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X1R5G5B5 ) ) ) )
  255.         return hr;
  256.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_R5G6B5 ) ) ) )
  257.         return hr;
  258.     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_A2R10G10B10 ) ) ) )
  259.         return hr;
  260.     D3DAdapterInfo* pAdapterInfo = NULL;
  261.     UINT numAdapters = m_pD3D->GetAdapterCount();
  262.     for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
  263.     {
  264.         pAdapterInfo = new D3DAdapterInfo;
  265.         if( pAdapterInfo == NULL )
  266.             return E_OUTOFMEMORY;
  267.         pAdapterInfo->pDisplayModeList = new CArrayList( AL_VALUE, sizeof(D3DDISPLAYMODE)); 
  268.         pAdapterInfo->pDeviceInfoList = new CArrayList( AL_REFERENCE );
  269.         if( pAdapterInfo->pDisplayModeList == NULL ||
  270.             pAdapterInfo->pDeviceInfoList == NULL )
  271.         {
  272.             delete pAdapterInfo;
  273.             return E_OUTOFMEMORY;
  274.         }
  275.         pAdapterInfo->AdapterOrdinal = adapterOrdinal;
  276.         m_pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
  277.         // Get list of all display modes on this adapter.  
  278.         // Also build a temporary list of all display adapter formats.
  279.         adapterFormatList.Clear();
  280.         for( UINT iaaf = 0; iaaf < m_pAllowedAdapterFormatList->Count(); iaaf++ )
  281.         {
  282.             D3DFORMAT allowedAdapterFormat = *(D3DFORMAT*)m_pAllowedAdapterFormatList->GetPtr( iaaf );
  283.             UINT numAdapterModes = m_pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
  284.             for (UINT mode = 0; mode < numAdapterModes; mode++)
  285.             {
  286.                 D3DDISPLAYMODE displayMode;
  287.                 m_pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
  288.                 if( displayMode.Width < AppMinFullscreenWidth ||
  289.                     displayMode.Height < AppMinFullscreenHeight ||
  290.                     ColorChannelBits(displayMode.Format) < AppMinColorChannelBits )
  291.                 {
  292.                     continue;
  293.                 }
  294.                 pAdapterInfo->pDisplayModeList->Add(&displayMode);
  295.                 if( !adapterFormatList.Contains( &displayMode.Format ) )
  296.                     adapterFormatList.Add( &displayMode.Format );
  297.             }
  298.         }
  299.         // Sort displaymode list
  300.         qsort( pAdapterInfo->pDisplayModeList->GetPtr(0), 
  301.             pAdapterInfo->pDisplayModeList->Count(), sizeof( D3DDISPLAYMODE ),
  302.             SortModesCallback );
  303.         // Get info for each device on this adapter
  304.         if( FAILED( hr = EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
  305.         {
  306.             delete pAdapterInfo;
  307.             return hr;
  308.         }
  309.         // If at least one device on this adapter is available and compatible
  310.         // with the app, add the adapterInfo to the list
  311.         if (pAdapterInfo->pDeviceInfoList->Count() == 0)
  312.             delete pAdapterInfo;
  313.         else
  314.             m_pAdapterInfoList->Add(pAdapterInfo);
  315.     }
  316.     return S_OK;
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Name: EnumerateDevices
  320. // Desc: Enumerates D3D devices for a particular adapter.
  321. //-----------------------------------------------------------------------------
  322. HRESULT CD3DEnumeration::EnumerateDevices( D3DAdapterInfo* pAdapterInfo, 
  323.                                            CArrayList* pAdapterFormatList )
  324. {
  325.     const D3DDEVTYPE devTypeArray[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF };
  326.     const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
  327.     HRESULT hr;
  328.     D3DDeviceInfo* pDeviceInfo = NULL;
  329.     for( UINT idt = 0; idt < devTypeArrayCount; idt++ )
  330.     {
  331.         pDeviceInfo = new D3DDeviceInfo;
  332.         if( pDeviceInfo == NULL )
  333.             return E_OUTOFMEMORY;
  334.         pDeviceInfo->pDeviceComboList = new CArrayList( AL_REFERENCE ); 
  335.         if( pDeviceInfo->pDeviceComboList == NULL )
  336.         {
  337.             delete pDeviceInfo;
  338.             return E_OUTOFMEMORY;
  339.         }
  340.         pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
  341.         pDeviceInfo->DevType = devTypeArray[idt];
  342.         if( FAILED( m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, 
  343.             pDeviceInfo->DevType, &pDeviceInfo->Caps ) ) )
  344.         {
  345.             delete pDeviceInfo;
  346.             continue;
  347.         }
  348.         // Get info for each devicecombo on this device
  349.         if( FAILED( hr = EnumerateDeviceCombos(pDeviceInfo, pAdapterFormatList) ) )
  350.         {
  351.             delete pDeviceInfo;
  352.             return hr;
  353.         }
  354.         // If at least one devicecombo for this device is found, 
  355.         // add the deviceInfo to the list
  356.         if (pDeviceInfo->pDeviceComboList->Count() == 0)
  357.         {
  358.             delete pDeviceInfo;
  359.             continue;
  360.         }
  361.         pAdapterInfo->pDeviceInfoList->Add(pDeviceInfo);
  362.     }
  363.     return S_OK;
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Name: EnumerateDeviceCombos
  367. // Desc: Enumerates DeviceCombos for a particular device.
  368. //-----------------------------------------------------------------------------
  369. HRESULT CD3DEnumeration::EnumerateDeviceCombos( D3DDeviceInfo* pDeviceInfo, 
  370.                                                CArrayList* pAdapterFormatList )
  371. {
  372.     const D3DFORMAT backBufferFormatArray[] = 
  373.         {   D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A2R10G10B10, 
  374.             D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5 };
  375.     const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
  376.     bool isWindowedArray[] = { false, true };
  377.     // See which adapter formats are supported by this device
  378.     D3DFORMAT adapterFormat;
  379.     for( UINT iaf = 0; iaf < pAdapterFormatList->Count(); iaf++ )
  380.     {
  381.         adapterFormat = *(D3DFORMAT*)pAdapterFormatList->GetPtr(iaf);
  382.         D3DFORMAT backBufferFormat;
  383.         for( UINT ibbf = 0; ibbf < backBufferFormatArrayCount; ibbf++ )
  384.         {
  385.             backBufferFormat = backBufferFormatArray[ibbf];
  386.             if (AlphaChannelBits(backBufferFormat) < AppMinAlphaChannelBits)
  387.                 continue;
  388.             bool isWindowed;
  389.             for( UINT iiw = 0; iiw < 2; iiw++)
  390.             {
  391.                 isWindowed = isWindowedArray[iiw];
  392.                 if (!isWindowed && AppRequiresWindowed)
  393.                     continue;
  394.                 if (isWindowed && AppRequiresFullscreen)
  395.                     continue;
  396.                 if (FAILED(m_pD3D->CheckDeviceType(pDeviceInfo->AdapterOrdinal, pDeviceInfo->DevType, 
  397.                     adapterFormat, backBufferFormat, isWindowed)))
  398.                 {
  399.                     continue;
  400.                 }
  401.                 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
  402.                 // DeviceCombo that is supported by the system.  We still need to confirm that it's 
  403.                 // compatible with the app, and find one or more suitable depth/stencil buffer format,
  404.                 // multisample type, vertex processing type, and present interval.
  405.                 D3DDeviceCombo* pDeviceCombo = NULL;
  406.                 pDeviceCombo = new D3DDeviceCombo;
  407.                 if( pDeviceCombo == NULL )
  408.                     return E_OUTOFMEMORY;
  409.                 pDeviceCombo->pDepthStencilFormatList = new CArrayList( AL_VALUE, sizeof( D3DFORMAT ) );
  410.                 pDeviceCombo->pMultiSampleTypeList = new CArrayList( AL_VALUE, sizeof( D3DMULTISAMPLE_TYPE ) );
  411.                 pDeviceCombo->pMultiSampleQualityList = new CArrayList( AL_VALUE, sizeof( DWORD ) );
  412.                 pDeviceCombo->pDSMSConflictList = new CArrayList( AL_VALUE, sizeof( D3DDSMSConflict ) );
  413.                 pDeviceCombo->pVertexProcessingTypeList = new CArrayList( AL_VALUE, sizeof( VertexProcessingType ) );
  414.                 pDeviceCombo->pPresentIntervalList = new CArrayList( AL_VALUE, sizeof( UINT ) );
  415.                 if( pDeviceCombo->pDepthStencilFormatList == NULL ||
  416.                     pDeviceCombo->pMultiSampleTypeList == NULL || 
  417.                     pDeviceCombo->pMultiSampleQualityList == NULL || 
  418.                     pDeviceCombo->pDSMSConflictList == NULL || 
  419.                     pDeviceCombo->pVertexProcessingTypeList == NULL ||
  420.                     pDeviceCombo->pPresentIntervalList == NULL )
  421.                 {
  422.                     delete pDeviceCombo;
  423.                     return E_OUTOFMEMORY;
  424.                 }
  425.                 pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;
  426.                 pDeviceCombo->DevType = pDeviceInfo->DevType;
  427.                 pDeviceCombo->AdapterFormat = adapterFormat;
  428.                 pDeviceCombo->BackBufferFormat = backBufferFormat;
  429.                 pDeviceCombo->IsWindowed = isWindowed;
  430.                 if (AppUsesDepthBuffer)
  431.                 {
  432.                     BuildDepthStencilFormatList(pDeviceCombo);
  433.                     if (pDeviceCombo->pDepthStencilFormatList->Count() == 0)
  434.                     {
  435.                         delete pDeviceCombo;
  436.                         continue;
  437.                     }
  438.                 }
  439.                 BuildMultiSampleTypeList(pDeviceCombo);
  440.                 if (pDeviceCombo->pMultiSampleTypeList->Count() == 0)
  441.                 {
  442.                     delete pDeviceCombo;
  443.                     continue;
  444.                 }
  445.                 BuildDSMSConflictList(pDeviceCombo);
  446.                 BuildVertexProcessingTypeList(pDeviceInfo, pDeviceCombo);
  447.                 if (pDeviceCombo->pVertexProcessingTypeList->Count() == 0)
  448.                 {
  449.                     delete pDeviceCombo;
  450.                     continue;
  451.                 }
  452.                 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo);
  453.                 pDeviceInfo->pDeviceComboList->Add(pDeviceCombo);
  454.             }
  455.         }
  456.     }
  457.     return S_OK;
  458. }
  459. //-----------------------------------------------------------------------------
  460. // Name: BuildDepthStencilFormatList
  461. // Desc: Adds all depth/stencil formats that are compatible with the device 
  462. //       and app to the given D3DDeviceCombo.
  463. //-----------------------------------------------------------------------------
  464. void CD3DEnumeration::BuildDepthStencilFormatList( D3DDeviceCombo* pDeviceCombo )
  465. {
  466.     const D3DFORMAT depthStencilFormatArray[] = 
  467.     {
  468.         D3DFMT_D16,
  469.         D3DFMT_D15S1,
  470.         D3DFMT_D24X8,
  471.         D3DFMT_D24S8,
  472.         D3DFMT_D24X4S4,
  473.         D3DFMT_D32,
  474.     };
  475.     const UINT depthStencilFormatArrayCount = sizeof(depthStencilFormatArray) / 
  476.                                               sizeof(depthStencilFormatArray[0]);
  477.     D3DFORMAT depthStencilFmt;
  478.     for( UINT idsf = 0; idsf < depthStencilFormatArrayCount; idsf++ )
  479.     {
  480.         depthStencilFmt = depthStencilFormatArray[idsf];
  481.         if (DepthBits(depthStencilFmt) < AppMinDepthBits)
  482.             continue;
  483.         if (StencilBits(depthStencilFmt) < AppMinStencilBits)
  484.             continue;
  485.         if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal, 
  486.             pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
  487.             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
  488.         {
  489.             if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal, 
  490.                 pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
  491.                 pDeviceCombo->BackBufferFormat, depthStencilFmt)))
  492.             {
  493.                 pDeviceCombo->pDepthStencilFormatList->Add(&depthStencilFmt);
  494.             }
  495.         }
  496.     }
  497. }
  498. //-----------------------------------------------------------------------------
  499. // Name: BuildMultiSampleTypeList
  500. // Desc: Adds all multisample types that are compatible with the device and app to
  501. //       the given D3DDeviceCombo.
  502. //-----------------------------------------------------------------------------
  503. void CD3DEnumeration::BuildMultiSampleTypeList( D3DDeviceCombo* pDeviceCombo )
  504. {
  505.     const D3DMULTISAMPLE_TYPE msTypeArray[] = { 
  506.         D3DMULTISAMPLE_NONE,
  507.         D3DMULTISAMPLE_NONMASKABLE,
  508.         D3DMULTISAMPLE_2_SAMPLES,
  509.         D3DMULTISAMPLE_3_SAMPLES,
  510.         D3DMULTISAMPLE_4_SAMPLES,
  511.         D3DMULTISAMPLE_5_SAMPLES,
  512.         D3DMULTISAMPLE_6_SAMPLES,
  513.         D3DMULTISAMPLE_7_SAMPLES,
  514.         D3DMULTISAMPLE_8_SAMPLES,
  515.         D3DMULTISAMPLE_9_SAMPLES,
  516.         D3DMULTISAMPLE_10_SAMPLES,
  517.         D3DMULTISAMPLE_11_SAMPLES,
  518.         D3DMULTISAMPLE_12_SAMPLES,
  519.         D3DMULTISAMPLE_13_SAMPLES,
  520.         D3DMULTISAMPLE_14_SAMPLES,
  521.         D3DMULTISAMPLE_15_SAMPLES,
  522.         D3DMULTISAMPLE_16_SAMPLES,
  523.     };
  524.     const UINT msTypeArrayCount = sizeof(msTypeArray) / sizeof(msTypeArray[0]);
  525.     D3DMULTISAMPLE_TYPE msType;
  526.     DWORD msQuality;
  527.     for( UINT imst = 0; imst < msTypeArrayCount; imst++ )
  528.     {
  529.         msType = msTypeArray[imst];
  530.         if (SUCCEEDED(m_pD3D->CheckDeviceMultiSampleType(pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType, 
  531.             pDeviceCombo->BackBufferFormat, pDeviceCombo->IsWindowed, msType, &msQuality)))
  532.         {
  533.             pDeviceCombo->pMultiSampleTypeList->Add(&msType);
  534.             pDeviceCombo->pMultiSampleQualityList->Add( &msQuality );
  535.         }
  536.     }
  537. }
  538. //-----------------------------------------------------------------------------
  539. // Name: BuildDSMSConflictList
  540. // Desc: Find any conflicts between the available depth/stencil formats and
  541. //       multisample types.
  542. //-----------------------------------------------------------------------------
  543. void CD3DEnumeration::BuildDSMSConflictList( D3DDeviceCombo* pDeviceCombo )
  544. {
  545.     D3DDSMSConflict DSMSConflict;
  546.     for( UINT ids = 0; ids < pDeviceCombo->pDepthStencilFormatList->Count(); ids++ )
  547.     {
  548.         D3DFORMAT dsFmt = *(D3DFORMAT*)pDeviceCombo->pDepthStencilFormatList->GetPtr(ids);
  549.         for( UINT ims = 0; ims < pDeviceCombo->pMultiSampleTypeList->Count(); ims++ )
  550.         {
  551.             D3DMULTISAMPLE_TYPE msType = *(D3DMULTISAMPLE_TYPE*)pDeviceCombo->pMultiSampleTypeList->GetPtr(ims);
  552.             if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType,
  553.                 dsFmt, pDeviceCombo->IsWindowed, msType, NULL ) ) )
  554.             {
  555.                 DSMSConflict.DSFormat = dsFmt;
  556.                 DSMSConflict.MSType = msType;
  557.                 pDeviceCombo->pDSMSConflictList->Add( &DSMSConflict );
  558.             }
  559.         }
  560.     }
  561. }
  562. //-----------------------------------------------------------------------------
  563. // Name: BuildVertexProcessingTypeList
  564. // Desc: Adds all vertex processing types that are compatible with the device 
  565. //       and app to the given D3DDeviceCombo.
  566. //-----------------------------------------------------------------------------
  567. void CD3DEnumeration::BuildVertexProcessingTypeList( D3DDeviceInfo* pDeviceInfo, 
  568.                                                      D3DDeviceCombo* pDeviceCombo )
  569. {
  570.     VertexProcessingType vpt;
  571.     if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
  572.     {
  573.         if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0)
  574.         {
  575.             if (ConfirmDeviceCallback == NULL ||
  576.                 ConfirmDeviceCallback(&pDeviceInfo->Caps, PURE_HARDWARE_VP, 
  577.                 pDeviceCombo->AdapterFormat, pDeviceCombo->BackBufferFormat))
  578.             {
  579.                 vpt = PURE_HARDWARE_VP;
  580.                 pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  581.             }
  582.         }
  583.         if (ConfirmDeviceCallback == NULL ||
  584.             ConfirmDeviceCallback(&pDeviceInfo->Caps, HARDWARE_VP, 
  585.             pDeviceCombo->AdapterFormat, pDeviceCombo->BackBufferFormat))
  586.         {
  587.             vpt = HARDWARE_VP;
  588.             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  589.         }
  590.         if (AppUsesMixedVP && (ConfirmDeviceCallback == NULL ||
  591.             ConfirmDeviceCallback(&pDeviceInfo->Caps, MIXED_VP, 
  592.             pDeviceCombo->AdapterFormat, pDeviceCombo->BackBufferFormat)))
  593.         {
  594.             vpt = MIXED_VP;
  595.             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  596.         }
  597.     }
  598.     if (ConfirmDeviceCallback == NULL ||
  599.         ConfirmDeviceCallback(&pDeviceInfo->Caps, SOFTWARE_VP, 
  600.         pDeviceCombo->AdapterFormat, pDeviceCombo->BackBufferFormat))
  601.     {
  602.         vpt = SOFTWARE_VP;
  603.         pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
  604.     }
  605. }
  606. //-----------------------------------------------------------------------------
  607. // Name: BuildPresentIntervalList
  608. // Desc: Adds all present intervals that are compatible with the device and app 
  609. //       to the given D3DDeviceCombo.
  610. //-----------------------------------------------------------------------------
  611. void CD3DEnumeration::BuildPresentIntervalList( D3DDeviceInfo* pDeviceInfo, 
  612.                                                 D3DDeviceCombo* pDeviceCombo )
  613. {
  614.     const UINT piArray[] = { 
  615.         D3DPRESENT_INTERVAL_IMMEDIATE,
  616.         D3DPRESENT_INTERVAL_DEFAULT,
  617.         D3DPRESENT_INTERVAL_ONE,
  618.         D3DPRESENT_INTERVAL_TWO,
  619.         D3DPRESENT_INTERVAL_THREE,
  620.         D3DPRESENT_INTERVAL_FOUR,
  621.     };
  622.     const UINT piArrayCount = sizeof(piArray) / sizeof(piArray[0]);
  623.     UINT pi;
  624.     for( UINT ipi = 0; ipi < piArrayCount; ipi++ )
  625.     {
  626.         pi = piArray[ipi];
  627.         if( pDeviceCombo->IsWindowed )
  628.         {
  629.             if( pi == D3DPRESENT_INTERVAL_TWO ||
  630.                 pi == D3DPRESENT_INTERVAL_THREE ||
  631.                 pi == D3DPRESENT_INTERVAL_FOUR )
  632.             {
  633.                 // These intervals are not supported in windowed mode.
  634.                 continue;
  635.             }
  636.         }
  637.         // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
  638.         // can't do a caps check for it -- it is always available.
  639.         if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
  640.             (pDeviceInfo->Caps.PresentationIntervals & pi) )
  641.         {
  642.             pDeviceCombo->pPresentIntervalList->Add( &pi );
  643.         }
  644.     }
  645. }