/// <summary> /// Enumerates D3D devices for a particular adapter. /// </summary> private static void EnumerateDevices(EnumAdapterInformation adapterInfo, ArrayList adapterFormatList) { // Ignore any exceptions while looking for these device types DirectXException.IgnoreExceptions(); // Enumerate each Direct3D device type for (uint i = 0; i < deviceTypeArray.Length; i++) { // Create a new device information object EnumDeviceInformation deviceInfo = new EnumDeviceInformation(); // Store the type deviceInfo.DeviceType = deviceTypeArray[i]; // Try to get the capabilities deviceInfo.Caps = Manager.GetDeviceCaps((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType); // Get information about each device combination on this device EnumerateDeviceCombos(adapterInfo, deviceInfo, adapterFormatList); // Do we have any device combinations? if (deviceInfo.deviceSettingsList.Count > 0) { // Yes, add it adapterInfo.deviceInfoList.Add(deviceInfo); } } // Turn exception handling back on DirectXException.EnableExceptions(); }
/// <summary> /// Get a specific device information for a device and type /// </summary> public static EnumDeviceInformation GetDeviceInfo(uint ordinal, DeviceType deviceType) { EnumAdapterInformation info = GetAdapterInformation(ordinal); if (info != null) { foreach (EnumDeviceInformation edi in info.deviceInfoList) { // Is this the right device type? if (edi.DeviceType == deviceType) { return(edi); } } } // Never found it return(null); }
// Implementation /// <summary> /// Enumerates available D3D adapters, devices, modes, etc /// </summary> public static void Enumerate(IDeviceCreation acceptableCallback) { DisplayModeSorter sorter = new DisplayModeSorter(); try { // Store the callback deviceCreationInterface = acceptableCallback; // Clear the adapter information stored currently adapterInformationList.Clear(); ArrayList adapterFormatList = new ArrayList(); // Look through every adapter on the system foreach (AdapterInformation ai in Manager.Adapters) { EnumAdapterInformation adapterInfo = new EnumAdapterInformation(); // Store some information adapterInfo.AdapterOrdinal = (uint)ai.Adapter; // Ordinal adapterInfo.AdapterInformation = ai.Information; // Information // Get list of all display modes on this adapter. // Also build a temporary list of all display adapter formats. adapterFormatList.Clear(); // Now check to see which formats are supported for (int i = 0; i < allowedFormats.Length; i++) { // Check each of the supported display modes for this format foreach (DisplayMode dm in ai.SupportedDisplayModes[allowedFormats[i]]) { if ((dm.Width < minimumWidth) || (dm.Height < minimumHeight) || (dm.Width > maximumWidth) || (dm.Height > maximumHeight) || (dm.RefreshRate < minimumRefresh) || (dm.RefreshRate > maximumRefresh)) { continue; // This format isn't valid } // Add this to the list adapterInfo.displayModeList.Add(dm); // Add this to the format list if it doesn't already exist if (!adapterFormatList.Contains(dm.Format)) { adapterFormatList.Add(dm.Format); } } } // Get the adapter display mode DisplayMode currentAdapterMode = ai.CurrentDisplayMode; // Check to see if this format is in the list if (!adapterFormatList.Contains(currentAdapterMode.Format)) { adapterFormatList.Add(currentAdapterMode.Format); } // Sort the display mode list adapterInfo.displayModeList.Sort(sorter); // Get information for each device with this adapter EnumerateDevices(adapterInfo, adapterFormatList); // If there was at least one device on the adapter, and it's compatible // add it to the list if (adapterInfo.deviceInfoList.Count > 0) { adapterInformationList.Add(adapterInfo); } } // See if all of the descriptions are unique bool isUnique = true; for (int i = 0; i < adapterInformationList.Count; i++) { for (int j = i + 1; j < adapterInformationList.Count; j++) { EnumAdapterInformation eai1 = adapterInformationList[i] as EnumAdapterInformation; EnumAdapterInformation eai2 = adapterInformationList[j] as EnumAdapterInformation; if (string.Compare(eai1.AdapterInformation.Description, eai2.AdapterInformation.Description, true) == 0) { isUnique = false; break; } } if (!isUnique) { break; } } // Now fill the unique description for (int i = 0; i < adapterInformationList.Count; i++) { EnumAdapterInformation eai1 = adapterInformationList[i] as EnumAdapterInformation; eai1.UniqueDescription = eai1.AdapterInformation.Description; // If the descriptions aren't unique, append the adapter ordinal if (!isUnique) { eai1.UniqueDescription += string.Format(" (#{0})", eai1.AdapterOrdinal); } } } catch (TypeLoadException) { // Couldn't load the manager class, no Direct is available. throw new NoDirect3DException(); } }
/// <summary> /// Enumerates device combinations for a particular device. /// </summary> private static void EnumerateDeviceCombos(EnumAdapterInformation adapterInfo, EnumDeviceInformation deviceInfo, ArrayList adapterFormatList) { // Find out which adapter formats are supported by this device foreach (Format adapterFormat in adapterFormatList) { for (int i = 0; i < backbufferFormatsArray.Length; i++) { // Go through each windowed mode for (int windowedIndex = 0; windowedIndex < 2; windowedIndex++) { bool isWindowedIndex = (windowedIndex == 1); if ((!isWindowedIndex) && (adapterInfo.displayModeList.Count == 0)) { continue; // Nothing here } if (!Manager.CheckDeviceType((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType, adapterFormat, backbufferFormatsArray[i], isWindowedIndex)) { continue; // Unsupported } // Do we require post pixel shader blending? if (isPostPixelShaderBlendingRequired) { // If the backbuffer format doesn't support Usage.QueryPostPixelShaderBlending // then alpha test, pixel fog, render-target blending, color write enable, and dithering // are not supported. if (!Manager.CheckDeviceFormat((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType, adapterFormat, Usage.QueryPostPixelShaderBlending, ResourceType.Textures, backbufferFormatsArray[i])) { continue; // Unsupported } } // If an application callback function has been provided, make sure this device // is acceptable to the app. if (deviceCreationInterface != null) { if (!deviceCreationInterface.IsDeviceAcceptable(deviceInfo.Caps, adapterFormat, backbufferFormatsArray[i], isWindowedIndex)) { continue; // Application doesn't like this device } } // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed // DeviceCombo that is supported by the system and acceptable to the app. We still // need to find one or more suitable depth/stencil buffer format, // multisample type, and present interval. EnumDeviceSettingsCombo deviceCombo = new EnumDeviceSettingsCombo(); // Store the information deviceCombo.AdapterOrdinal = adapterInfo.AdapterOrdinal; deviceCombo.DeviceType = deviceInfo.DeviceType; deviceCombo.AdapterFormat = adapterFormat; deviceCombo.BackBufferFormat = backbufferFormatsArray[i]; deviceCombo.IsWindowed = isWindowedIndex; // Build the depth stencil format and multisample type list BuildDepthStencilFormatList(deviceCombo); BuildMultiSampleTypeList(deviceCombo); if (deviceCombo.multiSampleTypeList.Count == 0) { // Nothing to do continue; } // Build the conflict and present lists BuildConflictList(deviceCombo); BuildPresentIntervalList(deviceInfo, deviceCombo); deviceCombo.adapterInformation = adapterInfo; deviceCombo.deviceInformation = deviceInfo; // Add the combo to the list of devices deviceInfo.deviceSettingsList.Add(deviceCombo); } } } }