예제 #1
0
        /// <summary>
        /// Function to find the nearest video mode to the one specified.
        /// </summary>
        /// <param name="output">Output for the video mode.</param>
        /// <param name="mode">Mode to find.</param>
        /// <returns>The closest matching video mode to the <paramref name="mode"/> parameter.</returns>
        internal GorgonVideoMode FindMode(GI.Output output, GorgonVideoMode mode)
        {
            GI.ModeDescription findMode = GorgonVideoMode.Convert(mode);
            GI.ModeDescription result;

            output.GetClosestMatchingMode(VideoDevice.Graphics.D3DDevice, findMode, out result);

            return(GorgonVideoMode.Convert(result));
        }
예제 #2
0
        /// <summary>
        /// Function to retrieve the video modes for the output.
        /// </summary>
        /// <param name="output">Output that owns the video modes.</param>
        /// <param name="D3DDevice">D3D device for filtering supported display modes.</param>
        /// <param name="giOutput">Output that contains the video modes.</param>
        private static void GetVideoModes(GorgonVideoOutput output, D3D.Device D3DDevice, Output giOutput)
        {
            var formats = (BufferFormat[])Enum.GetValues(typeof(BufferFormat));

            Gorgon.Log.Print("Retrieving video modes for output '{0}'...", LoggingLevel.Simple, output.Name);
            Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);

            // Test each format for display compatibility.
            foreach (var format in formats)
            {
                var giFormat            = (Format)format;
                ModeDescription[] modes = giOutput.GetDisplayModeList(giFormat, DisplayModeEnumerationFlags.Scaling | DisplayModeEnumerationFlags.Interlaced);

                if ((modes == null) || (modes.Length <= 0))
                {
                    continue;
                }

                GorgonVideoMode[] videoModes = (from mode in modes
                                                where (D3DDevice.CheckFormatSupport(giFormat) & D3D.FormatSupport.Display) == D3D.FormatSupport.Display
                                                select GorgonVideoMode.Convert(mode)).ToArray();

                if (videoModes.Length > 0)
                {
                    output.VideoModes = new ReadOnlyCollection <GorgonVideoMode>(videoModes);
                }
            }

            // Output to log.
            foreach (var videoMode in output.VideoModes)
            {
                Gorgon.Log.Print("Mode: {0}x{1}, Format: {2}, Refresh Rate: {3}/{4}", LoggingLevel.Verbose, videoMode.Width, videoMode.Height, videoMode.Format, videoMode.RefreshRateNumerator, videoMode.RefreshRateDenominator);
            }

            Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose);
            Gorgon.Log.Print("Found {0} video modes for output '{1}'.", LoggingLevel.Simple, output.VideoModes.Count, output.Name);
        }
