/// <summary> /// Initializes a new instance of the <see cref="EngineAdapterInfo" /> class. /// </summary> internal EngineAdapterInfo(int adapterIndex, IDXGIAdapter1 adapter) { this.Outputs = new List <EngineOutputInfo>(); this.AdapterIndex = adapterIndex; _adapterDescription = adapter.Description; this.IsSoftwareAdapter = _adapterDescription.Description == "Microsoft Basic Render Driver" || !string.IsNullOrEmpty(_adapterDescription.Description) && _adapterDescription.Description.Contains("Software") || !string.IsNullOrEmpty(_adapterDescription.Description) && _adapterDescription.Description.Contains("Microsoft Basic Render Driver"); _d3d11FeatureLevel = D3D11.D3D11.GetSupportedFeatureLevel(adapter); //Query for output information var lastResult = Result.Ok; var actIndex = 0; do { lastResult = adapter.EnumOutputs(actIndex, out var actOutput); if (lastResult.Success) { this.Outputs.Add(new EngineOutputInfo(adapterIndex, actIndex, actOutput)); } actIndex++; }while (lastResult.Success); }
public static int Main() { int result; using (IDXGIFactory1 factory1 = new DXGIFactory1()) { LinkedList <IDXGIAdapter1> adapters = new LinkedList <IDXGIAdapter1>(); uint adapterId = 0; while ((result = factory1.EnumAdapters1(adapterId, out IDXGIAdapter1 currentAdapter)) == 0) { adapterId++; result = currentAdapter.GetDesc1(out DXGIAdapterDescription1 adapterDescription); if (result != 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(1); } if ((adapterDescription.Flags & DXGIAdapterFlag.Software) != 0) { currentAdapter.Dispose(); continue; } adapters.AddLast(currentAdapter); } if (adapters.Count == 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(2); } FeatureLevel[] featureLevels = { FeatureLevel.Level_12_1, FeatureLevel.Level_12_0, FeatureLevel.Level_11_1, FeatureLevel.Level_11_0, FeatureLevel.Level_10_1, FeatureLevel.Level_10_0, FeatureLevel.Level_9_3, FeatureLevel.Level_9_2, FeatureLevel.Level_9_1 }; result = DXGINativeMethods.D3D11CreateDevice ( adapters.First.Value, DriverType.Unknown, IntPtr.Zero, 0x2, featureLevels, 7u, out IUnknown d3d11Device, out FeatureLevel selectedLevel, out IUnknown d3d11DeviceContext ); if (result != 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(3); } using (d3d11Device) { using (IDXGIAdapter1 adapter = adapters.First.Value) { using (d3d11DeviceContext) { result = adapter.EnumOutputs(0, out IDXGIOutput output); if (result != 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(4); } using (output) { result = output.QueryInterface(typeof(IDXGIOutput1).GUID, out IntPtr output1Ptr); if (result != 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(5); } using (IDXGIOutput1 output1 = new DXGIOutput1(output1Ptr)) { result = output1.DuplicateOutput(d3d11Device, out IDXGIOutputDuplication duplicationOutput); if (result != 0) { foreach (IDXGIAdapter1 dxgiAdapter1 in adapters) { dxgiAdapter1.Dispose(); } return(6); } duplicationOutput.GetDesc(out DXGIOutDuplDescription duplDescription); duplicationOutput.ReleaseFrame(); duplicationOutput.Dispose(); } } } } } } return(result); }
public static DesktopDuplicatorInternal CreateDesktopDuplicator(ILogger logger, int adapterIndex, int outputDeviceIndex) { var dd = new DesktopDuplicatorInternal { _outputDeviceIndex = outputDeviceIndex }; var createFactoryResult = DXGI.CreateDXGIFactory1(out IDXGIFactory1 factory); if (!createFactoryResult.Success) { throw new DesktopDuplicationException("Couldn't create a DXGI Factory."); } IDXGIAdapter1 adapter = null; IDXGIOutput output = null; try { var result = factory.EnumAdapters1(adapterIndex, out adapter); if (result.Failure) { throw new DesktopDuplicationException($"An error occurred attempting to retrieve the adapter at the specified index ({adapterIndex}): {result}"); } if (adapter == null) { throw new DesktopDuplicationException($"An adapter was not found at the specified index ({adapterIndex})."); } logger.LogInformation($"Using adapter at index {adapterIndex} - {adapter.Description.Description}"); var createD3dDeviceResult = D3D11.D3D11CreateDevice(adapter, DriverType.Unknown, DeviceCreationFlags.None, null, out dd._d3dDevice, out dd._immediateContext); if (!createD3dDeviceResult.Success) { throw new DesktopDuplicationException("Couldn't create a D3D device from the specified adapter."); } using var device = dd._d3dDevice.QueryInterface <IDXGIDevice>(); var outputResult = adapter.EnumOutputs(outputDeviceIndex, out output); if (outputResult.Failure) { throw new DesktopDuplicationException($"An error occurred attempting to retrieve the output device at the specified index ({outputDeviceIndex}): {outputResult}"); } if (output == null) { throw new DesktopDuplicationException($"An output was not found at the specified index ({outputDeviceIndex})."); } logger.LogInformation($"Using output device on adapter {adapterIndex} at index {outputDeviceIndex}."); var output6 = output.QueryInterface <IDXGIOutput6>(); try { // Copy the values to a new rect. var rectTemp = output6.Description.DesktopCoordinates; dd._desktopRect = new RawRect(rectTemp.Left, rectTemp.Top, rectTemp.Right, rectTemp.Bottom); dd._outputDuplication = output6.DuplicateOutput(device); var stagingTexture = new Texture2DDescription() { CpuAccessFlags = CpuAccessFlags.Read, BindFlags = BindFlags.None, Format = dd._outputDuplication.Description.ModeDescription.Format, Width = Math.Abs(dd._desktopRect.Right - dd._desktopRect.Left), Height = Math.Abs(dd._desktopRect.Bottom - dd._desktopRect.Top), OptionFlags = ResourceOptionFlags.None, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = Usage.Staging // << can be read by CPU }; // Initialize the Output Duplication -- If this isn't done occassionally an 'Unsupported' result will occur with DuplicationOutput1 dd._desktopImageTexture = dd._d3dDevice.CreateTexture2D(stagingTexture); } catch (SharpGenException ex) { if (ex.Descriptor.NativeApiCode == "DXGI_ERROR_UNSUPPORTED") { throw new DesktopDuplicationException("Unsupported desktop mode or scenario."); } else if (ex.Descriptor.NativeApiCode == "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE") { throw new DesktopDuplicationException("There is already the maximum number of applications using the Desktop Duplication API running, please close one of the applications and try again."); } else { throw; } } } finally { if (output != null) { output.Dispose(); } if (adapter != null) { adapter.Dispose(); } if (factory != null) { factory.Dispose(); } } return(dd); }