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)); }
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); }
/// <summary> /// Finds valid device settings based upon the desired settings. /// </summary> /// <param name="settings">The desired settings.</param> /// <returns>The best valid device settings matching the input settings.</returns> public static DeviceSettings FindValidSettings(DeviceSettings settings) { // check the desired API version try { GraphicsDeviceManager.EnsureD3D10(); } catch (Exception e) { throw new NoCompatibleDevicesException("Could not initialize Direct3D10.", e); } if (!Enumeration10.HasEnumerated) { Enumeration10.Enumerate(); } DeviceSettings newSettings = settings.Clone(); Direct3D10Settings d3d10 = FindValidD3D10Settings(settings); newSettings.Direct3D10 = d3d10; return(newSettings); }
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); }
public static Direct3D10Settings BuildOptimalSettings(DeviceSettings settings) { ModeDescription desktopMode = GetAdapterDisplayMode(0, 0); Direct3D10Settings optimal = new Direct3D10Settings(); SwapChainDescription swapChainDescription = new SwapChainDescription(); ModeDescription mode = new ModeDescription(); SampleDescription sample = new SampleDescription(); optimal.AdapterOrdinal = settings.AdapterOrdinal; optimal.DriverType = settings.DeviceType; optimal.PresentFlags = PresentFlags.None; swapChainDescription.IsWindowed = settings.Windowed; swapChainDescription.BufferCount = settings.BackBufferCount; sample.Count = settings.MultisampleCount; sample.Quality = settings.MultisampleQuality; swapChainDescription.SwapEffect = SwapEffect.Discard; if (settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0) { if (settings.Windowed) { mode.Width = 640; mode.Height = 480; } else { mode.Width = desktopMode.Width; mode.Height = desktopMode.Height; } } else { mode.Width = settings.BackBufferWidth; mode.Height = settings.BackBufferHeight; } if (settings.BackBufferFormat == Format.Unknown) { mode.Format = desktopMode.Format; } else { mode.Format = settings.BackBufferFormat; } swapChainDescription.Usage = Usage.RenderTargetOutput; optimal.DepthStencilFormat = settings.DepthStencilFormat; if (settings.RefreshRate == 0) { mode.RefreshRate = new Rational(0, 0); } else { mode.RefreshRate = new Rational(settings.RefreshRate, 1); } if (settings.EnableVSync) { optimal.SyncInterval = 1; } else { optimal.SyncInterval = 0; } swapChainDescription.SampleDescription = sample; swapChainDescription.ModeDescription = mode; optimal.SwapChainDescription = swapChainDescription; return(optimal); }