public Direct3D9Settings Clone() { Direct3D9Settings clone = new Direct3D9Settings(); clone.AdapterFormat = AdapterFormat; clone.AdapterOrdinal = AdapterOrdinal; clone.CreationFlags = CreationFlags; clone.DeviceType = DeviceType; clone.PresentParameters = PresentParameters; return(clone); }
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); }
/// <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) { try { GraphicsDeviceManager.EnsureD3D9(); } catch (Exception e) { throw new NoCompatibleDevicesException("Could not initialize Direct3D9.", e); } if (!Enumeration9.HasEnumerated) { Enumeration9.Enumerate(); } DeviceSettings newSettings = settings.Clone(); Direct3D9Settings d3d9 = FindValidD3D9Settings(settings); newSettings.Direct3D9 = d3d9; return(newSettings); }
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)); }
public static Direct3D9Settings BuildOptimalSettings(DeviceSettings settings) { DisplayMode desktopMode = GraphicsDeviceManager.Direct3D9Object.GetAdapterDisplayMode(0); Direct3D9Settings optimal = new Direct3D9Settings(); var pp = optimal.PresentParameters; optimal.AdapterOrdinal = settings.AdapterOrdinal; optimal.DeviceType = settings.DeviceType; pp.Windowed = settings.Windowed; pp.BackBufferCount = settings.BackBufferCount; pp.MultiSampleType = settings.MultisampleType; pp.MultiSampleQuality = settings.MultisampleQuality; pp.FullScreenRefreshRateInHz = settings.RefreshRate; if (settings.Multithreaded) { optimal.CreationFlags |= CreateFlags.Multithreaded; } if (optimal.PresentParameters.Windowed || ConversionMethods.GetColorBits(desktopMode.Format) >= 8) { optimal.AdapterFormat = desktopMode.Format; } else { optimal.AdapterFormat = Format.X8R8G8B8; } if (settings.BackBufferWidth == 0 || settings.BackBufferHeight == 0) { if (optimal.PresentParameters.Windowed) { pp.BackBufferWidth = 640; pp.BackBufferHeight = 480; } else { pp.BackBufferWidth = desktopMode.Width; pp.BackBufferHeight = desktopMode.Height; } } else { pp.BackBufferWidth = settings.BackBufferWidth; pp.BackBufferHeight = settings.BackBufferHeight; } if (settings.BackBufferFormat == Format.Unknown) { pp.BackBufferFormat = optimal.AdapterFormat; } else { pp.BackBufferFormat = settings.BackBufferFormat; } if (settings.DepthStencilFormat == Format.Unknown) { if (ConversionMethods.GetColorBits(optimal.PresentParameters.BackBufferFormat) >= 8) { pp.AutoDepthStencilFormat = Format.D32; } else { pp.AutoDepthStencilFormat = Format.D16; } } else { pp.AutoDepthStencilFormat = settings.DepthStencilFormat; } if (!settings.EnableVSync) { pp.PresentationInterval = PresentInterval.Immediate; } optimal.PresentParameters = pp; return(optimal); }
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); }