static Direct3D10Settings FindValidD3D10Settings(DeviceSettings settings)
        {
            Direct3D10Settings optimal = Direct3D10Settings.BuildOptimalSettings(settings);

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

            foreach (AdapterInfo10 adapterInfo in Enumeration10.Adapters)
            {
                foreach (SettingsCombo10 combo in adapterInfo.SettingsCombos)
                {
                    float ranking = Direct3D10Settings.RankSettingsCombo(combo, optimal);
                    if (ranking > bestRanking)
                    {
                        bestCombo   = combo;
                        bestRanking = ranking;
                    }
                }
            }

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

            return(Direct3D10Settings.BuildValidSettings(bestCombo, optimal));
        }
Beispiel #2
0
        static void EnumerateSettingsCombos(AdapterInfo10 adapterInfo)
        {
            Format[] backBufferFormats = { Format.R8G8B8A8_UNorm,     Format.R8G8B8A8_UNorm_SRGB,
                                           Format.R16G16B16A16_Float, Format.R10G10B10A2_UNorm };

            foreach (OutputInfo10 outputInfo in adapterInfo.Outputs)
            {
                foreach (DeviceInfo10 deviceInfo in adapterInfo.Devices)
                {
                    foreach (Format backBufferFormat in backBufferFormats)
                    {
                        if (MinimumSettings != null && MinimumSettings.BackBufferFormat != SlimDX.DXGI.Format.Unknown &&
                            MinimumSettings.BackBufferFormat != backBufferFormat)
                        {
                            continue;
                        }

                        for (int windowed = 0; windowed < 2; windowed++)
                        {
                            if (windowed == 0 && outputInfo.DisplayModes.Count == 0)
                            {
                                continue;
                            }

                            bool found = false;
                            foreach (ModeDescription mode in outputInfo.DisplayModes)
                            {
                                if (mode.Format == backBufferFormat)
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (!found)
                            {
                                continue;
                            }

                            SettingsCombo10 combo = new SettingsCombo10();
                            combo.AdapterOrdinal   = deviceInfo.AdapterOrdinal;
                            combo.DriverType       = deviceInfo.DriverType;
                            combo.BackBufferFormat = backBufferFormat;
                            combo.IsWindowed       = (windowed != 0);
                            combo.OutputOrdinal    = outputInfo.OutputOrdinal;
                            combo.OutputInfo       = outputInfo;

                            BuildMultisampleList(backBufferFormat, combo);

                            if (MinimumSettings != null && !combo.MultisampleCounts.Contains(MinimumSettings.MultisampleCount))
                            {
                                continue;
                            }

                            adapterInfo.SettingsCombos.Add(combo);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        static void BuildMultisampleList(Format backBufferFormat, SettingsCombo10 combo)
        {
            Adapter adapter = null;

            if (combo.DriverType == DriverType.Hardware)
            {
                adapter = GraphicsDeviceManager.Factory.GetAdapter(combo.AdapterOrdinal);
            }
            SlimDX.Direct3D10.Device device;

            try
            {
                device = new SlimDX.Direct3D10.Device(adapter, combo.DriverType, DeviceCreationFlags.None);
            }
            catch (Direct3D10Exception)
            {
                // no good
                if (adapter != null)
                {
                    adapter.Dispose();
                }
                return;
            }

            for (int i = 1; i <= SlimDX.Direct3D10.Device.MultisampleCountMaximum; i++)
            {
                try
                {
                    int quality = device.CheckMultisampleQualityLevels(backBufferFormat, i);
                    combo.MultisampleCounts.Add(i);
                    combo.MultisampleQualities.Add(quality);
                }
                catch (Direct3D10Exception)
                {
                    // eat the exception
                }
            }

            device.Dispose();

            if (adapter != null)
            {
                adapter.Dispose();
            }
        }
        static ModeDescription FindValidResolution(SettingsCombo10 combo, Direct3D10Settings input)
        {
            ModeDescription bestMode = new ModeDescription();

            if (combo.IsWindowed)
            {
                bestMode.Width  = input.SwapChainDescription.ModeDescription.Width;
                bestMode.Height = input.SwapChainDescription.ModeDescription.Height;
                return(bestMode);
            }

            int bestRanking = 100000;
            int ranking;

            foreach (ModeDescription mode in combo.OutputInfo.DisplayModes)
            {
                ranking = Math.Abs(mode.Width - input.SwapChainDescription.ModeDescription.Width) +
                          Math.Abs(mode.Height - input.SwapChainDescription.ModeDescription.Height);

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

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

            if (bestMode.Width == 0)
            {
                bestMode.Width  = input.SwapChainDescription.ModeDescription.Width;
                bestMode.Height = input.SwapChainDescription.ModeDescription.Height;
            }

            return(bestMode);
        }
        public static Direct3D10Settings BuildValidSettings(SettingsCombo10 combo, Direct3D10Settings input)
        {
            Direct3D10Settings   settings = new Direct3D10Settings();
            SwapChainDescription scd      = new SwapChainDescription();
            ModeDescription      mode     = new ModeDescription();
            SampleDescription    sample   = new SampleDescription();

            ModeDescription bestDisplayMode = FindValidResolution(combo, input);

            if (combo.IsWindowed)
            {
                bestDisplayMode.RefreshRate = new Rational(0, 0);
            }
            else
            {
                Rational match = input.SwapChainDescription.ModeDescription.RefreshRate;
                bestDisplayMode.RefreshRate = new Rational(0, 0);
                if (match != new Rational(0, 0))
                {
                    float bestRanking = 100000;
                    foreach (ModeDescription displayMode in combo.OutputInfo.DisplayModes)
                    {
                        if (displayMode.Width != bestDisplayMode.Width ||
                            displayMode.Height != bestDisplayMode.Height)
                        {
                            continue;
                        }

                        float ranking = Math.Abs(ConversionMethods.ToFloat(displayMode.RefreshRate) - ConversionMethods.ToFloat(match));

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

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

            int bestBackBufferCount = input.SwapChainDescription.BufferCount;

            if (bestBackBufferCount > 3)
            {
                bestBackBufferCount = 3;
            }
            if (bestBackBufferCount < 1)
            {
                bestBackBufferCount = 1;
            }

            int bestCount;
            int bestQuality;

            if (input.SwapChainDescription.SwapEffect != SwapEffect.Discard)
            {
                bestCount   = 1;
                bestQuality = 0;
            }
            else
            {
                bestCount   = 1;
                bestQuality = 0;

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

                    if (Math.Abs(type - input.SwapChainDescription.SampleDescription.Count) < Math.Abs(bestCount -
                                                                                                       input.SwapChainDescription.SampleDescription.Count))
                    {
                        bestCount   = type;
                        bestQuality = Math.Min(quality - 1, input.SwapChainDescription.SampleDescription.Quality);
                    }
                }
            }

            int bestSyncInterval = input.SyncInterval;

            if (combo.DriverType == DriverType.Reference)
            {
                bestSyncInterval = 0;
            }

            mode.Width       = bestDisplayMode.Width;
            mode.Height      = bestDisplayMode.Height;
            mode.Format      = combo.BackBufferFormat;
            mode.RefreshRate = bestDisplayMode.RefreshRate;

            sample.Count   = bestCount;
            sample.Quality = bestQuality;

            scd.Usage             = input.SwapChainDescription.Usage | Usage.RenderTargetOutput;
            scd.BufferCount       = bestBackBufferCount;
            scd.SwapEffect        = input.SwapChainDescription.SwapEffect;
            scd.IsWindowed        = combo.IsWindowed;
            scd.Flags             = SwapChainFlags.None;
            scd.ModeDescription   = mode;
            scd.SampleDescription = sample;

            settings.AdapterOrdinal       = combo.AdapterOrdinal;
            settings.DriverType           = combo.DriverType;
            settings.OutputOrdinal        = combo.OutputOrdinal;
            settings.SyncInterval         = bestSyncInterval;
            settings.DepthStencilFormat   = input.DepthStencilFormat;
            settings.CreationFlags        = input.CreationFlags;
            settings.SwapChainDescription = scd;

            return(settings);
        }
        public static float RankSettingsCombo(SettingsCombo10 combo, Direct3D10Settings optimal)
        {
            float ranking = 0.0f;

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

            if (combo.OutputOrdinal == optimal.OutputOrdinal)
            {
                ranking += 500.0f;
            }

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

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

            if (combo.IsWindowed == optimal.SwapChainDescription.IsWindowed)
            {
                ranking += 10.0f;
            }

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

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

                if (type == optimal.SwapChainDescription.SampleDescription.Count && quality > optimal.SwapChainDescription.SampleDescription.Quality)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            foreach (ModeDescription mode in combo.OutputInfo.DisplayModes)
            {
                if (mode.Width == optimal.SwapChainDescription.ModeDescription.Width &&
                    mode.Height == optimal.SwapChainDescription.ModeDescription.Height)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            foreach (ModeDescription mode in combo.OutputInfo.DisplayModes)
            {
                if (Math.Abs(ConversionMethods.ToFloat(mode.RefreshRate) - ConversionMethods.ToFloat(optimal.SwapChainDescription.ModeDescription.RefreshRate)) < 0.1f)
                {
                    ranking += 1.0f;
                    break;
                }
            }

            return(ranking);
        }