/// <summary> /// Release the memory from the VRAM. /// </summary> public void ReleaseMemory() { StagingBuffer?.Dispose(); StagingBuffer = null; IndexBuffer?.Dispose(); IndexBuffer = null; StagingVRAM?.Free(); VertexVRAM?.Free(); }
/// <summary> /// Upload the vertexs to the VRAM. /// </summary> public void Upload(CommandBuffer commands, int maxBytes) { if (StagingVRAM != null && VertexVRAM != null && IndexBuffer != null && StagingBuffer != null) { List <BufferCopy> uploadQueue = new List <BufferCopy>(); // - Order invalidated chunks by priority var invalidated = UsedSpace.Where(x => (x as BufferResource).Invalidated) .OrderByDescending(x => (x as BufferResource).UploadPriority); // - Keep track of the upload zone var uploadRange = (start : 0L, end : 0L); foreach (BufferResource chunk in invalidated) { if (chunk.UploadPriority == int.MaxValue || maxBytes > 0) { uploadQueue.Add(new BufferCopy(chunk.Offset, chunk.Offset, chunk.Size)); maxBytes -= (int)chunk.Size; chunk.Invalidated = false; chunk.UploadPriority = 0; uploadRange = ( start : Math.Min(uploadRange.start, chunk.Offset), end : Math.Max(uploadRange.end, chunk.Offset + chunk.Size) ); } } // - No invalidated chunks if (uploadQueue.Count <= 0) { return; } // - Calculate upload range int uploadOffset = (int)uploadRange.start; int uploadSize = (int)(uploadRange.end - uploadRange.start); // TODO: This can be improved by splitting large upload areas // - Gets the pointer to the staging memory IntPtr vram = StagingVRAM.Map(uploadOffset, uploadSize, MemoryMapFlags.None); unsafe { // - Perform the copy System.Buffer.MemoryCopy ( IntPtr.Add(RawMemory, uploadOffset).ToPointer(), vram.ToPointer(), uploadSize, uploadSize ); } // - Unmap the staging memory pointer StagingVRAM.Unmap(); // - Send the upload message to the GPU commands.CopyBuffer(StagingBuffer, IndexBuffer, uploadQueue.ToArray()); } }