int main(int argc, char** argv) { IDXGIFactory1* factory = 0; CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); IDXGIAdapter* adapter = NULL; for (unsigned int index = 0; SUCCEEDED(factory->EnumAdapters(index, &adapter)); ++index) { DXGI_ADAPTER_DESC ad = {}; adapter->GetDesc(&ad); if (ad.VendorId == 0x1414 && ad.DeviceId == 0x8c) continue; // Skip Microsoft Basic Render Driver printf("// GPU %d: %S (Vendor %04x Device %04x)\n", index, ad.Description, ad.VendorId, ad.DeviceId); if (argc == 1) { testCache(adapter); } else if (argc > 1 && strcmp(argv[1], "--") == 0) { testCacheSequence(adapter, argc, argv); } else { testCacheMeshes(adapter, argc, argv); } } }
STDMETHODIMP CDecD3D11::GetHWAccelDeviceInfo(DWORD dwIndex, BSTR *pstrDeviceName, DWORD *dwDeviceIdentifier) { IDXGIAdapter *pDXGIAdapter = nullptr; IDXGIFactory1 *pDXGIFactory = nullptr; HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory); if (FAILED(hr)) goto fail; hr = pDXGIFactory->EnumAdapters(dwIndex, &pDXGIAdapter); if (FAILED(hr)) goto fail; DXGI_ADAPTER_DESC desc; pDXGIAdapter->GetDesc(&desc); // stop when we hit the MS software device if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) { hr = E_INVALIDARG; goto fail; } if (pstrDeviceName) *pstrDeviceName = SysAllocString(desc.Description); if (dwDeviceIdentifier) *dwDeviceIdentifier = desc.DeviceId; fail: SafeRelease(&pDXGIFactory); SafeRelease(&pDXGIAdapter); return hr; }
STDMETHODIMP_(DWORD) CDecD3D11::GetHWAccelNumDevices() { DWORD nDevices = 0; UINT i = 0; IDXGIAdapter *pDXGIAdapter = nullptr; IDXGIFactory1 *pDXGIFactory = nullptr; HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory); if (FAILED(hr)) goto fail; DXGI_ADAPTER_DESC desc; while (SUCCEEDED(pDXGIFactory->EnumAdapters(i, &pDXGIAdapter))) { pDXGIAdapter->GetDesc(&desc); SafeRelease(&pDXGIAdapter); // stop when we hit the MS software device if (desc.VendorId == 0x1414 && desc.DeviceId == 0x8c) break; i++; } nDevices = i; fail: SafeRelease(&pDXGIFactory); return nDevices; }
std::vector<IDXGIAdapter*> EnumerateDXGIAdapters() { IDXGIAdapter * adaptor; std::vector <IDXGIAdapter*> adaptors; IDXGIFactory1* factory = NULL; // Create a DXGIFactory object. if(FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1) ,(void**)&factory))) { return adaptors; } for (auto i = 0; factory->EnumAdapters(i, &adaptor) != DXGI_ERROR_NOT_FOUND; ++i) { adaptors.push_back(adaptor); } SafeRelease(&factory); return adaptors; }
//-------------------------------------------------------------------------------------- // 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. //-------------------------------------------------------------------------------------- _Use_decl_annotations_ HRESULT CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, void* pIsD3D11DeviceAcceptableFuncUserContext ) { CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" ); HRESULT hr; IDXGIFactory1* pFactory = DXUTGetDXGIFactory(); if( !pFactory ) return E_FAIL; m_bHasEnumerated = true; m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc; m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext; ClearAdapterInfoList(); for( int index = 0; ; ++index ) { IDXGIAdapter* pAdapter = nullptr; hr = pFactory->EnumAdapters( index, &pAdapter ); if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit break; IDXGIAdapter2* pAdapter2 = nullptr; if ( SUCCEEDED( pAdapter->QueryInterface( __uuidof(IDXGIAdapter2), ( LPVOID* )&pAdapter2 ) ) ) { // Succeeds on DirectX 11.1 Runtime systems DXGI_ADAPTER_DESC2 desc; hr = pAdapter2->GetDesc2( &desc ); pAdapter2->Release(); if ( SUCCEEDED(hr) && ( desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE ) ) { // Skip "always there" Microsoft Basics Display Driver pAdapter->Release(); continue; } } CD3D11EnumAdapterInfo* pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { SAFE_RELEASE( pAdapter ); return E_OUTOFMEMORY; } pAdapterInfo->AdapterOrdinal = index; pAdapter->GetDesc( &pAdapterInfo->AdapterDesc ); pAdapterInfo->m_pAdapter = pAdapter; // Enumerate the device driver types on the adapter. hr = EnumerateDevices( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; continue; } hr = EnumerateOutputs( pAdapterInfo ); if( FAILED( hr ) || pAdapterInfo->outputInfoList.empty() ) { delete pAdapterInfo; continue; } // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombos( pAdapterInfo ) ) ) { delete pAdapterInfo; continue; } m_AdapterInfoList.push_back( pAdapterInfo ); } // If we did not get an adapter then we should still enumerate WARP and Ref. if (m_AdapterInfoList.size() == 0) { CD3D11EnumAdapterInfo* pAdapterInfo = new (std::nothrow) CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { return E_OUTOFMEMORY; } pAdapterInfo->bAdapterUnavailable = true; hr = EnumerateDevices( pAdapterInfo ); // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) ) { delete pAdapterInfo; } if (SUCCEEDED(hr)) m_AdapterInfoList.push_back( 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; for( size_t i = 0; i < m_AdapterInfoList.size(); i++ ) { auto pAdapterInfo1 = m_AdapterInfoList[ i ]; for( size_t j = i + 1; j < m_AdapterInfoList.size(); j++ ) { auto pAdapterInfo2 = m_AdapterInfoList[ j ]; if( wcsncmp( pAdapterInfo1->AdapterDesc.Description, pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( auto it = m_AdapterInfoList.begin(); it != m_AdapterInfoList.end(); ++it ) { wcscpy_s( (*it)->szUniqueDescription, 100, (*it)->AdapterDesc.Description ); if( !bUniqueDesc ) { WCHAR sz[100]; swprintf_s( sz, 100, L" (#%u)", (*it)->AdapterOrdinal ); wcscat_s( (*it)->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz ); } } D3D_FEATURE_LEVEL fLvl[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 }; // Check WARP max feature level { ID3D11Device* pDevice = nullptr; hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, fLvl, _countof(fLvl), D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 runtime will not recognize FL 11.1, so try without it hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_WARP, 0, 0, &fLvl[1], _countof(fLvl) - 1, D3D11_SDK_VERSION, &pDevice, &m_warpFL, nullptr ); } if ( SUCCEEDED(hr) ) { pDevice->Release(); } else m_warpFL = D3D_FEATURE_LEVEL_10_1; } // Check REF max feature level { ID3D11Device* pDevice = nullptr; hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, fLvl, _countof(fLvl), D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr ); if ( hr == E_INVALIDARG ) { // DirectX 11.0 runtime will not recognize FL 11.1, so try without it hr = DXUT_Dynamic_D3D11CreateDevice( nullptr, D3D_DRIVER_TYPE_REFERENCE, 0, 0, &fLvl[1], _countof(fLvl) - 1, D3D11_SDK_VERSION, &pDevice, &m_refFL, nullptr ); } if ( SUCCEEDED(hr) ) { pDevice->Release(); } else m_refFL = D3D_FEATURE_LEVEL_11_0; } return S_OK; }
//-------------------------------------------------------------------------------------- // 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 CD3D11Enumeration::Enumerate( LPDXUTCALLBACKISD3D11DEVICEACCEPTABLE IsD3D11DeviceAcceptableFunc, void* pIsD3D11DeviceAcceptableFuncUserContext ) { CDXUTPerfEventGenerator eventGenerator( DXUT_PERFEVENTCOLOR, L"DXUT D3D11 Enumeration" ); HRESULT hr; IDXGIFactory1* pFactory = DXUTGetDXGIFactory(); if( pFactory == NULL ) return E_FAIL; m_bHasEnumerated = true; m_IsD3D11DeviceAcceptableFunc = IsD3D11DeviceAcceptableFunc; m_pIsD3D11DeviceAcceptableFuncUserContext = pIsD3D11DeviceAcceptableFuncUserContext; ClearAdapterInfoList(); for( int index = 0; ; ++index ) { IDXGIAdapter* pAdapter = NULL; hr = pFactory->EnumAdapters( index, &pAdapter ); if( FAILED( hr ) ) // DXGIERR_NOT_FOUND is expected when the end of the list is hit break; CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { SAFE_RELEASE( pAdapter ); return E_OUTOFMEMORY; } ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); pAdapterInfo->AdapterOrdinal = index; pAdapter->GetDesc( &pAdapterInfo->AdapterDesc ); pAdapterInfo->m_pAdapter = pAdapter; // Enumerate the device driver types on the adapter. hr = EnumerateDevices( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; continue; } hr = EnumerateOutputs( pAdapterInfo ); if( FAILED( hr ) || pAdapterInfo->outputInfoList.GetSize() <= 0 ) { delete pAdapterInfo; continue; } // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombos( pFactory, pAdapterInfo ) ) ) { delete pAdapterInfo; continue; } hr = m_AdapterInfoList.Add( pAdapterInfo ); if( FAILED( hr ) ) { delete pAdapterInfo; return hr; } } // If we did not get an adapter then we should still enumerate WARP and Ref. if (m_AdapterInfoList.GetSize() == 0) { CD3D11EnumAdapterInfo* pAdapterInfo = new CD3D11EnumAdapterInfo; if( !pAdapterInfo ) { return E_OUTOFMEMORY; } ZeroMemory( pAdapterInfo, sizeof( CD3D11EnumAdapterInfo ) ); pAdapterInfo->bAdapterUnavailable = true; hr = EnumerateDevices( pAdapterInfo ); // Get info for each devicecombo on this device if( FAILED( hr = EnumerateDeviceCombosNoAdapter( pAdapterInfo ) ) ) { delete pAdapterInfo; } if (!FAILED(hr)) hr = m_AdapterInfoList.Add( 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; CD3D11EnumAdapterInfo* pAdapterInfo; for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { CD3D11EnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt( i ); for( int j = i + 1; j < m_AdapterInfoList.GetSize(); j++ ) { CD3D11EnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt( j ); if( wcsncmp( pAdapterInfo1->AdapterDesc.Description, pAdapterInfo2->AdapterDesc.Description, DXGI_MAX_DEVICE_IDENTIFIER_STRING ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( int i = 0; i < m_AdapterInfoList.GetSize(); i++ ) { pAdapterInfo = m_AdapterInfoList.GetAt( i ); wcscpy_s( pAdapterInfo->szUniqueDescription, 100, pAdapterInfo->AdapterDesc.Description ); if( !bUniqueDesc ) { WCHAR sz[100]; swprintf_s( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); wcscat_s( pAdapterInfo->szUniqueDescription, DXGI_MAX_DEVICE_IDENTIFIER_STRING, sz ); } } return S_OK; }
HRESULT VerifyD3D11Device(DWORD & dwIndex, DWORD dwDeviceId) { HRESULT hr = S_OK; DXGI_ADAPTER_DESC desc; HMODULE dxgi = LoadLibrary(L"dxgi.dll"); if (dxgi == nullptr) { hr = E_FAIL; goto done; } PFN_CREATE_DXGI_FACTORY1 mCreateDXGIFactory1 = (PFN_CREATE_DXGI_FACTORY1)GetProcAddress(dxgi, "CreateDXGIFactory1"); if (mCreateDXGIFactory1 == nullptr) { hr = E_FAIL; goto done; } IDXGIAdapter *pDXGIAdapter = nullptr; IDXGIFactory1 *pDXGIFactory = nullptr; hr = mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory); if (FAILED(hr)) goto done; // check the adapter specified by dwIndex hr = pDXGIFactory->EnumAdapters(dwIndex, &pDXGIAdapter); if (FAILED(hr)) goto done; // if it matches the device id, then all is well and we're done pDXGIAdapter->GetDesc(&desc); if (desc.DeviceId == dwDeviceId) goto done; SafeRelease(&pDXGIAdapter); // try to find a device that matches this device id UINT i = 0; while (SUCCEEDED(pDXGIFactory->EnumAdapters(i, &pDXGIAdapter))) { pDXGIAdapter->GetDesc(&desc); SafeRelease(&pDXGIAdapter); if (desc.DeviceId == dwDeviceId) { dwIndex = i; goto done; } i++; } // if none is found, fail hr = E_FAIL; done: SafeRelease(&pDXGIAdapter); SafeRelease(&pDXGIFactory); FreeLibrary(dxgi); return hr; }
STDMETHODIMP CDecD3D11::CreateD3D11Device(UINT nDeviceIndex, ID3D11Device **ppDevice, DXGI_ADAPTER_DESC *pDesc) { ID3D11Device *pD3D11Device = nullptr; // create DXGI factory IDXGIAdapter *pDXGIAdapter = nullptr; IDXGIFactory1 *pDXGIFactory = nullptr; HRESULT hr = dx.mCreateDXGIFactory1(IID_IDXGIFactory1, (void **)&pDXGIFactory); if (FAILED(hr)) { DbgLog((LOG_ERROR, 10, L"-> DXGIFactory creation failed")); goto fail; } // find the adapter enum_adapter: hr = pDXGIFactory->EnumAdapters(nDeviceIndex, &pDXGIAdapter); if (FAILED(hr)) { if (nDeviceIndex != 0) { DbgLog((LOG_ERROR, 10, L"-> Requested DXGI device %d not available, falling back to default", nDeviceIndex)); nDeviceIndex = 0; hr = pDXGIFactory->EnumAdapters(0, &pDXGIAdapter); } if (FAILED(hr)) { DbgLog((LOG_ERROR, 10, L"-> Failed to enumerate a valid DXGI device")); goto fail; } } // Create a device with video support, and BGRA support for Direct2D interoperability (drawing UI, etc) UINT nCreationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT | D3D11_CREATE_DEVICE_BGRA_SUPPORT; D3D_FEATURE_LEVEL d3dFeatureLevel; hr = dx.mD3D11CreateDevice(pDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, nCreationFlags, s_D3D11Levels, countof(s_D3D11Levels), D3D11_SDK_VERSION, &pD3D11Device, &d3dFeatureLevel, nullptr); if (FAILED(hr)) { if (nDeviceIndex != 0) { DbgLog((LOG_ERROR, 10, L"-> Failed to create a D3D11 device with video support on requested device %d, re-trying with default", nDeviceIndex)); SafeRelease(&pDXGIAdapter); nDeviceIndex = 0; goto enum_adapter; } DbgLog((LOG_ERROR, 10, L"-> Failed to create a D3D11 device with video support")); goto fail; } DbgLog((LOG_TRACE, 10, L"-> Created D3D11 device with feature level %d.%d", d3dFeatureLevel >> 12, (d3dFeatureLevel >> 8) & 0xF)); // enable multithreaded protection ID3D10Multithread *pMultithread = nullptr; hr = pD3D11Device->QueryInterface(&pMultithread); if (SUCCEEDED(hr)) { pMultithread->SetMultithreadProtected(TRUE); SafeRelease(&pMultithread); } // store adapter info if (pDesc) { ZeroMemory(pDesc, sizeof(*pDesc)); pDXGIAdapter->GetDesc(pDesc); } // return device *ppDevice = pD3D11Device; fail: SafeRelease(&pDXGIFactory); SafeRelease(&pDXGIAdapter); return hr; }