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