bool CVideoDriverDX9::initDriver( const core::dimension2d<u32>& screenSize, HWND hwnd, u32 bits, bool fullScreen, bool pureSoftware, bool highPrecisionFPU, bool vsync, u8 antiAlias ) { DXUTSetCursorSettings( true, true ); DXUTCreateDevice( !fullScreen, screenSize.Width,screenSize.Height ); this->pID3D=DXUTGetD3D9Object(); this->pID3DDevice=DXUTGetD3D9Device(); pID3DDevice->SetFVF(D3DFVF_XYZ); return true; }
//-------------------------------------------------------------------------------------- // Rejects any D3D9 devices that aren't acceptable to the app by returning false //-------------------------------------------------------------------------------------- bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) { // Typically want to skip back buffer formats that don't support alpha blending IDirect3D9* pD3D = DXUTGetD3D9Object(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) ) { return false; } return true; }
//-------------------------------------------------------------------------------------- // This callback function is called immediately before a device is created to allow the // application to modify the device settings. The supplied pDeviceSettings parameter // contains the settings that the framework has selected for the new device, and the // application can make any desired changes directly to this structure. Note however that // DXUT will not correct invalid device settings so care must be taken // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail. //-------------------------------------------------------------------------------------- bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) { assert( DXUT_D3D9_DEVICE == pDeviceSettings->ver ); HRESULT hr; IDirect3D9* pD3D = DXUTGetD3D9Object(); D3DCAPS9 caps; V( pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &caps ) ); // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW // then switch to SWVP. if( ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 || caps.VertexShaderVersion < D3DVS_VERSION( 1, 1 ) ) { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. #ifdef DEBUG_VS if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF ) { pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; #endif // Enable anti-aliasing for HAL devices which support it CD3D9Enumeration* pEnum = DXUTGetD3D9Enumeration(); CD3D9EnumDeviceSettingsCombo* pCombo = pEnum->GetDeviceSettingsCombo( &pDeviceSettings->d3d9 ); if( pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_HAL && pCombo->multiSampleTypeList.Contains( D3DMULTISAMPLE_4_SAMPLES ) ) { pDeviceSettings->d3d9.pp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; pDeviceSettings->d3d9.pp.MultiSampleQuality = 0; } // For the first device created if its a REF device, optionally display a warning dialog box static bool s_bFirstTime = true; if( s_bFirstTime ) { s_bFirstTime = false; if( pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF ) DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); } return true; }
//-------------------------------------------------------------------------------------- // This callback function is called immediately before a device is created to allow the // application to modify the device settings. The supplied pDeviceSettings parameter // contains the settings that the framework has selected for the new device, and the // application can make any desired changes directly to this structure. Note however that // DXUT will not correct invalid device settings so care must be taken // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail. //-------------------------------------------------------------------------------------- bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) { assert( DXUT_D3D9_DEVICE == pDeviceSettings->ver ); HRESULT hr; IDirect3D9* pD3D = DXUTGetD3D9Object(); D3DCAPS9 caps; V( pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &caps ) ); // Turn vsync off pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; g_SettingsDlg.GetDialogControl()->GetComboBox( DXUTSETTINGSDLG_PRESENT_INTERVAL )->SetEnabled( false ); // If device doesn't support HW T&L or doesn't support 2.0 vertex shaders in HW // then switch to SWVP. if( ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 || caps.VertexShaderVersion < D3DVS_VERSION( 2, 0 ) ) { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. #ifdef DEBUG_VS if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF ) { pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; #endif if( caps.MaxVertexBlendMatrices < 2 ) pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // For the first device created if its a REF device, optionally display a warning dialog box static bool s_bFirstTime = true; if( s_bFirstTime ) { s_bFirstTime = false; if( pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF ) DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); } return true; }
bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext) { IDirect3D9* pD3D = DXUTGetD3D9Object(); D3DCAPS9 caps; HRESULT hr; V(pD3D->GetDeviceCaps(pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &caps)); if((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 || caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } else { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; } // This application is designed to work on a pure device by not using // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP. if((caps.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && (pDeviceSettings->d3d9.BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0) pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_PUREDEVICE; // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. #ifdef DEBUG_VS if(pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF) { pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; #endif // Enable anti-aliasing for HAL devices which support it CD3D9Enumeration* pEnum = DXUTGetD3D9Enumeration(); CD3D9EnumDeviceSettingsCombo* pCombo = pEnum->GetDeviceSettingsCombo(&pDeviceSettings->d3d9); if(pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_HAL && pCombo->multiSampleTypeList.Contains(D3DMULTISAMPLE_4_SAMPLES)) { pDeviceSettings->d3d9.pp.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; pDeviceSettings->d3d9.pp.MultiSampleQuality = 0; } return true; }
//-------------------------------------------------------------------------------------- // Called right before creating a D3D9 or D3D10 device, allowing the app to modify the device settings as needed //-------------------------------------------------------------------------------------- bool RenderWin32DX9Imp::ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext ) { RenderWin32DX9Imp * const render = (RenderWin32DX9Imp*) pUserContext; if( pDeviceSettings->ver == DXUT_D3D9_DEVICE ) { IDirect3D9* pD3D = DXUTGetD3D9Object(); D3DCAPS9 Caps; pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &Caps ); // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW // then switch to SWVP. if( ( Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 || Caps.VertexShaderVersion < D3DVS_VERSION( 1, 1 ) ) { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } if( render->isBackbufferLockable() ) pDeviceSettings->d3d9.pp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; #ifdef DEBUG_VS // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF ) { pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; #endif } // For the first device created if its a REF device, optionally display a warning dialog box static bool s_bFirstTime = false; // true; if( s_bFirstTime ) { s_bFirstTime = false; if( ( DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF ) || ( DXUT_D3D10_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d10.DriverType == D3D10_DRIVER_TYPE_REFERENCE ) ) DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver ); } return true; }
//-------------------------------------------------------------------------------------- // Rejects any D3D9 devices that aren't acceptable to the app by returning false //-------------------------------------------------------------------------------------- bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) { // No fallback defined by this app, so reject any device that doesn't support at least ps2.0 if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) ) return false; // Skip backbuffer formats that don't support alpha blending IDirect3D9* pD3D = DXUTGetD3D9Object(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) ) return false; return true; }
//-------------------------------------------------------------------------------------- // Called during device initialization, this code checks the device for some // minimum set of capabilities, and rejects those that don't pass by returning false. //-------------------------------------------------------------------------------------- bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext ) { // Skip backbuffer formats that don't support alpha blending IDirect3D9* pD3D = DXUTGetD3D9Object(); if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) ) return false; // Determine texture support. Fail if not good enough D3DFORMAT fmtTexture, fmtCubeMap; GetSupportedTextureFormat( pD3D, pCaps, AdapterFormat, &fmtTexture, &fmtCubeMap ); if( D3DFMT_UNKNOWN == fmtTexture || D3DFMT_UNKNOWN == fmtCubeMap ) return false; // This sample requires pixel shader 2.0, but does showcase techniques which will // perform well on shader model 1.1 hardware. if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) ) return false; return true; }
//-------------------------------------------------------------------------------------- // This callback function will be called immediately after the Direct3D device has been // created, which will happen during application initialization and windowed/full screen // toggles. This is the best location to create D3DPOOL_MANAGED resources since these // resources need to be reloaded whenever the device is destroyed. Resources created // here should be released in the OnDestroyDevice callback. //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; V_RETURN( g_DialogResourceManager.OnD3D9CreateDevice( pd3dDevice ) ); V_RETURN( g_SettingsDlg.OnD3D9CreateDevice( pd3dDevice ) ); // Initialize the font V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial", &g_pFont ) ); // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the // shader debugger. Debugging vertex shaders requires either REF or software vertex // processing, and debugging pixel shaders requires REF. The // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the // shader debugger. It enables source level debugging, prevents instruction // reordering, prevents dead code elimination, and forces the compiler to compile // against the next higher available software target, which ensures that the // unoptimized shaders do not exceed the shader model limitations. Setting these // flags will cause slower rendering since the shaders will be unoptimized and // forced into software. See the DirectX documentation for more information about // using the shader debugger. DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE; #if defined( DEBUG ) || defined( _DEBUG ) // Set the D3DXSHADER_DEBUG flag to embed debug information in the shaders. // Setting this flag improves the shader debugging experience, but still allows // the shaders to be optimized and to run exactly the way they will run in // the release configuration of this program. dwShaderFlags |= D3DXSHADER_DEBUG; #endif #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; #endif // Determine which LDPRT texture and SH coefficient cubemap formats are supported IDirect3D9* pD3D = DXUTGetD3D9Object(); D3DCAPS9 Caps; pd3dDevice->GetDeviceCaps( &Caps ); D3DDISPLAYMODE DisplayMode; pd3dDevice->GetDisplayMode( 0, &DisplayMode ); GetSupportedTextureFormat( pD3D, &Caps, DisplayMode.Format, &g_fmtTexture, &g_fmtCubeMap ); if( D3DFMT_UNKNOWN == g_fmtTexture || D3DFMT_UNKNOWN == g_fmtCubeMap ) return E_FAIL; // Create the skybox g_Skybox.OnCreateDevice( pd3dDevice, 50, L"Light Probes\\rnl_cross.dds", L"SkyBox.fx" ); V( D3DXSHProjectCubeMap( 6, g_Skybox.GetEnvironmentMap(), g_fSkyBoxLightSH[0], g_fSkyBoxLightSH[1], g_fSkyBoxLightSH[2] ) ); // Now compute the SH projection of the skybox... LPDIRECT3DCUBETEXTURE9 pSHCubeTex = NULL; V( D3DXCreateCubeTexture( pd3dDevice, 256, 1, 0, D3DFMT_A16B16G16R16F, D3DPOOL_MANAGED, &pSHCubeTex ) ); SHCubeProj projData; projData.Init( g_fSkyBoxLightSH[0], g_fSkyBoxLightSH[1], g_fSkyBoxLightSH[2] ); V( D3DXFillCubeTexture( pSHCubeTex, SHCubeFill, &projData ) ); g_Skybox.InitSH( pSHCubeTex ); // Read the D3DX effect file WCHAR str[MAX_PATH]; V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, TEXT( "LocalDeformablePRT.fx" ) ) ); // If this fails, there should be debug output as to they the .fx file failed to compile V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) ); V_RETURN( LoadTechniqueObjects( "bat" ) ); V_RETURN( g_LightControl.StaticOnD3D9CreateDevice( pd3dDevice ) ); g_LightControl.SetRadius( 2.0f ); // Setup the camera's view parameters D3DXVECTOR3 vecEye( 0.0f, 0.0f, -5.0f ); D3DXVECTOR3 vecAt ( 0.0f, 0.0f, 0.0f ); g_Camera.SetViewParams( &vecEye, &vecAt ); // Set the model's initial orientation D3DXQUATERNION quatRotation; D3DXQuaternionRotationYawPitchRoll( &quatRotation, -0.5f, 0.7f, 0.0f ); g_Camera.SetWorldQuat( quatRotation ); return hr; }
//-------------------------------------------------------------------------------------- // Called right before creating a D3D9 or D3D10 device, allowing the app to modify the device settings as needed //-------------------------------------------------------------------------------------- bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext) { pDeviceSettings->d3d10.sd.SampleDesc.Count = 1; pDeviceSettings->d3d10.sd.SampleDesc.Quality = 0; if (DXUT_D3D9_DEVICE == pDeviceSettings->ver) { D3DCAPS9 Caps; IDirect3D9* pD3D = DXUTGetD3D9Object(); pD3D->GetDeviceCaps(pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType, &Caps); // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW // then switch to SWVP. if ((Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 || Caps.VertexShaderVersion < D3DVS_VERSION(1, 1)) { pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } // Debugging vertex shaders requires either REF or software vertex processing // and debugging pixel shaders requires REF. #ifdef DEBUG_VS if (pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF) { pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING; pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE; pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } #endif #ifdef DEBUG_PS pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF; #endif } else { // Uncomment this to get debug information from D3D10 //pDeviceSettings->d3d10.CreateFlags |= D3D10_CREATE_DEVICE_DEBUG; } // For the first device created if its a REF device, optionally display a warning dialog box static bool s_bFirstTime = true; if (s_bFirstTime) { s_bFirstTime = false; if ((DXUT_D3D9_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF) || (DXUT_D3D10_DEVICE == pDeviceSettings->ver && pDeviceSettings->d3d10.DriverType == D3D10_DRIVER_TYPE_REFERENCE)) { DXUTDisplaySwitchingToREFWarning(pDeviceSettings->ver); } } return true; }
//-------------------------------------------------------------------------------------- // Enumerate for each adapter all of the supported display modes, // device types, adapter formats, back buffer formats, window/full screen support, // depth stencil formats, multisampling types/qualities, and presentations intervals. // // For each combination of device type (HAL/REF), adapter format, back buffer format, and // IsWindowed it will call the app's ConfirmDevice callback. This allows the app // to reject or allow that combination based on its caps/etc. It also allows the // app to change the BehaviorFlags. The BehaviorFlags defaults non-pure HWVP // if supported otherwise it will default to SWVP, however the app can change this // through the ConfirmDevice callback. //-------------------------------------------------------------------------------------- HRESULT CD3D9Enumeration::Enumerate( LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE IsD3D9DeviceAcceptableFunc, void* pIsD3D9DeviceAcceptableFuncUserContext ) { CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D9 Enumeration" ); IDirect3D9* pD3D = DXUTGetD3D9Object(); if( pD3D == NULL ) { pD3D = DXUTGetD3D9Object(); if( pD3D == NULL ) return DXUTERR_NODIRECT3D; } m_bHasEnumerated = true; m_pD3D = pD3D; m_IsD3D9DeviceAcceptableFunc = IsD3D9DeviceAcceptableFunc; m_pIsD3D9DeviceAcceptableFuncUserContext = pIsD3D9DeviceAcceptableFuncUserContext; HRESULT hr; ClearAdapterInfoList(); CGrowableArray <D3DFORMAT> adapterFormatList; const D3DFORMAT allowedAdapterFormatArray[] = { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, D3DFMT_A2R10G10B10 }; const UINT allowedAdapterFormatArrayCount = sizeof( allowedAdapterFormatArray ) / sizeof ( allowedAdapterFormatArray[0] ); UINT numAdapters = pD3D->GetAdapterCount(); for( UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++ ) { CD3D9EnumAdapterInfo* pAdapterInfo = new CD3D9EnumAdapterInfo; if( pAdapterInfo == NULL ) return E_OUTOFMEMORY; pAdapterInfo->AdapterOrdinal = adapterOrdinal; pD3D->GetAdapterIdentifier( adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier ); // Get list of all display modes on this adapter. // Also build a temporary list of all display adapter formats. adapterFormatList.RemoveAll(); for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ ) { D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList]; UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat ); for( UINT mode = 0; mode < numAdapterModes; mode++ ) { D3DDISPLAYMODE displayMode; pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode ); if( displayMode.Width < m_nMinWidth || displayMode.Height < m_nMinHeight || displayMode.Width > m_nMaxWidth || displayMode.Height > m_nMaxHeight || displayMode.RefreshRate < m_nRefreshMin || displayMode.RefreshRate > m_nRefreshMax ) { continue; } pAdapterInfo->displayModeList.Add( displayMode ); if( !adapterFormatList.Contains( displayMode.Format ) ) adapterFormatList.Add( displayMode.Format ); } } D3DDISPLAYMODE displayMode; pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode ); if( !adapterFormatList.Contains( displayMode.Format ) ) adapterFormatList.Add( displayMode.Format ); // Sort displaymode list qsort( pAdapterInfo->displayModeList.GetData(), pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ), SortModesCallback ); // Get info for each device on this adapter if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) ) { delete pAdapterInfo; continue; } // If at least one device on this adapter is available and compatible // with the app, add the adapterInfo to the list if( pAdapterInfo->deviceInfoList.GetSize() > 0 ) { hr = m_AdapterInfoList.Add( pAdapterInfo ); if( FAILED( hr ) ) return hr; } else delete pAdapterInfo; } // // Check for 2 or more adapters with the same name. Append the name // with some instance number if that's the case to help distinguish // them. // bool bUniqueDesc = true; CD3D9EnumAdapterInfo* pAdapterInfo; for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { CD3D9EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i ); for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ ) { CD3D9EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j ); if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description, pAdapterInfo2->AdapterIdentifier.Description ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { pAdapterInfo = m_AdapterInfoList.GetAt( i ); MultiByteToWideChar( CP_ACP, 0, pAdapterInfo->AdapterIdentifier.Description, -1, pAdapterInfo->szUniqueDescription, 100 ); pAdapterInfo->szUniqueDescription[100] = 0; if( !bUniqueDesc ) { WCHAR sz[100]; swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); wcscat_s( pAdapterInfo->szUniqueDescription, 256, sz ); } } return S_OK; }