예제 #1
0
    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);
    }