0001: //-----------------------------------------------------------------------------
0002: // File: D3DEnumeration.cpp
0003: //
0004: // Desc: Enumerates D3D adapters, devices, modes, etc.
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #include <windows.h>
0008: #include <D3D9.h>
0009: #include "DXUtil.h"
0010: #include "D3DEnumeration.h"
0011: 
0012: 
0013: //-----------------------------------------------------------------------------
0014: // Name: ColorChannelBits
0015: // Desc: Returns the number of color channel bits in the specified D3DFORMAT
0016: //-----------------------------------------------------------------------------
0017: static UINT ColorChannelBits( D3DFORMAT fmt )
0018: {
0019:     switch( fmt )
0020:     {
0021:         case D3DFMT_R8G8B8:
0022:             return 8;
0023:         case D3DFMT_A8R8G8B8:
0024:             return 8;
0025:         case D3DFMT_X8R8G8B8:
0026:             return 8;
0027:         case D3DFMT_R5G6B5:
0028:             return 5;
0029:         case D3DFMT_X1R5G5B5:
0030:             return 5;
0031:         case D3DFMT_A1R5G5B5:
0032:             return 5;
0033:         case D3DFMT_A4R4G4B4:
0034:             return 4;
0035:         case D3DFMT_R3G3B2:
0036:             return 2;
0037:         case D3DFMT_A8R3G3B2:
0038:             return 2;
0039:         case D3DFMT_X4R4G4B4:
0040:             return 4;
0041:         case D3DFMT_A2B10G10R10:
0042:             return 10;
0043:         case D3DFMT_A2R10G10B10:
0044:             return 10;
0045:         default:
0046:             return 0;
0047:     }
0048: }
0049: 
0050: 
0051: 
0052: 
0053: //-----------------------------------------------------------------------------
0054: // Name: AlphaChannelBits
0055: // Desc: Returns the number of alpha channel bits in the specified D3DFORMAT
0056: //-----------------------------------------------------------------------------
0057: static UINT AlphaChannelBits( D3DFORMAT fmt )
0058: {
0059:     switch( fmt )
0060:     {
0061:         case D3DFMT_R8G8B8:
0062:             return 0;
0063:         case D3DFMT_A8R8G8B8:
0064:             return 8;
0065:         case D3DFMT_X8R8G8B8:
0066:             return 0;
0067:         case D3DFMT_R5G6B5:
0068:             return 0;
0069:         case D3DFMT_X1R5G5B5:
0070:             return 0;
0071:         case D3DFMT_A1R5G5B5:
0072:             return 1;
0073:         case D3DFMT_A4R4G4B4:
0074:             return 4;
0075:         case D3DFMT_R3G3B2:
0076:             return 0;
0077:         case D3DFMT_A8R3G3B2:
0078:             return 8;
0079:         case D3DFMT_X4R4G4B4:
0080:             return 0;
0081:         case D3DFMT_A2B10G10R10:
0082:             return 2;
0083:         case D3DFMT_A2R10G10B10:
0084:             return 2;
0085:         default:
0086:             return 0;
0087:     }
0088: }
0089: 
0090: 
0091: 
0092: 
0093: //-----------------------------------------------------------------------------
0094: // Name: DepthBits
0095: // Desc: Returns the number of depth bits in the specified D3DFORMAT
0096: //-----------------------------------------------------------------------------
0097: static UINT DepthBits( D3DFORMAT fmt )
0098: {
0099:     switch( fmt )
0100:     {
0101:         case D3DFMT_D16:
0102:             return 16;
0103:         case D3DFMT_D15S1:
0104:             return 15;
0105:         case D3DFMT_D24X8:
0106:             return 24;
0107:         case D3DFMT_D24S8:
0108:             return 24;
0109:         case D3DFMT_D24X4S4:
0110:             return 24;
0111:         case D3DFMT_D32:
0112:             return 32;
0113:         default:
0114:             return 0;
0115:     }
0116: }
0117: 
0118: 
0119: 
0120: 
0121: //-----------------------------------------------------------------------------
0122: // Name: StencilBits
0123: // Desc: Returns the number of stencil bits in the specified D3DFORMAT
0124: //-----------------------------------------------------------------------------
0125: static UINT StencilBits( D3DFORMAT fmt )
0126: {
0127:     switch( fmt )
0128:     {
0129:         case D3DFMT_D16:
0130:             return 0;
0131:         case D3DFMT_D15S1:
0132:             return 1;
0133:         case D3DFMT_D24X8:
0134:             return 0;
0135:         case D3DFMT_D24S8:
0136:             return 8;
0137:         case D3DFMT_D24X4S4:
0138:             return 4;
0139:         case D3DFMT_D32:
0140:             return 0;
0141:         default:
0142:             return 0;
0143:     }
0144: }
0145: 
0146: 
0147: 
0148: 
0149: //-----------------------------------------------------------------------------
0150: // Name: D3DAdapterInfo destructor
0151: // Desc: 
0152: //-----------------------------------------------------------------------------
0153: D3DAdapterInfo::~D3DAdapterInfo( void )
0154: {
0155:     if( pDisplayModeList != NULL )
0156:         delete pDisplayModeList;
0157:     if( pDeviceInfoList != NULL )
0158:     {
0159:         for( UINT idi = 0; idi < pDeviceInfoList->Count(); idi++ )
0160:             delete (D3DDeviceInfo*)pDeviceInfoList->GetPtr(idi);
0161:         delete pDeviceInfoList;
0162:     }
0163: }
0164: 
0165: 
0166: 
0167: 
0168: //-----------------------------------------------------------------------------
0169: // Name: D3DDeviceInfo destructor
0170: // Desc: 
0171: //-----------------------------------------------------------------------------
0172: D3DDeviceInfo::~D3DDeviceInfo( void )
0173: {
0174:     if( pDeviceComboList != NULL )
0175:     {
0176:         for( UINT idc = 0; idc < pDeviceComboList->Count(); idc++ )
0177:             delete (D3DDeviceCombo*)pDeviceComboList->GetPtr(idc);
0178:         delete pDeviceComboList;
0179:     }
0180: }
0181: 
0182: 
0183: 
0184: 
0185: //-----------------------------------------------------------------------------
0186: // Name: D3DDeviceCombo destructor
0187: // Desc: 
0188: //-----------------------------------------------------------------------------
0189: D3DDeviceCombo::~D3DDeviceCombo( void )
0190: {
0191:     if( pDepthStencilFormatList != NULL )
0192:         delete pDepthStencilFormatList;
0193:     if( pMultiSampleTypeList != NULL )
0194:         delete pMultiSampleTypeList;
0195:     if( pMultiSampleQualityList != NULL )
0196:         delete pMultiSampleQualityList;
0197:     if( pDSMSConflictList != NULL )
0198:         delete pDSMSConflictList;
0199:     if( pVertexProcessingTypeList != NULL )
0200:         delete pVertexProcessingTypeList;
0201:     if( pPresentIntervalList != NULL )
0202:         delete pPresentIntervalList;
0203: }
0204: 
0205: 
0206: 
0207: //-----------------------------------------------------------------------------
0208: // Name: CD3DEnumeration constructor
0209: // Desc: 
0210: //-----------------------------------------------------------------------------
0211: CD3DEnumeration::CD3DEnumeration()
0212: {
0213:     m_pAdapterInfoList = NULL;
0214:     m_pAllowedAdapterFormatList = NULL;
0215:     AppMinFullscreenWidth = 640;
0216:     AppMinFullscreenHeight = 480;
0217:     AppMinColorChannelBits = 5;
0218:     AppMinAlphaChannelBits = 0;
0219:     AppMinDepthBits = 15;
0220:     AppMinStencilBits = 0;
0221:     AppUsesDepthBuffer = false;
0222:     AppUsesMixedVP = false;
0223:     AppRequiresWindowed = false;
0224:     AppRequiresFullscreen = false;
0225: }
0226: 
0227: 
0228: 
0229: 
0230: //-----------------------------------------------------------------------------
0231: // Name: CD3DEnumeration destructor
0232: // Desc: 
0233: //-----------------------------------------------------------------------------
0234: CD3DEnumeration::~CD3DEnumeration()
0235: {
0236:     if( m_pAdapterInfoList != NULL )
0237:     {
0238:         for( UINT iai = 0; iai < m_pAdapterInfoList->Count(); iai++ )
0239:             delete (D3DAdapterInfo*)m_pAdapterInfoList->GetPtr(iai);
0240:         delete m_pAdapterInfoList;
0241:     }
0242:     SAFE_DELETE( m_pAllowedAdapterFormatList );
0243: }
0244: 
0245: 
0246: 
0247: 
0248: //-----------------------------------------------------------------------------
0249: // Name: SortModesCallback
0250: // Desc: Used to sort D3DDISPLAYMODEs
0251: //-----------------------------------------------------------------------------
0252: static int __cdecl SortModesCallback( const void* arg1, const void* arg2 )
0253: {
0254:     D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
0255:     D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
0256: 
0257:     if (pdm1->Width > pdm2->Width)
0258:         return 1;
0259:     if (pdm1->Width < pdm2->Width)
0260:         return -1;
0261:     if (pdm1->Height > pdm2->Height)
0262:         return 1;
0263:     if (pdm1->Height < pdm2->Height)
0264:         return -1;
0265:     if (pdm1->Format > pdm2->Format)
0266:         return 1;
0267:     if (pdm1->Format < pdm2->Format)
0268:         return -1;
0269:     if (pdm1->RefreshRate > pdm2->RefreshRate)
0270:         return 1;
0271:     if (pdm1->RefreshRate < pdm2->RefreshRate)
0272:         return -1;
0273:     return 0;
0274: }
0275: 
0276: 
0277: 
0278: 
0279: //-----------------------------------------------------------------------------
0280: // Name: Enumerate
0281: // Desc: Enumerates available D3D adapters, devices, modes, etc.
0282: //-----------------------------------------------------------------------------
0283: HRESULT CD3DEnumeration::Enumerate()
0284: {
0285:     HRESULT hr;
0286:     CArrayList adapterFormatList( AL_VALUE, sizeof(D3DFORMAT) );
0287: 
0288:     if( m_pD3D == NULL )
0289:         return E_FAIL;
0290: 
0291:     m_pAdapterInfoList = new CArrayList( AL_REFERENCE );
0292:     if( m_pAdapterInfoList == NULL )
0293:         return E_OUTOFMEMORY;
0294: 
0295:     m_pAllowedAdapterFormatList = new CArrayList( AL_VALUE, sizeof(D3DFORMAT) );
0296:     if( m_pAllowedAdapterFormatList == NULL )
0297:         return E_OUTOFMEMORY;
0298:     D3DFORMAT fmt;
0299:     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X8R8G8B8 ) ) ) )
0300:         return hr;
0301:     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_X1R5G5B5 ) ) ) )
0302:         return hr;
0303:     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_R5G6B5 ) ) ) )
0304:         return hr;
0305:     if( FAILED( hr = m_pAllowedAdapterFormatList->Add( &( fmt = D3DFMT_A2R10G10B10 ) ) ) )
0306:         return hr;
0307: 
0308:     D3DAdapterInfo* pAdapterInfo = NULL;
0309:     UINT numAdapters = m_pD3D->GetAdapterCount();
0310: 
0311:     for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++)
0312:     {
0313:         pAdapterInfo = new D3DAdapterInfo;
0314:         if( pAdapterInfo == NULL )
0315:             return E_OUTOFMEMORY;
0316:         pAdapterInfo->pDisplayModeList = new CArrayList( AL_VALUE, sizeof(D3DDISPLAYMODE)); 
0317:         pAdapterInfo->pDeviceInfoList = new CArrayList( AL_REFERENCE );
0318:         if( pAdapterInfo->pDisplayModeList == NULL ||
0319:             pAdapterInfo->pDeviceInfoList == NULL )
0320:         {
0321:             delete pAdapterInfo;
0322:             return E_OUTOFMEMORY;
0323:         }
0324:         pAdapterInfo->AdapterOrdinal = adapterOrdinal;
0325:         m_pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier);
0326: 
0327:         // Get list of all display modes on this adapter.  
0328:         // Also build a temporary list of all display adapter formats.
0329:         adapterFormatList.Clear();
0330:         for( UINT iaaf = 0; iaaf < m_pAllowedAdapterFormatList->Count(); iaaf++ )
0331:         {
0332:             D3DFORMAT allowedAdapterFormat = *(D3DFORMAT*)m_pAllowedAdapterFormatList->GetPtr( iaaf );
0333:             UINT numAdapterModes = m_pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat );
0334:             for (UINT mode = 0; mode < numAdapterModes; mode++)
0335:             {
0336:                 D3DDISPLAYMODE displayMode;
0337:                 m_pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode );
0338:                 if( displayMode.Width < AppMinFullscreenWidth ||
0339:                     displayMode.Height < AppMinFullscreenHeight ||
0340:                     ColorChannelBits(displayMode.Format) < AppMinColorChannelBits )
0341:                 {
0342:                     continue;
0343:                 }
0344:                 pAdapterInfo->pDisplayModeList->Add(&displayMode);
0345:                 if( !adapterFormatList.Contains( &displayMode.Format ) )
0346:                     adapterFormatList.Add( &displayMode.Format );
0347:             }
0348:         }
0349: 
0350:         // Sort displaymode list
0351:         qsort( pAdapterInfo->pDisplayModeList->GetPtr(0), 
0352:             pAdapterInfo->pDisplayModeList->Count(), sizeof( D3DDISPLAYMODE ),
0353:             SortModesCallback );
0354: 
0355:         // Get info for each device on this adapter
0356:         if( FAILED( hr = EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) )
0357:         {
0358:             delete pAdapterInfo;
0359:             return hr;
0360:         }
0361: 
0362:         // If at least one device on this adapter is available and compatible
0363:         // with the app, add the adapterInfo to the list
0364:         if (pAdapterInfo->pDeviceInfoList->Count() == 0)
0365:             delete pAdapterInfo;
0366:         else
0367:             m_pAdapterInfoList->Add(pAdapterInfo);
0368:     }
0369:     return S_OK;
0370: }
0371: 
0372: 
0373: 
0374: 
0375: //-----------------------------------------------------------------------------
0376: // Name: EnumerateDevices
0377: // Desc: Enumerates D3D devices for a particular adapter.
0378: //-----------------------------------------------------------------------------
0379: HRESULT CD3DEnumeration::EnumerateDevices( D3DAdapterInfo* pAdapterInfo, 
0380:                                            CArrayList* pAdapterFormatList )
0381: {
0382:     const D3DDEVTYPE devTypeArray[] = { D3DDEVTYPE_HAL, D3DDEVTYPE_SW, D3DDEVTYPE_REF };
0383:     const UINT devTypeArrayCount = sizeof(devTypeArray) / sizeof(devTypeArray[0]);
0384:     HRESULT hr;
0385: 
0386:     D3DDeviceInfo* pDeviceInfo = NULL;
0387:     for( UINT idt = 0; idt < devTypeArrayCount; idt++ )
0388:     {
0389:         pDeviceInfo = new D3DDeviceInfo;
0390:         if( pDeviceInfo == NULL )
0391:             return E_OUTOFMEMORY;
0392:         pDeviceInfo->pDeviceComboList = new CArrayList( AL_REFERENCE ); 
0393:         if( pDeviceInfo->pDeviceComboList == NULL )
0394:         {
0395:             delete pDeviceInfo;
0396:             return E_OUTOFMEMORY;
0397:         }
0398:         pDeviceInfo->AdapterOrdinal = pAdapterInfo->AdapterOrdinal;
0399:         pDeviceInfo->DevType = devTypeArray[idt];
0400:         if( FAILED( m_pD3D->GetDeviceCaps( pAdapterInfo->AdapterOrdinal, 
0401:             pDeviceInfo->DevType, &pDeviceInfo->Caps ) ) )
0402:         {
0403:             delete pDeviceInfo;
0404:             continue;
0405:         }
0406: 
0407:         // Get info for each devicecombo on this device
0408:         if( FAILED( hr = EnumerateDeviceCombos(pDeviceInfo, pAdapterFormatList) ) )
0409:         {
0410:             delete pDeviceInfo;
0411:             return hr;
0412:         }
0413: 
0414:         // If at least one devicecombo for this device is found, 
0415:         // add the deviceInfo to the list
0416:         if (pDeviceInfo->pDeviceComboList->Count() == 0)
0417:         {
0418:             delete pDeviceInfo;
0419:             continue;
0420:         }
0421:         pAdapterInfo->pDeviceInfoList->Add(pDeviceInfo);
0422:     }
0423:     return S_OK;
0424: }
0425: 
0426: 
0427: 
0428: 
0429: //-----------------------------------------------------------------------------
0430: // Name: EnumerateDeviceCombos
0431: // Desc: Enumerates DeviceCombos for a particular device.
0432: //-----------------------------------------------------------------------------
0433: HRESULT CD3DEnumeration::EnumerateDeviceCombos( D3DDeviceInfo* pDeviceInfo, 
0434:                                                CArrayList* pAdapterFormatList )
0435: {
0436:     const D3DFORMAT backBufferFormatArray[] = 
0437:         {   D3DFMT_A8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A2R10G10B10, 
0438:             D3DFMT_R5G6B5, D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5 };
0439:     const UINT backBufferFormatArrayCount = sizeof(backBufferFormatArray) / sizeof(backBufferFormatArray[0]);
0440:     bool isWindowedArray[] = { false, true };
0441: 
0442:     // See which adapter formats are supported by this device
0443:     D3DFORMAT adapterFormat;
0444:     for( UINT iaf = 0; iaf < pAdapterFormatList->Count(); iaf++ )
0445:     {
0446:         adapterFormat = *(D3DFORMAT*)pAdapterFormatList->GetPtr(iaf);
0447:         D3DFORMAT backBufferFormat;
0448:         for( UINT ibbf = 0; ibbf < backBufferFormatArrayCount; ibbf++ )
0449:         {
0450:             backBufferFormat = backBufferFormatArray[ibbf];
0451:             if (AlphaChannelBits(backBufferFormat) < AppMinAlphaChannelBits)
0452:                 continue;
0453:             bool isWindowed;
0454:             for( UINT iiw = 0; iiw < 2; iiw++)
0455:             {
0456:                 isWindowed = isWindowedArray[iiw];
0457:                 if (!isWindowed && AppRequiresWindowed)
0458:                     continue;
0459:                 if (isWindowed && AppRequiresFullscreen)
0460:                     continue;
0461:                 if (FAILED(m_pD3D->CheckDeviceType(pDeviceInfo->AdapterOrdinal, pDeviceInfo->DevType, 
0462:                     adapterFormat, backBufferFormat, isWindowed)))
0463:                 {
0464:                     continue;
0465:                 }
0466:                 // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
0467:                 // DeviceCombo that is supported by the system.  We still need to confirm that it's 
0468:                 // compatible with the app, and find one or more suitable depth/stencil buffer format,
0469:                 // multisample type, vertex processing type, and present interval.
0470:                 D3DDeviceCombo* pDeviceCombo = NULL;
0471:                 pDeviceCombo = new D3DDeviceCombo;
0472:                 if( pDeviceCombo == NULL )
0473:                     return E_OUTOFMEMORY;
0474:                 pDeviceCombo->pDepthStencilFormatList = new CArrayList( AL_VALUE, sizeof( D3DFORMAT ) );
0475:                 pDeviceCombo->pMultiSampleTypeList = new CArrayList( AL_VALUE, sizeof( D3DMULTISAMPLE_TYPE ) );
0476:                 pDeviceCombo->pMultiSampleQualityList = new CArrayList( AL_VALUE, sizeof( DWORD ) );
0477:                 pDeviceCombo->pDSMSConflictList = new CArrayList( AL_VALUE, sizeof( D3DDSMSConflict ) );
0478:                 pDeviceCombo->pVertexProcessingTypeList = new CArrayList( AL_VALUE, sizeof( VertexProcessingType ) );
0479:                 pDeviceCombo->pPresentIntervalList = new CArrayList( AL_VALUE, sizeof( UINT ) );
0480:                 if( pDeviceCombo->pDepthStencilFormatList == NULL ||
0481:                     pDeviceCombo->pMultiSampleTypeList == NULL || 
0482:                     pDeviceCombo->pMultiSampleQualityList == NULL || 
0483:                     pDeviceCombo->pDSMSConflictList == NULL || 
0484:                     pDeviceCombo->pVertexProcessingTypeList == NULL ||
0485:                     pDeviceCombo->pPresentIntervalList == NULL )
0486:                 {
0487:                     delete pDeviceCombo;
0488:                     return E_OUTOFMEMORY;
0489:                 }
0490:                 pDeviceCombo->AdapterOrdinal = pDeviceInfo->AdapterOrdinal;
0491:                 pDeviceCombo->DevType = pDeviceInfo->DevType;
0492:                 pDeviceCombo->AdapterFormat = adapterFormat;
0493:                 pDeviceCombo->BackBufferFormat = backBufferFormat;
0494:                 pDeviceCombo->IsWindowed = isWindowed;
0495:                 if (AppUsesDepthBuffer)
0496:                 {
0497:                     BuildDepthStencilFormatList(pDeviceCombo);
0498:                     if (pDeviceCombo->pDepthStencilFormatList->Count() == 0)
0499:                     {
0500:                         delete pDeviceCombo;
0501:                         continue;
0502:                     }
0503:                 }
0504:                 BuildMultiSampleTypeList(pDeviceCombo);
0505:                 if (pDeviceCombo->pMultiSampleTypeList->Count() == 0)
0506:                 {
0507:                     delete pDeviceCombo;
0508:                     continue;
0509:                 }
0510:                 BuildDSMSConflictList(pDeviceCombo);
0511:                 BuildVertexProcessingTypeList(pDeviceInfo, pDeviceCombo);
0512:                 if (pDeviceCombo->pVertexProcessingTypeList->Count() == 0)
0513:                 {
0514:                     delete pDeviceCombo;
0515:                     continue;
0516:                 }
0517:                 BuildPresentIntervalList(pDeviceInfo, pDeviceCombo);
0518: 
0519:                 pDeviceInfo->pDeviceComboList->Add(pDeviceCombo);
0520:             }
0521:         }
0522:     }
0523: 
0524:     return S_OK;
0525: }
0526: 
0527: 
0528: 
0529: 
0530: //-----------------------------------------------------------------------------
0531: // Name: BuildDepthStencilFormatList
0532: // Desc: Adds all depth/stencil formats that are compatible with the device 
0533: //       and app to the given D3DDeviceCombo.
0534: //-----------------------------------------------------------------------------
0535: void CD3DEnumeration::BuildDepthStencilFormatList( D3DDeviceCombo* pDeviceCombo )
0536: {
0537:     const D3DFORMAT depthStencilFormatArray[] = 
0538:     {
0539:         D3DFMT_D16,
0540:         D3DFMT_D15S1,
0541:         D3DFMT_D24X8,
0542:         D3DFMT_D24S8,
0543:         D3DFMT_D24X4S4,
0544:         D3DFMT_D32,
0545:     };
0546:     const UINT depthStencilFormatArrayCount = sizeof(depthStencilFormatArray) / 
0547:                                               sizeof(depthStencilFormatArray[0]);
0548: 
0549:     D3DFORMAT depthStencilFmt;
0550:     for( UINT idsf = 0; idsf < depthStencilFormatArrayCount; idsf++ )
0551:     {
0552:         depthStencilFmt = depthStencilFormatArray[idsf];
0553:         if (DepthBits(depthStencilFmt) < AppMinDepthBits)
0554:             continue;
0555:         if (StencilBits(depthStencilFmt) < AppMinStencilBits)
0556:             continue;
0557:         if (SUCCEEDED(m_pD3D->CheckDeviceFormat(pDeviceCombo->AdapterOrdinal, 
0558:             pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
0559:             D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFmt)))
0560:         {
0561:             if (SUCCEEDED(m_pD3D->CheckDepthStencilMatch(pDeviceCombo->AdapterOrdinal, 
0562:                 pDeviceCombo->DevType, pDeviceCombo->AdapterFormat, 
0563:                 pDeviceCombo->BackBufferFormat, depthStencilFmt)))
0564:             {
0565:                 pDeviceCombo->pDepthStencilFormatList->Add(&depthStencilFmt);
0566:             }
0567:         }
0568:     }
0569: }
0570: 
0571: 
0572: 
0573: 
0574: //-----------------------------------------------------------------------------
0575: // Name: BuildMultiSampleTypeList
0576: // Desc: Adds all multisample types that are compatible with the device and app to
0577: //       the given D3DDeviceCombo.
0578: //-----------------------------------------------------------------------------
0579: void CD3DEnumeration::BuildMultiSampleTypeList( D3DDeviceCombo* pDeviceCombo )
0580: {
0581:     const D3DMULTISAMPLE_TYPE msTypeArray[] = { 
0582:         D3DMULTISAMPLE_NONE,
0583:         D3DMULTISAMPLE_NONMASKABLE,
0584:         D3DMULTISAMPLE_2_SAMPLES,
0585:         D3DMULTISAMPLE_3_SAMPLES,
0586:         D3DMULTISAMPLE_4_SAMPLES,
0587:         D3DMULTISAMPLE_5_SAMPLES,
0588:         D3DMULTISAMPLE_6_SAMPLES,
0589:         D3DMULTISAMPLE_7_SAMPLES,
0590:         D3DMULTISAMPLE_8_SAMPLES,
0591:         D3DMULTISAMPLE_9_SAMPLES,
0592:         D3DMULTISAMPLE_10_SAMPLES,
0593:         D3DMULTISAMPLE_11_SAMPLES,
0594:         D3DMULTISAMPLE_12_SAMPLES,
0595:         D3DMULTISAMPLE_13_SAMPLES,
0596:         D3DMULTISAMPLE_14_SAMPLES,
0597:         D3DMULTISAMPLE_15_SAMPLES,
0598:         D3DMULTISAMPLE_16_SAMPLES,
0599:     };
0600:     const UINT msTypeArrayCount = sizeof(msTypeArray) / sizeof(msTypeArray[0]);
0601: 
0602:     D3DMULTISAMPLE_TYPE msType;
0603:     DWORD msQuality;
0604:     for( UINT imst = 0; imst < msTypeArrayCount; imst++ )
0605:     {
0606:         msType = msTypeArray[imst];
0607:         if (SUCCEEDED(m_pD3D->CheckDeviceMultiSampleType(pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType, 
0608:             pDeviceCombo->BackBufferFormat, pDeviceCombo->IsWindowed, msType, &msQuality)))
0609:         {
0610:             pDeviceCombo->pMultiSampleTypeList->Add(&msType);
0611:             pDeviceCombo->pMultiSampleQualityList->Add( &msQuality );
0612:         }
0613:     }
0614: }
0615: 
0616: 
0617: 
0618: 
0619: //-----------------------------------------------------------------------------
0620: // Name: BuildDSMSConflictList
0621: // Desc: Find any conflicts between the available depth/stencil formats and
0622: //       multisample types.
0623: //-----------------------------------------------------------------------------
0624: void CD3DEnumeration::BuildDSMSConflictList( D3DDeviceCombo* pDeviceCombo )
0625: {
0626:     D3DDSMSConflict DSMSConflict;
0627: 
0628:     for( UINT ids = 0; ids < pDeviceCombo->pDepthStencilFormatList->Count(); ids++ )
0629:     {
0630:         D3DFORMAT dsFmt = *(D3DFORMAT*)pDeviceCombo->pDepthStencilFormatList->GetPtr(ids);
0631:         for( UINT ims = 0; ims < pDeviceCombo->pMultiSampleTypeList->Count(); ims++ )
0632:         {
0633:             D3DMULTISAMPLE_TYPE msType = *(D3DMULTISAMPLE_TYPE*)pDeviceCombo->pMultiSampleTypeList->GetPtr(ims);
0634:             if( FAILED( m_pD3D->CheckDeviceMultiSampleType( pDeviceCombo->AdapterOrdinal, pDeviceCombo->DevType,
0635:                 dsFmt, pDeviceCombo->IsWindowed, msType, NULL ) ) )
0636:             {
0637:                 DSMSConflict.DSFormat = dsFmt;
0638:                 DSMSConflict.MSType = msType;
0639:                 pDeviceCombo->pDSMSConflictList->Add( &DSMSConflict );
0640:             }
0641:         }
0642:     }
0643: }
0644: 
0645: 
0646: 
0647: 
0648: //-----------------------------------------------------------------------------
0649: // Name: BuildVertexProcessingTypeList
0650: // Desc: Adds all vertex processing types that are compatible with the device 
0651: //       and app to the given D3DDeviceCombo.
0652: //-----------------------------------------------------------------------------
0653: void CD3DEnumeration::BuildVertexProcessingTypeList( D3DDeviceInfo* pDeviceInfo, 
0654:                                                      D3DDeviceCombo* pDeviceCombo )
0655: {
0656:     VertexProcessingType vpt;
0657:     if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0)
0658:     {
0659:         if ((pDeviceInfo->Caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0)
0660:         {
0661:             if (ConfirmDeviceCallback == NULL ||
0662:                 ConfirmDeviceCallback(&pDeviceInfo->Caps, PURE_HARDWARE_VP, pDeviceCombo->BackBufferFormat))
0663:             {
0664:                 vpt = PURE_HARDWARE_VP;
0665:                 pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
0666:             }
0667:         }
0668:         if (ConfirmDeviceCallback == NULL ||
0669:             ConfirmDeviceCallback(&pDeviceInfo->Caps, HARDWARE_VP, pDeviceCombo->BackBufferFormat))
0670:         {
0671:             vpt = HARDWARE_VP;
0672:             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
0673:         }
0674:         if (AppUsesMixedVP && (ConfirmDeviceCallback == NULL ||
0675:             ConfirmDeviceCallback(&pDeviceInfo->Caps, MIXED_VP, pDeviceCombo->BackBufferFormat)))
0676:         {
0677:             vpt = MIXED_VP;
0678:             pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
0679:         }
0680:     }
0681:     if (ConfirmDeviceCallback == NULL ||
0682:         ConfirmDeviceCallback(&pDeviceInfo->Caps, SOFTWARE_VP, pDeviceCombo->BackBufferFormat))
0683:     {
0684:         vpt = SOFTWARE_VP;
0685:         pDeviceCombo->pVertexProcessingTypeList->Add(&vpt);
0686:     }
0687: }
0688: 
0689: 
0690: 
0691: 
0692: //-----------------------------------------------------------------------------
0693: // Name: BuildPresentIntervalList
0694: // Desc: Adds all present intervals that are compatible with the device and app 
0695: //       to the given D3DDeviceCombo.
0696: //-----------------------------------------------------------------------------
0697: void CD3DEnumeration::BuildPresentIntervalList( D3DDeviceInfo* pDeviceInfo, 
0698:                                                 D3DDeviceCombo* pDeviceCombo )
0699: {
0700:     const UINT piArray[] = { 
0701:         D3DPRESENT_INTERVAL_IMMEDIATE,
0702:         D3DPRESENT_INTERVAL_DEFAULT,
0703:         D3DPRESENT_INTERVAL_ONE,
0704:         D3DPRESENT_INTERVAL_TWO,
0705:         D3DPRESENT_INTERVAL_THREE,
0706:         D3DPRESENT_INTERVAL_FOUR,
0707:     };
0708:     const UINT piArrayCount = sizeof(piArray) / sizeof(piArray[0]);
0709: 
0710:     UINT pi;
0711:     for( UINT ipi = 0; ipi < piArrayCount; ipi++ )
0712:     {
0713:         pi = piArray[ipi];
0714:         if( pDeviceCombo->IsWindowed )
0715:         {
0716:             if( pi == D3DPRESENT_INTERVAL_TWO ||
0717:                 pi == D3DPRESENT_INTERVAL_THREE ||
0718:                 pi == D3DPRESENT_INTERVAL_FOUR )
0719:             {
0720:                 // These intervals are not supported in windowed mode.
0721:                 continue;
0722:             }
0723:         }
0724:         // Note that D3DPRESENT_INTERVAL_DEFAULT is zero, so you
0725:         // can't do a caps check for it -- it is always available.
0726:         if( pi == D3DPRESENT_INTERVAL_DEFAULT ||
0727:             (pDeviceInfo->Caps.PresentationIntervals & pi) )
0728:         {
0729:             pDeviceCombo->pPresentIntervalList->Add( &pi );
0730:         }
0731:     }
0732: }
0733: