static uint32 CountAdapterOutputs(TRefCountPtr<IDXGIAdapter>& Adapter) { uint32 OutputCount = 0; for(;;) { TRefCountPtr<IDXGIOutput> Output; HRESULT hr = Adapter->EnumOutputs(OutputCount, Output.GetInitReference()); if(FAILED(hr)) { break; } ++OutputCount; } return OutputCount; }
/** * Returns a supported screen resolution that most closely matches the input. * @param Width - Input: Desired resolution width in pixels. Output: A width that the platform supports. * @param Height - Input: Desired resolution height in pixels. Output: A height that the platform supports. */ void FD3D11DynamicRHI::RHIGetSupportedResolution( uint32 &Width, uint32 &Height ) { uint32 InitializedMode = false; DXGI_MODE_DESC BestMode; BestMode.Width = 0; BestMode.Height = 0; { HRESULT hr = S_OK; TRefCountPtr<IDXGIAdapter> Adapter; hr = DXGIFactory->EnumAdapters(ChosenAdapter,Adapter.GetInitReference()); if( DXGI_ERROR_NOT_FOUND == hr ) { return; } if( FAILED(hr) ) { return; } // get the description of the adapter DXGI_ADAPTER_DESC AdapterDesc; VERIFYD3D11RESULT(Adapter->GetDesc(&AdapterDesc)); // Enumerate outputs for this adapter // TODO: Cap at 1 for default output for(uint32 o = 0;o < 1; o++) { TRefCountPtr<IDXGIOutput> Output; hr = Adapter->EnumOutputs(o,Output.GetInitReference()); if(DXGI_ERROR_NOT_FOUND == hr) break; if(FAILED(hr)) return; // TODO: GetDisplayModeList is a terribly SLOW call. It can take up to a second per invocation. // We might want to work around some DXGI badness here. DXGI_FORMAT Format = DXGI_FORMAT_R8G8B8A8_UNORM; uint32 NumModes = 0; hr = Output->GetDisplayModeList(Format,0,&NumModes,NULL); if(hr == DXGI_ERROR_NOT_FOUND) { return; } else if(hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { UE_LOG(LogD3D11RHI, Fatal, TEXT("This application cannot be run over a remote desktop configuration") ); return; } DXGI_MODE_DESC* ModeList = new DXGI_MODE_DESC[ NumModes ]; VERIFYD3D11RESULT(Output->GetDisplayModeList(Format,0,&NumModes,ModeList)); for(uint32 m = 0;m < NumModes;m++) { // Search for the best mode // Suppress static analysis warnings about a potentially out-of-bounds read access to ModeList. This is a false positive - Index is always within range. CA_SUPPRESS( 6385 ); bool IsEqualOrBetterWidth = FMath::Abs((int32)ModeList[m].Width - (int32)Width) <= FMath::Abs((int32)BestMode.Width - (int32)Width); bool IsEqualOrBetterHeight = FMath::Abs((int32)ModeList[m].Height - (int32)Height) <= FMath::Abs((int32)BestMode.Height - (int32)Height); if(!InitializedMode || (IsEqualOrBetterWidth && IsEqualOrBetterHeight)) { BestMode = ModeList[m]; InitializedMode = true; } } delete[] ModeList; } } check(InitializedMode); Width = BestMode.Width; Height = BestMode.Height; }