예제 #1
0
        public UnmanagedBlock Read(int offset = 0, long size = 0)
        {
            var block = new UnmanagedBlock(size);

            Read(block.Pointer, offset, size <= 0 ? Size : size);
            return(block);
        }
예제 #2
0
        public void Read(IntPtr target, int readOffset, long bytesToRead)
        {
            DataBox mappedResource = null;

            try
            {
                Device.ImmediateContext.CopyResource(mHardwareBuffer, mSwapBuffer);
                mappedResource = Device.ImmediateContext.MapSubresource(mSwapBuffer, MapMode.Read, MapFlags.None);

                if (Context.IsDebugModeEnabled)
                {
                    Context.DiagnosticsWriter.WriteDebug(
                        "Reading {2:###,###,###,###,###,##0} bytes from staging buffer (0x{0:X16}+{3:X8}) into RAM (0x{1:X16})",
                        mappedResource.Data.DataPointer.ToInt64(),
                        target.ToInt64(),
                        bytesToRead,
                        readOffset);
                }

                UnmanagedBlock.Copy(mappedResource.Data.DataPointer, target, readOffset, 0, bytesToRead);
            }
            finally
            {
                if (mappedResource != null)
                {
                    Device.ImmediateContext.UnmapSubresource(mSwapBuffer, 0);
                }
            }
        }
예제 #3
0
        protected override IEnumerable <object> Deconstruct(object value)
        {
            var structureType = CreateClrType();
            var structureSize = Marshal.SizeOf(structureType);

            using (var memory = new UnmanagedBlock(structureSize))
            {
                Marshal.StructureToPtr(value, memory, true);

                var offset = 0;

                foreach (var field in Fields)
                {
                    var fieldType     = field.Type.CreateClrType();
                    var fieldSize     = Marshal.SizeOf(fieldType);
                    var fieldInstance = Activator.CreateInstance(fieldType);

                    Marshal.PtrToStructure(memory.Pointer + offset, fieldInstance);

                    yield return(fieldInstance);

                    offset += fieldSize;
                }
            }
        }
예제 #4
0
        private void SimpleCopy(int totalCount, int sourceOffset, int targetOffset, int copyCount)
        {
            IntPtr
                adr1 = IntPtr.Zero,
                adr2 = IntPtr.Zero;

            try
            {
                var input = Enumerable.Range(1, totalCount).Select(x => (byte)x).ToArray();

                adr1 = Load(input);
                adr2 = Load(new byte[totalCount]);

                UnmanagedBlock.Copy(adr1, adr2, sourceOffset, targetOffset, copyCount);
            }

            finally
            {
                if (adr1 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(adr1);
                }
                if (adr2 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(adr2);
                }
            }
        }
예제 #5
0
        public void Write(IntPtr source, int writeOffset, long bytesToWrite)
        {
            var     buffer         = GetBuffer();
            DataBox mappedResource = null;

            try
            {
                mappedResource = Device.ImmediateContext.MapSubresource(buffer, MapMode.WriteDiscard, MapFlags.None);

                if (Context.IsDebugModeEnabled)
                {
                    Context.DiagnosticsWriter.WriteDebug(
                        "Writing {2:###,###,###,###,###,##0} bytes from RAM (0x{0:X16}) into device memory (0x{1:X16}+{3:X8})",
                        source.ToInt64(),
                        (mappedResource.Data.DataPointer + writeOffset).ToInt64(),
                        bytesToWrite,
                        writeOffset);
                }

                UnmanagedBlock.Copy(source, mappedResource.Data.DataPointer, 0, writeOffset, bytesToWrite);
            }
            finally
            {
                if (mappedResource != null)
                {
                    Device.ImmediateContext.UnmapSubresource(buffer, 0);
                }
            }
        }
예제 #6
0
 private void UpdateBuffer()
 {
     using (var temp = new UnmanagedBlock(Marshal.SizeOf(mType)))
     {
         Marshal.StructureToPtr(mData, temp, true);
         mBuffer.Write(temp, 0, temp.Size);
     }
 }
예제 #7
0
        public void Write([NotNull] UnmanagedBlock block, int offset = 0, long size = 0)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            Write(block.Pointer, offset, size <= 0 ? block.Size : size);
        }
