Example #1
0
        /// <summary>
        /// Function to update the settings for the swap chain.
        /// </summary>
        /// <param name="mode">New video mode to use.</param>
        /// <param name="depthStencilFormat">The format of the internal depth/stencil buffer.</param>
        /// <param name="isWindowed">TRUE to switch to windowed mode, FALSE to switch to full screen.</param>
        /// <param name="bufferCount">Number of back buffers.</param>
        /// <remarks>If the <see cref="P:GorgonLibrary.Graphics.GorgonSwapChainSettings.SwapEffect">SwapEffect</see> for the swap chain is set to discard, then the <paramref name="bufferCount"/> must be greater than 1.</remarks>
        /// <exception cref="System.ArgumentException">Thrown when the <see cref="P:GorgonLibrary.Graphics.GorgonSwapChainSettings.Window">GorgonSwapChainSettings.Window</see> property is NULL (Nothing in VB.Net), and the <see cref="P:GorgonLibrary.Gorgon.ApplicationForm">Gorgon application window</see> is NULL.
        /// <para>-or-</para>
        /// <para>Thrown when the <see cref="GorgonLibrary.Graphics.GorgonVideoMode.Format">GorgonSwapChainSettings.VideoMode.Format</see> property cannot be used by the video device for displaying data.</para>
        /// </exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the video output could not be determined from the window.
        /// <para>-or-</para>
        /// <para>Thrown when the swap chain is going to full screen mode and another swap chain is already on the video output.</para>
        /// </exception>
        public void UpdateSettings(GorgonVideoMode mode, bool isWindowed, BufferFormat depthStencilFormat, int bufferCount)
        {
            if (GISwapChain == null)
            {
                return;
            }

            if (_parentForm != null)
            {
                _parentForm.Activated  -= _parentForm_Activated;
                _parentForm.Deactivate -= _parentForm_Deactivate;
            }

            // Assign the new settings.
            Settings.IsWindowed         = isWindowed;
            Settings.VideoMode          = mode;
            Settings.BufferCount        = bufferCount;
            Settings.DepthStencilFormat = depthStencilFormat;

            // Validate and modify the settings as appropriate.
            Graphics.ImmediateContext.Output.ValidateSwapChainSettings(Settings);

            ModeStateUpdate();

            // Ensure our window is the proper size.
            if ((_parentForm == Settings.Window) &&
                (Settings.IsWindowed) &&
                ((Settings.VideoMode.Width != Settings.Window.ClientSize.Width) ||
                 (Settings.VideoMode.Height != Settings.Window.ClientSize.Height)))
            {
                Settings.Window.ClientSize = new Size(Settings.VideoMode.Width, Settings.VideoMode.Height);
            }
        }
Example #2
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));
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonVideoOutput"/> class.
        /// </summary>
        internal GorgonVideoOutput()
        {
            var area = Screen.AllScreens.Aggregate(Rectangle.Empty, (current, t) => Rectangle.Union(current, t.Bounds));

            Index  = 0;
            Handle = Win32API.GetMonitor(null);
            IsAttachedToDesktop = true;
            Name             = Resources.GORGFX_OUTPUT_SOFTWARE_DEV_NAME;
            OutputBounds     = Screen.PrimaryScreen.Bounds;
            Rotation         = 0;
            DefaultVideoMode = new GorgonVideoMode(area.Width, area.Height, BufferFormat.R8G8B8A8_UIntNormal);
        }
Example #4
0
#pragma warning disable 0618
        /// <summary>
        /// Function to find the nearest video mode to the one specified.
        /// </summary>
        /// <param name="mode">Mode to find.</param>
        /// <returns>The closest matching video mode to the <paramref name="mode"/> parameter.</returns>
        public GorgonVideoMode FindMode(GorgonVideoMode mode)
        {
            if ((VideoDevice.Graphics == null) || (VideoDevice.Graphics.D3DDevice == null))
            {
                return(mode);
            }

            using (var output = VideoDevice.Graphics.Adapter.GetOutput(Index))
            {
                return(FindMode(output, mode));
            }
        }
        /// <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);
        }
Example #6
0
 /// <summary>
 /// Function to update the settings for the render target.
 /// </summary>
 /// <param name="mode">New video mode to use.</param>
 /// <param name="depthStencilFormat">The format of the internal depth/stencil buffer.</param>
 /// <exception cref="GorgonLibrary.GorgonException">
 /// Thrown when the <see cref="GorgonLibrary.Graphics.GorgonVideoMode.Format">GorgonSwapChainSettings.VideoMode.Format</see> property cannot be used by the video device for displaying data.
 ///   <para>-or-</para>
 ///   <para>The width and height are not valid for the render target.</para>
 ///   </exception>
 public void UpdateSettings(GorgonVideoMode mode, BufferFormat depthStencilFormat)
 {
     UpdateSettings(mode, Settings.IsWindowed, depthStencilFormat, Settings.BufferCount);
 }
Example #7
0
 /// <summary>
 /// Function to update the settings for the swap chain.
 /// </summary>
 /// <param name="mode">New video mode to use.</param>
 /// <param name="isWindowed">TRUE to use windowed mode, FALSE to use full screen mode.</param>
 /// <exception cref="System.ArgumentException">Thrown when the <see cref="P:GorgonLibrary.Graphics.GorgonSwapChainSettings.Window">GorgonSwapChainSettings.Window</see> property is NULL (Nothing in VB.Net), and the <see cref="P:GorgonLibrary.Gorgon.ApplicationForm">Gorgon application window</see> is NULL.
 /// <para>-or-</para>
 /// <para>Thrown when the <see cref="GorgonLibrary.Graphics.GorgonVideoMode.Format">GorgonSwapChainSettings.VideoMode.Format</see> property cannot be used by the video device for displaying data.</para>
 /// <para>-or-</para>
 /// <para>Thrown when the <see cref="GorgonLibrary.Graphics.GorgonMultisampling.Quality">GorgonSwapChainSettings.Multisamplings.Quality</see> property is higher than what the video device can support.</para>
 /// </exception>
 /// <exception cref="GorgonLibrary.GorgonException">Thrown when the video output could not be determined from the window.
 /// <para>-or-</para>
 /// <para>Thrown when the swap chain is going to full screen mode and another swap chain is already on the video output.</para>
 /// </exception>
 public void UpdateSettings(GorgonVideoMode mode, bool isWindowed)
 {
     UpdateSettings(Settings.VideoMode, isWindowed, Settings.DepthStencilFormat, Settings.BufferCount);
 }
Example #8
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;
        }
Example #9
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));
            }
        }
                #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);
        }