예제 #1
0
        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();
        }
예제 #2
0
        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();
        }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
        public void MapAndUnmapMemory()
        {
            const int allocationSize = 32;

            using (DeviceMemory memory = AllocateMappableMemory(allocationSize))
            {
                memory.Map(0, allocationSize);
                memory.Unmap();
            }
        }
예제 #5
0
 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;
 }
예제 #6
0
        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));
        }
예제 #7
0
        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));
        }
예제 #8
0
        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();
        }
예제 #9
0
        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));
        }