static void BuildMultisampleTypeList(SettingsCombo9 combo)
        {
            List <MultisampleType> possibleMultisampleTypes = new List <MultisampleType>()
            {
                MultisampleType.None, MultisampleType.NonMaskable,
                MultisampleType.TwoSamples, MultisampleType.ThreeSamples,
                MultisampleType.FourSamples, MultisampleType.FiveSamples,
                MultisampleType.SixSamples, MultisampleType.SevenSamples,
                MultisampleType.EightSamples, MultisampleType.NineSamples,
                MultisampleType.TenSamples, MultisampleType.ElevenSamples,
                MultisampleType.TwelveSamples, MultisampleType.ThirteenSamples,
                MultisampleType.FourteenSamples, MultisampleType.FifteenSamples,
                MultisampleType.SixteenSamples
            };

            int quality;

            foreach (MultisampleType type in possibleMultisampleTypes)
            {
                if (GraphicsDeviceManager.Direct3D9Object.CheckDeviceMultisampleType(combo.AdapterOrdinal, combo.DeviceType,
                                                                                     combo.AdapterFormat, combo.Windowed, type, out quality))
                {
                    combo.MultisampleTypes.Add(type);
                    combo.MultisampleQualities.Add(quality);
                }
            }
        }
        static void BuildDepthStencilFormatList(SettingsCombo9 combo)
        {
            List <Format> possibleDepthStencilFormats = new List <Format> {
                Format.D16, Format.D15S1, Format.D24X8,
                Format.D24S8, Format.D24X4S4, Format.D32
            };

            foreach (Format format in possibleDepthStencilFormats)
            {
                if (GraphicsDeviceManager.Direct3D9Object.CheckDeviceFormat(combo.AdapterOrdinal, combo.DeviceType, combo.AdapterFormat,
                                                                            Usage.DepthStencil, ResourceType.Surface, format) &&
                    GraphicsDeviceManager.Direct3D9Object.CheckDepthStencilMatch(combo.AdapterOrdinal, combo.DeviceType,
                                                                                 combo.AdapterFormat, combo.BackBufferFormat, format))
                {
                    combo.DepthStencilFormats.Add(format);
                }
            }
        }
        static DisplayMode FindValidResolution(SettingsCombo9 combo, Direct3D9Settings input)
        {
            DisplayMode bestMode = new DisplayMode();

            if (combo.Windowed)
            {
                bestMode.Width  = input.PresentParameters.BackBufferWidth;
                bestMode.Height = input.PresentParameters.BackBufferHeight;
                return(bestMode);
            }

            int bestRanking = 100000;
            int ranking;

            foreach (DisplayMode mode in combo.AdapterInfo.DisplayModes)
            {
                if (mode.Format != combo.AdapterFormat)
                {
                    continue;
                }

                ranking = Math.Abs(mode.Width - input.PresentParameters.BackBufferWidth) +
                          Math.Abs(mode.Height - input.PresentParameters.BackBufferHeight);

                if (ranking < bestRanking)
                {
                    bestMode    = mode;
                    bestRanking = ranking;

                    if (bestRanking == 0)
                    {
                        break;
                    }
                }
            }

            if (bestMode.Width == 0)
            {
                bestMode.Width  = input.PresentParameters.BackBufferWidth;
                bestMode.Height = input.PresentParameters.BackBufferHeight;
            }

            return(bestMode);
        }
        static void BuildPresentIntervalList(SettingsCombo9 combo)
        {
            List <PresentInterval> possiblePresentIntervals = new List <PresentInterval>()
            {
                PresentInterval.Immediate, PresentInterval.Default,
                PresentInterval.One, PresentInterval.Two,
                PresentInterval.Three, PresentInterval.Four
            };

            foreach (PresentInterval interval in possiblePresentIntervals)
            {
                if (combo.Windowed && (interval == PresentInterval.Two ||
                                       interval == PresentInterval.Three || interval == PresentInterval.Four))
                {
                    continue;
                }

                if (interval == PresentInterval.Default ||
                    (combo.DeviceInfo.Capabilities.PresentationIntervals & interval) != 0)
                {
                    combo.PresentIntervals.Add(interval);
                }
            }
        }
        static Direct3D9Settings FindValidD3D9Settings(DeviceSettings settings)
        {
            Direct3D9Settings optimal = Direct3D9Settings.BuildOptimalSettings(settings);

            SettingsCombo9 bestCombo   = null;
            float          bestRanking = -1.0f;

            foreach (AdapterInfo9 adapterInfo in Enumeration9.Adapters)
            {
                DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(adapterInfo.AdapterOrdinal);
                foreach (DeviceInfo9 deviceInfo in adapterInfo.Devices)
                {
                    foreach (SettingsCombo9 combo in deviceInfo.DeviceSettings)
                    {
                        if (combo.Windowed && combo.AdapterFormat != desktopMode.Format)
                        {
                            continue;
                        }

                        float ranking = Direct3D9Settings.RankSettingsCombo(combo, optimal, desktopMode);
                        if (ranking > bestRanking)
                        {
                            bestCombo   = combo;
                            bestRanking = ranking;
                        }
                    }
                }
            }

            if (bestCombo == null)
            {
                throw new NoCompatibleDevicesException("No compatible Direct3D9 devices found.");
            }

            return(Direct3D9Settings.BuildValidSettings(bestCombo, optimal));
        }
        static void EnumerateSettingsCombos(AdapterInfo9 adapterInfo, DeviceInfo9 deviceInfo, List <Format> adapterFormats)
        {
            Format[] backBufferFormats = { Format.A8R8G8B8, Format.X8R8G8B8, Format.A2R10G10B10,
                                           Format.R5G6B5,   Format.A1R5G5B5, Format.X1R5G5B5 };

            foreach (Format adapterFormat in adapterFormats)
            {
                foreach (Format backBufferFormat in backBufferFormats)
                {
                    for (int windowed = 0; windowed < 2; windowed++)
                    {
                        if (windowed == 0 && adapterInfo.DisplayModes.Count == 0)
                        {
                            continue;
                        }

                        if (!GraphicsDeviceManager.Direct3D9Object.CheckDeviceType(adapterInfo.AdapterOrdinal, deviceInfo.DeviceType,
                                                                                   adapterFormat, backBufferFormat, (windowed == 1)))
                        {
                            continue;
                        }

                        if (!GraphicsDeviceManager.Direct3D9Object.CheckDeviceFormat(adapterInfo.AdapterOrdinal,
                                                                                     deviceInfo.DeviceType, adapterFormat, Usage.QueryPostPixelShaderBlending,
                                                                                     ResourceType.Texture, backBufferFormat))
                        {
                            continue;
                        }

                        SettingsCombo9 combo = new SettingsCombo9();
                        combo.AdapterOrdinal   = adapterInfo.AdapterOrdinal;
                        combo.DeviceType       = deviceInfo.DeviceType;
                        combo.AdapterFormat    = adapterFormat;
                        combo.BackBufferFormat = backBufferFormat;
                        combo.Windowed         = (windowed == 1);
                        combo.AdapterInfo      = adapterInfo;
                        combo.DeviceInfo       = deviceInfo;

                        BuildDepthStencilFormatList(combo);
                        BuildMultisampleTypeList(combo);

                        if (combo.MultisampleTypes.Count == 0)
                        {
                            continue;
                        }

                        BuildPresentIntervalList(combo);

                        if (MinimumSettings != null)
                        {
                            if (MinimumSettings.BackBufferFormat != Format.Unknown &&
                                MinimumSettings.BackBufferFormat != backBufferFormat)
                            {
                                continue;
                            }

                            if (MinimumSettings.DepthStencilFormat != Format.Unknown &&
                                !combo.DepthStencilFormats.Contains(MinimumSettings.DepthStencilFormat))
                            {
                                continue;
                            }

                            if (!combo.MultisampleTypes.Contains(MinimumSettings.MultisampleType))
                            {
                                continue;
                            }
                        }

                        deviceInfo.DeviceSettings.Add(combo);
                    }
                }
            }
        }
        public static Direct3D9Settings BuildValidSettings(SettingsCombo9 combo, Direct3D9Settings input)
        {
            Direct3D9Settings settings = new Direct3D9Settings();
            var pp = settings.PresentParameters;

            settings.AdapterOrdinal = combo.AdapterOrdinal;
            settings.DeviceType     = combo.DeviceType;
            settings.AdapterFormat  = combo.AdapterFormat;
            pp.Windowed             = combo.Windowed;
            pp.BackBufferFormat     = combo.BackBufferFormat;
            pp.SwapEffect           = input.PresentParameters.SwapEffect;
            pp.PresentFlags         = input.PresentParameters.PresentFlags | PresentFlags.DiscardDepthStencil;

            settings.CreationFlags = input.CreationFlags;
            if ((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) == 0 &&
                ((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 ||
                 (settings.CreationFlags & CreateFlags.MixedVertexProcessing) != 0))
            {
                settings.CreationFlags &= ~CreateFlags.HardwareVertexProcessing;
                settings.CreationFlags &= ~CreateFlags.MixedVertexProcessing;
                settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
            }

            if ((settings.CreationFlags & CreateFlags.HardwareVertexProcessing) == 0 &&
                (settings.CreationFlags & CreateFlags.MixedVertexProcessing) == 0 &&
                (settings.CreationFlags & CreateFlags.SoftwareVertexProcessing) == 0)
            {
                if ((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
                {
                    settings.CreationFlags |= CreateFlags.HardwareVertexProcessing;
                }
                else
                {
                    settings.CreationFlags |= CreateFlags.SoftwareVertexProcessing;
                }
            }

            DisplayMode bestDisplayMode = FindValidResolution(combo, input);

            pp.BackBufferWidth  = bestDisplayMode.Width;
            pp.BackBufferHeight = bestDisplayMode.Height;

            pp.BackBufferCount = input.PresentParameters.BackBufferCount;
            if (pp.BackBufferCount > 3)
            {
                pp.BackBufferCount = 3;
            }
            if (pp.BackBufferCount < 1)
            {
                pp.BackBufferCount = 1;
            }

            if (input.PresentParameters.SwapEffect != SwapEffect.Discard)
            {
                pp.MultiSampleType    = MultisampleType.None;
                pp.MultiSampleQuality = 0;
            }
            else
            {
                MultisampleType bestType    = MultisampleType.None;
                int             bestQuality = 0;

                for (int i = 0; i < combo.MultisampleTypes.Count; i++)
                {
                    MultisampleType type    = combo.MultisampleTypes[i];
                    int             quality = combo.MultisampleQualities[i];

                    if (Math.Abs(type - input.PresentParameters.MultiSampleType) < Math.Abs(bestType - input.PresentParameters.MultiSampleType))
                    {
                        bestType    = type;
                        bestQuality = Math.Min(quality - 1, input.PresentParameters.MultiSampleQuality);
                    }
                }

                pp.MultiSampleType    = bestType;
                pp.MultiSampleQuality = bestQuality;
            }

            List <int> rankings             = new List <int>();
            int        inputDepthBitDepth   = ConversionMethods.GetDepthBits(input.PresentParameters.AutoDepthStencilFormat);
            int        inputStencilBitDepth = ConversionMethods.GetStencilBits(input.PresentParameters.AutoDepthStencilFormat);

            foreach (Format format in combo.DepthStencilFormats)
            {
                int currentBitDepth     = ConversionMethods.GetDepthBits(format);
                int currentStencilDepth = ConversionMethods.GetStencilBits(format);

                int ranking = Math.Abs(currentBitDepth - inputDepthBitDepth);
                ranking += Math.Abs(currentStencilDepth - inputStencilBitDepth);
                rankings.Add(ranking);
            }

            int bestRanking = int.MaxValue;

            foreach (int ranking in rankings)
            {
                if (ranking < bestRanking)
                {
                    bestRanking = ranking;
                }
            }
            int bestIndex = rankings.IndexOf(bestRanking);

            if (bestIndex >= 0)
            {
                pp.AutoDepthStencilFormat = combo.DepthStencilFormats[bestIndex];
                pp.EnableAutoDepthStencil = true;
            }
            else
            {
                pp.AutoDepthStencilFormat = Format.Unknown;
                pp.EnableAutoDepthStencil = false;
            }

            if (combo.Windowed)
            {
                pp.FullScreenRefreshRateInHz = 0;
            }
            else
            {
                int match = input.PresentParameters.FullScreenRefreshRateInHz;
                bestDisplayMode.RefreshRate = 0;
                if (match != 0)
                {
                    bestRanking = 100000;
                    foreach (DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
                    {
                        if (displayMode.Format != combo.AdapterFormat ||
                            displayMode.Width != bestDisplayMode.Width ||
                            displayMode.Height != bestDisplayMode.Height)
                        {
                            continue;
                        }

                        int ranking = Math.Abs(displayMode.RefreshRate - match);

                        if (ranking < bestRanking)
                        {
                            bestDisplayMode.RefreshRate = displayMode.RefreshRate;
                            bestRanking = ranking;

                            if (bestRanking == 0)
                            {
                                break;
                            }
                        }
                    }
                }

                pp.FullScreenRefreshRateInHz = bestDisplayMode.RefreshRate;
            }

            if (combo.PresentIntervals.Contains(input.PresentParameters.PresentationInterval))
            {
                pp.PresentationInterval = input.PresentParameters.PresentationInterval;
            }
            else
            {
                pp.PresentationInterval = PresentInterval.Default;
            }

            settings.PresentParameters = pp;
            return(settings);
        }
        public static float RankSettingsCombo(SettingsCombo9 combo, Direct3D9Settings optimal, DisplayMode desktopMode)
        {
            float ranking = 0.0f;

            if (combo.AdapterOrdinal == optimal.AdapterOrdinal)
            {
                ranking += 1000.0f;
            }

            if (combo.DeviceType == optimal.DeviceType)
            {
                ranking += 100.0f;
            }

            if (combo.DeviceType == DeviceType.Hardware)
            {
                ranking += 0.1f;
            }

            if (combo.Windowed == optimal.PresentParameters.Windowed)
            {
                ranking += 10.0f;
            }

            if (combo.AdapterFormat == optimal.AdapterFormat)
            {
                ranking += 1.0f;
            }
            else
            {
                int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.AdapterFormat) -
                                             ConversionMethods.GetColorBits(optimal.AdapterFormat));
                float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
                ranking += scale;
            }

            if (!combo.Windowed)
            {
                bool match;
                if (ConversionMethods.GetColorBits(desktopMode.Format) >= 8)
                {
                    match = (combo.AdapterFormat == desktopMode.Format);
                }
                else
                {
                    match = (combo.AdapterFormat == Format.X8R8G8B8);
                }

                if (match)
                {
                    ranking += 0.1f;
                }
            }

            if ((optimal.CreationFlags & CreateFlags.HardwareVertexProcessing) != 0 &&
                (optimal.CreationFlags & CreateFlags.MixedVertexProcessing) != 0)
            {
                if ((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
                {
                    ranking += 1.0f;
                }
            }

            if ((combo.DeviceInfo.Capabilities.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0)
            {
                ranking += 0.1f;
            }

            foreach (DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
            {
                if (displayMode.Format == combo.AdapterFormat &&
                    displayMode.Width == optimal.PresentParameters.BackBufferWidth &&
                    displayMode.Height == optimal.PresentParameters.BackBufferHeight)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            if (combo.BackBufferFormat == optimal.PresentParameters.BackBufferFormat)
            {
                ranking += 1.0f;
            }
            else
            {
                int bitDepthDelta = Math.Abs(ConversionMethods.GetColorBits(combo.BackBufferFormat) -
                                             ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat));
                float scale = Math.Max(0.9f - bitDepthDelta * 0.2f, 0.0f);
                ranking += scale;
            }

            if (combo.BackBufferFormat == combo.AdapterFormat)
            {
                ranking += 0.1f;
            }

            for (int i = 0; i < combo.MultisampleTypes.Count; i++)
            {
                MultisampleType type    = combo.MultisampleTypes[i];
                int             quality = combo.MultisampleQualities[i];

                if (type == optimal.PresentParameters.MultiSampleType && quality == optimal.PresentParameters.MultiSampleQuality)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            if (combo.DepthStencilFormats.Contains(optimal.PresentParameters.AutoDepthStencilFormat))
            {
                ranking += 1.0f;
            }

            foreach (DisplayMode displayMode in combo.AdapterInfo.DisplayModes)
            {
                if (displayMode.Format == combo.AdapterFormat &&
                    displayMode.RefreshRate == optimal.PresentParameters.FullScreenRefreshRateInHz)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            if (combo.PresentIntervals.Contains(optimal.PresentParameters.PresentationInterval))
            {
                ranking += 1.0f;
            }

            return(ranking);
        }