/// <summary> /// Initializes a new instance of the <see cref="GorgonVideoDevice"/> class. /// </summary> /// <param name="adapter">DXGI video adapter.</param> /// <param name="deviceType">Type of video device.</param> /// <param name="index">Index of the device.</param> internal GorgonVideoDevice(GI.Adapter1 adapter, VideoDeviceType deviceType, int index) { VideoDeviceType = deviceType; Index = index; DedicatedSystemMemory = adapter.Description1.DedicatedSystemMemory; DedicatedVideoMemory = adapter.Description1.DedicatedVideoMemory; DeviceID = adapter.Description1.DeviceId; HardwareFeatureLevel = DeviceFeatureLevel.Unsupported; UUID = adapter.Description1.Luid; Revision = adapter.Description1.Revision; SharedSystemMemory = adapter.Description1.SharedSystemMemory; SubSystemID = adapter.Description1.SubsystemId; VendorID = adapter.Description1.VendorId; switch (deviceType) { case VideoDeviceType.Software: Name = Resources.GORGFX_DEVICE_NAME_WARP; HardwareFeatureLevel = SupportedFeatureLevel = DeviceFeatureLevel.SM4_1; break; case VideoDeviceType.ReferenceRasterizer: Name = Resources.GORGFX_DEVICE_NAME_REFRAST; HardwareFeatureLevel = SupportedFeatureLevel = DeviceFeatureLevel.SM5; break; default: Name = adapter.Description1.Description; EnumerateFeatureLevels(D3D.Device.GetSupportedFeatureLevel(adapter)); break; } Outputs = new GorgonNamedObjectReadOnlyCollection <GorgonVideoOutput>(false, new GorgonVideoOutput[] { }); }
#pragma warning restore 0618 #endregion #region Constructor/Destructor. /// <summary> /// Initializes the <see cref="GorgonVideoDeviceEnumerator"/> class. /// </summary> static GorgonVideoDeviceEnumerator() { VideoDevices = new GorgonNamedObjectReadOnlyCollection <GorgonVideoDevice>(false, new GorgonVideoDevice[] { }); Enumerate(false, false); }
/// <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); } }