/// <summary> /// Initializes all adapters with the specified factory. /// </summary> internal static void InitializeInternal() { staticCollector.Dispose(); #if DIRECTX11_1 using (var factory = new Factory1()) NativeFactory = factory.QueryInterface <Factory2>(); #elif SILICONSTUDIO_PLATFORM_UWP // Maybe this will become default code for everybody if we switch to DX 11.1/11.2 SharpDX dll? NativeFactory = new Factory2(); #else NativeFactory = new Factory1(); #endif staticCollector.Add(NativeFactory); int countAdapters = NativeFactory.GetAdapterCount1(); var adapterList = new List <GraphicsAdapter>(); for (int i = 0; i < countAdapters; i++) { var adapter = new GraphicsAdapter(NativeFactory, i); staticCollector.Add(adapter); adapterList.Add(adapter); } defaultAdapter = adapterList.Count > 0 ? adapterList[0] : null; adapters = adapterList.ToArray(); }
public void getCaps() { Factory1 fac = new Factory1(); int numAdapters = fac.GetAdapterCount1(); List <Adapter1> adapts = new List <Adapter1>(); for (int i = 0; i < numAdapters; i++) { adapts.Add(fac.GetAdapter1(i)); } Output outp = adapts[0].GetOutput(0); List <Format> formats = new List <Format>(); foreach (Format format in Enum.GetValues(typeof(Format))) { formats.Add(format); } //List<ReadOnlyCollection<ModeDescription>> ll = new List<ReadOnlyCollection<ModeDescription>>(); List <ModeDescription[]> ll = new List <ModeDescription[]>(); for (int i = 0; i < formats.Count - 1; i++) { //ReadOnlyCollection<ModeDescription> mdl; ModeDescription[] mdl; mdl = outp.GetDisplayModeList(formats[i], DisplayModeEnumerationFlags.Interlaced); ll.Add(mdl); if (mdl != null) { Console.WriteLine(formats[i].ToString()); } } }
public DesktopDuplicator(IntPtr window) { User32.GetWindowRect(window, out var rectNative); var windowRect = rectNative.ToRect(); // Search all outputs on all adapters and find the window rect. var factory = new Factory1(); for (var j = 0; j < factory.GetAdapterCount1(); j++) { var adapter = factory.GetAdapter1(j); for (var i = 0; i < adapter.GetOutputCount(); i++) { var output = adapter.GetOutput(i); var bounds = output.Description.DesktopBounds.ToRectangle(); if (bounds.Contains(windowRect)) { Initialize(0, i); return; } } } throw new Exception($"Didn't find the {window} window on any display output."); }
/// <summary> /// 最適グラフィックスアダプタを返す /// </summary> /// <returns></returns> static Adapter GetAdapter(Factory1 factory) { // 優先順 string[] vender_string = new string[] { "nvidia", "ati", }; Adapter1 result = factory.GetAdapter1(0); int adapterCount = factory.GetAdapterCount1(); for (int i = 1; i < adapterCount; i++) { Adapter1 adapter = factory.GetAdapter1(i); var device_name = adapter.Description.Description.ToLower(); for (int j = 0; j < vender_string.Length; j++) { if (device_name.Contains(vender_string[j])) { result = adapter; } } } return(result); }
/// <inheritdoc /> /// <summary> /// Class constructor /// </summary> /// <param name="x">Horizontal coordinate, in pixels, for the virtual capture location</param> /// <param name="y">Vertical coordinate, in pixels, for the virtual cpature location</param> /// <param name="width">Width, in pixels, for the captured region</param> /// <param name="height">Height, in pixels, for the captured region</param> public DxgiVideoCaptureDevice(int x, int y, int width, int height) : base(x, y, width, height) { // we'll need the system timer frequency in order to convert the output duplication present time to ticks Kernel32.QueryPerformanceFrequency(out this.perfFreq); this.virtualRect = new Rectangle(x, y, width, height); // obtain a list of capture sources // obtain a list of capture sources using (var factory = new Factory1()) { if (factory.GetAdapterCount1() == 0) { throw new NotSupportedException("No suitable video adapters found"); } var captureSources = new List <DxgiCaptureSource>(); foreach (Adapter1 adapter in factory.Adapters1) { Debug.WriteLine($"+ {adapter.Description1.Description}"); foreach (Output output in adapter.Outputs) { Debug.Write($"+ {output.Description.DeviceName} "); var intersection = Rectangle.Intersect(this.virtualRect, output.Description.DesktopBounds); if (intersection.Width > 0 && intersection.Height > 0) { try { Debug.WriteLine($"[XSECT: {intersection}]"); captureSources.Add(new DxgiCaptureSource(adapter, output, new Rectangle(intersection.X, intersection.Y, intersection.Width, intersection.Height))); } catch (NotSupportedException exception) when(exception.InnerException?.HResult == ResultCode.Unsupported.Result) { // HACK: when Captain itself is running on the dGPU, DDA calls fail with DXGI_ERROR_UNSPUPORTED // if the main desktop is not bound to it (see https://support.microsoft.com/en-us/kb/3019314). // We fix this by trying the next adapter } } else { Debug.WriteLine("[MISMATCH]"); } } } this.sources = captureSources.ToArray(); } }
private Tuple <int, int>[] GetCapturedOutputs() { var ret = new List <Tuple <int, int> >(6);//most cases for (var adapterIndex = _factory.GetAdapterCount1() - 1; adapterIndex >= 0; adapterIndex--) { using (var adapter = _factory.GetAdapter1(adapterIndex)) for (var outputIndex = adapter.GetOutputCount() - 1; outputIndex >= 0; outputIndex--) { using (var output = adapter.GetOutput(outputIndex)) if (output.Description.DesktopBounds.ToGDIRect().IntersectsWith(_sourceRect.Value)) { ret.Add(new Tuple <int, int>(adapterIndex, outputIndex)); } } } return(ret.ToArray()); }
/// <inheritdoc /> /// <summary> /// Class constructor /// </summary> /// <param name="x">Horizontal coordinate, in pixels, for the virtual capture location</param> /// <param name="y">Vertical coordinate, in pixels, for the virtual cpature location</param> /// <param name="width">Width, in pixels, for the captured region</param> /// <param name="height">Height, in pixels, for the captured region</param> public DxgiVideoCaptureDevice(int x, int y, int width, int height) : base(x, y, width, height) { // we'll need the system timer frequency in order to convert the output duplication present time to ticks Kernel32.QueryPerformanceFrequency(out this.perfFreq); this.virtualRect = new Rectangle(x, y, width, height); // obtain a list of capture sources // obtain a list of capture sources using (var factory = new Factory1()) { if (factory.GetAdapterCount1() == 0) { throw new NotSupportedException("No suitable video adapters found"); } var captureSources = new List <DxgiCaptureSource>(); foreach (Adapter1 adapter in factory.Adapters1) { foreach (Output output in adapter.Outputs) { Rectangle intersection = Rectangle.Intersect(this.virtualRect, output.Description.DesktopBounds); if (intersection.Width > 0 && intersection.Height > 0) { captureSources.Add(new DxgiCaptureSource(adapter, output, new Rectangle(intersection.X, intersection.Y, intersection.Width, intersection.Height))); } output.Dispose(); } adapter.Dispose(); } this.sources = captureSources.ToArray(); } }
private static void QueryAdapters() { var adapt = new Dictionary <string, string>(); var displ = new Dictionary <string, List <string> >(); using (var factory = new Factory1()) { var acount = factory.GetAdapterCount1(); for (var i = 0; i < acount; i++) { using (var adapter = factory.GetAdapter1(i)) { var adesc = adapter.Description1; if (adesc.Flags.HasFlag(AdapterFlags.Software)) { continue; } var disp = new List <string>(); displ.Add(adesc.DeviceId.ToString(), disp); adapt.Add(adesc.DeviceId.ToString(), adesc.Description); var ocount = adapter.GetOutputCount(); for (var j = 0; j < ocount; j++) { using (var output = adapter.GetOutput(i)) { var odesc = output.Description; var width = odesc.DesktopBounds.Right - odesc.DesktopBounds.Left; var height = odesc.DesktopBounds.Bottom - odesc.DesktopBounds.Top; disp.Add($"{odesc.DeviceName} ({width} x {height})"); } } } } } adapters = adapt; displays = displ; }
internal static Adapter1 GetAdapter(int deviceId) { using (var factory = new Factory1()) { var count = factory.GetAdapterCount1(); Adapter1 adapter = null; for (var i = 0; i < count; i++) { try { adapter = factory.GetAdapter1(i); if (adapter.Description1.DeviceId == deviceId) { return(adapter); } adapter.Dispose(); } catch { adapter?.Dispose(); } } } throw new ArgumentException($"Invalid adapter {deviceId}"); }
/// <summary> /// Creates a capture source with the same properties as this one /// </summary> /// <param name="bounds">Target screen bounds</param> /// <returns>A new <see cref="DxgiCaptureSource"/> instance</returns> internal static DxgiCaptureSource Recreate(Rectangle bounds) { DxgiCaptureSource source = null; using (var factory = new Factory1()) { if (factory.GetAdapterCount1() == 0) { throw new NotSupportedException("No suitable video adapters found"); } foreach (Adapter1 adapter in factory.Adapters1) { foreach (Output output in adapter.Outputs) { var intersection = Rectangle.Intersect(bounds, output.Description.DesktopBounds); if (intersection.Width > 0 && intersection.Height > 0) { source = new DxgiCaptureSource(adapter, output, new Rectangle(intersection.X, intersection.Y, intersection.Width, intersection.Height)); break; } output.Dispose(); } adapter.Dispose(); if (source != null) { break; } } } return(source ?? throw new Exception("No suitable capture sources were found")); }
/// <summary> /// Initializes all adapters with the specified factory. /// </summary> /// <param name="factory1">The factory1.</param> internal static void Initialize(Factory1 factory1) { if (staticCollector != null) { staticCollector.Dispose(); } staticCollector = new DisposeCollector(); defaultFactory = factory1; staticCollector.Collect(defaultFactory); int countAdapters = defaultFactory.GetAdapterCount1(); var adapterList = new List <GraphicsAdapter>(); for (int i = 0; i < countAdapters; i++) { var adapter = new GraphicsAdapter(i); staticCollector.Collect(adapter); adapterList.Add(adapter); } defaultAdapter = adapterList.Count > 0 ? adapterList[0] : null; adapters = adapterList.ToArray(); }
/// <summary> /// Initializes all adapters with the specified factory. /// </summary> /// <param name="factory1">The factory1.</param> internal static void Initialize(Factory1 factory1) { if (staticCollector != null) { staticCollector.Dispose(); } staticCollector = new DisposeCollector(); Factory = factory1; staticCollector.Collect(Factory); int countAdapters = Factory.GetAdapterCount1(); var adapters = new List <GraphicsAdapter>(); for (int i = 0; i < countAdapters; i++) { var adapter = new GraphicsAdapter(i); staticCollector.Collect(adapter); adapters.Add(adapter); } Default = adapters[0]; Adapters = adapters.ToArray(); }
/// <inheritdoc /> /// <summary> /// Class constructor /// </summary> /// <param name="rect">Screen region</param> /// <exception cref="NotSupportedException">Thrown when no video adapters were found</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown when the capture region is empty</exception> internal DxgiVideoProvider(Rectangle rect) { Log.WriteLine(LogLevel.Debug, "creating DXGI video provider"); var factory = new Factory1(); var intersections = new List <(Adapter Adapter, Output Output, Rectangle Rectangle, Rectangle Bounds)>(); // enumerate outputs if (factory.GetAdapterCount1() == 0) { throw new NotSupportedException("No suitable video adapters found"); } foreach (Adapter adapter in factory.Adapters) { intersections.AddRange(from output in adapter.Outputs let outputRect = new Rectangle(output.Description.DesktopBounds.Left, output.Description.DesktopBounds.Top, output.Description.DesktopBounds.Right - output.Description.DesktopBounds.Left, output.Description.DesktopBounds.Bottom - output.Description.DesktopBounds.Top) let intersection = Rectangle.Intersect(rect, outputRect) where intersection.Width > 0 && intersection.Height > 0 select(adapter, output, intersection, outputRect)); } // make sure we do not capture out of bounds //this.rect = triples.Select(t => Rectangle.Union(this.rect, t.Rectangle)).Last(); CaptureBounds = rect; if (CaptureBounds.IsEmpty) { throw new ArgumentOutOfRangeException(nameof(rect)); } // create adapter, output arrays this.adapters = intersections.Select(t => t.Adapter).ToArray(); this.outputs = intersections.Select(t => t.Output).ToArray(); // set rectangles for each output this.rects = intersections.Select(t => t.Rectangle).ToArray(); this.regions = intersections.Select(t => { var region = new ResourceRegion(t.Rectangle.X - t.Bounds.X, t.Rectangle.Y - t.Bounds.Y, 0, t.Rectangle.Width, t.Rectangle.Height, 1); region.Right += region.Left; region.Bottom += region.Top; return(region); }) .ToArray(); // create devices for each adapter this.devices = this.adapters.Select((a, i) => { var flags = DeviceCreationFlags.VideoSupport; #if DEBUG flags |= DeviceCreationFlags.Debug; #endif var device = new Device(a, flags, FeatureLevel.Level_12_1, FeatureLevel.Level_12_0, FeatureLevel.Level_11_0) { #if DEBUG DebugName = $"[#{i}] {a.Description.Description}" #endif }; device.QueryInterface <Multithread>().SetMultithreadProtected(new RawBool(true)); return(device); }) .ToArray(); // create the shared texture in this device StagingTextures = this.devices.Select((d, i) => new Texture2D(d, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.Read, BindFlags = BindFlags.None, Format = Format.B8G8R8A8_UNorm, Width = intersections[i].Rectangle.Width, Height = intersections[i].Rectangle.Height, OptionFlags = ResourceOptionFlags.None, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Staging })) .ToArray(); // let video encoders use the screen texture if a single monitor is being captured // TODO: implement D3D12 multi-adapter support /*if (...) { * // create full capture texture * SharedTexture = new Texture2D(this.devices[0], * new Texture2DDescription { * CpuAccessFlags = CpuAccessFlags.Read | CpuAccessFlags.Write, * BindFlags = BindFlags.None, * Format = Format.B8G8R8A8_UNorm, * Width = CaptureBounds.Width, * Height = CaptureBounds.Height, * OptionFlags = ResourceOptionFlags.None, * MipLevels = 1, * ArraySize = 1, * SampleDescription = {Count = 1, Quality = 0}, * Usage = ResourceUsage.Staging * }); * } else*/ if (StagingTextures.Length == 1) { SharedTexture = StagingTextures[0]; } // duplicate desktops this.duplications = this.outputs.Select((o, i) => { try { // attempt to use DuplicateOutput1 for improved performance and SRGB support Format[] formats = { Format.B8G8R8A8_UNorm }; return(o.QueryInterface <Output6>().DuplicateOutput1(this.devices[i], 0, formats.Length, formats)); } catch (SharpDXException exception1) when(exception1.HResult == ResultCode.Unsupported.Result) { try { return(o.QueryInterface <Output1>().DuplicateOutput(this.devices[i])); } catch (SharpDXException exception) when(exception.HResult == ResultCode.Unsupported.Result || exception.HResult == NotImplementedHResult) { throw new NotSupportedException("Platform is not supported"); } } }) .ToArray(); }
/// <summary> /// Function to perform an enumeration of the video devices attached to the system. /// </summary> /// <param name="enumerateWARPDevice">TRUE to enumerate the WARP software device. FALSE to exclude it.</param> /// <param name="enumerateReferenceDevice">TRUE to enumerate the reference device. FALSE to exclude it.</param> /// <remarks>This method will populate the <see cref="GorgonLibrary.Graphics.GorgonVideoDeviceEnumerator">GorgonVideoDeviceEnumerator</see> with information about the video devices /// installed in the system. /// <para>You may include the WARP device, which is a software based device that emulates most of the functionality of a video device, by setting the <paramref name="enumerateWARPDevice"/> to TRUE.</para> /// <para>You may include the reference device, which is a software based device that all the functionality of a video device, by setting the <paramref name="enumerateReferenceDevice"/> to TRUE. /// If a reference device is used in rendering, the performance will be poor and as such, this device is only useful to diagnosing issues with video drivers.</para> /// <para>The reference device is a DEBUG only device, and as such, it will only appear under the following conditions: /// <list type="bullet"> /// <item> /// <description>The DEBUG version of the Gorgon library is used.</description> /// <description>The Direct 3D SDK is installed. The reference rasterizer is only included with the SDK.</description> /// </item> /// </list> /// </para> /// </remarks> public static void Enumerate(bool enumerateWARPDevice, bool enumerateReferenceDevice) { #if DEBUG // Turn on object tracking if it's not already enabled. if (!DX.Configuration.EnableObjectTracking) { DX.Configuration.EnableObjectTracking = true; } #endif try { // Create the DXGI factory object used to gather the information. if (Interlocked.Increment(ref _lockIncr) > 1) { return; } List <GorgonVideoDevice> devices; using (var factory = new Factory1()) { int adapterCount = factory.GetAdapterCount1(); devices = new List <GorgonVideoDevice>(adapterCount + 2); Gorgon.Log.Print("Enumerating video devices...", LoggingLevel.Simple); // Begin gathering device information. for (int i = 0; i < adapterCount; i++) { // Get the video device information. using (var adapter = factory.GetAdapter1(i)) { // Only enumerate local devices. int outputCount = adapter.GetOutputCount(); if (((adapter.Description1.Flags & AdapterFlags.Remote) != 0) || (outputCount <= 0)) { continue; } var videoDevice = new GorgonVideoDevice(adapter, VideoDeviceType.Hardware, i); // Don't allow unsupported devices. if (videoDevice.HardwareFeatureLevel == DeviceFeatureLevel.Unsupported) { continue; } // We create a D3D device here to filter out unsupported video modes from the format list. using (var D3DDevice = new D3D.Device(adapter)) { D3DDevice.DebugName = "Output enumerator device."; PrintLog(videoDevice); GetOutputs(videoDevice, D3DDevice, adapter, outputCount, false); // Ensure we actually have outputs to use. if (videoDevice.Outputs.Count > 0) { devices.Add(videoDevice); } else { Gorgon.Log.Print("Video device {0} has no outputs!", LoggingLevel.Verbose, videoDevice.Name); } } } } // Get software devices. if (enumerateWARPDevice) { var device = GetWARPSoftwareDevice(devices.Count); if (device.Outputs.Count > 0) { devices.Add(device); } } #if DEBUG if (enumerateReferenceDevice) { var device = GetRefSoftwareDevice(devices.Count); if (device.Outputs.Count > 0) { devices.Add(device); } } #endif } VideoDevices = new GorgonNamedObjectReadOnlyCollection <GorgonVideoDevice>(false, devices); if (devices.Count == 0) { throw new GorgonException(GorgonResult.CannotEnumerate, Resources.GORGFX_DEVICE_CANNOT_FIND_DEVICES); } Gorgon.Log.Print("Found {0} video devices.", LoggingLevel.Simple, VideoDevices.Count); } finally { Interlocked.Decrement(ref _lockIncr); } }