void FOculusRiftPlugin::SetGraphicsAdapter(const ovrGraphicsLuid& luid) { TRefCountPtr<IDXGIFactory> DXGIFactory; if(SUCCEEDED(CreateDXGIFactory(__uuidof(IDXGIFactory), (void**) DXGIFactory.GetInitReference()))) { for(int32 adapterIndex = 0;; adapterIndex++) { TRefCountPtr<IDXGIAdapter> DXGIAdapter; DXGI_ADAPTER_DESC DXGIAdapterDesc; if( FAILED(DXGIFactory->EnumAdapters(adapterIndex, DXGIAdapter.GetInitReference())) || FAILED(DXGIAdapter->GetDesc(&DXGIAdapterDesc)) ) { break; } if(!FMemory::Memcmp(&luid, &DXGIAdapterDesc.AdapterLuid, sizeof(LUID))) { // Remember this adapterIndex so we use the right adapter, even when we startup without HMD connected GConfig->SetInt(TEXT("Oculus.Settings"), TEXT("GraphicsAdapter"), adapterIndex, GEngineIni); break; } } } }
void FD3D12DynamicRHIModule::FindAdapter() { // Once we chosen one we don't need to do it again. check(ChosenAdapter.IsValid() == 0); // Try to create the DXGIFactory. This will fail if we're not running Vista. TRefCountPtr<IDXGIFactory4> DXGIFactory; SafeCreateDXGIFactory(DXGIFactory.GetInitReference()); if (!DXGIFactory) { return; } bool bAllowPerfHUD = true; #if UE_BUILD_SHIPPING || UE_BUILD_TEST bAllowPerfHUD = false; #endif int32 CVarValue = CVarGraphicsAdapter.GetValueOnGameThread(); const bool bFavorNonIntegrated = CVarValue == -1; TRefCountPtr<IDXGIAdapter> TempAdapter; D3D_FEATURE_LEVEL MaxAllowedFeatureLevel = GetAllowedD3DFeatureLevel(); FD3D12Adapter FirstWithoutIntegratedAdapter; FD3D12Adapter FirstAdapter; bool bIsAnyAMD = false; bool bIsAnyIntel = false; bool bIsAnyNVIDIA = false; // Enumerate the DXGIFactory's adapters. for (uint32 AdapterIndex = 0; DXGIFactory->EnumAdapters(AdapterIndex, TempAdapter.GetInitReference()) != DXGI_ERROR_NOT_FOUND; ++AdapterIndex) { // Check that if adapter supports D3D11. if (TempAdapter) { D3D_FEATURE_LEVEL ActualFeatureLevel = (D3D_FEATURE_LEVEL)0; if (SafeTestD3D12CreateDevice(TempAdapter, MaxAllowedFeatureLevel, &ActualFeatureLevel)) { // Log some information about the available D3D12 adapters. DXGI_ADAPTER_DESC AdapterDesc; VERIFYD3D11RESULT(TempAdapter->GetDesc(&AdapterDesc)); uint32 OutputCount = CountAdapterOutputs(TempAdapter); UE_LOG(LogD3D12RHI, Log, TEXT("Found D3D12 adapter %u: %s (Feature Level %s)"), AdapterIndex, AdapterDesc.Description, GetFeatureLevelString(ActualFeatureLevel) ); UE_LOG(LogD3D12RHI, Log, TEXT("Adapter has %uMB of dedicated video memory, %uMB of dedicated system memory, and %uMB of shared system memory, %d output[s]"), (uint32)(AdapterDesc.DedicatedVideoMemory / (1024*1024)), (uint32)(AdapterDesc.DedicatedSystemMemory / (1024*1024)), (uint32)(AdapterDesc.SharedSystemMemory / (1024*1024)), OutputCount ); bool bIsAMD = AdapterDesc.VendorId == 0x1002; bool bIsIntel = AdapterDesc.VendorId == 0x8086; bool bIsNVIDIA = AdapterDesc.VendorId == 0x10DE; bool bIsWARP = FParse::Param(FCommandLine::Get(), TEXT("warp")); if (bIsAMD) bIsAnyAMD = true; if (bIsIntel) bIsAnyIntel = true; if (bIsNVIDIA) bIsAnyNVIDIA = true; // Simple heuristic but without profiling it's hard to do better const bool bIsIntegrated = bIsIntel; // PerfHUD is for performance profiling const bool bIsPerfHUD = !FCString::Stricmp(AdapterDesc.Description, TEXT("NVIDIA PerfHUD")); FD3D12Adapter CurrentAdapter(AdapterIndex, ActualFeatureLevel); if (!OutputCount && !bIsWARP) { // Add special check to support WARP, which does not have an output associated with it. // This device has no outputs. Reject it, // http://msdn.microsoft.com/en-us/library/windows/desktop/bb205075%28v=vs.85%29.aspx#WARP_new_for_Win8 continue; } if(bIsPerfHUD && !bAllowPerfHUD) { // we don't allow the PerfHUD adapter continue; } if (CVarValue >= 0 && AdapterIndex != CVarValue) { // the user wants a specific adapter, not this one continue; } if (!bIsIntegrated && !FirstWithoutIntegratedAdapter.IsValid()) { FirstWithoutIntegratedAdapter = CurrentAdapter; } if (!FirstAdapter.IsValid()) { FirstAdapter = CurrentAdapter; } } } } if (bFavorNonIntegrated && (bIsAnyAMD || bIsAnyNVIDIA)) { ChosenAdapter = FirstWithoutIntegratedAdapter; // We assume Intel is integrated graphics (slower than discrete) than NVIDIA or AMD cards and rather take a different one if (!ChosenAdapter.IsValid()) { ChosenAdapter = FirstAdapter; } } else { ChosenAdapter = FirstAdapter; } if (ChosenAdapter.IsValid()) { UE_LOG(LogD3D12RHI, Log, TEXT("Chosen D3D12 Adapter Id = %u"), ChosenAdapter.AdapterIndex); } else { UE_LOG(LogD3D12RHI, Error, TEXT("Failed to choose a D3D12 Adapter.")); } }