public void Write <T>(ref T value) where T : struct { if (WriteUsingStagingBuffer) { MemoryRequirements stagingReq = StagingBuffer.GetMemoryRequirements(); IntPtr vertexPtr = StagingMemory.Map(0, stagingReq.Size); Interop.Write(vertexPtr, ref value); StagingMemory.Unmap(); // Copy the data from staging buffers to device local buffers. StagingCommandBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); StagingCommandBuffer.CmdCopyBuffer(StagingBuffer, Buffer, new BufferCopy(Size)); StagingCommandBuffer.End(); // Submit. Context.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { StagingCommandBuffer }), Fence); Fence.Wait(); Fence.Reset(); StagingCommandBuffer.Reset(); return; } IntPtr ptr = Memory.Map(0, Interop.SizeOf <T>()); Interop.Write(ptr, ref value); Memory.Unmap(); }
public void Read() { IntPtr srcPtr = DeviceMemory.Map(0, HostSize); GCHandle handle = GCHandle.Alloc(HostResource, GCHandleType.Pinned); IntPtr dstPtr = handle.AddrOfPinnedObject(); if (HostStride == DeviceStride) { System.Buffer.MemoryCopy( srcPtr.ToPointer(), dstPtr.ToPointer(), HostSize, HostSize); } else { var srcWalk = (byte *)srcPtr; var dstWalk = (byte *)dstPtr; for (int i = 0; i < Count; i++) { System.Buffer.MemoryCopy(srcWalk, dstWalk, HostStride, HostStride); srcWalk += DeviceStride; dstWalk += HostStride; } } handle.Free(); DeviceMemory.Unmap(); }
public unsafe void SaveRenderedImage() { List <byte> image = new List <byte>(); // Map the buffer memory, so that we can read from it on the CPU. IntPtr mappedMemory = bufferMemory.Map(0, bufferSize); Pixel *pmappedMemory = (Pixel *)mappedMemory.ToPointer(); // Get the color data from the buffer, and cast it to bytes. // We save the data to a vector. image.Capacity = (WIDTH * HEIGHT * 4); for (int i = 0; i < WIDTH * HEIGHT; i += 1) { Pixel p = pmappedMemory[i]; image.Add((byte)(255.0f * (p.r))); image.Add((byte)(255.0f * (p.g))); image.Add((byte)(255.0f * (p.b))); image.Add((byte)(255.0f * (p.a))); } // Done reading, so unmap. bufferMemory.Unmap(); // Now we save the acquired color data to a .png. using (var stream = new MemoryStream(image.ToArray())) { using (var bmp = new Bitmap(WIDTH, HEIGHT, PixelFormat.Format32bppArgb)) { BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); IntPtr pNative = bmData.Scan0; Marshal.Copy(image.ToArray(), 0, pNative, image.Count); bmp.UnlockBits(bmData); bmp.Save("mandelbrot.png", ImageFormat.Png); } } }
public void MapAndUnmapMemory() { const int allocationSize = 32; using (DeviceMemory memory = AllocateMappableMemory(allocationSize)) { memory.Map(0, allocationSize); memory.Unmap(); } }
internal void Unmap() { if (location != Chunk.Location.Host) { throw new Exception($"[{nameof(Chunk)}] Only host memory can be mapped"); } if (!currentlyMapped) { throw new Exception($"[{nameof(Chunk)}] Memory is not currently mapped"); } memory.Unmap(); currentlyMapped = false; currentMapOffset = -1; currentMapSize = -1; }
public static VulkanBuffer Vertex <T>(VulkanContext ctx, T[] vertices) where T : struct { long size = vertices.Length * Interop.SizeOf <T>(); // Create a staging buffer that is writable by host. Buffer stagingBuffer = ctx.Device.CreateBuffer(new BufferCreateInfo(size, BufferUsages.TransferSrc)); MemoryRequirements stagingReq = stagingBuffer.GetMemoryRequirements(); int stagingMemoryTypeIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( stagingReq.MemoryTypeBits, MemoryProperties.HostVisible | MemoryProperties.HostCoherent); DeviceMemory stagingMemory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(stagingReq.Size, stagingMemoryTypeIndex)); IntPtr vertexPtr = stagingMemory.Map(0, stagingReq.Size); Interop.Write(vertexPtr, vertices); stagingMemory.Unmap(); stagingBuffer.BindMemory(stagingMemory); // Create a device local buffer where the vertex data will be copied and which will be used for rendering. Buffer buffer = ctx.Device.CreateBuffer(new BufferCreateInfo(size, BufferUsages.VertexBuffer | BufferUsages.TransferDst)); MemoryRequirements req = buffer.GetMemoryRequirements(); int memoryTypeIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( req.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(req.Size, memoryTypeIndex)); buffer.BindMemory(memory); // Copy the data from staging buffers to device local buffers. CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]; cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); cmdBuffer.CmdCopyBuffer(stagingBuffer, buffer, new BufferCopy(size)); cmdBuffer.End(); // Submit. Fence fence = ctx.Device.CreateFence(); ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence); fence.Wait(); // Cleanup. fence.Dispose(); cmdBuffer.Dispose(); stagingBuffer.Dispose(); stagingMemory.Dispose(); return(new VulkanBuffer(buffer, memory, vertices.Length)); }
internal static VKBuffer Index(Context ctx, int[] indices) { long size = indices.Length * sizeof(int); // Create staging buffer. VulkanCore.Buffer stagingBuffer = ctx.Device.CreateBuffer(new BufferCreateInfo(size, BufferUsages.TransferSrc)); MemoryRequirements stagingReq = stagingBuffer.GetMemoryRequirements(); int stagingMemoryTypeIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( stagingReq.MemoryTypeBits, MemoryProperties.HostVisible | MemoryProperties.HostCoherent); DeviceMemory stagingMemory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(stagingReq.Size, stagingMemoryTypeIndex)); IntPtr indexPtr = stagingMemory.Map(0, stagingReq.Size); Interop.Write(indexPtr, indices); stagingMemory.Unmap(); stagingBuffer.BindMemory(stagingMemory); // Create a device local buffer. VulkanCore.Buffer buffer = ctx.Device.CreateBuffer(new BufferCreateInfo(size, BufferUsages.IndexBuffer | BufferUsages.TransferDst)); MemoryRequirements req = buffer.GetMemoryRequirements(); int memoryTypeIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( req.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(req.Size, memoryTypeIndex)); buffer.BindMemory(memory); // Copy the data from staging buffer to device local buffer. CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]; cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); cmdBuffer.CmdCopyBuffer(stagingBuffer, buffer, new BufferCopy(size)); cmdBuffer.End(); // Submit. Fence fence = ctx.Device.CreateFence(); ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence); fence.Wait(); // Cleanup. fence.Dispose(); cmdBuffer.Dispose(); stagingBuffer.Dispose(); stagingMemory.Dispose(); return(new VKBuffer(ctx, buffer, memory, null, indices.Length, size)); }
public void CopyStuffIntoMemory <T>(string memName, T[] stuff) where T : struct { if (!mDeviceMems.ContainsKey(memName)) { Misc.SafeInvoke(eErrorSpam, "No memory chunk " + memName + "..."); return; } DeviceMemory dm = mDeviceMems[memName]; long size = stuff.Length * Interop.SizeOf <T>(); IntPtr pVBMem = dm.Map(0, size); Interop.Write(pVBMem, stuff); dm.Unmap(); }
internal static VulkanImage Texture2D(VulkanContext ctx, TextureData tex2D) { Buffer stagingBuffer = ctx.Device.CreateBuffer( new BufferCreateInfo(tex2D.Mipmaps[0].Size, BufferUsages.TransferSrc)); MemoryRequirements stagingMemReq = stagingBuffer.GetMemoryRequirements(); int heapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( stagingMemReq.MemoryTypeBits, MemoryProperties.HostVisible); DeviceMemory stagingMemory = ctx.Device.AllocateMemory( new MemoryAllocateInfo(stagingMemReq.Size, heapIndex)); stagingBuffer.BindMemory(stagingMemory); IntPtr ptr = stagingMemory.Map(0, stagingMemReq.Size); Interop.Write(ptr, tex2D.Mipmaps[0].Data); stagingMemory.Unmap(); // Setup buffer copy regions for each mip level. var bufferCopyRegions = new BufferImageCopy[tex2D.Mipmaps.Length]; int offset = 0; for (int i = 0; i < bufferCopyRegions.Length; i++) { bufferCopyRegions = new[] { new BufferImageCopy { ImageSubresource = new ImageSubresourceLayers(ImageAspects.Color, i, 0, 1), ImageExtent = tex2D.Mipmaps[0].Extent, BufferOffset = offset } }; offset += tex2D.Mipmaps[i].Size; } // Create optimal tiled target image. Image image = ctx.Device.CreateImage(new ImageCreateInfo { ImageType = ImageType.Image2D, Format = tex2D.Format, MipLevels = tex2D.Mipmaps.Length, ArrayLayers = 1, Samples = SampleCounts.Count1, Tiling = ImageTiling.Optimal, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Extent = tex2D.Mipmaps[0].Extent, Usage = ImageUsages.Sampled | ImageUsages.TransferDst }); MemoryRequirements imageMemReq = image.GetMemoryRequirements(); int imageHeapIndex = ctx.MemoryProperties.MemoryTypes.IndexOf( imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal); DeviceMemory memory = ctx.Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, imageHeapIndex)); image.BindMemory(memory); var subresourceRange = new ImageSubresourceRange(ImageAspects.Color, 0, tex2D.Mipmaps.Length, 0, 1); // Copy the data from staging buffers to device local buffers. CommandBuffer cmdBuffer = ctx.GraphicsCommandPool.AllocateBuffers(new CommandBufferAllocateInfo(CommandBufferLevel.Primary, 1))[0]; cmdBuffer.Begin(new CommandBufferBeginInfo(CommandBufferUsages.OneTimeSubmit)); cmdBuffer.CmdPipelineBarrier(PipelineStages.TopOfPipe, PipelineStages.TopOfPipe, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, 0, Accesses.TransferWrite, ImageLayout.Undefined, ImageLayout.TransferDstOptimal) }); cmdBuffer.CmdCopyBufferToImage(stagingBuffer, image, ImageLayout.TransferDstOptimal, bufferCopyRegions); cmdBuffer.CmdPipelineBarrier(PipelineStages.TopOfPipe, PipelineStages.TopOfPipe, imageMemoryBarriers: new[] { new ImageMemoryBarrier( image, subresourceRange, Accesses.TransferWrite, Accesses.ShaderRead, ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal) }); cmdBuffer.End(); // Submit. Fence fence = ctx.Device.CreateFence(); ctx.GraphicsQueue.Submit(new SubmitInfo(commandBuffers: new[] { cmdBuffer }), fence); fence.Wait(); // Cleanup staging resources. fence.Dispose(); stagingMemory.Dispose(); stagingBuffer.Dispose(); // Create image view. ImageView view = image.CreateView(new ImageViewCreateInfo(tex2D.Format, subresourceRange)); return(new VulkanImage(image, memory, view, tex2D.Format)); }