public unsafe void ShaderWithAssemblyLevelAttributesAndOverriddenOptions() { ReadOnlyMemory <byte> bytecode = D2D1PixelShader.LoadBytecode <ShaderWithOverriddenOptions>(); Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out MemoryManager <byte>?manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); D2D1PixelShader.LoadBytecode <ShaderWithOverriddenOptions>( shaderProfile: D2D1ShaderProfile.PixelShader41, options: D2D1CompileOptions.Debug | D2D1CompileOptions.AvoidFlowControl | D2D1CompileOptions.PartialPrecision); Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); }
public static void MemoryPoolPinBadOffsetTooLarge() { MemoryPool <int> pool = MemoryPool <int> .Shared; IMemoryOwner <int> block = pool.Rent(10); Memory <int> memory = block.Memory; Span <int> sp = memory.Span; Assert.Equal(memory.Length, sp.Length); int elementIndex = memory.Length + 1; Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(memory, out MemoryManager <int> manager)); Assert.Throws <ArgumentOutOfRangeException>(() => manager.Pin(elementIndex: elementIndex)); }
public unsafe void ShaderWithAssemblyLevelAttributesAndOverriddenProfile() { ReadOnlyMemory <byte> bytecode = D2D1PixelShader.LoadBytecode <ShaderWithOverriddenProfile>(); Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out MemoryManager <byte>?manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); D2D1PixelShader.LoadBytecode <ShaderWithOverriddenProfile>( shaderProfile: D2D1ShaderProfile.PixelShader50, options: D2D1CompileOptions.IeeeStrictness | D2D1CompileOptions.OptimizationLevel2 | D2D1CompileOptions.PartialPrecision); Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); }
public static void TryGetMemoryManager() { int[] array = new int[10]; MemoryManager <int> originalManager = new CustomMemoryForTest <int>(array); ReadOnlyMemory <int> memory = originalManager.Memory; Assert.True(MemoryMarshal.TryGetMemoryManager(memory, out CustomMemoryForTest <int> customManager)); Assert.Same(originalManager, customManager); Assert.True(MemoryMarshal.TryGetMemoryManager(memory, out MemoryManager <int> manager)); Assert.Same(originalManager, manager); Assert.False(MemoryMarshal.TryGetMemoryManager(memory, out OtherMemoryForTest <int> notManager)); Assert.Null(notManager); }
public unsafe void ShaderWithAssemblyLevelAttributes() { ReadOnlyMemory <byte> bytecode = D2D1PixelShader.LoadBytecode <ShaderWithNoCompileAttributes>(); // Verify the shader was precompiled Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out MemoryManager <byte>?manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); D2D1PixelShader.LoadBytecode <ShaderWithNoCompileAttributes>( shaderProfile: D2D1ShaderProfile.PixelShader41, options: D2D1CompileOptions.IeeeStrictness | D2D1CompileOptions.OptimizationLevel2 | D2D1CompileOptions.PartialPrecision); // Verify the expected options were used Assert.IsTrue(MemoryMarshal.TryGetMemoryManager(bytecode, out manager)); Assert.AreEqual("PinnedBufferMemoryManager", manager !.GetType().Name); }
public static void MemoryPoolTryGetArray() { using (IMemoryOwner <int> block = MemoryPool <int> .Shared.Rent(42)) { Memory <int> memory = block.Memory; bool success = MemoryMarshal.TryGetArray(memory, out ArraySegment <int> arraySegment); Assert.True(success); Assert.Equal(memory.Length, arraySegment.Count); unsafe { Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(memory, out MemoryManager <int> manager)); void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(manager.GetSpan())); fixed(int *pArray = arraySegment.Array) { Assert.Equal((IntPtr)pSpan, (IntPtr)pArray); } } } }
public static void EachRentalIsUniqueUntilDisposed() { MemoryPool <int> pool = MemoryPool <int> .Shared; List <IMemoryOwner <int> > priorBlocks = new List <IMemoryOwner <int> >(); Random r = new Random(42); List <int> testInputs = new List <int>(); for (int i = 0; i < 100; i++) { testInputs.Add((Math.Abs(r.Next() % 1000)) + 1); } foreach (int minBufferSize in testInputs) { IMemoryOwner <int> newBlock = pool.Rent(minBufferSize); Memory <int> memory = newBlock.Memory; Assert.True(memory.Length >= minBufferSize); Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(newBlock.Memory, out MemoryManager <int> newManager)); foreach (IMemoryOwner <int> prior in priorBlocks) { Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(prior.Memory, out MemoryManager <int> priorManager)); using (MemoryHandle priorMemoryHandle = priorManager.Pin()) { using (MemoryHandle newMemoryHandle = newManager.Pin()) { unsafe { Assert.NotEqual((IntPtr)priorMemoryHandle.Pointer, (IntPtr)newMemoryHandle.Pointer); } } } } priorBlocks.Add(newBlock); } foreach (IMemoryOwner <int> prior in priorBlocks) { Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(prior.Memory, out MemoryManager <int> priorManager)); priorManager.Unpin(); prior.Dispose(); } }
public static void MemoryPoolPin(int elementIndex) { MemoryPool <int> pool = MemoryPool <int> .Shared; using (IMemoryOwner <int> block = pool.Rent(10)) { Memory <int> memory = block.Memory; Span <int> sp = memory.Span; Assert.Equal(memory.Length, sp.Length); Assert.True(MemoryMarshal.TryGetMemoryManager <int, MemoryManager <int> >(memory, out MemoryManager <int> manager)); using (MemoryHandle newMemoryHandle = manager.Pin(elementIndex: elementIndex)) { unsafe { void *pSpan = Unsafe.AsPointer(ref MemoryMarshal.GetReference(sp.Slice(elementIndex))); Assert.Equal((IntPtr)pSpan, ((IntPtr)newMemoryHandle.Pointer)); } } } }
public RetainedMemory(Memory <T> memory, bool pin = true) // TODO pin param added later and before it behaved like with true, but better to change to false and review usage { if (MemoryMarshal.TryGetMemoryManager <T, RetainableMemory <T> >(memory, out var manager)) { if (!manager.IsPinned && pin) { // TODO review. This uses implementation detail of RetainableMemory: // if pointer is null then it is an non-pinned array for which we did not create // a GCHandle (very expensive). Call to Pin() checks if pointer is null and // creates a GCHandle + pointer. Try to avoid pinning non-pooled ArrayMemory // because it is very expensive. manager.Pin(); } else { manager.Increment(); } _manager = manager; _offset = 0; _length = memory.Length; } else if (MemoryMarshal.TryGetArray <T>(memory, out var segment)) { _manager = ArrayMemory <T> .Create(segment.Array, segment.Offset, segment.Count, externallyOwned : true, pin); _manager.Increment(); _offset = 0; _length = _manager.Length; } else { ThrowNotSupportedMemoryType(); _manager = default; _offset = 0; _length = 0; } #if DETECT_LEAKS _finalizeChecker = new PanicOnFinalize(); #endif }
public void Test_MemoryExtensions_FromMemoryManager_CastFromByteAndBack_WithSlice() { // Just like the one above, but with the slice var data = new ArrayMemoryManager <byte>(512); Memory <byte> memoryOfBytes = data.Memory.Slice(128, 128); Memory <float> memoryOfFloats = memoryOfBytes.Cast <byte, float>(); Memory <byte> memoryBack = memoryOfFloats.Cast <float, byte>(); Assert.AreEqual(memoryOfBytes.Length, memoryBack.Length); // Here we also need to validate that the offset was maintained Assert.IsTrue(MemoryMarshal.TryGetMemoryManager <byte, ArrayMemoryManager <byte> >(memoryBack, out var manager, out var start, out var length)); Assert.AreSame(manager !, data); Assert.AreEqual(start, 128); Assert.AreEqual(length, 128); Assert.IsTrue(memoryOfBytes.Equals(memoryBack)); Span <byte> span1 = memoryOfBytes.Span; Span <byte> span2 = memoryBack.Span; Assert.IsTrue(span1 == span2); }
public void Test_MemoryExtensions_FromMemoryManager_CastFromByteAndBack() { // Equivalent to the one with an array, but with a memory manager var data = new ArrayMemoryManager <byte>(128); Memory <byte> memoryOfBytes = data; Memory <float> memoryOfFloats = memoryOfBytes.Cast <byte, float>(); Memory <byte> memoryBack = memoryOfFloats.Cast <float, byte>(); Assert.AreEqual(memoryOfBytes.Length, memoryBack.Length); // Here we expect to get back the original memory manager, due to the same optimization we // checked for when using an array. We need to check they're the same, and the other parameters. Assert.IsTrue(MemoryMarshal.TryGetMemoryManager <byte, ArrayMemoryManager <byte> >(memoryBack, out var manager, out var start, out var length)); Assert.AreSame(manager !, data); Assert.AreEqual(start, 0); Assert.AreEqual(length, 128); Assert.IsTrue(memoryOfBytes.Equals(memoryBack)); Span <byte> span1 = memoryOfBytes.Span; Span <byte> span2 = memoryBack.Span; Assert.IsTrue(span1 == span2); }
public static Stream Create(ReadOnlyMemory <byte> memory, bool isReadOnly) { if (memory.IsEmpty) { // Return an empty stream if the memory was empty return(new MemoryStream <ArrayOwner>(ArrayOwner.Empty, isReadOnly)); } if (MemoryMarshal.TryGetArray(memory, out ArraySegment <byte> segment)) { var arraySpanSource = new ArrayOwner(segment.Array !, segment.Offset, segment.Count); return(new MemoryStream <ArrayOwner>(arraySpanSource, isReadOnly)); } if (MemoryMarshal.TryGetMemoryManager <byte, MemoryManager <byte> >(memory, out var memoryManager, out int start, out int length)) { MemoryManagerOwner memoryManagerSpanSource = new MemoryManagerOwner(memoryManager, start, length); return(new MemoryStream <MemoryManagerOwner>(memoryManagerSpanSource, isReadOnly)); } return(ThrowNotSupportedExceptionForInvalidMemory()); }