예제 #1
0
    /// <summary>
    /// Saves a texture to a specified stream.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="stream">The stream to save the image to.</param>
    /// <param name="format">The target image format to use.</param>
    public static void Save <T>(this ReadBackTexture2D <T> texture, Stream stream, ImageFormat format)
        where T : unmanaged
    {
        Guard.IsNotNull(stream, nameof(stream));

        WICHelper.Instance.SaveTexture(texture.View, stream, format);
    }
예제 #2
0
    /// <summary>
    /// Saves a texture to a specified file.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="filename">The filename of the image file to save.</param>
    public static void Save <T>(this ReadBackTexture2D <T> texture, ReadOnlySpan <char> filename)
        where T : unmanaged
    {
        Guard.IsNotNull(texture);

        WICHelper.Instance.SaveTexture(texture.View, filename);
    }
예제 #3
0
    /// <summary>
    /// Saves a texture to a specified file.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="filename">The filename of the image file to save.</param>
    public static void Save <T>(this ReadBackTexture2D <T> texture, string filename)
        where T : unmanaged
    {
        Guard.IsNotNull(filename, nameof(filename));

        WICHelper.Instance.SaveTexture(texture.View, filename.AsSpan());
    }
예제 #4
0
    public unsafe void Allocate_ReadBackTexture2D_Copy_Range(Device device, int x, int y, int width, int height)
    {
        int[,] source = new int[2048, 2048];

        fixed(int *p = source)
        {
            new Random(42).NextBytes(new Span <int>(p, source.Length).AsBytes());
        }

        using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source);
        using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(2048, 2048);

        readOnlyTexture2D.CopyTo(readBackTexture2D, x, y, width, height);

        fixed(int *p = source)
        {
            for (int i = 0; i < height; i++)
            {
                Span <int> sourceRow      = new Span <int>(Unsafe.AsPointer(ref source[i + y, 0]), source.GetLength(1)).Slice(x, width);
                Span <int> destinationRow = readBackTexture2D.View.GetRowSpan(i).Slice(0, width);

                Assert.IsTrue(sourceRow.SequenceEqual(destinationRow));
            }
        }
    }
예제 #5
0
    public unsafe void Allocate_ReadBackTexture2D_Copy_Full(Device device)
    {
        int[,] source = new int[256, 256];

        fixed(int *p = source)
        {
            new Random(42).NextBytes(new Span <int>(p, source.Length).AsBytes());
        }

        using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source);
        using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(256, 256);

        readOnlyTexture2D.CopyTo(readBackTexture2D);

        Assert.AreEqual(readBackTexture2D.Width, 256);
        Assert.AreEqual(readBackTexture2D.Height, 256);

        fixed(int *p = source)
        {
            for (int i = 0; i < readBackTexture2D.Height; i++)
            {
                Assert.IsTrue(readBackTexture2D.View.GetRowSpan(i).SequenceEqual(new Span <int>(Unsafe.AsPointer(ref source[i, 0]), source.GetLength(1))));
            }
        }
    }
예제 #6
0
    /// <summary>
    /// Saves a texture to a specified buffer writer.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="writer">The buffer writer to save the image to.</param>
    /// <param name="format">The target image format to use.</param>
    public static void Save <T>(this ReadBackTexture2D <T> texture, IBufferWriter <byte> writer, ImageFormat format)
        where T : unmanaged
    {
        Guard.IsNotNull(writer, nameof(writer));

        WICHelper.Instance.SaveTexture(texture.View, writer, format);
    }
예제 #7
0
 public void AddObject(ReadBackTexture2D texture)
 {
     lock (readBackTextureList)
     {
         readBackTextureList.Add(texture);
     }
 }
예제 #8
0
    /// <summary>
    /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance.
    /// </summary>
    /// <typeparam name="T">The type of items stored on the texture.</typeparam>
    /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param>
    /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param>
    public static void CopyTo <T>(this Texture2D <T> source, ReadBackTexture2D <T> destination)
        where T : unmanaged
    {
        Guard.IsNotNull(source);
        Guard.IsNotNull(destination);

        source.CopyTo(destination, 0, 0, 0, 0, source.Width, source.Height);
    }
