/// <summary> /// Function to determine if the specified format is supported for a render target. /// </summary> /// <param name="format">Format to check.</param> /// <param name="isMultiSampled">TRUE if using a multisampled render target, FALSE if not.</param> /// <returns>TRUE if the format is supported for the render target, FALSE if not.</returns> public bool SupportsRenderTargetFormat(BufferFormat format, bool isMultiSampled) { D3D.Device device = (Graphics != null) ? Graphics.D3DDevice : null; Tuple <GI.Factory1, GI.Adapter1, D3D.Device> tempInterfaces = null; try { if (device != null) { return(((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.RenderTarget) == D3D.FormatSupport.RenderTarget) && ((isMultiSampled) && ((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.MultisampleRenderTarget) == D3D.FormatSupport.MultisampleRenderTarget) || (!isMultiSampled))); } tempInterfaces = GetDevice(VideoDeviceType, HardwareFeatureLevel); device = tempInterfaces.Item3; return(((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.RenderTarget) == D3D.FormatSupport.RenderTarget) && ((isMultiSampled) && ((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.MultisampleRenderTarget) == D3D.FormatSupport.MultisampleRenderTarget) || (!isMultiSampled))); } finally { ReleaseInterfaces(tempInterfaces); } }
internal DeviceFeatures(Device device) { mapFeaturesPerFormat = new FeaturesPerFormat[256]; // Check global features level = device.FeatureLevel; hasComputeShaders = device.CheckFeatureSupport(Feature.ComputeShaders); hasDoublePrecision = device.CheckFeatureSupport(Feature.ShaderDoubles); device.CheckThreadingSupport(out hasMultiThreadingConcurrentResources, out hasDriverCommandLists); // Check features for each DXGI.Format foreach (var format in Enum.GetValues(typeof(Format))) { var dxgiFormat = (Format)format; var maximumMSAA = MSAALevel.None; var computeShaderFormatSupport = ComputeShaderFormatSupport.None; var formatSupport = FormatSupport.None; if (!ObsoleteFormatToExcludes.Contains(dxgiFormat)) { maximumMSAA = GetMaximumMSAASampleCount(device, dxgiFormat); if (hasComputeShaders) { computeShaderFormatSupport = device.CheckComputeShaderFormatSupport(dxgiFormat); } formatSupport = device.CheckFormatSupport(dxgiFormat); } mapFeaturesPerFormat[(int)dxgiFormat] = new FeaturesPerFormat(dxgiFormat, maximumMSAA, computeShaderFormatSupport, formatSupport); } }
/// <summary> /// Function to determine if the device supports a given format for unordered access views. /// </summary> /// <param name="format">Format to evaluate.</param> /// <returns>TRUE if the format is supported, FALSE if not.</returns> /// <remarks>This is meant for UAVs that are used with a texture/buffer. For structured buffers only Unknown is supported and for raw buffers only R32 (typeless) is supported.</remarks> public bool SupportsUnorderedAccessViewFormat(BufferFormat format) { D3D.Device device = (Graphics != null) ? Graphics.D3DDevice : null; Tuple <GI.Factory1, GI.Adapter1, D3D.Device> tempInterfaces = null; try { if (device == null) { tempInterfaces = GetDevice(VideoDeviceType, HardwareFeatureLevel); device = tempInterfaces.Item3; } switch (SupportedFeatureLevel) { case DeviceFeatureLevel.SM4: case DeviceFeatureLevel.SM4_1: return(false); default: return((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.TypedUnorderedAccessView) == D3D.FormatSupport.TypedUnorderedAccessView); } } finally { ReleaseInterfaces(tempInterfaces); } }
/// <summary> /// Function to determine if the specified depth buffer format is supported. /// </summary> /// <param name="format">Format to check.</param> /// <returns>TRUE if the format is supported as a depth/stencil buffer, FALSE if not.</returns> public bool SupportsDepthFormat(BufferFormat format) { D3D.Device device = (Graphics != null) ? Graphics.D3DDevice : null; Tuple <GI.Factory1, GI.Adapter1, D3D.Device> tempInterfaces = null; try { if (device != null) { return((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.DepthStencil) == D3D.FormatSupport.DepthStencil); } tempInterfaces = GetDevice(VideoDeviceType, HardwareFeatureLevel); device = tempInterfaces.Item3; return((device.CheckFormatSupport((GI.Format)format) & D3D.FormatSupport.DepthStencil) == D3D.FormatSupport.DepthStencil); } finally { ReleaseInterfaces(tempInterfaces); } }
/// <summary> /// Function to retrieve the video modes for the output. /// </summary> /// <param name="output">Output that owns the video modes.</param> /// <param name="D3DDevice">D3D device for filtering supported display modes.</param> /// <param name="giOutput">Output that contains the video modes.</param> private static void GetVideoModes(GorgonVideoOutput output, D3D.Device D3DDevice, Output giOutput) { var formats = (BufferFormat[])Enum.GetValues(typeof(BufferFormat)); Gorgon.Log.Print("Retrieving video modes for output '{0}'...", LoggingLevel.Simple, output.Name); Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose); // Test each format for display compatibility. foreach (var format in formats) { var giFormat = (Format)format; ModeDescription[] modes = giOutput.GetDisplayModeList(giFormat, DisplayModeEnumerationFlags.Scaling | DisplayModeEnumerationFlags.Interlaced); if ((modes == null) || (modes.Length <= 0)) { continue; } GorgonVideoMode[] videoModes = (from mode in modes where (D3DDevice.CheckFormatSupport(giFormat) & D3D.FormatSupport.Display) == D3D.FormatSupport.Display select GorgonVideoMode.Convert(mode)).ToArray(); if (videoModes.Length > 0) { output.VideoModes = new ReadOnlyCollection <GorgonVideoMode>(videoModes); } } // Output to log. foreach (var videoMode in output.VideoModes) { Gorgon.Log.Print("Mode: {0}x{1}, Format: {2}, Refresh Rate: {3}/{4}", LoggingLevel.Verbose, videoMode.Width, videoMode.Height, videoMode.Format, videoMode.RefreshRateNumerator, videoMode.RefreshRateDenominator); } Gorgon.Log.Print("===================================================================", LoggingLevel.Verbose); Gorgon.Log.Print("Found {0} video modes for output '{1}'.", LoggingLevel.Simple, output.VideoModes.Count, output.Name); }
protected override bool GetPixelFormatSupportCore( PixelFormat format, TextureType type, TextureUsage usage, out PixelFormatProperties properties) { if (D3D11Formats.IsUnsupportedFormat(format)) { properties = default(PixelFormatProperties); return(false); } Format dxgiFormat = D3D11Formats.ToDxgiFormat(format, (usage & TextureUsage.DepthStencil) != 0); FormatSupport fs = _device.CheckFormatSupport(dxgiFormat); if ((usage & TextureUsage.RenderTarget) != 0 && (fs & FormatSupport.RenderTarget) == 0 || (usage & TextureUsage.DepthStencil) != 0 && (fs & FormatSupport.DepthStencil) == 0 || (usage & TextureUsage.Sampled) != 0 && (fs & FormatSupport.ShaderSample) == 0 || (usage & TextureUsage.Cubemap) != 0 && (fs & FormatSupport.TextureCube) == 0 || (usage & TextureUsage.Storage) != 0 && (fs & FormatSupport.TypedUnorderedAccessView) == 0) { properties = default(PixelFormatProperties); return(false); } const uint MaxTextureDimension = 16384; const uint MaxVolumeExtent = 2048; uint sampleCounts = 0; if (CheckFormatMultisample(dxgiFormat, 1)) { sampleCounts |= (1 << 0); } if (CheckFormatMultisample(dxgiFormat, 2)) { sampleCounts |= (1 << 1); } if (CheckFormatMultisample(dxgiFormat, 4)) { sampleCounts |= (1 << 2); } if (CheckFormatMultisample(dxgiFormat, 8)) { sampleCounts |= (1 << 3); } if (CheckFormatMultisample(dxgiFormat, 16)) { sampleCounts |= (1 << 4); } if (CheckFormatMultisample(dxgiFormat, 32)) { sampleCounts |= (1 << 5); } properties = new PixelFormatProperties( MaxTextureDimension, type == TextureType.Texture1D ? 1 : MaxTextureDimension, type != TextureType.Texture3D ? 1 : MaxVolumeExtent, uint.MaxValue, type == TextureType.Texture3D ? 1 : MaxVolumeExtent, sampleCounts); return(true); }
public static void SetupDisplay(Control control) { Display.Width = control.ClientSize.Width; Display.Height = control.ClientSize.Height; var description = new SwapChainDescription() { BufferCount = 1, Usage = Usage.RenderTargetOutput, OutputHandle = control.Handle, IsWindowed = !Display.Fullscreen, ModeDescription = new ModeDescription(0, 0, new Rational(), Format.R8G8B8A8_UNorm), SampleDescription = new SampleDescription(Antialias, 0), Flags = SwapChainFlags.AllowModeSwitch, SwapEffect = SwapEffect.Discard }; var factory = new Factory(); Logger.Log("D3D11 Factory initialized."); int adapterCount = factory.GetAdapterCount(); Logger.Log("D3D11 Amount of adapters: " + adapterCount); if (adapterCount == 0) { Logger.Log("ERROR : No adapters found !"); throw new Exception("ERROR : No adapters found !"); } bool perfHUDenabled = false; Adapter adapter = null; for (int i = 0; i < adapterCount; i++) { Adapter ad = factory.GetAdapter(i); Logger.Log("D3D11 Adapter " + i + " : (" + ad.Description.DeviceId + ") " + ad.Description.Description); if (ad.Description.Description == "NVIDIA PerfHUD") { perfHUDenabled = true; adapter = ad; } } if (adapter == null) { adapter = factory.GetAdapter(0); } Logger.Log("D3D11 Adapter chosen : " + adapter.Description.Description); if (perfHUDenabled) { Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, description, out device, out swapChain); } else { try { #if DEBUG try { device = new Device(adapter, DeviceCreationFlags.Debug); } catch (Exception e) { Logger.Log("! Warning : D3D11 Could not init DEBUG Device. (" + e.Message + ")"); device = new Device(adapter, DeviceCreationFlags.None); } #else device = new Device(adapter, DeviceCreationFlags.None); #endif } catch (Exception e) { Logger.Log("! ERROR : D3D11 Could not init the Device at all ! (" + e.Message + ")"); device = new Device(adapter, DeviceCreationFlags.None); } } Logger.Log("D3D11 Device initialized."); bool supConcurrentRess, supCommandList; device.CheckThreadingSupport(out supConcurrentRess, out supCommandList); Logger.Log("D3D11 Concurrent ressource load supported : " + supConcurrentRess); Logger.Log("D3D11 Command lists supported : " + supCommandList); // Main textures Logger.Log("D3D11 Format R8G8B8A8_UNorm supported : " + device.CheckFormatSupport(Format.R8G8B8A8_UNorm).HasFlag(FormatSupport.RenderTarget)); Logger.Log("D3D11 Format D24_UNorm_S8_UInt supported : " + device.CheckFormatSupport(Format.D24_UNorm_S8_UInt).HasFlag(FormatSupport.DepthStencil)); Logger.Log("D3D11 Format D32_Float supported : " + device.CheckFormatSupport(Format.D32_Float).HasFlag(FormatSupport.DepthStencil)); //Shadow textures Logger.Log("D3D11 Format R16_Typeless supported : " + device.CheckFormatSupport(Format.R16_Typeless).HasFlag(FormatSupport.Texture2D)); Logger.Log("D3D11 Format D16_UNorm supported : " + device.CheckFormatSupport(Format.D16_UNorm).HasFlag(FormatSupport.Texture2D)); Logger.Log("D3D11 Format R16_UNorm supported : " + device.CheckFormatSupport(Format.R16_UNorm).HasFlag(FormatSupport.Texture2D)); swapChain = new SwapChain(factory, device, description); factory.MakeWindowAssociation(Main.Form.Handle, WindowAssociationFlags.IgnoreAll); //device.CheckMultisampleQualityLevels(Format.R8G8B8A8_UNorm, 1); //swapChain. Logger.Log("D3D11 SwapChain initialized."); Display.context = device.ImmediateContext; //Display.width = Main.Form.ClientSize.Width; //Display.height = Main.Form.ClientSize.Height; //Global.Viewport = new Rectangle(0, 0, (int)Display.width, (int)Display.height); Result res = Display.device.DeviceRemovedReason; if (res.Failure) { Logger.Log("! ERROR : a weird one : " + res.Code); throw new Exception("ERROR, this is weird, here's the reason why : " + res.ToString()); } if (device.IsDisposed) { Logger.Log("! ERROR : a REALLY weird one."); throw new Exception("DISPOSED ERROR, this is F*****G weird ... "); } backBuffer = SharpDX.Direct3D11.Resource.FromSwapChain <Texture2D>(swapChain, 0); renderTarget = new RenderTargetView(device, backBuffer); Logger.Log("D3D11 Backbuffer initialized."); backBufferCopyDesc = new Texture2DDescription() { ArraySize = 1, BindFlags = BindFlags.ShaderResource, CpuAccessFlags = CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, Width = Display.Width, Height = Display.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, }; backBufferCopy = new Texture2D(Display.device, backBufferCopyDesc); backBufferCopySRV = new ShaderResourceView(Display.device, backBufferCopy); Logger.Log("D3D11 Backbuffer copy initialized."); depthBufferDesc = new Texture2DDescription() { ArraySize = 1, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, Format = Format.D24_UNorm_S8_UInt, Width = Display.Width, Height = Display.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = description.SampleDescription, Usage = ResourceUsage.Default, }; using (var depthBuffer = new Texture2D(device, depthBufferDesc)) depthStencil = new DepthStencilView(device, depthBuffer); Logger.Log("D3D11 Depthbuffer initialized."); DeviceStates.Initialize(); Logger.Log("D3D11 Device states initialized."); context.OutputMerger.DepthStencilState = DeviceStates.depthDefaultState; context.Rasterizer.State = DeviceStates.rastStateSolid; context.OutputMerger.BlendState = DeviceStates.blendStateSolid; context.OutputMerger.SetTargets(depthStencil, renderTarget); context.Rasterizer.SetViewports(new Viewport(0, 0, Display.Width, Display.Height, 0.0f, 1.0f)); Logger.Log("D3D11 engine states set."); screenMatrix = Matrix.Scaling(2f / Display.Width, -2f / Display.Height, 0) * Matrix.Translation(-1, 1, 0); screenMatrix.Transpose(); screenBuffer = new Buffer(device, DataStream.Create <Matrix>(new[] { screenMatrix }, false, false), 64, ResourceUsage.Immutable, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); Logger.Log("D3D11 screen buffer created."); }