예제 #1
0
#pragma warning restore 0618
        #endregion

        #region Constructor/Destructor.
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonVideoOutput"/> class.
        /// </summary>
        /// <param name="output">Output to evaluate.</param>
        /// <param name="device">Video device that owns the output.</param>
        /// <param name="index">The index of the output.</param>
        internal GorgonVideoOutput(GI.Output output, GorgonVideoDevice device, int index)
        {
            VideoDevice = device;

            Index  = index;
            Handle = output.Description.MonitorHandle;
            IsAttachedToDesktop = output.Description.IsAttachedToDesktop;
            Name         = output.Description.DeviceName;
            OutputBounds = new Rectangle(output.Description.DesktopBounds.Left,
                                         output.Description.DesktopBounds.Top,
                                         output.Description.DesktopBounds.Width,
                                         output.Description.DesktopBounds.Height);
            switch (output.Description.Rotation)
            {
            case GI.DisplayModeRotation.Rotate90:
                Rotation = 90;
                break;

            case GI.DisplayModeRotation.Rotate270:
                Rotation = 270;
                break;

            case GI.DisplayModeRotation.Rotate180:
                Rotation = 180;
                break;

            default:
                Rotation = 0;
                break;
            }
        }
예제 #2
0
                #pragma warning disable 0618
        /// <summary>
        /// Function to add the WARP software device.
        /// </summary>
        /// <param name="index">Index of the device.</param>
        /// <returns>The video device used for WARP software rendering.</returns>
        private static GorgonVideoDevice GetWARPSoftwareDevice(int index)
        {
            GorgonVideoDevice device;

#if DEBUG
            using (var D3DDevice = new D3D.Device(D3DCommon.DriverType.Warp, D3D.DeviceCreationFlags.Debug,
                                                  D3DCommon.FeatureLevel.Level_10_1, D3DCommon.FeatureLevel.Level_10_0, D3DCommon.FeatureLevel.Level_9_3))
            {
#else
            using (var D3DDevice = new D3D.Device(D3DCommon.DriverType.Warp, D3D.DeviceCreationFlags.None,
                                                  D3DCommon.FeatureLevel.Level_10_1, D3DCommon.FeatureLevel.Level_10_0, D3DCommon.FeatureLevel.Level_9_3))
            {
#endif
                using (var giDevice = D3DDevice.QueryInterface <Device1>())
                {
                    using (var adapter = giDevice.GetParent <Adapter1>())
                    {
                        device = new GorgonVideoDevice(adapter, VideoDeviceType.Software, index);

                        PrintLog(device);

                        // Get the outputs for the device.
                        int outputCount = adapter.GetOutputCount();

                        GetOutputs(device, D3DDevice, adapter, outputCount, outputCount == 0);
                    }
                }
            }

            return(device);
        }
예제 #3
0
        /// <summary>
        /// Initializes the <see cref="GorgonGraphics"/> class.
        /// </summary>
        /// <param name="device">Video device to use.</param>
        /// <param name="featureLevel">The maximum feature level to support for the devices enumerated.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="featureLevel"/> parameter is invalid.</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when Gorgon could not find any video devices that are Shader Model 5, or the down level interfaces (Shader Model 4, and lesser).
        /// <para>-or-</para>
        /// <para>Thrown if the operating system version is not supported.  Gorgon Graphics requires at least Windows Vista Service Pack 2 or higher.</para>
        /// </exception>
        /// <remarks>
        /// The <paramref name="device"/> parameter is the video device that should be used with Gorgon.  If the user passes NULL (Nothing in VB.Net), then the primary device will be used.
        /// To determine the devices on the system, check the <see cref="GorgonLibrary.Graphics.GorgonVideoDeviceEnumerator">GorgonVideoDeviceEnumerator</see> class.  The primary device will be the first device in this collection.
        /// <para>The user may pass in a feature level to the featureLevel parameter to limit the feature levels available.  Note that the feature levels imply all feature levels up until the feature level passed in, for example, passing <c>DeviceFeatureLevel.SM4</c> will only allow functionality
        /// for both Shader Model 4, and Shader Model 2/3 capable video devices, while DeviceFeatureLevel.SM4_1 will include Shader Model 4 with a 4.1 profile and Shader model 2/3 video devices.</para>
        /// <para>If a feature level is not supported by the hardware, then Gorgon will not use that feature level.  That is, passing a SM5 feature level with a SM4 card will only use a SM4 feature level.  If the user omits the feature level (in one of the constructor
        /// overloads), then Gorgon will use the best available feature level for the video device being used.</para>
        /// </remarks>
        public GorgonGraphics(GorgonVideoDevice device, DeviceFeatureLevel featureLevel)
        {
            ResetFullscreenOnFocus = true;
            ImmediateContext       = this;

            if (featureLevel == DeviceFeatureLevel.Unsupported)
            {
                throw new ArgumentException(Resources.GORGFX_FEATURE_LEVEL_UNKNOWN);
            }

            if (GorgonComputerInfo.OperatingSystemVersion.Major < 6)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_INVALID_OS);
            }

            Gorgon.Log.Print("Gorgon Graphics initializing...", LoggingLevel.Simple);

            // Track our objects.
            _trackedObjects = new GorgonDisposableObjectCollection();