예제 #9
0
    /// <summary>
    /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance.
    /// </summary>
    /// <typeparam name="T">The type of items stored on the texture.</typeparam>
    /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param>
    /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param>
    /// <param name="sourceOffsetX">The horizontal offset in the source texture.</param>
    /// <param name="sourceOffsetY">The vertical offset in the source texture.</param>
    /// <param name="destinationOffsetX">The horizontal offset in the destination texture.</param>
    /// <param name="destinationOffsetY">The vertical offset in the destination texture.</param>
    /// <param name="width">The width of the memory area to copy.</param>
    /// <param name="height">The height of the memory area to copy.</param>
    public static void CopyTo <T>(this Texture2D <T> source, ReadBackTexture2D <T> destination, int sourceOffsetX, int sourceOffsetY, int destinationOffsetX, int destinationOffsetY, int width, int height)
        where T : unmanaged
    {
        Guard.IsNotNull(source);
        Guard.IsNotNull(destination);

        source.CopyTo(destination, sourceOffsetX, sourceOffsetY, destinationOffsetX, destinationOffsetY, width, height);
    }
    /// <summary>
    /// Saves a texture to a specified file.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="filename">The filename of the image file to save.</param>
    public static void Save <T>(this Texture2D <T> texture, ReadOnlySpan <char> filename)
        where T : unmanaged
    {
        using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        WICHelper.Instance.SaveTexture(readback.View, filename);
    }
    /// <summary>
    /// Saves a texture to a specified buffer writer.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="writer">The buffer writer to save the image to.</param>
    /// <param name="format">The target image format to use.</param>
    public static void Save <T>(this Texture2D <T> texture, IBufferWriter <byte> writer, ImageFormat format)
        where T : unmanaged
    {
        Guard.IsNotNull(writer, nameof(writer));

        using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        WICHelper.Instance.SaveTexture(readback.View, writer, format);
    }
    /// <summary>
    /// Saves a texture to a specified stream.
    /// </summary>
    /// <typeparam name="T">The type of items to store in the texture.</typeparam>
    /// <param name="texture">The texture to save to an image.</param>
    /// <param name="stream">The stream to save the image to.</param>
    /// <param name="format">The target image format to use.</param>
    public static void Save <T>(this Texture2D <T> texture, Stream stream, ImageFormat format)
        where T : unmanaged
    {
        Guard.IsNotNull(stream, nameof(stream));

        using ReadBackTexture2D <T> readback = texture.GraphicsDevice.AllocateReadBackTexture2D <T>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        WICHelper.Instance.SaveTexture(readback.View, stream, format);
    }
예제 #13
0
    public void SaveRgba32AsJpeg_ToBufferWriter_WithReadBackTexture_WithNullBufferWriter(Device device, Type textureType)
    {
        string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging", "city.jpg");

        using Texture2D <Rgba32> texture          = device.Get().LoadTexture2D <Rgba32, float4>(textureType, typeof(string), path);
        using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        readback.Save((IBufferWriter <byte>)null !, ImageFormat.Jpeg);
    }
