Example #1
0
    /// <summary>
    /// Reads the contents of the specified range from an input <see cref="ReadBackBuffer{T}"/> instance and writes them to the current the current <see cref="StructuredBuffer{T}"/> instance.
    /// </summary>
    /// <param name="source">The input <see cref="UploadBuffer{T}"/> instance to read data from.</param>
    /// <param name="sourceOffset">The starting offset within <paramref name="source"/> to read data from.</param>
    /// <param name="destinationOffset">The offset to start reading writing data to.</param>
    /// <param name="count">The number of items to read.</param>
    internal unsafe void CopyFrom(UploadBuffer <T> source, int sourceOffset, int destinationOffset, int count)
    {
        GraphicsDevice.ThrowIfDisposed();

        ThrowIfDisposed();

        source.ThrowIfDeviceMismatch(GraphicsDevice);
        source.ThrowIfDisposed();

        Guard.IsBetweenOrEqualTo(count, 0, Length);
        Guard.IsBetweenOrEqualTo(count, 0, source.Length);
        Guard.IsInRange(sourceOffset, 0, source.Length);
        Guard.IsLessThanOrEqualTo(sourceOffset + count, source.Length, nameof(sourceOffset));
        Guard.IsInRange(destinationOffset, 0, Length);
        Guard.IsLessThanOrEqualTo(destinationOffset + count, Length, nameof(destinationOffset));

        if (GraphicsDevice.IsCacheCoherentUMA)
        {
            using ID3D12ResourceMap resource = D3D12Resource->Map();

            MemoryHelper.Copy <T>(
                source: source.MappedData,
                destination: resource.Pointer,
                sourceElementOffset: (uint)sourceOffset,
                destinationElementOffset: (uint)destinationOffset,
                sourceElementPitchInBytes: (uint)sizeof(T),
                destinationElementPitchInBytes: (uint)sizeof(T),
                count: (uint)count);
        }
        else
        {
            ulong byteSourceOffset = (uint)sourceOffset * (uint)sizeof(T);
            ulong byteOffset       = (uint)destinationOffset * (uint)sizeof(T);
            ulong byteLength       = (uint)count * (uint)sizeof(T);

            using CommandList copyCommandList = new(GraphicsDevice, D3D12_COMMAND_LIST_TYPE_COPY);

            copyCommandList.D3D12GraphicsCommandList->CopyBufferRegion(D3D12Resource, byteOffset, source.D3D12Resource, byteSourceOffset, byteLength);
            copyCommandList.ExecuteAndWaitForCompletion();
        }
    }
        /// <summary>
        /// Reads the contents of the specified range from an input <see cref="ReadBackBuffer{T}"/> instance and writes them to the current the current <see cref="StructuredBuffer{T}"/> instance.
        /// </summary>
        /// <param name="source">The input <see cref="UploadBuffer{T}"/> instance to read data from.</param>
        /// <param name="sourceOffset">The starting offset within <paramref name="source"/> to read data from.</param>
        /// <param name="length">The number of items to read.</param>
        /// <param name="offset">The offset to start reading writing data to.</param>
        internal unsafe void CopyFrom(UploadBuffer <T> source, int sourceOffset, int length, int offset)
        {
            GraphicsDevice.ThrowIfDisposed();

            ThrowIfDisposed();

            source.ThrowIfDeviceMismatch(GraphicsDevice);
            source.ThrowIfDisposed();

            Guard.IsInRange(offset, 0, Length, nameof(offset));
            Guard.IsLessThanOrEqualTo(offset + length, Length, nameof(length));
            Guard.IsInRange(sourceOffset, 0, source.Length, nameof(sourceOffset));
            Guard.IsLessThanOrEqualTo(sourceOffset + length, source.Length, nameof(length));

            if (GraphicsDevice.IsCacheCoherentUMA)
            {
                using ID3D12ResourceMap resource = D3D12Resource->Map();

                MemoryHelper.Copy(
                    source.MappedData,
                    (uint)sourceOffset,
                    (uint)length,
                    (uint)sizeof(T),
                    (T *)resource.Pointer + offset);
            }
            else
            {
                ulong
                    byteSourceOffset = (uint)sourceOffset * (uint)sizeof(T),
                    byteOffset       = (uint)offset * (uint)sizeof(T),
                    byteLength       = (uint)length * (uint)sizeof(T);

                using CommandList copyCommandList = new(GraphicsDevice, D3D12_COMMAND_LIST_TYPE_COPY);

                copyCommandList.D3D12GraphicsCommandList->CopyBufferRegion(D3D12Resource, byteOffset, source.D3D12Resource, byteSourceOffset, byteLength);
                copyCommandList.ExecuteAndWaitForCompletion();
            }
        }