#if DEBUG
            if (!SharpDX.Configuration.EnableObjectTracking)
            {
                SharpDX.Configuration.EnableObjectTracking = true;
            }
#else
            SharpDX.Configuration.EnableObjectTracking = false;
#endif

            if (device == null)
            {
                if (GorgonVideoDeviceEnumerator.VideoDevices.Count == 0)
                {
                    GorgonVideoDeviceEnumerator.Enumerate(false, false);
                }

                // Use the first device in the list.
                device = GorgonVideoDeviceEnumerator.VideoDevices[0];
            }

            VideoDevice = device;

            var D3DDeviceData = VideoDevice.GetDevice(VideoDevice.VideoDeviceType, featureLevel);

            // Create the DXGI factory for the video device.
            GIFactory = D3DDeviceData.Item1;
            Adapter   = D3DDeviceData.Item2;
            D3DDevice = D3DDeviceData.Item3;

            Context = D3DDevice.ImmediateContext;
            Context.ClearState();
            VideoDevice.Graphics = ImmediateContext;

            CreateStates();

            Gorgon.AddTrackedObject(this);

            Gorgon.Log.Print("Gorgon Graphics initialized.", LoggingLevel.Simple);
        }
예제 #4
0
                #pragma warning restore 0618

        /// <summary>
        /// Function to print device log information.
        /// </summary>
        /// <param name="device">Device to print.</param>
        private static void PrintLog(GorgonVideoDevice device)
        {
            Gorgon.Log.Print(
                device.VideoDeviceType == VideoDeviceType.ReferenceRasterizer
                                        ? "Device found: {0} ---> !!!** WARNING:  A reference rasterizer has very poor performance."
                                        : "Device found: {0}", LoggingLevel.Simple, device.Name);
            Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);
            Gorgon.Log.Print("Hardware feature level: {0}", LoggingLevel.Verbose, device.HardwareFeatureLevel);
            Gorgon.Log.Print("Limited to feature level: {0}", LoggingLevel.Verbose, device.SupportedFeatureLevel);
            Gorgon.Log.Print("Video memory: {0}", LoggingLevel.Verbose, device.DedicatedVideoMemory.FormatMemory());
            Gorgon.Log.Print("System memory: {0}", LoggingLevel.Verbose, device.DedicatedSystemMemory.FormatMemory());
            Gorgon.Log.Print("Shared memory: {0}", LoggingLevel.Verbose, device.SharedSystemMemory.FormatMemory());
            Gorgon.Log.Print("Device ID: 0x{0}", LoggingLevel.Verbose, device.DeviceID.FormatHex());
            Gorgon.Log.Print("Sub-system ID: 0x{0}", LoggingLevel.Verbose, device.SubSystemID.FormatHex());
            Gorgon.Log.Print("Vendor ID: 0x{0}", LoggingLevel.Verbose, device.VendorID.FormatHex());
            Gorgon.Log.Print("Revision: {0}", LoggingLevel.Verbose, device.Revision);
            Gorgon.Log.Print("Unique ID: 0x{0}", LoggingLevel.Verbose, device.UUID.FormatHex());
            Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);
        }
예제 #5
0
        /// <summary>
        /// Function to add the reference device.
        /// </summary>
        /// <param name="index">Index of the device.</param>
        /// <returns>The video device used for reference software rendering.</returns>
        private static GorgonVideoDevice GetRefSoftwareDevice(int index)
        {
            GorgonVideoDevice device;

            using (var D3DDevice = new D3D.Device(D3DCommon.DriverType.Reference, D3D.DeviceCreationFlags.Debug))
            {
                using (var giDevice = D3DDevice.QueryInterface <Device1>())
                {
                    using (var adapter = giDevice.GetParent <Adapter1>())
                    {
                        device = new GorgonVideoDevice(adapter, VideoDeviceType.ReferenceRasterizer, index);

                        PrintLog(device);

                        int outputCount = adapter.GetOutputCount();
                        GetOutputs(device, D3DDevice, adapter, outputCount, outputCount == 0);
                    }
                }
            }

            return(device);
        }