예제 #14
0
        /// <summary>
        /// Reads the contents of the specified range from the current <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance.
        /// </summary>
        /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param>
        /// <param name="destinationX">The horizontal offset within <paramref name="destination"/>.</param>
        /// <param name="destinationY">The vertical offset within <paramref name="destination"/>.</param>
        /// <param name="sourceX">The horizontal offset in the source texture.</param>
        /// <param name="sourceY">The vertical offset in the source texture.</param>
        /// <param name="width">The width of the memory area to copy.</param>
        /// <param name="height">The height of the memory area to copy.</param>
        internal void CopyTo(ReadBackTexture2D <T> destination, int destinationX, int destinationY, int sourceX, int sourceY, int width, int height)
        {
            GraphicsDevice.ThrowIfDisposed();

            ThrowIfDisposed();

            destination.ThrowIfDeviceMismatch(GraphicsDevice);
            destination.ThrowIfDisposed();

            Guard.IsInRange(destinationX, 0, destination.Width, nameof(destinationX));
            Guard.IsInRange(destinationY, 0, destination.Height, nameof(destinationY));
            Guard.IsInRange(sourceX, 0, Width, nameof(sourceX));
            Guard.IsInRange(sourceY, 0, Height, nameof(sourceY));
            Guard.IsBetweenOrEqualTo(width, 1, Width, nameof(width));
            Guard.IsBetweenOrEqualTo(height, 1, Height, nameof(height));
            Guard.IsBetweenOrEqualTo(width, 1, destination.Width, nameof(width));
            Guard.IsBetweenOrEqualTo(height, 1, destination.Height, nameof(height));
            Guard.IsBetweenOrEqualTo(destinationX + width, 1, destination.Width, nameof(destinationX));
            Guard.IsBetweenOrEqualTo(destinationY + height, 1, destination.Height, nameof(destinationY));
            Guard.IsLessThanOrEqualTo(sourceX + width, Width, nameof(sourceX));
            Guard.IsLessThanOrEqualTo(sourceY + height, Height, nameof(sourceY));

            using CommandList copyCommandList = new(GraphicsDevice, this.d3D12CommandListType);

            if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE)
            {
                copyCommandList.D3D12GraphicsCommandList->ResourceBarrier(D3D12Resource, this.d3D12ResourceState, D3D12_RESOURCE_STATE_COPY_SOURCE);
            }

            fixed(D3D12_PLACED_SUBRESOURCE_FOOTPRINT *d3D12PlacedSubresourceFootprintDestination = &destination.D3D12PlacedSubresourceFootprint)
            {
                copyCommandList.D3D12GraphicsCommandList->CopyTextureRegion(
                    d3D12ResourceDestination: destination.D3D12Resource,
                    d3D12PlacedSubresourceFootprintDestination,
                    (uint)destinationX,
                    (uint)destinationY,
                    destinationZ: 0,
                    d3D12ResourceSource: D3D12Resource,
                    (uint)sourceX,
                    (uint)sourceY,
                    sourceZ: 0,
                    (uint)width,
                    (uint)height,
                    1);
            }

            if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE)
            {
                copyCommandList.D3D12GraphicsCommandList->ResourceBarrier(D3D12Resource, D3D12_RESOURCE_STATE_COPY_SOURCE, this.d3D12ResourceState);
            }

            copyCommandList.ExecuteAndWaitForCompletion();
        }
예제 #15
0
    public void SaveRgba32AsJpeg_ToFile_WithReadBackTexture(Device device, Type textureType, Type inputType)
    {
        string path         = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging");
        string expectedPath = Path.Combine(path, "city.jpg");
        string actualPath   = Path.Combine(path, "city_rgba32_saved.jpg");

        using Texture2D <Rgba32> texture          = device.Get().LoadTexture2D <Rgba32, float4>(textureType, inputType, expectedPath);
        using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        readback.Save(inputType, actualPath);

        TolerantImageComparer.AssertEqual(expectedPath, actualPath, 0.00001023f);
    }
