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 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); } } } } }
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); }