/// <summary> /// Function to retrieve the outputs attached to a video adapter. /// </summary> /// <param name="device">The Direct 3D device used to filter display modes.</param> /// <param name="adapter">The adapter to retrieve the outputs from.</param> /// <param name="outputCount">The number of outputs for the device.</param> /// <param name="log">The logging interface used to capture debug messages.</param> /// <returns>A list if video output info values.</returns> private static Dictionary <string, VideoOutputInfo> GetOutputs(D3D11.Device5 device, Adapter4 adapter, int outputCount, IGorgonLog log) { var result = new Dictionary <string, VideoOutputInfo>(StringComparer.OrdinalIgnoreCase); // Devices created under RDP/TS do not support output selection. if (SystemInformation.TerminalServerSession) { log.Print("Devices under terminal services and software devices devices do not use outputs, no outputs enumerated.", LoggingLevel.Intermediate); return(result); } for (int i = 0; i < outputCount; ++i) { using (Output output = adapter.GetOutput(i)) using (Output6 output6 = output.QueryInterface <Output6>()) { var outputInfo = new VideoOutputInfo(i, output6, GetVideoModes(device, output6)); if (outputInfo.VideoModes.Count == 0) { log.Print($"Output '{output.Description.DeviceName}' on adapter '{adapter.Description1.Description}' has no full screen video modes.", LoggingLevel.Intermediate); } result.Add(output.Description.DeviceName, outputInfo); } } return(result); }
/// <inheritdoc /> /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources /// </summary> public void Dispose() { // release resources Alive = false; Duplication.Dispose(); Duplication = null; Output.Dispose(); Output = null; Output1?.Dispose(); Output1 = null; Output6?.Dispose(); Output6 = null; DxgiDevice.Dispose(); DxgiDevice = null; Device.Dispose(); Device = null; Texture.Dispose(); Texture = null; Adapter1.Dispose(); Adapter1 = null; }
/// <summary> /// Initializes a new instance of the <see cref="VideoOutputInfo" /> class. /// </summary> /// <param name="index">The index of the output.</param> /// <param name="output">The output used to provide information.</param> /// <param name="modes">The list of full screen display modes supported by this output on the video adapter.</param> public VideoOutputInfo(int index, Output6 output, IEnumerable <ModeDescription1> modes) { Index = index; _desc = output.Description; Name = _desc.DeviceName.Replace("\0", string.Empty); Rotation = (RotationMode)_desc.Rotation; VideoModes = modes.Select(item => new GorgonVideoMode(item)).ToArray(); }
/// <inheritdoc /> /// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources /// </summary> public void Dispose() { // release resources Duplication.Dispose(); Output.Dispose(); Output1?.Dispose(); Output6?.Dispose(); Context.Dispose(); DxgiDevice.Dispose(); Device.Dispose(); Texture.Dispose(); Adapter1.Dispose(); }
public DxCapture(int width, int height, int adapter, int monitor, FileLogger logger) { try { _logger = logger; _width = width; _height = height; _factory = new Factory1(); _adapter = _factory.GetAdapter1(adapter); _device = new SharpDX.Direct3D11.Device(_adapter); _output = _adapter.GetOutput(monitor); _output6 = _output.QueryInterface <Output6>(); _duplicatedOutput = _output6.DuplicateOutput1(_device, 0, 1, new Format[] { Format.B8G8R8A8_UNorm }); var textureDesc = new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.Read, BindFlags = BindFlags.None, Format = Format.B8G8R8A8_UNorm, Width = _width, Height = _height, OptionFlags = ResourceOptionFlags.None, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Staging }; _screenTexture = new Texture2D(_device, textureDesc); } catch (Exception ex) { Task.Run(() => _logger?.WriteLog(ex.ToString())); throw; } }
/// <summary> /// Struct constructor /// </summary> /// <param name="adapter1">DXGI adapter device instance</param> /// <param name="output">DXGI output associated with this source</param> /// <param name="region">Region of the DXGI output device</param> internal DxgiCaptureSource(Adapter1 adapter1, Output output, Rectangle region) { Device = null; Adapter1 = adapter1; Output = output; Output1 = null; Output6 = null; Region = region; if (region != output.Description.DesktopBounds) { Subregion = new ResourceRegion(region.Left - output.Description.DesktopBounds.Left, region.Top - output.Description.DesktopBounds.Top, 0, region.Width + region.Left, region.Height + region.Top, 1); } else { Subregion = null; } try { // create device Device = new Device(adapter1, DeviceCreationFlags.None, FeatureLevel.Level_11_0) { #if DEBUG DebugName = output.Description.DeviceName + " // " + adapter1.Description.Description #endif }; DxgiDevice = Device.QueryInterface <SharpDX.DXGI.Device>(); // create texture Texture = new Texture2D(Device, new Texture2DDescription { CpuAccessFlags = CpuAccessFlags.Read, BindFlags = BindFlags.None, Format = Format.B8G8R8A8_UNorm, Width = region.Width, Height = region.Height, OptionFlags = ResourceOptionFlags.None, MipLevels = 1, ArraySize = 1, SampleDescription = { Count = 1, Quality = 0 }, Usage = ResourceUsage.Staging }); // duplicate desktop try { Format[] formats = { Format.B8G8R8A8_UNorm }; Output6 = output.QueryInterface <Output6>(); Duplication = Output6.DuplicateOutput1(Device, 0, formats.Length, formats); } catch (Exception exception) when(exception is NotSupportedException || exception.HResult == ResultCode.Unsupported.Result || exception.HResult == Result.NoInterface.Result) { Output1 = output.QueryInterface <Output1>(); Duplication = Output1.DuplicateOutput(Device); } } catch (Exception exception) when(exception is NotSupportedException || exception is NotImplementedException || exception.HResult == ResultCode.Unsupported.Result || exception.HResult == Result.NotImplemented.Result || exception.HResult == Result.NoInterface.Result) { throw new NotSupportedException("Platform not supported", exception); } Alive = true; }
/// <summary> /// Initializes the <see cref="GraphicsDevice" />. /// </summary> /// <param name="parameters"> [in,out] Options for controlling the operation. </param> public void Initialize(ref GameGraphicsParameters parameters) { if (IsInitialized) { return; } _vSync = parameters.UseVSync ? 1 : 0; using (Factory4 factory4 = new Factory4()) { _dxgiFactory = factory4.QueryInterface <Factory5>(); } ModeDescription modeDescription = new ModeDescription( parameters.Width, parameters.Height, parameters.Rational, parameters.Format); if (parameters.AdapterLuid != -1 && parameters.OutputIndex != -1) { using (Adapter adapter = _dxgiFactory.GetAdapterByLuid(parameters.AdapterLuid)) using (Output output = adapter.GetOutput(parameters.OutputIndex)) { _adapter4 = adapter.QueryInterface <Adapter4>(); _output6 = output.QueryInterface <Output6>(); _output6.GetClosestMatchingMode( null, modeDescription, out modeDescription); } } else { IEnumerable <Adapter> adapters = _dxgiFactory.Adapters1 .Where( a => (a.Description1.Flags & AdapterFlags.Software) != AdapterFlags.Software && a.GetOutputCount() > 0) .Select( a => (adapter: a, featureLevel: SharpDX.Direct3D11.Device.GetSupportedFeatureLevel(a))) .GroupBy(t => t.featureLevel) .OrderByDescending(t => t.Key) .First() .Select(k => k.adapter); _adapter4 = null; foreach (Adapter adapter in adapters) { using (adapter) { for (int o = 0; o < adapter.GetOutputCount(); o++) { using (Output output = adapter.GetOutput(o)) { output.GetClosestMatchingMode( null, modeDescription, out ModeDescription desc); if (_adapter4 == null || desc.RefreshRate.Numerator / desc.RefreshRate.Denominator > modeDescription.RefreshRate.Numerator / modeDescription.RefreshRate.Denominator) { modeDescription = desc; Interlocked.Exchange(ref _output6, output.QueryInterface <Output6>())?.Dispose(); Interlocked.Exchange(ref _adapter4, adapter.QueryInterface <Adapter4>())?.Dispose(); } } } } } } // ReSharper disable once VariableHidesOuterVariable Device CreateDevice(in GameGraphicsParameters parameters) { if (_adapter4 != null) { Console.WriteLine("------- GRAPHIC CARD INFORMATION -------"); Console.WriteLine($"Luid:\t\t\t{_adapter4.Description2.Luid}"); Console.WriteLine( $"Description:\t\t{_adapter4.Description2.Description.TrimEnd('\t', ' ', '\r', '\n', (char)0)}"); Console.WriteLine($"DeviceId:\t\t{_adapter4.Description2.DeviceId}"); Console.WriteLine($"VendorId:\t\t{_adapter4.Description2.VendorId}"); Console.WriteLine($"Revision:\t\t{_adapter4.Description2.Revision}"); Console.WriteLine($"SubsystemId:\t\t{_adapter4.Description2.SubsystemId}"); #if x64 Console.WriteLine(); Console.WriteLine($"SystemMemory:\t\t{_adapter4.Description2.DedicatedSystemMemory}"); Console.WriteLine($"VideoMemory:\t\t{_adapter4.Description2.DedicatedVideoMemory}"); Console.WriteLine($"SharedSystemMemory:\t{_adapter4.Description2.SharedSystemMemory}"); #endif Console.WriteLine(); Console.WriteLine($"Format:\t\t\t{modeDescription.Format}"); Console.WriteLine($"Width x Height:\t\t{modeDescription.Width} x {modeDescription.Height}"); Console.WriteLine( $"RefreshRate:\t\t{modeDescription.RefreshRate} ({modeDescription.RefreshRate.Numerator / modeDescription.RefreshRate.Denominator}HZ)"); Console.WriteLine($"Scaling:\t\t{modeDescription.Scaling}"); Console.WriteLine($"ScanlineOrdering:\t{modeDescription.ScanlineOrdering}"); Console.WriteLine(); Console.WriteLine($"DeviceName:\t\t{_output6.Description.DeviceName}"); Console.WriteLine( $"DesktopBounds:\t\t{_output6.Description.DesktopBounds.Left};{_output6.Description.DesktopBounds.Top};{_output6.Description.DesktopBounds.Right};{_output6.Description.DesktopBounds.Bottom}"); Console.WriteLine($"MonitorHandle:\t\t{_output6.Description.MonitorHandle}"); Console.WriteLine($"IsAttachedToDesktop:\t{_output6.Description.IsAttachedToDesktop}"); Console.WriteLine($"Rotation:\t\t{_output6.Description.Rotation}"); Console.WriteLine("----------------------------------------\n"); return(new Device(_adapter4, parameters.DeviceCreationFlags, s_featureLevels)); } return(new Device(parameters.DriverType, parameters.DeviceCreationFlags, s_featureLevels)); } using (Device defaultDevice = CreateDevice(in parameters)) { _d3DDevice5 = defaultDevice.QueryInterface <Device5>(); } _d3DDeviceContext = _d3DDevice5.ImmediateContext3.QueryInterface <DeviceContext4>(); _dxgiDevice4 = _d3DDevice5.QueryInterface <Device4>(); SampleDescription sampleDescription = new SampleDescription(1, 0); if (parameters.EnableMultiSampling && parameters.MultiSampleCount != MultiSampleCount.None) { sampleDescription.Count = (int)parameters.MultiSampleCount; sampleDescription.Quality = Math.Max( _d3DDevice5.CheckMultisampleQualityLevels( modeDescription.Format, sampleDescription.Count) - 1, 0); } SwapChainDescription swapChainDescription = new SwapChainDescription { BufferCount = parameters.BufferCount, ModeDescription = modeDescription, IsWindowed = true, OutputHandle = parameters.Handle, SampleDescription = sampleDescription, SwapEffect = parameters.SwapEffect, Usage = parameters.Usage, Flags = parameters.SwapChainFlags }; using (SwapChain swapChain = new SwapChain(_dxgiFactory, _d3DDevice5, swapChainDescription)) { _swapChain4 = swapChain.QueryInterface <SwapChain4>(); } _dxgiFactory.MakeWindowAssociation(parameters.Handle, parameters.WindowAssociationFlags); _swapChain4.ResizeTarget(ref modeDescription); SetFullscreenState(parameters.DisplayType == DisplayType.Fullscreen); _resizeParameters = new ResizeParameters { BufferCount = parameters.BufferCount, Width = parameters.Width, Height = parameters.Height, SwapChainFlags = parameters.SwapChainFlags }; Resize(_resizeParameters); _blendStates = new BlendStates(this); _depthStencilStates = new DepthStencilStates(this); _rasterizerStates = new RasterizerStates(this); _samplerStates = new SamplerStates(this); _textures = new Textures(this); IsInitialized = true; }