home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / Managed / Common / dxmutenum.cs < prev    next >
Encoding:
Text File  |  2004-09-27  |  35.2 KB  |  874 lines

  1. //--------------------------------------------------------------------------------------
  2. // File: DXMUTEnum.cs
  3. //
  4. // Enumerates D3D adapters, devices, modes, etc.
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. using System;
  9. using System.Collections;
  10. using Microsoft.DirectX;
  11. using Microsoft.DirectX.Direct3D;
  12.  
  13. namespace Microsoft.Samples.DirectX.UtilityToolkit
  14. {
  15.     /// <summary>
  16.     /// Enumerates available Direct3D adapters, devices, modes, etc.  Singleton.
  17.     /// </summary>
  18.     public sealed class Enumeration
  19.     {
  20.         #region Creation (Not allowed)
  21.         private Enumeration() {} // Do Not allow Creation
  22.         /// <summary>
  23.         /// Static constructor to create default lists
  24.         /// </summary>
  25.         static Enumeration()
  26.         {
  27.             // Create the default lists
  28.             ResetPossibleDepthStencilFormats();
  29.             ResetPossibleMultisampleTypeList();
  30.             ResetPossiblePresentIntervalList();
  31.         } 
  32.         #endregion
  33.  
  34.         // Static Data
  35.         private static bool isPostPixelShaderBlendingRequired = true;
  36.         private static IDeviceCreation deviceCreationInterface = null;
  37.  
  38.         // Vertex processing
  39.         private static bool isSoftwareVertexProcessing = true;
  40.         private static bool isHardwareVertexProcessing = true;
  41.         private static bool isPureHardwareVertexProcessing = true;
  42.         private static bool isMixedVertexProcessing = false;
  43.  
  44.         // Limits
  45.         private static uint minimumWidth = 0;
  46.         private static uint maximumWidth = uint.MaxValue;
  47.         private static uint minimumHeight = 0;
  48.         private static uint maximumHeight = uint.MaxValue;
  49.         private static uint minimumRefresh = 0;
  50.         private static uint maximumRefresh = uint.MaxValue;
  51.         private static uint multisampleQualityMax = 0xffff;
  52.  
  53.         // Lists
  54.         private static ArrayList depthStencilPossibleList = new ArrayList();
  55.         private static ArrayList multiSampleTypeList = new ArrayList();
  56.         private static ArrayList presentIntervalList = new ArrayList();
  57.         private static ArrayList adapterInformationList = new ArrayList();
  58.  
  59.         // Default arrays
  60.         private static readonly Format[] allowedFormats = new Format[] {
  61.                         Format.X8R8G8B8, 
  62.                         Format.X1R5G5B5,
  63.                         Format.R5G6B5,
  64.                         Format.A2R10G10B10 };
  65.         private static readonly Format[] backbufferFormatsArray = new Format[] {
  66.                         Format.A8R8G8B8,
  67.                         Format.X8R8G8B8, 
  68.                         Format.A1R5G5B5,
  69.                         Format.X1R5G5B5,
  70.                         Format.R5G6B5,
  71.                         Format.A2R10G10B10 };
  72.         private static readonly DeviceType[] deviceTypeArray = new DeviceType[] {
  73.                         DeviceType.Hardware,
  74.                         DeviceType.Software,
  75.                         DeviceType.Reference };
  76.  
  77.  
  78.         // Implementation
  79.  
  80.         /// <summary>
  81.         /// Enumerates available D3D adapters, devices, modes, etc
  82.         /// </summary>
  83.         public static void Enumerate(IDeviceCreation acceptableCallback)
  84.         {
  85.             DisplayModeSorter sorter = new DisplayModeSorter();
  86.             try
  87.             {
  88.                 // Store the callback
  89.                 deviceCreationInterface = acceptableCallback;
  90.  
  91.                 // Clear the adapter information stored currently
  92.                 adapterInformationList.Clear();
  93.                 ArrayList adapterFormatList = new ArrayList();
  94.  
  95.                 // Look through every adapter on the system
  96.                 foreach(AdapterInformation ai in Manager.Adapters)
  97.                 {
  98.                     EnumAdapterInformation adapterInfo = new EnumAdapterInformation();
  99.                     // Store some information
  100.                     adapterInfo.AdapterOrdinal = (uint)ai.Adapter; // Ordinal
  101.                     adapterInfo.AdapterInformation = ai.Information; // Information
  102.  
  103.                     // Get list of all display modes on this adapter.  
  104.                     // Also build a temporary list of all display adapter formats.
  105.                     adapterFormatList.Clear();
  106.  
  107.                     // Now check to see which formats are supported
  108.                     for(int i = 0; i < allowedFormats.Length; i++)
  109.                     {
  110.                         // Check each of the supported display modes for this format
  111.                         foreach(DisplayMode dm in ai.SupportedDisplayModes[allowedFormats[i]])
  112.                         {
  113.                             if ( (dm.Width < minimumWidth) ||
  114.                                 (dm.Height < minimumHeight) ||
  115.                                 (dm.Width > maximumWidth) ||
  116.                                 (dm.Height > maximumHeight) ||
  117.                                 (dm.RefreshRate < minimumRefresh) ||
  118.                                 (dm.RefreshRate > maximumRefresh) )
  119.                             {
  120.                                 continue; // This format isn't valid
  121.                             }
  122.  
  123.                             // Add this to the list
  124.                             adapterInfo.displayModeList.Add(dm);
  125.  
  126.                             // Add this to the format list if it doesn't already exist
  127.                             if (!adapterFormatList.Contains(dm.Format))
  128.                             {
  129.                                 adapterFormatList.Add(dm.Format);
  130.                             }
  131.                         }
  132.                     }
  133.  
  134.                     // Get the adapter display mode
  135.                     DisplayMode currentAdapterMode = ai.CurrentDisplayMode;
  136.                     // Check to see if this format is in the list
  137.                     if (!adapterFormatList.Contains(currentAdapterMode.Format))
  138.                     {
  139.                         adapterFormatList.Add(currentAdapterMode.Format);
  140.                     }
  141.  
  142.                     // Sort the display mode list
  143.                     adapterInfo.displayModeList.Sort(sorter);
  144.  
  145.                     // Get information for each device with this adapter
  146.                     EnumerateDevices(adapterInfo, adapterFormatList);
  147.  
  148.                     // If there was at least one device on the adapter, and it's compatible
  149.                     // add it to the list
  150.                     if (adapterInfo.deviceInfoList.Count > 0)
  151.                     {
  152.                         adapterInformationList.Add(adapterInfo);
  153.                     }
  154.                 }
  155.  
  156.                 // See if all of the descriptions are unique
  157.                 bool isUnique = true;
  158.                 for(int i = 0; i < adapterInformationList.Count; i++)
  159.                 {
  160.                     for (int j = i+1; j < adapterInformationList.Count; j++)
  161.                     {
  162.                         EnumAdapterInformation eai1 = adapterInformationList[i] as EnumAdapterInformation;
  163.                         EnumAdapterInformation eai2 = adapterInformationList[j] as EnumAdapterInformation;
  164.  
  165.                         if (string.Compare(eai1.AdapterInformation.Description,
  166.                             eai2.AdapterInformation.Description, true) == 0)
  167.                         {
  168.                             isUnique = false;
  169.                             break;
  170.                         }
  171.                     }
  172.                     if (!isUnique)
  173.                         break;
  174.                 }
  175.  
  176.                 // Now fill the unique description
  177.                 for(int i = 0; i < adapterInformationList.Count; i++)
  178.                 {
  179.                     EnumAdapterInformation eai1 = adapterInformationList[i] as EnumAdapterInformation;
  180.  
  181.                     eai1.UniqueDescription = eai1.AdapterInformation.Description;
  182.                     // If the descriptions aren't unique, append the adapter ordinal
  183.                     if (!isUnique)
  184.                         eai1.UniqueDescription += string.Format(" (#{0})", eai1.AdapterOrdinal);
  185.                 }
  186.             }
  187.             catch (TypeLoadException)
  188.             {
  189.                 // Couldn't load the manager class, no Direct is available.
  190.                 throw new NoDirect3DException();
  191.             }
  192.         }
  193.  
  194.         /// <summary>
  195.         /// Enumerates D3D devices for a particular adapter.
  196.         /// </summary>
  197.         private static void EnumerateDevices(EnumAdapterInformation adapterInfo, ArrayList adapterFormatList)
  198.         {
  199.             // Ignore any exceptions while looking for these device types
  200.             DirectXException.IgnoreExceptions();
  201.             // Enumerate each Direct3D device type
  202.             for(uint i = 0; i < deviceTypeArray.Length; i++)
  203.             {
  204.                 // Create a new device information object
  205.                 EnumDeviceInformation deviceInfo = new EnumDeviceInformation();
  206.  
  207.                 // Store the type
  208.                 deviceInfo.DeviceType = deviceTypeArray[i];
  209.  
  210.                 // Try to get the capabilities
  211.                 deviceInfo.Caps = Manager.GetDeviceCaps((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType);
  212.  
  213.                 // Get information about each device combination on this device
  214.                 EnumerateDeviceCombos( adapterInfo, deviceInfo, adapterFormatList);
  215.  
  216.                 // Do we have any device combinations?
  217.                 if (deviceInfo.deviceSettingsList.Count > 0)
  218.                 {
  219.                     // Yes, add it
  220.                     adapterInfo.deviceInfoList.Add(deviceInfo);
  221.                 }
  222.             }
  223.             // Turn exception handling back on
  224.             DirectXException.EnableExceptions();
  225.         }
  226.  
  227.         /// <summary>
  228.         /// Enumerates device combinations for a particular device.
  229.         /// </summary>
  230.         private static void EnumerateDeviceCombos(EnumAdapterInformation adapterInfo, EnumDeviceInformation deviceInfo, 
  231.             ArrayList adapterFormatList)
  232.         {
  233.             // Find out which adapter formats are supported by this device
  234.             foreach(Format adapterFormat in adapterFormatList)
  235.             {
  236.                 for(int i = 0; i < backbufferFormatsArray.Length; i++)
  237.                 {
  238.                     // Go through each windowed mode
  239.                     for (int windowedIndex = 0; windowedIndex < 2; windowedIndex++)
  240.                     {
  241.                         bool isWindowedIndex = (windowedIndex == 1);
  242.                         if ((!isWindowedIndex) && (adapterInfo.displayModeList.Count == 0))
  243.                             continue; // Nothing here
  244.  
  245.                         if (!Manager.CheckDeviceType((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType,
  246.                             adapterFormat, backbufferFormatsArray[i], isWindowedIndex))
  247.                             continue; // Unsupported
  248.  
  249.                         // Do we require post pixel shader blending?
  250.                         if (isPostPixelShaderBlendingRequired)
  251.                         {
  252.                             // If the backbuffer format doesn't support Usage.QueryPostPixelShaderBlending
  253.                             // then alpha test, pixel fog, render-target blending, color write enable, and dithering
  254.                             // are not supported.
  255.                             if (!Manager.CheckDeviceFormat((int)adapterInfo.AdapterOrdinal, deviceInfo.DeviceType,
  256.                                     adapterFormat, Usage.QueryPostPixelShaderBlending, 
  257.                                     ResourceType.Textures, backbufferFormatsArray[i]))
  258.                                 continue; // Unsupported
  259.                         }
  260.  
  261.                         // If an application callback function has been provided, make sure this device
  262.                         // is acceptable to the app.
  263.                         if (deviceCreationInterface != null)
  264.                         {
  265.                             if (!deviceCreationInterface.IsDeviceAcceptable(deviceInfo.Caps, 
  266.                                 adapterFormat, backbufferFormatsArray[i],isWindowedIndex))
  267.                                 continue; // Application doesn't like this device
  268.                         }
  269.  
  270.                         // At this point, we have an adapter/device/adapterformat/backbufferformat/iswindowed
  271.                         // DeviceCombo that is supported by the system and acceptable to the app. We still 
  272.                         // need to find one or more suitable depth/stencil buffer format,
  273.                         // multisample type, and present interval.
  274.  
  275.                         EnumDeviceSettingsCombo deviceCombo = new EnumDeviceSettingsCombo();
  276.  
  277.                         // Store the information
  278.                         deviceCombo.AdapterOrdinal = adapterInfo.AdapterOrdinal;
  279.                         deviceCombo.DeviceType = deviceInfo.DeviceType;
  280.                         deviceCombo.AdapterFormat = adapterFormat;
  281.                         deviceCombo.BackBufferFormat = backbufferFormatsArray[i];
  282.                         deviceCombo.IsWindowed = isWindowedIndex;
  283.  
  284.                         // Build the depth stencil format and multisample type list
  285.                         BuildDepthStencilFormatList(deviceCombo);
  286.                         BuildMultiSampleTypeList(deviceCombo);
  287.                         if (deviceCombo.multiSampleTypeList.Count == 0)
  288.                         {
  289.                             // Nothing to do
  290.                             continue;
  291.                         }
  292.                         // Build the conflict and present lists
  293.                         BuildConflictList(deviceCombo);
  294.                         BuildPresentIntervalList(deviceInfo, deviceCombo);
  295.  
  296.                         deviceCombo.adapterInformation = adapterInfo;
  297.                         deviceCombo.deviceInformation = deviceInfo;
  298.  
  299.                         // Add the combo to the list of devices
  300.                         deviceInfo.deviceSettingsList.Add(deviceCombo);
  301.                     }
  302.                 }
  303.             }
  304.         }
  305.  
  306.         /// <summary>
  307.         /// Adds all depth/stencil formats that are compatible with the device 
  308.         /// and application to the given device combo
  309.         /// </summary>
  310.         private static void BuildDepthStencilFormatList(EnumDeviceSettingsCombo deviceCombo)
  311.         {
  312.             foreach(DepthFormat depthStencil in depthStencilPossibleList)
  313.             {
  314.                 if (Manager.CheckDeviceFormat((int)deviceCombo.AdapterOrdinal,
  315.                     deviceCombo.DeviceType, deviceCombo.AdapterFormat,
  316.                     Usage.DepthStencil, ResourceType.Surface, depthStencil))
  317.                 {
  318.                     // This can be used as a depth stencil, make sure it matches
  319.                     if (Manager.CheckDepthStencilMatch((int)deviceCombo.AdapterOrdinal,
  320.                         deviceCombo.DeviceType, deviceCombo.AdapterFormat,
  321.                         deviceCombo.BackBufferFormat, depthStencil))
  322.                     {
  323.                         // Yup, add it
  324.                         deviceCombo.depthStencilFormatList.Add(depthStencil);
  325.                     }
  326.                 }
  327.             }
  328.         }
  329.  
  330.         /// <summary>
  331.         /// Adds all multisample types that are compatible with the device and app to
  332.         /// the given device combo
  333.         /// </summary>
  334.         private static void BuildMultiSampleTypeList(EnumDeviceSettingsCombo deviceCombo)
  335.         {
  336.             foreach(MultiSampleType msType in multiSampleTypeList)
  337.             {
  338.                 int result, quality;
  339.                 // Check this
  340.                 if (Manager.CheckDeviceMultiSampleType((int)deviceCombo.AdapterOrdinal,
  341.                     deviceCombo.DeviceType, deviceCombo.BackBufferFormat,
  342.                     deviceCombo.IsWindowed, msType, out result, out quality))
  343.                 {
  344.                     deviceCombo.multiSampleTypeList.Add(msType);
  345.                     if (quality > multisampleQualityMax + 1)
  346.                         quality = (int)(multisampleQualityMax + 1);
  347.  
  348.                     deviceCombo.multiSampleQualityList.Add(quality);
  349.                 }
  350.             }
  351.         }
  352.  
  353.  
  354.         /// <summary>
  355.         /// Find any conflicts between the available depth/stencil formats and
  356.         /// multisample types.
  357.         /// </summary>
  358.         private static void BuildConflictList(EnumDeviceSettingsCombo deviceCombo)
  359.         {
  360.             foreach(DepthFormat depthFormat in deviceCombo.depthStencilFormatList)
  361.             {
  362.                 foreach(MultiSampleType msType in deviceCombo.multiSampleTypeList)
  363.                 {
  364.                     // Check this for conflict
  365.                     if (!Manager.CheckDeviceMultiSampleType((int)deviceCombo.AdapterOrdinal,
  366.                         deviceCombo.DeviceType, (Format)depthFormat,
  367.                         deviceCombo.IsWindowed, msType))
  368.                     {
  369.                         // Add it to the list
  370.                         EnumDepthStencilMultisampleConflict conflict = new EnumDepthStencilMultisampleConflict();
  371.                         conflict.DepthStencilFormat = depthFormat;
  372.                         conflict.MultisampleType = msType;
  373.                         deviceCombo.depthStencilConflictList.Add(conflict);
  374.                     }
  375.                 }
  376.             }
  377.         }
  378.  
  379.  
  380.         /// <summary>
  381.         /// Adds all present intervals that are compatible with the device and app 
  382.         /// to the given device combo
  383.         /// </summary>
  384.         private static void BuildPresentIntervalList(EnumDeviceInformation deviceInfo, EnumDeviceSettingsCombo deviceCombo)
  385.         {
  386.             for (int i = 0; i < presentIntervalList.Count; i++)
  387.             {
  388.                 PresentInterval pi = (PresentInterval)presentIntervalList[i];
  389.                 if (deviceCombo.IsWindowed)
  390.                 {
  391.                     if ( (pi == PresentInterval.Two) ||
  392.                         (pi == PresentInterval.Three) ||
  393.                         (pi == PresentInterval.Four) )
  394.                     {
  395.                         // These intervals are never supported in windowed mode
  396.                         continue;
  397.                     }
  398.                 }
  399.  
  400.                 // Not that PresentInterval.Default is zero so you can't do a bitwise
  401.                 // check for it, it's always available
  402.                 if ( (pi == PresentInterval.Default) ||
  403.                     ((deviceInfo.Caps.PresentationIntervals & pi) != 0))
  404.                 {
  405.                     deviceCombo.presentIntervalList.Add(pi);
  406.                 }
  407.             }
  408.         }
  409.  
  410.         /// <summary>
  411.         /// Resets the list of possible depth stencil formats
  412.         /// </summary>
  413.         public static void ResetPossibleDepthStencilFormats()
  414.         {
  415.             depthStencilPossibleList.Clear();
  416.             depthStencilPossibleList.AddRange(new DepthFormat[] {
  417.                                                              DepthFormat.D16,
  418.                                                              DepthFormat.D15S1,
  419.                                                              DepthFormat.D24X8,
  420.                                                              DepthFormat.D24S8,
  421.                                                              DepthFormat.D24X4S4,
  422.                                                              DepthFormat.D32 });
  423.         }
  424.  
  425.         /// <summary>
  426.         /// Resets the possible multisample type list
  427.         /// </summary>
  428.         public static void ResetPossibleMultisampleTypeList()
  429.         {
  430.             multiSampleTypeList.Clear();
  431.             multiSampleTypeList.AddRange(new MultiSampleType[] {
  432.                                                             MultiSampleType.None,
  433.                                                             MultiSampleType.NonMaskable,
  434.                                                             MultiSampleType.TwoSamples,
  435.                                                             MultiSampleType.ThreeSamples,
  436.                                                             MultiSampleType.FourSamples,
  437.                                                             MultiSampleType.FiveSamples,
  438.                                                             MultiSampleType.SixSamples,
  439.                                                             MultiSampleType.SevenSamples,
  440.                                                             MultiSampleType.EightSamples,
  441.                                                             MultiSampleType.NineSamples,
  442.                                                             MultiSampleType.TenSamples,
  443.                                                             MultiSampleType.ElevenSamples,
  444.                                                             MultiSampleType.TwelveSamples,
  445.                                                             MultiSampleType.ThirteenSamples,
  446.                                                             MultiSampleType.FourteenSamples,
  447.                                                             MultiSampleType.FifteenSamples,
  448.                                                             MultiSampleType.SixteenSamples });
  449.         }
  450.  
  451.         /// <summary>
  452.         /// Resets the possible present interval list
  453.         /// </summary>
  454.         public static void ResetPossiblePresentIntervalList()
  455.         {
  456.             presentIntervalList.Clear();
  457.             presentIntervalList.AddRange(new PresentInterval[] {
  458.                                                             PresentInterval.Immediate,
  459.                                                             PresentInterval.Default,
  460.                                                             PresentInterval.One,
  461.                                                             PresentInterval.Two,
  462.                                                             PresentInterval.Three,
  463.                                                             PresentInterval.Four });
  464.         }
  465.  
  466.         /// <summary>
  467.         /// Set the minimum and maximum resolution items
  468.         /// </summary>
  469.         public static void SetResolutionMinMax(uint minWidth, uint minHeight, uint maxWidth, uint maxHeight)
  470.         {
  471.             minimumWidth = minWidth;
  472.             minimumHeight = minHeight;
  473.             maximumWidth = maxHeight;
  474.             maximumWidth = maxWidth;
  475.         }
  476.  
  477.         /// <summary>
  478.         /// Sets the minimum and maximum refresh
  479.         /// </summary>
  480.         public static void SetRefreshMinMax(uint minRefresh, uint maxRefresh)
  481.         {
  482.             minimumRefresh = minRefresh;
  483.             maximumRefresh = maxRefresh;
  484.         }
  485.  
  486.         /// <summary>
  487.         /// Property for MultisampleQualityMax
  488.         /// </summary>
  489.         public static uint MultisampleQualityMax
  490.         {
  491.             get { return multisampleQualityMax; }
  492.             set 
  493.             {
  494.                 if (value > 0xffff)
  495.                     multisampleQualityMax = 0xffff;
  496.                 else
  497.                     multisampleQualityMax = value;
  498.             }
  499.         }
  500.  
  501.         /// <summary>
  502.         /// Allows the user to set if post pixel shader blending is required
  503.         /// </summary>
  504.         public static bool IsPostPixelShaderBlendingRequred
  505.         {
  506.             get { return isPostPixelShaderBlendingRequired; }
  507.             set { isPostPixelShaderBlendingRequired = value; }
  508.         }
  509.  
  510.         /// <summary>
  511.         /// Allows the user to set if software vertex processing is available
  512.         /// </summary>
  513.         public static bool IsSoftwareVertexProcessingPossible
  514.         {
  515.             get { return isSoftwareVertexProcessing; }
  516.             set { isSoftwareVertexProcessing = value; }
  517.         }
  518.  
  519.         /// <summary>
  520.         /// Allows the user to set if hardware vertex processing is available
  521.         /// </summary>
  522.         public static bool IsHardwareVertexProcessingPossible
  523.         {
  524.             get { return isHardwareVertexProcessing; }
  525.             set { isHardwareVertexProcessing = value; }
  526.         }
  527.  
  528.         /// <summary>
  529.         /// Allows the user to set if pure hardware vertex processing is available
  530.         /// </summary>
  531.         public static bool IsPureHardwareVertexProcessingPossible
  532.         {
  533.             get { return isPureHardwareVertexProcessing; }
  534.             set { isPureHardwareVertexProcessing = value; }
  535.         }
  536.  
  537.         /// <summary>
  538.         /// Allows the user to set if mixed vertex processing is available
  539.         /// </summary>
  540.         public static bool IsMixedVertexProcessingPossible
  541.         {
  542.             get { return isMixedVertexProcessing; }
  543.             set { isMixedVertexProcessing = value; }
  544.         }
  545.  
  546.         /// <summary>
  547.         /// Allows the user to get the possible depth stencil formats
  548.         /// </summary>
  549.         public static ArrayList PossibleDepthStencilFormatList
  550.         {
  551.             get { return depthStencilPossibleList; }
  552.         }
  553.  
  554.         /// <summary>
  555.         /// Allows the user to get the possible multisample types
  556.         /// </summary>
  557.         public static ArrayList PossibleMultisampleTypeList
  558.         {
  559.             get { return multiSampleTypeList; }
  560.         }
  561.  
  562.         /// <summary>
  563.         /// Allows the user to get the possible present intervals
  564.         /// </summary>
  565.         public static ArrayList PossiblePresentIntervalsList
  566.         {
  567.             get { return presentIntervalList; }
  568.         }
  569.  
  570.         /// <summary>
  571.         /// Use this after Enumerate to get the list of adapter information
  572.         /// </summary>
  573.         public static ArrayList AdapterInformationList
  574.         {
  575.             get { return adapterInformationList; }
  576.         }
  577.  
  578.         /// <summary>
  579.         /// Get the adapter information for a specific adapter
  580.         /// </summary>
  581.         public static EnumAdapterInformation GetAdapterInformation(uint ordinal)
  582.         {
  583.             foreach(EnumAdapterInformation eai in adapterInformationList)
  584.             {
  585.                 if (eai.AdapterOrdinal == ordinal)
  586.                 {
  587.                     return eai;
  588.                 }
  589.             }
  590.  
  591.             // Never found it
  592.             return null;
  593.         }
  594.  
  595.         /// <summary>
  596.         /// Get a specific device information for a device and type
  597.         /// </summary>
  598.         public static EnumDeviceInformation GetDeviceInfo(uint ordinal, DeviceType deviceType)
  599.         {
  600.             EnumAdapterInformation info = GetAdapterInformation(ordinal);
  601.             if (info != null)
  602.             {
  603.                 foreach(EnumDeviceInformation edi in info.deviceInfoList)
  604.                 {
  605.                     // Is this the right device type?
  606.                     if (edi.DeviceType == deviceType)
  607.                     {
  608.                         return edi;
  609.                     }
  610.                 }
  611.             }
  612.  
  613.             // Never found it
  614.             return null;
  615.         }
  616.  
  617.         /// <summary>
  618.         /// Returns a specific device combination
  619.         /// </summary>
  620.         public static EnumDeviceSettingsCombo GetDeviceSettingsCombo(uint ordinal, DeviceType deviceType,
  621.             Format adapterFormat, Format backBufferFormat, bool isWindowed)
  622.         {
  623.             EnumDeviceInformation info = GetDeviceInfo(ordinal, deviceType);
  624.             if (info != null)
  625.             {
  626.                 foreach(EnumDeviceSettingsCombo edsc in info.deviceSettingsList)
  627.                 {
  628.                     // Is this the right settings combo?
  629.                     if ( (edsc.AdapterFormat == adapterFormat) && 
  630.                         (edsc.BackBufferFormat == backBufferFormat) &&
  631.                         (edsc.IsWindowed == isWindowed) )
  632.                     {
  633.                         return edsc;
  634.                     }
  635.                 }
  636.             }
  637.  
  638.             // Never found it
  639.             return null;
  640.         }
  641.  
  642.         /// <summary>
  643.         /// Returns a specific device combination from a device settings object
  644.         /// </summary>
  645.         public static EnumDeviceSettingsCombo GetDeviceSettingsCombo(DeviceSettings settings)
  646.         {
  647.             return GetDeviceSettingsCombo(settings.AdapterOrdinal, settings.DeviceType, settings.AdapterFormat,
  648.                 settings.presentParams.BackBufferFormat, settings.presentParams.Windowed);
  649.         }
  650.     }
  651.  
  652.     /// <summary>
  653.     /// Class describing an adapter which contains a unique adapter ordinal that
  654.     /// is installed on the system.
  655.     /// </summary>
  656.     public class EnumAdapterInformation
  657.     {
  658.         public uint AdapterOrdinal; // Ordinal for this adapter
  659.         public AdapterDetails AdapterInformation; // Information about this adapter
  660.         public ArrayList displayModeList = new ArrayList(); // Array of display modes
  661.         public ArrayList deviceInfoList = new ArrayList(); // Array of device information
  662.         public string UniqueDescription; // Unique description of this device
  663.     }
  664.  
  665.     /// <summary>
  666.     /// Class describing a Direct3D device that contains a 
  667.     /// unique supported device type
  668.     /// </summary>
  669.     public class EnumDeviceInformation
  670.     {
  671.         public uint AdapterOrdinal; // Ordinal for this adapter
  672.         public DeviceType DeviceType; // Type of the device
  673.         public Caps Caps; // Capabilities of the device
  674.         public ArrayList deviceSettingsList = new ArrayList(); // Array with unique set of adapter format, back buffer format, and windowed
  675.     }
  676.  
  677.     /// <summary>
  678.     /// Class describing device settings that contain a unique combination
  679.     /// of adapter format, back buffer format, and windowed that is compatible
  680.     /// with a particular Direct3D device and the application
  681.     /// </summary>
  682.     public class EnumDeviceSettingsCombo
  683.     {
  684.         public uint AdapterOrdinal;
  685.         public DeviceType DeviceType;
  686.         public Format AdapterFormat;
  687.         public Format BackBufferFormat;
  688.         public bool IsWindowed;
  689.  
  690.         // Array lists
  691.         public ArrayList depthStencilFormatList = new ArrayList();
  692.         public ArrayList multiSampleTypeList = new ArrayList();
  693.         public ArrayList multiSampleQualityList = new ArrayList();
  694.         public ArrayList presentIntervalList = new ArrayList();
  695.         public ArrayList depthStencilConflictList = new ArrayList();
  696.  
  697.         public EnumAdapterInformation adapterInformation = null;
  698.         public EnumDeviceInformation deviceInformation = null;
  699.     }
  700.  
  701.     /// <summary>
  702.     /// A depth/stencil buffer format that is incompatible
  703.     /// with a multisample type
  704.     /// </summary>
  705.     public struct EnumDepthStencilMultisampleConflict
  706.     {
  707.         public DepthFormat DepthStencilFormat;
  708.         public MultiSampleType MultisampleType;
  709.     }
  710.  
  711.     /// <summary>
  712.     /// Used to sort display modes
  713.     /// </summary>
  714.     public class DisplayModeSorter : IComparer
  715.     {
  716.         #region IComparer Members
  717.  
  718.         /// <summary>
  719.         /// Compare two display modes
  720.         /// </summary>
  721.         public int Compare(object x, object y)
  722.         {
  723.             DisplayMode d1 = (DisplayMode)x;
  724.             DisplayMode d2 = (DisplayMode)y;
  725.  
  726.             if (d1.Width > d2.Width)
  727.                 return +1;
  728.             if (d1.Width < d2.Width)
  729.                 return -1;
  730.             if (d1.Height > d2.Height)
  731.                 return +1;
  732.             if (d1.Height < d2.Height)
  733.                 return -1;
  734.             if (d1.Format > d2.Format)
  735.                 return +1;
  736.             if (d1.Format < d2.Format)
  737.                 return -1;
  738.             if (d1.RefreshRate > d2.RefreshRate)
  739.                 return +1;
  740.             if (d1.RefreshRate < d2.RefreshRate)
  741.                 return -1;
  742.  
  743.             // They must be the same, return 0
  744.             return 0;
  745.         }
  746.  
  747.         #endregion
  748.     }
  749.  
  750.     #region Helper Utility Class
  751.     /// <summary>
  752.     /// Helper methods
  753.     /// </summary>
  754.     class ManagedUtility
  755.     {
  756.         private ManagedUtility() { } // No creation
  757.  
  758.         /// <summary>
  759.         /// Gets the number of ColorChanelBits from a format
  760.         /// </summary>
  761.         public static uint GetColorChannelBits(Format format)
  762.         {
  763.             switch (format)
  764.             {
  765.                 case Format.R8G8B8:
  766.                 case Format.A8R8G8B8:
  767.                 case Format.X8R8G8B8:
  768.                     return 8;
  769.                 case Format.R5G6B5:
  770.                 case Format.X1R5G5B5:
  771.                 case Format.A1R5G5B5:
  772.                     return 5;
  773.                 case Format.A4R4G4B4:
  774.                 case Format.X4R4G4B4:
  775.                     return 4;
  776.                 case Format.R3G3B2:
  777.                 case Format.A8R3G3B2:
  778.                     return 2;
  779.                 case Format.A2B10G10R10:
  780.                 case Format.A2R10G10B10:
  781.                     return 10;
  782.                 default:
  783.                     return 0;
  784.             }
  785.         }
  786.  
  787.         /// <summary>
  788.         /// Gets the number of alpha channel bits 
  789.         /// </summary>
  790.         public static uint GetAlphaChannelBits(Format format)
  791.         {
  792.             switch (format)
  793.             {
  794.                 case Format.X8R8G8B8:
  795.                 case Format.R8G8B8:
  796.                 case Format.R5G6B5:
  797.                 case Format.X1R5G5B5:
  798.                 case Format.R3G3B2:
  799.                 case Format.X4R4G4B4:
  800.                     return 0;
  801.                 case Format.A8R3G3B2:
  802.                 case Format.A8R8G8B8:
  803.                     return 8;
  804.                 case Format.A1R5G5B5:
  805.                     return 1;
  806.                 case Format.A4R4G4B4:
  807.                     return 4;
  808.                 case Format.A2B10G10R10:
  809.                 case Format.A2R10G10B10:
  810.                     return 2;
  811.                 default:
  812.                     return 0;
  813.             }
  814.         }
  815.  
  816.         /// <summary>
  817.         /// Gets the number of depth bits
  818.         /// </summary>
  819.         public static uint GetDepthBits(DepthFormat format)
  820.         {
  821.             switch (format)
  822.             {
  823.                 case DepthFormat.D16:
  824.                 case DepthFormat.D16Lockable:
  825.                     return 16;
  826.  
  827.                 case DepthFormat.D15S1:
  828.                     return 15;
  829.  
  830.                 case DepthFormat.D24X8:
  831.                 case DepthFormat.D24S8:
  832.                 case DepthFormat.D24X4S4:
  833.                 case DepthFormat.D24SingleS8:
  834.                     return 24;
  835.  
  836.                 case DepthFormat.D32:
  837.                 case DepthFormat.D32SingleLockable:
  838.                     return 32;
  839.                 default:
  840.                     return 0;
  841.             }
  842.         }
  843.  
  844.         /// <summary>
  845.         /// Gets the number of stencil bits
  846.         /// </summary>
  847.         public static uint GetStencilBits(DepthFormat format)
  848.         {
  849.             switch (format)
  850.             {
  851.                 case DepthFormat.D16:
  852.                 case DepthFormat.D16Lockable:
  853.                 case DepthFormat.D24X8:
  854.                 case DepthFormat.D32:
  855.                 case DepthFormat.D32SingleLockable:
  856.                     return 0;
  857.  
  858.                 case DepthFormat.D15S1:
  859.                     return 1;
  860.  
  861.                 case DepthFormat.D24X4S4:
  862.                     return 4;
  863.  
  864.                 case DepthFormat.D24SingleS8:
  865.                 case DepthFormat.D24S8:
  866.                     return 8;
  867.  
  868.                 default:
  869.                     return 0;
  870.             }
  871.         }
  872.     }
  873.     #endregion
  874. }