/// <inheritdoc/> public override void GetData(Span <T> span, int offset, int count) { if (IsPaddingPresent) { // Create the temporary array byte[] temporaryArray = ArrayPool <byte> .Shared.Rent(count *PaddedElementSizeInBytes); Span <byte> temporarySpan = temporaryArray.AsSpan(0, count * PaddedElementSizeInBytes); // Copy the padded data to the temporary array Map(0); MemoryHelper.Copy(MappedResource, offset * PaddedElementSizeInBytes, temporarySpan, 0, count * PaddedElementSizeInBytes); Unmap(0); ref byte tin = ref temporarySpan.GetPinnableReference(); ref T tout = ref span.GetPinnableReference();
private void EnsureCpacity(int n) { if (n >= _capacity) { int newCapacity = _capacity * 2; int *newEntries = (int *)HeapAllocator.New(newCapacity * sizeof(int)); MemoryHelper.Copy((byte *)_entries, (byte *)newEntries, _capacity * sizeof(int)); HeapAllocator.Free((byte *)_entries); for (int i = _capacity; i < newCapacity; i++) { newEntries[i] = i + _idOffset; } _entries = newEntries; _capacity = newCapacity; } }
/// <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(); } }
/// <inheritdoc/> public override unsafe void CopyFrom(Buffer <T> source) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); source.ThrowIfDeviceMismatch(GraphicsDevice); source.ThrowIfDisposed(); Guard.IsLessThanOrEqualTo(source.Length, Length, nameof(Length)); if (source is ConstantBuffer <T> buffer) { using ID3D12ResourceMap sourceMap = buffer.D3D12Resource->Map(); using ID3D12ResourceMap destinationMap = D3D12Resource->Map(); if (IsPaddingPresent) { MemoryHelper.Copy <T>( sourceMap.Pointer, destinationMap.Pointer, 0, (uint)source.Length, (uint)GetPaddedSize(), isPaddingInSourceToo: true); } else { MemoryHelper.Copy( sourceMap.Pointer, 0, (uint)source.Length, (uint)sizeof(T), destinationMap.Pointer); } } else { CopyFromWithCpuBuffer(source); } }
public static string GetString(this byte[] value) { if (value == null) { return(null); } int length = value.Length; char[] buf = new char[length / MemoryHelper.CharSizeInBytes]; unsafe { fixed(byte *src = value) fixed(char *dst = buf) { MemoryHelper.Copy(dst, src, length); } } return(new string(buf)); }
public static char[] GetChars(this string value) { if (value == null) { return(null); } int length = value.Length; char[] buf = new char[length]; unsafe { fixed(char *src = value) fixed(char *dst = buf) { MemoryHelper.Copy(dst, src, length * MemoryHelper.CharSizeInBytes); } } return(buf); }
public static byte[] GetBytes(this char[] value) { if (value == null) { return(null); } int length = value.Length; byte[] buf = new byte[length * MemoryHelper.CharSizeInBytes]; unsafe { fixed(char *src = value) fixed(byte *dst = buf) { MemoryHelper.Copy(dst, src, buf.Length); } } return(buf); }
/// <summary> /// Reads the contents of the specified range from the current <see cref="StructuredBuffer{T}"/> instance and writes them into a target <see cref="ReadBackBuffer{T}"/> instance. /// </summary> /// <param name="destination">The target <see cref="ReadBackBuffer{T}"/> instance to write data to.</param> /// <param name="destinationOffset">The starting offset within <paramref name="destination"/> to write data to.</param> /// <param name="length">The number of items to read.</param> /// <param name="offset">The offset to start reading data from.</param> internal unsafe void CopyTo(ReadBackBuffer <T> destination, int destinationOffset, int length, int offset) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); destination.ThrowIfDeviceMismatch(GraphicsDevice); destination.ThrowIfDisposed(); Guard.IsInRange(offset, 0, Length, nameof(offset)); Guard.IsLessThanOrEqualTo(offset + length, Length, nameof(length)); Guard.IsInRange(destinationOffset, 0, destination.Length, nameof(destinationOffset)); Guard.IsLessThanOrEqualTo(destinationOffset + length, destination.Length, nameof(length)); if (GraphicsDevice.IsCacheCoherentUMA) { using ID3D12ResourceMap resource = D3D12Resource->Map(); MemoryHelper.Copy( resource.Pointer, (uint)offset, (uint)length, (uint)sizeof(T), destination.MappedData + destinationOffset); } else { ulong byteDestinationOffset = (uint)destinationOffset * (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(destination.D3D12Resource, byteDestinationOffset, D3D12Resource, byteOffset, 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(); } }
protected void SetArray(int index, byte *source, int lenght) { if (index >= _descriptor.VariablePartCount) { throw new Exception("Index is out of variable parts records."); } InBlockArrayRecord *arrayRecords = ArrayRecords; int delta = lenght - arrayRecords[index].Lenght; if (delta != 0) { if (ChangeRangeLenght(arrayRecords[index].Offset, arrayRecords[index].Lenght, lenght)) { arrayRecords = ArrayRecords; } } arrayRecords[index].Lenght = lenght; MemoryHelper.Copy(source, GetArray(index).Address, lenght); for (int i = index + 1; i < _descriptor.VariablePartCount; i++) { arrayRecords[i].Offset += delta; } }
/// <inheritdoc/> internal override unsafe void CopyTo(ref T destination, int offset, int length) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); Guard.IsBetweenOrEqualTo(length, 0, Length); Guard.IsInRange(offset, 0, Length); Guard.IsLessThanOrEqualTo(offset + length, Length, nameof(offset)); using ID3D12ResourceMap resource = D3D12Resource->Map(); fixed(void *destinationPointer = &destination) { MemoryHelper.Copy <T>( source: resource.Pointer, destination: destinationPointer, sourceElementOffset: (uint)offset, destinationElementOffset: 0, sourceElementPitchInBytes: (uint)GetPaddedSize(), destinationElementPitchInBytes: (uint)sizeof(T), count: (uint)length); } }
/// <summary> /// Writes the contents of a given memory area to a specified area of the current <see cref="Texture2D{T}"/> instance. /// </summary> /// <param name="source">The input memory area to read data from.</param> /// <param name="size">The size of the memory area to read data from.</param> /// <param name="x">The horizontal offset in the destination texture.</param> /// <param name="y">The vertical offset in the destination texture.</param> /// <param name="width">The width of the memory area to write to.</param> /// <param name="height">The height of the memory area to write to.</param> internal void CopyFrom(ref T source, int size, int x, int y, int width, int height) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); Guard.IsInRange(x, 0, Width, nameof(x)); Guard.IsInRange(y, 0, Height, nameof(y)); Guard.IsBetweenOrEqualTo(width, 1, Width, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, Height, nameof(height)); Guard.IsLessThanOrEqualTo(x + width, Width, nameof(x)); Guard.IsLessThanOrEqualTo(y + height, Height, nameof(y)); Guard.IsGreaterThanOrEqualTo(size, (nint)width * height, nameof(size)); GraphicsDevice.D3D12Device->GetCopyableFootprint( DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, out D3D12_PLACED_SUBRESOURCE_FOOTPRINT d3D12PlacedSubresourceFootprintSource, out ulong rowSizeInBytes, out ulong totalSizeInBytes); using UniquePtr <D3D12MA_Allocation> allocation = default; using ComPtr <ID3D12Resource> d3D12Resource = default; if (GraphicsDevice.IsCacheCoherentUMA) { *&d3D12Resource = GraphicsDevice.D3D12Device->CreateCommittedResource(ResourceType.Upload, AllocationMode.Default, totalSizeInBytes, true); } else { *&allocation = GraphicsDevice.Allocator->CreateResource(ResourceType.Upload, AllocationMode.Default, totalSizeInBytes); *&d3D12Resource = new ComPtr <ID3D12Resource>(allocation.Get()->GetResource()); } using (ID3D12ResourceMap resource = d3D12Resource.Get()->Map()) fixed(void *sourcePointer = &source) { MemoryHelper.Copy( sourcePointer, resource.Pointer, (uint)height, rowSizeInBytes, d3D12PlacedSubresourceFootprintSource.Footprint.RowPitch); } 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_DEST); } copyCommandList.D3D12GraphicsCommandList->CopyTextureRegion( d3D12ResourceDestination: D3D12Resource, destinationX: (uint)x, destinationY: (uint)y, destinationZ: 0, d3D12ResourceSource: d3D12Resource.Get(), &d3D12PlacedSubresourceFootprintSource, sourceX: 0, sourceY: 0, sourceZ: 0, (uint)width, (uint)height, depth: 1); if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE) { copyCommandList.D3D12GraphicsCommandList->ResourceBarrier(D3D12Resource, D3D12_RESOURCE_STATE_COPY_DEST, this.d3D12ResourceState); } copyCommandList.ExecuteAndWaitForCompletion(); }
/// <summary> /// Reads the contents of the specified range from the current <see cref="Texture2D{T}"/> instance and writes them into a target memory area. /// </summary> /// <param name="destination">The target memory area to write data to.</param> /// <param name="size">The size of the target memory area 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="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(ref T destination, int size, int sourceOffsetX, int sourceOffsetY, int width, int height) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); Guard.IsInRange(sourceOffsetX, 0, Width, nameof(sourceOffsetX)); Guard.IsInRange(sourceOffsetY, 0, Height, nameof(sourceOffsetY)); Guard.IsBetweenOrEqualTo(width, 1, Width, nameof(width)); Guard.IsBetweenOrEqualTo(height, 1, Height, nameof(height)); Guard.IsLessThanOrEqualTo(sourceOffsetX + width, Width, nameof(sourceOffsetX)); Guard.IsLessThanOrEqualTo(sourceOffsetY + height, Height, nameof(sourceOffsetY)); Guard.IsGreaterThanOrEqualTo(size, (nint)width * height, nameof(size)); GraphicsDevice.D3D12Device->GetCopyableFootprint( DXGIFormatHelper.GetForType <T>(), (uint)width, (uint)height, out D3D12_PLACED_SUBRESOURCE_FOOTPRINT d3D12PlacedSubresourceFootprintDestination, out ulong rowSizeInBytes, out ulong totalSizeInBytes); #if NET6_0_OR_GREATER using ComPtr <D3D12MA_Allocation> allocation = GraphicsDevice.Allocator->CreateResource( GraphicsDevice.Pool, ResourceType.ReadBack, AllocationMode.Default, totalSizeInBytes); using ComPtr <ID3D12Resource> d3D12Resource = new(allocation.Get()->GetResource()); #else using ComPtr <ID3D12Resource> d3D12Resource = GraphicsDevice.D3D12Device->CreateCommittedResource( ResourceType.ReadBack, totalSizeInBytes, GraphicsDevice.IsCacheCoherentUMA); #endif using (CommandList copyCommandList = new(GraphicsDevice, this.d3D12CommandListType)) { if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE) { copyCommandList.D3D12GraphicsCommandList->TransitionBarrier(D3D12Resource, this.d3D12ResourceState, D3D12_RESOURCE_STATE_COPY_SOURCE); } copyCommandList.D3D12GraphicsCommandList->CopyTextureRegion( d3D12ResourceDestination: d3D12Resource.Get(), &d3D12PlacedSubresourceFootprintDestination, destinationX: 0, destinationY: 0, destinationZ: 0, d3D12ResourceSource: D3D12Resource, sourceX: (uint)sourceOffsetX, sourceY: (uint)sourceOffsetY, sourceZ: 0, (uint)width, (uint)height, depth: 1); if (copyCommandList.D3D12CommandListType == D3D12_COMMAND_LIST_TYPE_COMPUTE) { copyCommandList.D3D12GraphicsCommandList->TransitionBarrier(D3D12Resource, D3D12_RESOURCE_STATE_COPY_SOURCE, this.d3D12ResourceState); } copyCommandList.ExecuteAndWaitForCompletion(); } using ID3D12ResourceMap resource = d3D12Resource.Get()->Map(); fixed(void *destinationPointer = &destination) { MemoryHelper.Copy( resource.Pointer, (uint)height, rowSizeInBytes, d3D12PlacedSubresourceFootprintDestination.Footprint.RowPitch, destinationPointer); } }
/// <inheritdoc/> internal override unsafe void CopyTo(ref T destination, int sourceOffset, int count) { GraphicsDevice.ThrowIfDisposed(); ThrowIfDisposed(); Guard.IsBetweenOrEqualTo(count, 0, Length); Guard.IsInRange(sourceOffset, 0, Length); Guard.IsLessThanOrEqualTo(sourceOffset + count, Length, nameof(sourceOffset)); if (GraphicsDevice.IsCacheCoherentUMA) { using ID3D12ResourceMap resource = D3D12Resource->Map(); fixed(void *destinationPointer = &destination) { MemoryHelper.Copy <T>( source: resource.Pointer, destination: destinationPointer, sourceElementOffset: (uint)sourceOffset, destinationElementOffset: 0, sourceElementPitchInBytes: (uint)sizeof(T), destinationElementPitchInBytes: (uint)sizeof(T), count: (uint)count); } } else { nint byteOffset = (nint)sourceOffset * sizeof(T); nint byteLength = count * sizeof(T); #if NET6_0_OR_GREATER using ComPtr <D3D12MA_Allocation> allocation = GraphicsDevice.Allocator->CreateResource(null, ResourceType.ReadBack, AllocationMode.Default, (ulong)byteLength); #else using ComPtr <ID3D12Resource> d3D12Resource = GraphicsDevice.D3D12Device->CreateCommittedResource( ResourceType.ReadBack, (ulong)byteLength, GraphicsDevice.IsCacheCoherentUMA); #endif using (CommandList copyCommandList = new(GraphicsDevice, D3D12_COMMAND_LIST_TYPE_COPY)) { #if NET6_0_OR_GREATER copyCommandList.D3D12GraphicsCommandList->CopyBufferRegion(allocation.Get()->GetResource(), 0, D3D12Resource, (ulong)byteOffset, (ulong)byteLength); #else copyCommandList.D3D12GraphicsCommandList->CopyBufferRegion(d3D12Resource.Get(), 0, D3D12Resource, (ulong)byteOffset, (ulong)byteLength); #endif copyCommandList.ExecuteAndWaitForCompletion(); } #if NET6_0_OR_GREATER using ID3D12ResourceMap resource = allocation.Get()->GetResource()->Map(); #else using ID3D12ResourceMap resource = d3D12Resource.Get()->Map(); #endif fixed(void *destinationPointer = &destination) { MemoryHelper.Copy <T>( source: resource.Pointer, destination: destinationPointer, sourceElementOffset: 0, destinationElementOffset: 0, sourceElementPitchInBytes: (uint)sizeof(T), destinationElementPitchInBytes: (uint)sizeof(T), count: (uint)count); } } }
private bool ParseMeshData(Assimp.Scene scene) { if (!scene.HasMeshes) { return(false); } Assimp.Mesh[] meshes = scene.Meshes; if (meshes.Length == 0) { return(false); } m_meshData = new MeshData[meshes.Length]; m_meshMatInfo = new MeshMaterialInfo[meshes.Length]; for (int i = 0; i < meshes.Length; i++) { Assimp.Mesh mesh = meshes[i]; MeshData md = new MeshData(); MeshMaterialInfo info = new MeshMaterialInfo(); if (mesh.HasVertices) { Assimp.Vector3D[] assimpPos = mesh.Vertices; DataBuffer <Vector3> positions = new DataBuffer <Vector3>(assimpPos.Length); MemoryHelper.Copy(assimpPos, positions.Buffer, Vector3.SizeInBytes * assimpPos.Length); md.Positions = positions; } if (mesh.HasNormals) { Assimp.Vector3D[] assimpNorms = mesh.Normals; DataBuffer <Vector3> normals = new DataBuffer <Vector3>(assimpNorms.Length); MemoryHelper.Copy(assimpNorms, normals.Buffer, Vector3.SizeInBytes * assimpNorms.Length); md.Normals = normals; info.HasNormals = true; } if (mesh.HasTangentBasis) { Assimp.Vector3D[] assimpTangs = mesh.Tangents; Assimp.Vector3D[] assimpBitangs = mesh.BiTangents; DataBuffer <Vector3> tangents = new DataBuffer <Vector3>(assimpTangs.Length); DataBuffer <Vector3> bitangents = new DataBuffer <Vector3>(assimpBitangs.Length); MemoryHelper.Copy(assimpTangs, tangents.Buffer, Vector3.SizeInBytes * assimpTangs.Length); MemoryHelper.Copy(assimpBitangs, bitangents.Buffer, Vector3.SizeInBytes * assimpBitangs.Length); md.Tangents = tangents; md.Binormals = bitangents; info.HasTangentBasis = true; } if (mesh.HasVertexColors(0)) { Assimp.Color4D[] assimpColors = mesh.GetVertexColors(0); md.Colors = new DataBuffer <Color>(ConvertColors(assimpColors)); info.HasVertexColors = true; } if (mesh.HasTextureCoords(0)) { Assimp.Vector3D[] assimpUV = mesh.GetTextureCoords(0); md.TextureCoordinates = new DataBuffer <Vector2>(ConvertVectors(assimpUV)); info.HasTexCoords = true; } md.Indices = new DataBuffer <int>(mesh.GetIntIndices()); md.Reconstruct(); m_meshMatInfo[i] = info; m_meshData[i] = md; } ParseMaterials(scene); return(true); }