Example #1
0
        /// <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);
            }
        }