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