public MappedBuffer(uint id, BufferAccessMask mask, Action <uint> callback) { ID = id; Mask = mask; this.callback = callback; Map(); }
/// <summary> /// Get a portion of the buffer's memory as pointer to it, allowing you to map data. /// When finished mapping you should invoke <see cref="FinishMapping" /> to flush the data to the GPU. /// </summary> /// <param name="offset">Offset for the mapping region from the beginning of the buffer - in bytes.</param> /// <param name="length">The length to map in bytes.</param> /// <param name="mask">The mapping access params.</param> /// <returns>A mapper used to map data in the buffer.</returns> public unsafe byte *CreateUnsafeMapper(int offset = 0, uint length = 0, BufferAccessMask mask = BufferAccessMask.MapWriteBit) { if (!Mapping) { StartMapping(offset, length, mask); } return(!Mapping ? null : _mappingPtr); }
/// <summary> /// Maps the buffer. /// </summary> /// <param name="mask"></param> /// <returns></returns> /// <exception cref="InvalidOperationException"></exception> public IntPtr MapBufferRange(BufferAccessMask mask) { if (IsMapped) { throw new InvalidOperationException("Buffer is already mapped."); } IsMapped = true; MapLocation = GL.MapNamedBufferRange(Handle, IntPtr.Zero, SizeInBytes, mask); return(MapLocation); }
/// <summary> /// Map a portion of the buffer to program memory for writing/reading /// </summary> /// <param name="bufferAccess"></param> /// <param name="start">Element to start at</param> /// <param name="count"></param> public unsafe IntPtr Map(BufferAccessMask bufferAccess, long start, long count) { this.Assert(); Bind(BufferTarget.ArrayBuffer); return(GL.MapBufferRange( BufferTarget.ArrayBuffer, (IntPtr)(start * TypeInfo <T> .TypeSize), (IntPtr)(count * TypeInfo <T> .TypeSize), bufferAccess )); }
public PersistentBufferObject(BufferUsageHint hint, UInt32 size) : base(BufferTarget.ArrayBuffer, hint) { mySize = size; bind(); BufferStorageFlags flags = BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapPersistentBit | BufferStorageFlags.MapCoherentBit; GL.BufferStorage(BufferTarget.ArrayBuffer, new IntPtr(size), IntPtr.Zero, flags); BufferAccessMask flags2 = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit; myPtr = GL.MapBufferRange(BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr(size), flags2); unbind(); }
internal BufferMap(BaseBuffer buffer, int first, int count, BufferAccessMask access) { this.buffer = buffer; this.count = count; this.offset = new IntPtr(first * Size); if (buffer.GetInt32(BufferParameterName.BufferMapped) != 0) { throw new Exception("The buffer is already mapped."); } using (buffer.Lock()) this.pointer = GL.MapBufferRange(buffer.Target, offset, new IntPtr(count * Size), access); }
///<summary> Begin a write. Select position and size. (datasize=0=all buffer). /// Buffer access mask decides what to keep about the range, default is to wipe the mapped area. Use 0 in bam not to do this. Trap for young players here</summary> public void StartWrite(int fillpos, int datasize = 0, BufferAccessMask bufferaccessmask = BufferAccessMask.MapInvalidateRangeBit) { if (datasize == 0) { datasize = Length - fillpos; } System.Diagnostics.Debug.Assert(mapmode == MapMode.None && fillpos >= 0 && fillpos + datasize <= Length); // catch double maps System.Diagnostics.Debug.Assert(context == GLStatics.GetContext(), "Context incorrect"); // safety CurrentPtr = GL.MapNamedBufferRange(Id, (IntPtr)fillpos, datasize, BufferAccessMask.MapWriteBit | bufferaccessmask); CurrentPos = fillpos; mapmode = MapMode.Write; GLStatics.Check(); }
void CreateMappableBuffer() { // int localBuffer = GL.GenBuffer (); // GL.BindBuffer( BufferTarget.ElementArrayBuffer, localBuffer); // var indices = new ushort[] { 0, 1, 2, 1, 2, 3 }; // // var bufferSize = (IntPtr)(indices.Length * sizeof(ushort)); // GL.BufferData (BufferTarget.ElementArrayBuffer, bufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw); // GL.Arb.BufferStorage( // // IntPtr VideoMemoryIntPtr = GL.Ext.MapNamedBufferRange(localBuffer, IntPtr.Zero, bufferSize, BufferAccessMask.MapWriteBit); // GL.Ext.UnmapNamedBuffer(localBuffer); // // GL.DeleteBuffer (localBuffer); var buffers = new int[1]; // ARB_direct_state_access // Allows buffer objects to be initialised without binding them GL.CreateBuffers(1, buffers); var targetType = BufferTarget.ElementArrayBuffer; //GL.BindBuffer (targetType, buffers[0]); var bufferSize = (indices.Length * sizeof(ushort)); BufferStorageFlags flags = BufferStorageFlags.MapCoherentBit; GL.NamedBufferStorage(buffers[0], bufferSize, IntPtr.Zero, BufferStorageFlags.MapWriteBit | BufferStorageFlags.MapPersistentBit | BufferStorageFlags.MapCoherentBit); var error = GL.GetError(); Debug.WriteLineIf(error != ErrorCode.NoError, "NamedBufferStorage " + error); BufferAccessMask rangeFlags = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit; IntPtr Handle = GL.MapNamedBufferRange(buffers[0], IntPtr.Zero, bufferSize, rangeFlags); error = GL.GetError(); Debug.WriteLineIf(error != ErrorCode.NoError, "MapNamedBufferRange " + error); var result = GL.Ext.UnmapNamedBuffer(buffers[0]); error = GL.GetError(); Debug.WriteLineIf(error != ErrorCode.NoError, "UnmapNamedBuffer " + error); GL.DeleteBuffer(buffers[0]); }
public GraphicsBuffer( BufferTarget target, BufferStorageFlags storageFlags = BufferStorageFlags.MapReadBit | BufferStorageFlags.MapWriteBit | BufferStorageFlags.DynamicStorageBit | BufferStorageFlags.MapCoherentBit | BufferStorageFlags.MapPersistentBit, BufferAccessMask accessMask = BufferAccessMask.MapReadBit | BufferAccessMask.MapWriteBit | BufferAccessMask.MapCoherentBit | BufferAccessMask.MapPersistentBit) { Target = target; StorageFlags = storageFlags; AccessMask = accessMask; Cursor = 0; Length = DefaultLength; Allocate(); }
public Result MapMemory(IMgDevice device, ulong offset, ulong size, uint flags, out IntPtr ppData) { if (mIsHostCached) { if (offset > (ulong)Int32.MaxValue) { throw new ArgumentOutOfRangeException("offset >= Int32.MaxValue"); } var handleOffset = (Int32)offset; ppData = IntPtr.Add(mHandle, handleOffset); mIsMapped = true; return(Result.SUCCESS); } else { if (offset >= (ulong)Int64.MaxValue) { throw new ArgumentOutOfRangeException("offset >= Int64.MaxValue"); } if (size >= (ulong)int.MaxValue) { throw new ArgumentOutOfRangeException("size >= Int64.MaxValue"); } var handleOffset = (IntPtr)((Int64)offset); var handleSize = (int)size; // TODO: flags translate BufferAccessMask rangeFlags = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit; ppData = GL.MapNamedBufferRange(mBufferId, IntPtr.Zero, handleSize, rangeFlags); mErrHandler.LogGLError("GL.MapNamedBufferRange"); //ppData = GL.Ext.MapNamedBufferRange(BufferId, handleOffset, handleSize, BufferAccessMask.MapWriteBit | BufferAccessMask.MapCoherentBit); mIsMapped = true; return(Result.SUCCESS); } }
public void StartMapping(BufferTarget target = BufferTarget.ArrayBuffer, bool invalidate = false) { const BufferAccessMask access = BufferAccessMask.MapWriteBit | BufferAccessMask.MapUnsynchronizedBit; if (_mapping) { return; } Bind(target); unsafe { var newAccess = access; if (invalidate) { newAccess |= BufferAccessMask.MapInvalidateBufferBit; } _pointer = GL.MapBufferRange(target, IntPtr.Zero, _size, newAccess).ToPointer(); } _mapping = true; }
/// <summary> /// Start mapping the memory of the buffer. /// </summary> public unsafe void StartMapping(int byteOffset = 0, uint length = 0, BufferAccessMask mask = BufferAccessMask.MapWriteBit) { if (Mapping) { Engine.Log.Warning("Tried to start mapping a buffer which is already mapping.", MessageSource.GL); return; } if (Size == 0) { Engine.Log.Warning("Tried to start mapping a buffer with no memory.", MessageSource.GL); return; } if (length == 0) { length = Size; } if (Engine.Renderer.Dsa) { _mappingPtr = (byte *)Gl.MapNamedBufferRange(Pointer, (IntPtr)byteOffset, length, mask); } else { EnsureBound(Pointer, Type); _mappingPtr = (byte *)Gl.MapBufferRange(Type, (IntPtr)byteOffset, length, mask); } if ((IntPtr)_mappingPtr == IntPtr.Zero) { Engine.Log.Warning("Couldn't start mapping buffer. Expect a crash.", MessageSource.GL); Debug.Assert(false); } Mapping = true; }
public StreamBuffer(string name, BufferTarget target, int size, BufferStorageFlags flags = BufferStorageFlags.MapWriteBit, BufferAccessMask mask = (BufferAccessMask)0, int bufferingLevel = 3) { Size = size; TotalBytesPerFrame += size; _bufferingLevel = bufferingLevel; _fences = new FenceSync[bufferingLevel]; _handle = GL.GenBuffer(); GL.BindBuffer(target, _handle); GL.BufferStorage(target, new IntPtr(size * bufferingLevel), IntPtr.Zero, (BufferStorageFlags)flags | BufferStorageFlags.MapPersistentBit); Glob.Utils.SetObjectLabel(ObjectLabelIdentifier.Buffer, _handle, name); var accessFlags = (BufferAccessMask)0; if (flags.HasFlag(BufferStorageFlags.MapWriteBit)) { accessFlags = accessFlags | BufferAccessMask.MapWriteBit; } if (flags.HasFlag(BufferStorageFlags.MapReadBit)) { accessFlags = accessFlags | BufferAccessMask.MapReadBit; } _bufferPointer = GL.MapBufferRange(target, IntPtr.Zero, new IntPtr(size * bufferingLevel), accessFlags | mask | BufferAccessMask.MapPersistentBit); }
public IntPtr MapRange(BufferAccessMask mask) { return(IGL.Primary.MapBufferRange((int)BufferTarget.ShaderStorageBuffer, IntPtr.Zero, lastKnownSize, (int)mask)); }
void CreateVAOs() { int[] result = new int[1]; GL.CreateVertexArrays(1, result); Debug.Assert(GL.IsVertexArray(result[0])); mRender_VertexArray = result[0]; var indexOffset = IntPtr.Zero; var indexSize = sizeof(uint) * indicesVboData.Length; var bufferIndex = 0; GL.VertexArrayElementBuffer(mRender_VertexArray, mRender_VBO_position); var positionOffset = new IntPtr(indexSize); GL.VertexArrayVertexBuffer(mRender_VertexArray, bufferIndex, mRender_VBO_position, positionOffset, Vector3.SizeInBytes); var stride = Marshal.SizeOf(typeof(Vector3)); int positionSize = stride * positionVboData.Length; var positionIndex = 0; GL.VertexArrayAttribBinding(mRender_VertexArray, positionIndex, bufferIndex); GL.EnableVertexArrayAttrib(mRender_VertexArray, positionIndex); GL.VertexArrayAttribFormat(mRender_VertexArray, positionIndex, 3, VertexAttribType.Float, true, 0); // SAME DATA var normalOffset = positionOffset; var normalSize = positionSize; var normalIndex = 1; GL.VertexArrayAttribBinding(mRender_VertexArray, normalIndex, bufferIndex); GL.EnableVertexArrayAttrib(mRender_VertexArray, normalIndex); //GL.VertexArrayVertexBuffer (vaoHandle, normalIndex, positionVboHandle, positionOffset, Vector3.SizeInBytes); GL.VertexArrayAttribFormat(mRender_VertexArray, normalIndex, 3, VertexAttribType.Float, true, 0); BufferAccessMask rangeFlags = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit; var indexDest = GL.MapNamedBufferRange(mRender_VBO_position, indexOffset, indexSize, rangeFlags); // Copy here const int START_INDEX = 0; Marshal.Copy(indicesVboData, START_INDEX, indexDest, indicesVboData.Length); GL.Ext.UnmapNamedBuffer(mRender_VBO_position); // Copy here IntPtr vertexDest = GL.MapNamedBufferRange(mRender_VBO_position, positionOffset, positionSize, rangeFlags); // Copy the struct to unmanaged memory. int copyOffset = 0; int elementCount = positionVboData.Length; var dest = vertexDest; var data = positionVboData; var startIndex = 0; for (int i = 0; i < elementCount; ++i) { IntPtr localDest = IntPtr.Add(dest, copyOffset); Marshal.StructureToPtr(data[i + startIndex], localDest, false); copyOffset += stride; } GL.Ext.UnmapNamedBuffer(mRender_VBO_position); { var error = GL.GetError(); //Debug.WriteLineIf (error != ErrorCode.NoError, "GL.Ext.UnmapNamedBuffer " + error); } }
void CreateVAOs() { int[] result = new int[1]; GL.CreateVertexArrays(1, result); Debug.Assert(GL.IsVertexArray(result [0])); vaoHandle = result [0]; // GL3 allows us to store the vertex layout in a "vertex array object" (VAO). // This means we do not have to re-issue VertexAttribPointer calls // every time we try to use a different vertex layout - these calls are // stored in the VAO so we simply need to bind the correct VAO. //GL.BindVertexArray(vaoHandle); var indexOffset = IntPtr.Zero; var indexSize = sizeof(uint) * indicesVboData.Length; var bufferIndex = 0; GL.VertexArrayElementBuffer(vaoHandle, positionVboHandle); var positionOffset = new IntPtr(indexSize); GL.VertexArrayVertexBuffer(vaoHandle, bufferIndex, positionVboHandle, positionOffset, Vector3.SizeInBytes); //GL.BindBufferRange(BufferTarget.ElementArrayBuffer, 0, positionVboHandle, indexOffset, indexSize); // GL.EnableVertexAttribArray(0); // GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); var stride = Marshal.SizeOf(typeof(Vector3)); int positionSize = stride * positionVboData.Length; var positionIndex = 0; GL.VertexArrayAttribBinding(vaoHandle, positionIndex, bufferIndex); GL.EnableVertexArrayAttrib(vaoHandle, positionIndex); GL.VertexArrayAttribFormat(vaoHandle, positionIndex, 3, VertexAttribType.Float, true, 0); //GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, positionOffset); // GL.EnableVertexAttribArray(1); // GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); // SAME DATA var normalOffset = positionOffset; var normalSize = positionSize; var normalIndex = 1; //GL.VertexArrayAttribFormat (vaoHandle, 0, 3, VertexAttribType.Float, true, positionOffset); //GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, normalOffset); GL.VertexArrayAttribBinding(vaoHandle, normalIndex, bufferIndex); GL.EnableVertexArrayAttrib(vaoHandle, normalIndex); //GL.VertexArrayVertexBuffer (vaoHandle, normalIndex, positionVboHandle, positionOffset, Vector3.SizeInBytes); GL.VertexArrayAttribFormat(vaoHandle, normalIndex, 3, VertexAttribType.Float, true, 0); BufferAccessMask rangeFlags = BufferAccessMask.MapWriteBit | BufferAccessMask.MapPersistentBit | BufferAccessMask.MapCoherentBit; var indexDest = GL.MapNamedBufferRange(positionVboHandle, indexOffset, indexSize, rangeFlags); // Copy here const int START_INDEX = 0; Marshal.Copy(indicesVboData, START_INDEX, indexDest, indicesVboData.Length); GL.Ext.UnmapNamedBuffer(positionVboHandle); // Copy here IntPtr vertexDest = GL.MapNamedBufferRange(positionVboHandle, positionOffset, positionSize, rangeFlags); // Copy the struct to unmanaged memory. int copyOffset = 0; int elementCount = positionVboData.Length; var dest = vertexDest; var data = positionVboData; var startIndex = 0; for (int i = 0; i < elementCount; ++i) { IntPtr localDest = IntPtr.Add(dest, copyOffset); Marshal.StructureToPtr(data[i + startIndex], localDest, false); copyOffset += stride; } GL.Ext.UnmapNamedBuffer(positionVboHandle); { var error = GL.GetError(); //Debug.WriteLineIf (error != ErrorCode.NoError, "GL.Ext.UnmapNamedBuffer " + error); } // Copy here // var normalDest = GL.MapNamedBufferRange (positionVboHandle, normalOffset, normalSize, rangeFlags); // // GL.Ext.UnmapNamedBuffer (positionVboHandle); // GL.BindVertexArray(0); }
/// <summary> /// Map a range of the GPU buffer allocated by this Buffer. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> required for mapping this Buffer. /// </param> /// <param name="mask"> /// A <see cref="BufferAccessMask"/> that specify the map access. /// </param> /// <exception cref="InvalidOperationException"> /// Exception thrown if this Buffer is already mapped. /// </exception> /// <exception cref="InvalidOperationException"> /// Exception thrown if this Buffer does not exist for <paramref name="ctx"/>. /// </exception> public void Map(GraphicsContext ctx, BufferAccessMask mask, IntPtr offset = default(IntPtr), uint size = 0) { CheckThisExistence(ctx); uint mapSize = size != 0 ? size : Size; if (IsMapRangeSupported(ctx)) { #if !MONODROID if (ctx.Extensions.DirectStateAccess_ARB || ctx.Version.IsCompatible(Gl.Version_450)) { if ((MappedBuffer = Gl.MapNamedBufferRange(ObjectName, offset, mapSize, mask)) == IntPtr.Zero) { Gl.CheckErrors(); } } else { #endif ctx.Bind(this); if ((MappedBuffer = Gl.MapBufferRange(Target, offset, mapSize, mask)) == IntPtr.Zero) { Gl.CheckErrors(); } #if !MONODROID } #endif } else { if (GpuBuffer == null) { throw new GlException(ErrorCode.InvalidOperation); } if (GpuBuffer.AlignedBuffer == IntPtr.Zero) { throw new GlException(ErrorCode.InvalidOperation); } MappedBuffer = new IntPtr(GpuBuffer.AlignedBuffer.ToInt64() + offset.ToInt64()); } // Determine map access if (mask.HasFlag(BufferAccessMask.MapReadBit) && mask.HasFlag(BufferAccessMask.MapWriteBit)) { _Access = BufferAccess.ReadWrite; } else if (mask.HasFlag(BufferAccessMask.MapReadBit)) { _Access = BufferAccess.ReadOnly; } else if (mask.HasFlag(BufferAccessMask.MapWriteBit)) { _Access = BufferAccess.WriteOnly; } else { _Access = 0; } Debug.Assert(MappedBuffer != IntPtr.Zero); MapOffset = offset; MapSize = mapSize; _AccessMask = mask; }
public MappedBuffer(uint id, BufferAccessMask mask) { ID = id; Mask = mask; Map(); }
public static IntPtr MapBufferRange(BufferTarget target, IntPtr offset, IntPtr length, BufferAccessMask access) { glMapBufferRange deleg = BaseGraphicsContext.Current.Loader.Get<glMapBufferRange>(); if (deleg != null) return deleg(target, offset, length, access); return default(IntPtr); }