/// <summary> /// Function to add the WARP software device. /// </summary> /// <param name="index">Index of the device.</param> /// <param name="factory">The factory used to query the adapter.</param> /// <param name="log">The log interface used to send messages to a debug log.</param> /// <returns>The video adapter used for WARP software rendering.</returns> private static VideoAdapterInfo GetWARPSoftwareDevice(int index, Factory5 factory, IGorgonLog log) { D3D11.DeviceCreationFlags flags = D3D11.DeviceCreationFlags.None; if (GorgonGraphics.IsDebugEnabled) { flags = D3D11.DeviceCreationFlags.Debug; } using (Adapter warp = factory.GetWarpAdapter()) using (Adapter4 warpAdapter4 = warp.QueryInterface <Adapter4>()) using (var D3DDevice = new D3D11.Device(warpAdapter4, flags)) using (D3D11.Device5 D3DDevice5 = D3DDevice.QueryInterface <D3D11.Device5>()) { FeatureSet?featureSet = GetFeatureLevel(D3DDevice5); if (featureSet == null) { log.Print("WARNING: The WARP software adapter does not support the minimum feature set of 12.0. This device will be excluded.", LoggingLevel.All); return(null); } var result = new VideoAdapterInfo(index, warpAdapter4, featureSet.Value, new Dictionary <string, VideoOutputInfo>(), VideoDeviceType.Software); PrintLog(result, log); return(result); } }
/// <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; }
/// <summary> /// Initializes a new instance of the <see cref="Device4"/> class. /// </summary> /// <param name="factory"><para>The <see cref="Factory5"/> object used when creating the <see cref="SharpDX.Direct2D1.Device3"/>. </para></param> /// <param name="device"><para>The <see cref="SharpDX.DXGI.Device"/> object used when creating the <see cref="SharpDX.Direct2D1.Device4"/>. </para></param> /// <remarks> /// Each call to CreateDevice returns a unique <see cref="SharpDX.Direct2D1.Device4"/> object.The <see cref="SharpDX.DXGI.Device4"/> object is obtained by calling QueryInterface on an ID3D10Device or an ID3D11Device. /// </remarks> /// <unmanaged>HRESULT ID2D1Factory5::CreateDevice([In] IDXGIDevice* dxgiDevice,[Out] ID2D1Device5** d2dDevice4)</unmanaged> public Device4(Factory5 factory, SharpDX.DXGI.Device device) : base(IntPtr.Zero) { factory.CreateDevice(device, this); }
/// <summary> /// Function to perform an enumeration of the video adapters attached to the system and populate this list. /// </summary> /// <param name="enumerateWARPDevice"><b>true</b> to enumerate the WARP software device, or <b>false</b> to exclude it.</param> /// <param name="log">The log that will capture debug logging messages.</param> /// <remarks> /// <para> /// Use this method to populate a list with information about the video adapters installed in the system. /// </para> /// <para> /// You may include the WARP device, which is a software based device that emulates most of the functionality of a video adapter, by setting the <paramref name="enumerateWARPDevice"/> to <b>true</b>. /// </para> /// <para> /// Gorgon requires a video adapter that is capable of supporting Direct 3D 12.0 at minimum. If no suitable devices are found installed in the computer, then the resulting list will be empty. /// </para> /// </remarks> public static IReadOnlyList <IGorgonVideoAdapterInfo> Enumerate(bool enumerateWARPDevice, IGorgonLog log) { var devices = new List <IGorgonVideoAdapterInfo>(); if (log == null) { log = GorgonLog.NullLog; } using (var factory2 = new Factory2(GorgonGraphics.IsDebugEnabled)) using (Factory5 factory5 = factory2.QueryInterface <Factory5>()) { int adapterCount = factory5.GetAdapterCount1(); log.Print("Enumerating video adapters...", LoggingLevel.Simple); // Begin gathering device information. for (int i = 0; i < adapterCount; i++) { // Get the video adapter information. using (Adapter1 adapter1 = factory5.GetAdapter1(i)) using (Adapter4 adapter = adapter1.QueryInterface <Adapter4>()) { // ReSharper disable BitwiseOperatorOnEnumWithoutFlags if (((adapter.Desc3.Flags & AdapterFlags3.Remote) == AdapterFlags3.Remote) || ((adapter.Desc3.Flags & AdapterFlags3.Software) == AdapterFlags3.Software)) { continue; } // ReSharper restore BitwiseOperatorOnEnumWithoutFlags D3D11.DeviceCreationFlags flags = D3D11.DeviceCreationFlags.None; if (GorgonGraphics.IsDebugEnabled) { flags = D3D11.DeviceCreationFlags.Debug; } // We create a D3D device here to filter out unsupported video modes from the format list. using (var D3DDevice = new D3D11.Device(adapter, flags, D3D.FeatureLevel.Level_12_1, D3D.FeatureLevel.Level_12_0)) using (D3D11.Device5 D3DDevice5 = D3DDevice.QueryInterface <D3D11.Device5>()) { D3DDevice5.DebugName = "Output enumerator device."; FeatureSet?featureSet = GetFeatureLevel(D3DDevice5); // Do not enumerate this device if its feature set is not supported. if (featureSet == null) { log.Print("This video adapter is not supported by Gorgon and will be skipped.", LoggingLevel.Verbose); continue; } Dictionary <string, VideoOutputInfo> outputs = GetOutputs(D3DDevice5, adapter, adapter.GetOutputCount(), log); if (outputs.Count <= 0) { log.Print($"WARNING: Video adapter {adapter.Description1.Description.Replace("\0", string.Empty)} has no outputs. Full screen mode will not be possible.", LoggingLevel.Verbose); } var videoAdapter = new VideoAdapterInfo(i, adapter, featureSet.Value, outputs, VideoDeviceType.Hardware); devices.Add(videoAdapter); PrintLog(videoAdapter, log); } } } // Get software devices. if (!enumerateWARPDevice) { return(devices); } VideoAdapterInfo device = GetWARPSoftwareDevice(devices.Count, factory5, log); if (device != null) { devices.Add(device); } } log.Print("Found {0} video adapters.", LoggingLevel.Simple, devices.Count); return(devices); }