예제 #16
0
    public void SaveRgba32AsJpeg_ToBufferWriter_WithReadBackTexture(Device device, Type textureType)
    {
        string path         = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) !, "Imaging");
        string expectedPath = Path.Combine(path, "city.jpg");
        string actualPath   = Path.Combine(path, "city_rgba32_saved.jpg");

        using Texture2D <Rgba32> texture          = device.Get().LoadTexture2D <Rgba32, float4>(textureType, typeof(string), expectedPath);
        using ReadBackTexture2D <Rgba32> readback = device.Get().AllocateReadBackTexture2D <Rgba32>(texture.Width, texture.Height);

        texture.CopyTo(readback);

        using (ArrayPoolBufferWriter <byte> writer = new())
        {
            readback.Save(writer, ImageFormat.Jpeg);

            File.WriteAllBytes(actualPath, writer.WrittenSpan.ToArray());
        }

        TolerantImageComparer.AssertEqual(expectedPath, actualPath, 0.00001023f);
    }
        public void Allocate_ReadBackTexture2D_Copy_Range(Device device, int x, int y, int width, int height)
        {
            int[,] source = new int[2048, 2048];

            for (int i = 0; i < 2048; i++)
            {
                new Random(42).NextBytes(source.GetRowSpan(i).AsBytes());
            }

            using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source);
            using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(2048, 2048);

            readOnlyTexture2D.CopyTo(readBackTexture2D, x, y, width, height);

            for (int i = 0; i < height; i++)
            {
                Span <int> sourceRow      = source.GetRowSpan(i + y).Slice(x, width);
                Span <int> destinationRow = readBackTexture2D.View.GetRowSpan(i).Slice(0, width);

                Assert.IsTrue(sourceRow.SequenceEqual(destinationRow));
            }
        }
        public void Allocate_ReadBackTexture2D_Copy_Full(Device device)
        {
            int[,] source = new int[256, 256];

            for (int i = 0; i < 256; i++)
            {
                new Random(42).NextBytes(source.GetRowSpan(i).AsBytes());
            }

            using ReadOnlyTexture2D <int> readOnlyTexture2D = device.Get().AllocateReadOnlyTexture2D(source);
            using ReadBackTexture2D <int> readBackTexture2D = device.Get().AllocateReadBackTexture2D <int>(256, 256);

            readOnlyTexture2D.CopyTo(readBackTexture2D);

            Assert.AreEqual(readBackTexture2D.Width, 256);
            Assert.AreEqual(readBackTexture2D.Height, 256);

            for (int i = 0; i < readBackTexture2D.Height; i++)
            {
                Assert.IsTrue(readBackTexture2D.View.GetRowSpan(i).SequenceEqual(source.GetRowSpan(i)));
            }
        }
예제 #19
0
 public void UnsafeAdd(ReadBackTexture2D texture)
 {
     readBackTextureList.Add(texture);
 }
예제 #20
0
 /// <summary>
 /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance.
 /// </summary>
 /// <typeparam name="T">The type of items stored on the texture.</typeparam>
 /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param>
 /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param>
 public static void CopyFrom <T>(this ReadBackTexture2D <T> destination, Texture2D <T> source)
     where T : unmanaged
 {
     source.CopyTo(destination, 0, 0, 0, 0, source.Width, source.Height);
 }
예제 #21
0
 /// <summary>
 /// Reads the contents of a <see cref="Texture2D{T}"/> instance and writes them into a target <see cref="ReadBackTexture2D{T}"/> instance.
 /// </summary>
 /// <typeparam name="T">The type of items stored on the texture.</typeparam>
 /// <param name="destination">The target <see cref="ReadBackTexture2D{T}"/> instance to write data to.</param>
 /// <param name="source">The input <see cref="Texture2D{T}"/> instance to read data from.</param>
 /// <param name="sourceOffsetX">The horizontal offset in the source texture.</param>
 /// <param name="sourceOffsetY">The vertical offset in the source texture.</param>
 /// <param name="destinationOffsetX">The horizontal offset in the destination texture.</param>
 /// <param name="destinationOffsetY">The vertical offset in the destination texture.</param>
 /// <param name="width">The width of the memory area to copy.</param>
 /// <param name="height">The height of the memory area to copy.</param>
 public static void CopyFrom <T>(this ReadBackTexture2D <T> destination, Texture2D <T> source, int sourceOffsetX, int sourceOffsetY, int destinationOffsetX, int destinationOffsetY, int width, int height)
     where T : unmanaged
 {
     source.CopyTo(destination, sourceOffsetX, sourceOffsetY, destinationOffsetX, destinationOffsetY, width, height);
 }