예제 #3
0
        /// <summary>
        /// Function to intialize the swap chain.
        /// </summary>
        internal void Initialize()
        {
            var D3DSettings = new GI.SwapChainDescription();

            // Resize the window to match requested mode size.
            if ((_parentForm == Settings.Window) && (Settings.IsWindowed) && (!Settings.NoClientResize))
            {
                _parentForm.ClientSize = new Size(Settings.VideoMode.Width, Settings.VideoMode.Height);
            }

            AutoResize = !Settings.NoClientResize;
            Graphics.GetFullScreenSwapChains();
            D3DSettings.BufferCount = Settings.BufferCount;
            D3DSettings.Flags       = GI.SwapChainFlags.AllowModeSwitch;

            D3DSettings.IsWindowed        = true;
            D3DSettings.ModeDescription   = GorgonVideoMode.Convert(Settings.VideoMode);
            D3DSettings.OutputHandle      = Settings.Window.Handle;
            D3DSettings.SampleDescription = GorgonMultisampling.Convert(Settings.Multisampling);
            D3DSettings.SwapEffect        = GorgonSwapChainSettings.Convert(Settings.SwapEffect);

            if ((Settings.Flags & SwapChainUsageFlags.RenderTarget) == SwapChainUsageFlags.RenderTarget)
            {
                D3DSettings.Usage = GI.Usage.RenderTargetOutput;
            }

            if ((Settings.Flags & SwapChainUsageFlags.AllowShaderView) == SwapChainUsageFlags.AllowShaderView)
            {
                D3DSettings.Usage |= GI.Usage.ShaderInput;
            }

            if ((Settings.Flags & SwapChainUsageFlags.AllowUnorderedAccessView) == SwapChainUsageFlags.AllowUnorderedAccessView)
            {
                D3DSettings.Usage |= GI.Usage.UnorderedAccess;
            }

            Gorgon.Log.Print("GorgonSwapChain '{0}': Creating D3D11 swap chain...", LoggingLevel.Simple, Name);
            GISwapChain = new GI.SwapChain(Graphics.GIFactory, Graphics.D3DDevice, D3DSettings)
            {
                DebugName = Name + " DXGISwapChain"
            };

            // Due to an issue with winforms and DXGI, we have to manually handle transitions ourselves.
            Graphics.GIFactory.MakeWindowAssociation(Settings.Window.Handle, GI.WindowAssociationFlags.IgnoreAll);

            CreateResources();

            if (!Settings.IsWindowed)
            {
                ModeStateUpdate();
            }

            Settings.Window.Resize += Window_Resize;

            if (_parentForm == null)
            {
                return;
            }

            _parentForm.ResizeBegin += _parentForm_ResizeBegin;
            _parentForm.ResizeEnd   += _parentForm_ResizeEnd;
        }
예제 #4
0
        /// <summary>
        /// Function to update the fullscreen/windowed mode state.
        /// </summary>
        private void ModeStateUpdate()
        {
            var e = new GorgonBeforeStateTransitionEventArgs(!Settings.IsWindowed);

            GI.ModeDescription mode = GorgonVideoMode.Convert(Settings.VideoMode);

            try
            {
                GISwapChain.ResizeTarget(ref mode);

                if (!Settings.IsWindowed)
                {
                    if (BeforeStateTransition != null)
                    {
                        BeforeStateTransition(this, new GorgonBeforeStateTransitionEventArgs(true));
                    }

                    if (!e.Cancel)
                    {
                        // We don't need to force an output.  We'll just let DXGI figure it out from the
                        // window area on the monitor.  Currently SharpDX's ContainingOutput property is
                        // buggy in 2.4.2 and will return multiple ref counts for each time the property is
                        // read.  v2.5.0 is in dev, but now has the problem of not returning the correct output.
                        GISwapChain.SetFullscreenState(true, null);
                        if (_parentForm != null)
                        {
                            _parentForm.Activated  += _parentForm_Activated;
                            _parentForm.Deactivate += _parentForm_Deactivate;
                        }
                    }
                }
                else
                {
                    if (BeforeStateTransition != null)
                    {
                        BeforeStateTransition(this, new GorgonBeforeStateTransitionEventArgs(false));
                    }

                    if (!e.Cancel)
                    {
                        GISwapChain.SetFullscreenState(false, null);
                    }
                }
            }
            catch (SharpDXException sdEx)
            {
                switch (sdEx.ResultCode.Code)
                {
                case (int)GI.DXGIStatus.ModeChangeInProgress:
                    Gorgon.Log.Print("GorgonSwapChain '{0}': Could not switch to full screen mode because the device was busy switching to full screen on another output.", LoggingLevel.All, Name);
                    break;

                default:
                    if (sdEx.ResultCode != GI.ResultCode.NotCurrentlyAvailable)
                    {
                        throw;
                    }

                    Gorgon.Log.Print(
                        "GorgonSwapChain '{0}': Could not switch to full screen mode because the device is not currently available.  Possible causes are:  .",
                        LoggingLevel.All,
                        Name);
                    break;
                }
            }

            ResizeBuffers();

            if ((!e.Cancel) && (AfterStateTransition != null))
            {
                AfterStateTransition(this, new GorgonAfterSwapChainResizedEventArgs(this));
            }
        }
예제 #5
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);
        }