예제 #6
0
 /// <summary>
 /// Initializes the <see cref="GorgonGraphics"/> class.
 /// </summary>
 /// <param name="device">Video device to use.</param>
 /// <exception cref="GorgonLibrary.GorgonException">Thrown when Gorgon could not find any video devices that are Shader Model 5, or the down level interfaces (Shader Model 4, and lesser).
 /// <para>-or-</para>
 /// <para>Thrown if the operating system version is not supported.  Gorgon Graphics requires at least Windows Vista Service Pack 2 or higher.</para>
 /// </exception>
 /// <remarks>
 /// The <paramref name="device"/> parameter is the video device that should be used with Gorgon.  If the user passes NULL (Nothing in VB.Net), then the primary device will be used.
 /// To determine the devices on the system, check the <see cref="GorgonLibrary.Graphics.GorgonVideoDeviceEnumerator">GorgonVideoDeviceEnumerator</see> class.  The primary device will be the first device in this collection.
 /// </remarks>
 public GorgonGraphics(GorgonVideoDevice device)
     : this(device, DeviceFeatureLevel.SM5)
 {
 }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
                #pragma warning disable 0618
        /// <summary>
        /// Function to retrieve the list of outputs for the video device.
        /// </summary>
        /// <param name="adapter">Adapter containing the outputs.</param>
        /// <param name="D3DDevice">D3D device to find closest matching mode.</param>
        /// <param name="device">Device used to filter video modes that aren't supported.</param>
        /// <param name="outputCount">The number of outputs attached to the device.</param>
        /// <param name="noOutputDevice">TRUE if the device has no outputs, FALSE if it does.</param>
        private static void GetOutputs(GorgonVideoDevice device, D3D.Device D3DDevice, Adapter adapter, int outputCount, bool noOutputDevice)
        {
            var outputs = new List <GorgonVideoOutput>(outputCount);

            // We need to fake outputs.
            // Windows 8 does not support outputs on WARP devices and ref rasterizer devices.
            if ((noOutputDevice) || (SystemInformation.TerminalServerSession))
            {
                var output = new GorgonVideoOutput();

                Gorgon.Log.Print("Found output {0}.", LoggingLevel.Simple, output.Name);
                Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);
                Gorgon.Log.Print("Output bounds: ({0}x{1})-({2}x{3})", LoggingLevel.Verbose, output.OutputBounds.Left, output.OutputBounds.Top, output.OutputBounds.Right, output.OutputBounds.Bottom);
                Gorgon.Log.Print("Monitor handle: 0x{0}", LoggingLevel.Verbose, output.Handle.FormatHex());
                Gorgon.Log.Print("Attached to desktop: {0}", LoggingLevel.Verbose, output.IsAttachedToDesktop);
                Gorgon.Log.Print("Monitor rotation: {0}\u00B0", LoggingLevel.Verbose, output.Rotation);
                Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);

                outputs.Add(output);

                // No video modes for these devices.
                output.VideoModes = new GorgonVideoMode[0];

                device.Outputs = new GorgonNamedObjectReadOnlyCollection <GorgonVideoOutput>(false, outputs);

                Gorgon.Log.Print("Output {0} on device {1} has no video modes.", LoggingLevel.Verbose, output.Name, device.Name);
                return;
            }

            // Get outputs.
            for (int i = 0; i < outputCount; i++)
            {
                using (Output giOutput = adapter.GetOutput(i))
                {
                    var output = new GorgonVideoOutput(giOutput, device, i);

                    ModeDescription findMode = GorgonVideoMode.Convert(new GorgonVideoMode(output.OutputBounds.Width, output.OutputBounds.Height, BufferFormat.R8G8B8A8_UIntNormal, 60, 1));
                    ModeDescription result;

                    // Get the default (desktop) video mode.
                    giOutput.GetClosestMatchingMode(D3DDevice, findMode, out result);
                    output.DefaultVideoMode = GorgonVideoMode.Convert(result);

                    GetVideoModes(output, D3DDevice, giOutput);

                    Gorgon.Log.Print("Found output {0}.", LoggingLevel.Simple, output.Name);
                    Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);
                    Gorgon.Log.Print("Output bounds: ({0}x{1})-({2}x{3})", LoggingLevel.Verbose, output.OutputBounds.Left, output.OutputBounds.Top, output.OutputBounds.Right, output.OutputBounds.Bottom);
                    Gorgon.Log.Print("Monitor handle: 0x{0}", LoggingLevel.Verbose, output.Handle.FormatHex());
                    Gorgon.Log.Print("Attached to desktop: {0}", LoggingLevel.Verbose, output.IsAttachedToDesktop);
                    Gorgon.Log.Print("Monitor rotation: {0}\u00B0", LoggingLevel.Verbose, output.Rotation);
                    Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);

                    if (output.VideoModes.Count > 0)
                    {
                        outputs.Add(output);
                    }
                    else
                    {
                        Gorgon.Log.Print("Output {0} on device {1} has no video modes!", LoggingLevel.Verbose, output.Name, device.Name);
                    }
                }
            }

            device.Outputs = new GorgonNamedObjectReadOnlyCollection <GorgonVideoOutput>(false, outputs);
        }