public ID3D11Texture2D CaptureTexture(ID3D11Texture2D source) { ID3D11Texture2D stagingTexture; Texture2DDescription desc = source.Description; if (desc.ArraySize > 1 || desc.MipLevels > 1) { Console.WriteLine("WARNING: ScreenGrab does not support 2D arrays, cubemaps, or mipmaps; only the first surface is written. Consider using DirectXTex instead."); return(null); } if (desc.SampleDescription.Count > 1) { // MSAA content must be resolved before being copied to a staging texture desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; ID3D11Texture2D temp = Device.CreateTexture2D(desc); Format format = desc.Format; FormatSupport formatSupport = Device.CheckFormatSupport(format); if ((formatSupport & FormatSupport.MultisampleResolve) == FormatSupport.None) { throw new NotSupportedException($"Format {format} doesn't support multisample resolve"); } for (int item = 0; item < desc.ArraySize; ++item) { for (int level = 0; level < desc.MipLevels; ++level) { int index = CalculateSubResourceIndex(level, item, desc.MipLevels); DeviceContext.ResolveSubresource(temp, index, source, index, format); } } desc.BindFlags = BindFlags.None; desc.MiscFlags &= ResourceOptionFlags.TextureCube; desc.CPUAccessFlags = CpuAccessFlags.Read; desc.Usage = ResourceUsage.Staging; stagingTexture = Device.CreateTexture2D(desc); DeviceContext.CopyResource(stagingTexture, temp); } else if ((desc.Usage == ResourceUsage.Staging) && ((desc.CPUAccessFlags & CpuAccessFlags.Read) != CpuAccessFlags.None)) { // Handle case where the source is already a staging texture we can use directly stagingTexture = source; } else { // Otherwise, create a staging texture from the non-MSAA source desc.BindFlags = 0; desc.MiscFlags &= ResourceOptionFlags.TextureCube; desc.CPUAccessFlags = CpuAccessFlags.Read; desc.Usage = ResourceUsage.Staging; stagingTexture = Device.CreateTexture2D(desc); DeviceContext.CopyResource(stagingTexture, source); } return(stagingTexture); }
private D3D11GraphicsDevice(Window?window, SizeI size, Format depthStencilFormat = Format.D32_Float) { Window = window; Size = size; Factory = CreateDXGIFactory1 <IDXGIFactory2>(); using (IDXGIAdapter1 adapter = GetHardwareAdapter()) { DeviceCreationFlags creationFlags = DeviceCreationFlags.BgraSupport; #if DEBUG if (SdkLayersAvailable()) { creationFlags |= DeviceCreationFlags.Debug; } #endif if (D3D11CreateDevice( adapter, DriverType.Unknown, creationFlags, s_featureLevels, out ID3D11Device tempDevice, out FeatureLevel, out ID3D11DeviceContext tempContext).Failure) { // If the initialization fails, fall back to the WARP device. // For more information on WARP, see: // http://go.microsoft.com/fwlink/?LinkId=286690 D3D11CreateDevice( IntPtr.Zero, DriverType.Warp, creationFlags, s_featureLevels, out tempDevice, out FeatureLevel, out tempContext).CheckError(); } Device = tempDevice.QueryInterface <ID3D11Device1>(); DeviceContext = tempContext.QueryInterface <ID3D11DeviceContext1>(); tempContext.Dispose(); tempDevice.Dispose(); } if (window != null) { IntPtr hwnd = window.Handle; SwapChainDescription1 swapChainDescription = new() { Width = window.ClientSize.Width, Height = window.ClientSize.Height, Format = Format.R8G8B8A8_UNorm, BufferCount = FrameCount, BufferUsage = Usage.RenderTargetOutput, SampleDescription = SampleDescription.Default, Scaling = Scaling.Stretch, SwapEffect = SwapEffect.FlipDiscard, AlphaMode = AlphaMode.Ignore }; SwapChainFullscreenDescription fullscreenDescription = new SwapChainFullscreenDescription { Windowed = true }; SwapChain = Factory.CreateSwapChainForHwnd(Device, hwnd, swapChainDescription, fullscreenDescription); Factory.MakeWindowAssociation(hwnd, WindowAssociationFlags.IgnoreAltEnter); BackBufferTexture = SwapChain.GetBuffer <ID3D11Texture2D>(0); RenderTargetView = Device.CreateRenderTargetView(BackBufferTexture); } else { // Create offscreen texture OffscreenTexture = Device.CreateTexture2D(Format.R8G8B8A8_UNorm, Size.Width, Size.Height, 1, 1, null, BindFlags.ShaderResource | BindFlags.RenderTarget); RenderTargetView = Device.CreateRenderTargetView(OffscreenTexture); } if (depthStencilFormat != Format.Unknown) { DepthStencilTexture = Device.CreateTexture2D(depthStencilFormat, Size.Width, Size.Height, 1, 1, null, BindFlags.DepthStencil); DepthStencilView = Device.CreateDepthStencilView(DepthStencilTexture !, new DepthStencilViewDescription(DepthStencilTexture, DepthStencilViewDimension.Texture2D)); } ReadOnlySpan <VertexPositionColor> triangleVertices = stackalloc VertexPositionColor[] { new VertexPositionColor(new Vector3(0f, 0.5f, 0.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f)), new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f)), new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f)) }; bool dynamic = false; if (dynamic) { _vertexBuffer = Device.CreateBuffer(VertexPositionColor.SizeInBytes * 3, BindFlags.VertexBuffer, ResourceUsage.Dynamic, CpuAccessFlags.Write); MappedSubresource mappedSubresource = DeviceContext.Map(_vertexBuffer, 0, MapMode.WriteDiscard); triangleVertices.CopyTo(mappedSubresource.AsSpan <VertexPositionColor>(3)); DeviceContext.Unmap(_vertexBuffer, 0); } else { _vertexBuffer = Device.CreateBuffer(triangleVertices, BindFlags.VertexBuffer); } InputElementDescription[] inputElementDescs = new[] { new InputElementDescription("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElementDescription("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }; Span <byte> vertexShaderByteCode = CompileBytecode("Triangle.hlsl", "VSMain", "vs_4_0"); Span <byte> pixelShaderByteCode = CompileBytecode("Triangle.hlsl", "PSMain", "ps_4_0"); _vertexShader = Device.CreateVertexShader(vertexShaderByteCode); _pixelShader = Device.CreatePixelShader(pixelShaderByteCode); _inputLayout = Device.CreateInputLayout(inputElementDescs, vertexShaderByteCode); }
private D3D11GraphicsDevice(Window?window, Size size) { Window = window; Size = size; if (CreateDXGIFactory1(out Factory).Failure) { throw new InvalidOperationException("Cannot create IDXGIFactory1"); } using (IDXGIAdapter1? adapter = GetHardwareAdapter()) { DeviceCreationFlags creationFlags = DeviceCreationFlags.BgraSupport; #if DEBUG if (SdkLayersAvailable()) { creationFlags |= DeviceCreationFlags.Debug; } #endif if (D3D11CreateDevice( adapter !, DriverType.Unknown, creationFlags, s_featureLevels, out ID3D11Device tempDevice, out FeatureLevel, out ID3D11DeviceContext tempContext).Failure) { // If the initialization fails, fall back to the WARP device. // For more information on WARP, see: // http://go.microsoft.com/fwlink/?LinkId=286690 D3D11CreateDevice( null, DriverType.Warp, creationFlags, s_featureLevels, out tempDevice, out FeatureLevel, out tempContext).CheckError(); } Device = tempDevice.QueryInterface <ID3D11Device1>(); DeviceContext = tempContext.QueryInterface <ID3D11DeviceContext1>(); tempContext.Dispose(); tempDevice.Dispose(); } if (window != null) { IntPtr hwnd = window.Handle; SwapChainDescription1 swapChainDescription = new SwapChainDescription1() { Width = window.ClientSize.Width, Height = window.ClientSize.Height, Format = Format.R8G8B8A8_UNorm, BufferCount = FrameCount, Usage = Vortice.DXGI.Usage.RenderTargetOutput, SampleDescription = new SampleDescription(1, 0), Scaling = Scaling.Stretch, SwapEffect = SwapEffect.FlipDiscard, AlphaMode = AlphaMode.Ignore }; SwapChainFullscreenDescription fullscreenDescription = new SwapChainFullscreenDescription { Windowed = true }; SwapChain = Factory.CreateSwapChainForHwnd(Device, hwnd, swapChainDescription, fullscreenDescription); Factory.MakeWindowAssociation(hwnd, WindowAssociationFlags.IgnoreAltEnter); BackBufferTexture = SwapChain.GetBuffer <ID3D11Texture2D>(0); RenderTargetView = Device.CreateRenderTargetView(BackBufferTexture); } else { // Create offscreen texture OffscreenTexture = Device.CreateTexture2D(new Texture2DDescription(Format.R8G8B8A8_UNorm, Size.Width, Size.Height, 1, 1, BindFlags.ShaderResource | BindFlags.RenderTarget)); RenderTargetView = Device.CreateRenderTargetView(OffscreenTexture); } }