예제 #8
0
        IDynamicBuffer IDynamicBufferBuilder.Commit()
        {
            mType   = mTypeBuilder.CreateTypeInfo();
            mData   = Activator.CreateInstance(mType);
            mBuffer = new UnmanagedBlock(Marshal.SizeOf(mType.UnderlyingSystemType));

            foreach (var fieldKey in mFieldNames)
            {
                var field = mType.GetField(fieldKey).AssertNotNull();
                mFields.Add(fieldKey, field);
            }

            UpdateBuffer();
            return(this);
        }
예제 #9
0
        protected override Result <object> Construct(IEnumerable <object> values)
        {
            var structureType = CreateClrType();
            var structureSize = Marshal.SizeOf(structureType);
            var instance      = GetDefaultValue();

            var valueArray = values.ToArray();

            if (valueArray.Length > Fields.Length)
            {
                return(Result.CreateError <Result <object> >($"Expected {Fields.Length} values, received {valueArray.Length}"));
            }

            using (var memory = new UnmanagedBlock(structureSize))
            {
                Marshal.StructureToPtr(instance, memory, true);

                var offset = 0;
                var index  = 0;

                foreach (var field in Fields)
                {
                    var fieldType = field.Type.CreateClrType();
                    var fieldSize = Marshal.SizeOf(fieldType);

                    object fieldValue;
                    try
                    {
                        fieldValue = System.Convert.ChangeType(valueArray[index], fieldType, CultureInfo.InvariantCulture);
                    }
                    catch (Exception)
                    {
                        return(Result.CreateError($"Element \"{index + 1}\" failed to convert from \"{valueArray[index].GetType()}\" to \"{field.Type.Key}\"."));
                    }

                    Marshal.StructureToPtr(fieldValue, memory.Pointer + offset, true);

                    offset += fieldSize;
                    index++;
                }

                Marshal.PtrToStructure(memory, instance);
            }

            return(instance);
        }
예제 #10
0
        private void CopyAndAssertEquivalence(int totalCount, int sourceOffset, int targetOffset, int copyCount)
        {
            IntPtr
                adr1 = IntPtr.Zero,
                adr2 = IntPtr.Zero;

            try
            {
                var input = Enumerable.Range(1, totalCount).Select(x => (byte)x).ToArray();

                adr1 = Load(input);
                adr2 = Load(new byte[totalCount]);

                UnmanagedBlock.Copy(adr1, adr2, sourceOffset, targetOffset, copyCount);

                var expected = new byte[totalCount];
                var actual   = Fetch(adr2, input.Length);

                Array.Copy(input, sourceOffset, expected, targetOffset, copyCount);

                mOutput.WriteLine($" in: [ {string.Join(", ", input.Select(x => $"{x}"))} ]");
                mOutput.WriteLine($"out: [ {string.Join(", ", actual.Select(x => $"{x}"))} ]");
                mOutput.WriteLine($"ref: [ {string.Join(", ", expected.Select(x => $"{x}"))} ]");

                for (var i = 0; i < totalCount; i++)
                {
                    Assert.Equal(expected[i], actual[i]);
                }
            }

            finally
            {
                if (adr1 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(adr1);
                }
                if (adr2 != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(adr2);
                }
            }
        }
예제 #11
0
        protected override void DisposeOverride()
        {
            if (mIsDisposed)
            {
                return;
            }

            mFieldBuilders.Clear();
            mFieldNames.Clear();
            mFields.Clear();

            mBuffer?.Dispose();
            mContext.RemoveBuilder(mTypeName);

            mTypeBuilder = null;
            mBuffer      = null;
            mType        = null;
            mData        = null;

            mIsDisposed = true;
        }
예제 #12
0
 public void Write(IntPtr source, int writeOffset, long bytesToWrite)
 => UnmanagedBlock.Copy(source, mBox.Data.DataPointer, 0, writeOffset, bytesToWrite);
예제 #13
0
 public void Read(IntPtr target, int readOffset, long bytesToRead)
 => UnmanagedBlock.Copy(mBox.Data.DataPointer, target, readOffset, 0, bytesToRead);