DeviceMemory BindBuffer(Buffer buffer, MemoryAllocateInfo allocInfo) { var bufferMem = device.AllocateMemory(allocInfo); device.BindBufferMemory(buffer, bufferMem, 0); return(bufferMem); }
protected unsafe void AllocateMemory(MemoryPropertyFlags memoryProperties, MemoryRequirements memoryRequirements) { if (NativeMemory != DeviceMemory.Null) return; if (memoryRequirements.Size == 0) return; var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, }; PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; GraphicsDevice.NativePhysicalDevice.GetMemoryProperties(out physicalDeviceMemoryProperties); var typeBits = memoryRequirements.MemoryTypeBits; for (uint i = 0; i < physicalDeviceMemoryProperties.MemoryTypeCount; i++) { if ((typeBits & 1) == 1) { // Type is available, does it match user properties? var memoryType = *((MemoryType*)&physicalDeviceMemoryProperties.MemoryTypes + i); if ((memoryType.PropertyFlags & memoryProperties) == memoryProperties) { allocateInfo.MemoryTypeIndex = i; break; } } typeBits >>= 1; } NativeMemory = GraphicsDevice.NativeDevice.AllocateMemory(ref allocateInfo); }
public void AllocateMemory() { var allocateInfo = new MemoryAllocateInfo(32, 0); using (Device.AllocateMemory(allocateInfo)) { } using (Device.AllocateMemory(allocateInfo, CustomAllocator)) { } }
protected unsafe DeviceMemory AllocateMemory(MemoryPropertyFlags memoryProperties, MemoryRequirements memoryRequirements) { var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, }; PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; physicalDevice.GetMemoryProperties(out physicalDeviceMemoryProperties); var typeBits = memoryRequirements.MemoryTypeBits; for (uint i = 0; i < physicalDeviceMemoryProperties.MemoryTypeCount; i++) { if ((typeBits & 1) == 1) { // Type is available, does it match user properties? var memoryType = *((MemoryType *)&physicalDeviceMemoryProperties.MemoryTypes + i); if ((memoryType.PropertyFlags & memoryProperties) == memoryProperties) { allocateInfo.MemoryTypeIndex = i; break; } } typeBits >>= 1; } return(device.AllocateMemory(ref allocateInfo)); }
public void CreateDepth() { ImageCreateInfo imageInfo = new ImageCreateInfo { ImageType = ImageType.Image2D, Format = Format.D16Unorm, Extent = new Extent3D { Width = BackBufferWidth, Height = BackBufferHeight, Depth = 1, }, MipLevels = 1, ArrayLayers = 1, Samples = (uint)SampleCountFlags.Count1, Tiling = ImageTiling.Optimal, Usage = (uint)ImageUsageFlags.DepthStencilAttachment, Flags = 0, }; Image image = Device.CreateImage(imageInfo, null); MemoryRequirements memReq = Device.GetImageMemoryRequirements(image); uint memTypeIndex; if (!TryGetMemoryTypeFromProperties(memReq.MemoryTypeBits, 0, out memTypeIndex)) { throw new Exception("Failed to create back buffer"); } MemoryAllocateInfo allocInfo = new MemoryAllocateInfo { AllocationSize = 0, MemoryTypeIndex = memTypeIndex, }; DeviceMemory imageMem = Device.AllocateMemory(allocInfo, null); Device.BindImageMemory(image, imageMem, 0); SetImageLayout(image, ImageAspectFlags.Depth, ImageLayout.Undefined, ImageLayout.DepthStencilAttachmentOptimal, 0); ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo { Image = image, Format = imageInfo.Format, SubresourceRange = new ImageSubresourceRange { AspectMask = (uint)ImageAspectFlags.Depth, BaseMipLevel = 0, LevelCount = 1, BaseArrayLayer = 0, LayerCount = 1, }, Flags = 0, ViewType = ImageViewType.View2D, }; ImageView imageView = Device.CreateImageView(imageViewInfo, null); }
private unsafe IntPtr SetupCopy <T>(int mySize) { if (SizeOfBuffer == 0) { SizeOfInternalStructure = mySize; var memoryReq = myActiveDevice.LogicalDevice.GetBufferMemoryRequirements(this); SizeOfBuffer = memoryReq.Size; allocInfo = new MemoryAllocateInfo { AllocationSize = memoryReq.Size }; var memoryProperties = myActiveDevice.GetMemoryProperties(); bool heapIndexSet = false; var memoryTypes = memoryProperties.MemoryTypes; for (uint i = 0; i < memoryProperties.MemoryTypeCount; i++) { if (((memoryReq.MemoryTypeBits >> (int)i) & 1) == 1 && (memoryTypes[i].PropertyFlags & MemoryPropertyFlags.HostVisible) == MemoryPropertyFlags.HostVisible) { allocInfo.MemoryTypeIndex = i; heapIndexSet = true; } } if (!heapIndexSet) { allocInfo.MemoryTypeIndex = memoryProperties.MemoryTypes[0].HeapIndex; } } deviceMemory = new DeviceMemory(myActiveDevice.LogicalDevice, allocInfo); return(myActiveDevice.LogicalDevice.MapMemory(deviceMemory, 0, mySize, 0)); }
public Image(VulkanPhysicalDevice myDevice, ImageCreateInfo pCreateInfo, AllocationCallbacks pAllocator = null) { this.Device = myDevice; Result result; unsafe { fixed(UInt64 *ptrpImage = &this.m) { result = Interop.NativeMethods.vkCreateImage(myDevice.LogicalDevice.m, pCreateInfo != null ? pCreateInfo.m : (Interop.ImageCreateInfo *) default(IntPtr), pAllocator != null ? pAllocator.m : null, ptrpImage); } if (result != Result.Success) { throw new ResultException(result); } } MemoryRequirements myRequirements = GetImageMemoryRequirements(); MemoryAllocateInfo MemInfo = new MemoryAllocateInfo(); MemInfo.AllocationSize = myRequirements.Size; MemInfo.MemoryTypeIndex = myDevice.GetMemoryIndexFromProperty(myRequirements.MemoryTypeBits, MemoryPropertyFlags.DeviceLocal); deviceMemory = new DeviceMemory(myDevice.LogicalDevice, MemInfo); BindImageMemory(deviceMemory, 0); }
public unsafe DepthImage(uint width, uint height, PhysicalDevice physicalDevice, Device device) { _width = width; _height = height; _vk = VkUtil.Vk; _physicalDevice = physicalDevice; _device = device; Format = FindFormat(FormatFeatureFlags.FormatFeatureDepthStencilAttachmentBit, Format.D32SfloatS8Uint, Format.D24UnormS8Uint); ImageCreateInfo imageCreateInfo = VkInit.ImageCreateInfo(ImageType.ImageType2D, Format, _width, _height); VkUtil.AssertVulkan(_vk.CreateImage(_device, imageCreateInfo, null, out _image)); _vk.GetImageMemoryRequirements(_device, _image, out MemoryRequirements memReqs); _vk.GetPhysicalDeviceMemoryProperties(_physicalDevice, out PhysicalDeviceMemoryProperties memoryProperties); uint index = VkUtil.FindMemoryTypeIndex(memReqs.MemoryTypeBits, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit, memoryProperties); MemoryAllocateInfo memoryAllocateInfo = VkInit.MemoryAllocateInfo(memReqs.Size, index); VkUtil.AssertVulkan(_vk.AllocateMemory(_device, memoryAllocateInfo, null, out _memory)); VkUtil.AssertVulkan(_vk.BindImageMemory(_device, _image, _memory, 0)); ImageViewCreateInfo imageViewCreateInfo = VkInit.ImageViewCreateInfo(Format, _image, ImageAspectFlags.ImageAspectDepthBit); VkUtil.AssertVulkan(_vk.CreateImageView(_device, imageViewCreateInfo, null, out _imageView)); }
Buffer CreateBuffer(PhysicalDevice physicalDevice, object values, BufferUsageFlags usageFlags, System.Type type) { var array = values as System.Array; var length = (array != null) ? array.Length : 1; var size = System.Runtime.InteropServices.Marshal.SizeOf(type) * length; var createBufferInfo = new BufferCreateInfo { Size = size, Usage = usageFlags, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint [] { 0 } }; var buffer = device.CreateBuffer(createBufferInfo); var memoryReq = device.GetBufferMemoryRequirements(buffer); var allocInfo = new MemoryAllocateInfo { AllocationSize = memoryReq.Size }; var memoryProperties = physicalDevice.GetMemoryProperties(); bool heapIndexSet = false; var memoryTypes = memoryProperties.MemoryTypes; for (uint i = 0; i < memoryProperties.MemoryTypeCount; i++) { if (((memoryReq.MemoryTypeBits >> (int)i) & 1) == 1 && (memoryTypes [i].PropertyFlags & MemoryPropertyFlags.HostVisible) == MemoryPropertyFlags.HostVisible) { allocInfo.MemoryTypeIndex = i; heapIndexSet = true; } } if (!heapIndexSet) { allocInfo.MemoryTypeIndex = memoryProperties.MemoryTypes [0].HeapIndex; } var deviceMemory = device.AllocateMemory(allocInfo); var memPtr = device.MapMemory(deviceMemory, 0, size, 0); if (type == typeof(float)) { System.Runtime.InteropServices.Marshal.Copy(values as float [], 0, memPtr, length); } else if (type == typeof(short)) { System.Runtime.InteropServices.Marshal.Copy(values as short [], 0, memPtr, length); } else if (type == typeof(AreaUniformBuffer)) { System.Runtime.InteropServices.Marshal.StructureToPtr(values, memPtr, false); } device.UnmapMemory(deviceMemory); device.BindBufferMemory(buffer, deviceMemory, 0); return(buffer); }
DeviceMemory BindImage(Image image) { var memRequirements = device.GetImageMemoryRequirements(image); var memTypeIndex = FindMemoryIndex(MemoryPropertyFlags.DeviceLocal); var memAlloc = new MemoryAllocateInfo(memRequirements.Size, memTypeIndex); var deviceMem = device.AllocateMemory(memAlloc); device.BindImageMemory(image, deviceMem, 0); return(deviceMem); }
public unsafe MemoryAllocation Allocate(ulong size, ulong alignment, bool map) { // Ensure we have a sane alignment value. if ((ulong)(int)alignment != alignment || (int)alignment <= 0) { throw new ArgumentOutOfRangeException(nameof(alignment), $"Invalid alignment 0x{alignment:X}."); } for (int i = 0; i < _blocks.Count; i++) { var block = _blocks[i]; if (block.Mapped == map && block.Size >= size) { ulong offset = block.Allocate(size, alignment); if (offset != InvalidOffset) { return(new MemoryAllocation(this, block, block.Memory, GetHostPointer(block, offset), offset, size)); } } } ulong blockAlignedSize = BitUtils.AlignUp(size, _blockAlignment); var memoryAllocateInfo = new MemoryAllocateInfo() { SType = StructureType.MemoryAllocateInfo, AllocationSize = blockAlignedSize, MemoryTypeIndex = (uint)MemoryTypeIndex }; _api.AllocateMemory(_device, memoryAllocateInfo, null, out var deviceMemory).ThrowOnError(); IntPtr hostPointer = IntPtr.Zero; if (map) { unsafe { void *pointer = null; _api.MapMemory(_device, deviceMemory, 0, blockAlignedSize, 0, ref pointer).ThrowOnError(); hostPointer = (IntPtr)pointer; } } var newBlock = new Block(deviceMemory, hostPointer, blockAlignedSize); InsertBlock(newBlock); ulong newBlockOffset = newBlock.Allocate(size, alignment); Debug.Assert(newBlockOffset != InvalidOffset); return(new MemoryAllocation(this, newBlock, deviceMemory, GetHostPointer(newBlock, newBlockOffset), newBlockOffset, size)); }
VertexData CreateVertexData() { var data = new VertexData(); var quadVertices = new[, ] { { 1.0f, 1.0f, 0.0f, /* UV: */ 1.0f, 1.0f, /* Normal: */ 0.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.0f, /* UV: */ 0.0f, 1.0f, /* Normal: */ 0.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 0.0f, /* UV: */ 0.0f, 0.0f, /* Normal: */ 0.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 0.0f, /* UV: */ 1.0f, 0.0f, /* Normal: */ 0.0f, 0.0f, 1.0f }, }; DeviceSize memorySize = (ulong)(sizeof(float) * quadVertices.Length); data.Buffer = CreateBuffer(memorySize, BufferUsageFlags.VertexBuffer); var memoryRequirements = device.GetBufferMemoryRequirements(data.Buffer); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var allocateInfo = new MemoryAllocateInfo(memoryRequirements.Size, memoryIndex); data.DeviceMemory = BindBuffer(data.Buffer, allocateInfo); var vertexPtr = device.MapMemory(data.DeviceMemory, 0, memorySize); VulkanUtils.Copy2DArray(quadVertices, vertexPtr, memorySize, memorySize); device.UnmapMemory(data.DeviceMemory); data.Indicies = new[] { 0, 1, 2, 2, 3, 0 }; memorySize = (ulong)(sizeof(uint) * data.Indicies.Length); data.IndexBuffer = CreateBuffer(memorySize, BufferUsageFlags.IndexBuffer); memoryRequirements = device.GetBufferMemoryRequirements(data.IndexBuffer); memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); allocateInfo = new MemoryAllocateInfo(memoryRequirements.Size, memoryIndex); data.IndexDeviceMemory = BindBuffer(data.IndexBuffer, allocateInfo); var bytes = data.Indicies.SelectMany(BitConverter.GetBytes).ToArray(); // oh man, dat Linq tho CopyArrayToBuffer(data.IndexDeviceMemory, memorySize, bytes); data.BindingDescriptions = new[] { new VertexInputBindingDescription(0, (uint)(sizeof(float) * quadVertices.GetLength(1)), VertexInputRate.Vertex) }; data.AttributeDescriptions = new[] { new VertexInputAttributeDescription(0, 0, Format.R32g32b32Sfloat, 0), // Vertex: X, Y, Z new VertexInputAttributeDescription(1, 0, Format.R32g32Sfloat, sizeof(float) * 3), // UV: U, V new VertexInputAttributeDescription(2, 0, Format.R32g32b32Sfloat, sizeof(float) * 5), // Normal: X, Y, Z }; return(data); }
public unsafe DeviceMemory(Device myDevice, MemoryAllocateInfo myAllocation, AllocationCallbacks pAllocator = null) { Result result; fixed(UInt64 *ptrpMemory = &this.m) { result = Interop.NativeMethods.vkAllocateMemory(myDevice.m, myAllocation.m, pAllocator != null ? pAllocator.m : null, ptrpMemory); } if (result != Result.Success) { throw new ResultException(result); } }
void CreateBuffer() { /* * We will now create a buffer. We will render the mandelbrot set into this buffer * in a computer shade later. */ BufferCreateInfo bufferCreateInfo = new BufferCreateInfo() { Size = bufferSize, // buffer size in bytes. Usage = BufferUsages.StorageBuffer, // VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; // buffer is used as a storage buffer. SharingMode = SharingMode.Exclusive // VK_SHARING_MODE_EXCLUSIVE; // buffer is exclusive to a single queue family at a time. }; buffer = device.CreateBuffer(bufferCreateInfo); /* * But the buffer doesn't allocate memory for itself, so we must do that manually. */ /* * First, we find the memory requirements for the buffer. */ MemoryRequirements memoryRequirements = buffer.GetMemoryRequirements(); /* * Now use obtained memory requirements info to allocate the memory for the buffer. */ MemoryAllocateInfo allocateInfo = new MemoryAllocateInfo() { AllocationSize = memoryRequirements.Size, // specify required memory. /* * There are several types of memory that can be allocated, and we must choose a memory type that: * 1) Satisfies the memory requirements(memoryRequirements.memoryTypeBits). * 2) Satifies our own usage requirements. We want to be able to read the buffer memory from the GPU to the CPU * with vkMapMemory, so we set VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT. * Also, by setting VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, memory written by the device(GPU) will be easily * visible to the host(CPU), without having to call any extra flushing commands. So mainly for convenience, we set * this flag. */ MemoryTypeIndex = FindMemoryType( memoryRequirements.MemoryTypeBits, MemoryProperties.HostCoherent | MemoryProperties.HostVisible)// VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT); }; bufferMemory = device.AllocateMemory(allocateInfo); // allocate memory on device. // Now associate that allocated memory with the buffer. With that, the buffer is backed by actual memory. buffer.BindMemory(bufferMemory); }
public unsafe DeviceMemory(Api api, ulong size, uint memoryTypeBits, MemoryAllocateFlags allocateFlags, MemoryPropertyFlags propertyFlags) { _api = api; var flagsInfo = new MemoryAllocateFlagsInfo(); flagsInfo.SType = StructureType.MemoryAllocateFlagsInfo; flagsInfo.PNext = null; flagsInfo.Flags = allocateFlags; var allocInfo = new MemoryAllocateInfo(); allocInfo.SType = StructureType.MemoryAllocateInfo; allocInfo.PNext = &flagsInfo; allocInfo.AllocationSize = size; allocInfo.MemoryTypeIndex = FindMemoryType(memoryTypeBits, propertyFlags); Util.Verify(_api.Vk.AllocateMemory(_api.Device.VkDevice, allocInfo, null, out _vkDeviceMemory), $"{nameof(DeviceMemory)}: Unable to allocate memory."); }
UniformData CreateUniformBuffer(Type targetType) { var data = new UniformData(); var size = Marshal.SizeOf(targetType); data.Buffer = CreateBuffer((ulong)size, BufferUsageFlags.UniformBuffer); var memRequirements = device.GetBufferMemoryRequirements(data.Buffer); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var memAlloc = new MemoryAllocateInfo(memRequirements.Size, memoryIndex); data.Memory = BindBuffer(data.Buffer, memAlloc); data.Descriptor = new DescriptorBufferInfo(data.Buffer, 0, (ulong)size); data.AllocSize = (uint)memAlloc.AllocationSize; return(data); }
public void BindMemoryAndCreateBufferView() { using (Buffer buffer = CreateBuffer()) { PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties(); MemoryRequirements memReq = buffer.GetMemoryRequirements(); var memoryAllocateInfo = new MemoryAllocateInfo( memReq.Size, deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0)); using (DeviceMemory memory = Device.AllocateMemory(memoryAllocateInfo)) { buffer.BindMemory(memory); var bufferViewCreateInfo = new BufferViewCreateInfo(Format.R32UInt); using (buffer.CreateView(bufferViewCreateInfo)) { } using (buffer.CreateView(bufferViewCreateInfo, CustomAllocator)) { } } } }
protected unsafe void AllocateMemory(MemoryPropertyFlags memoryProperties) { MemoryRequirements memoryRequirements; NativeDevice.GetBufferMemoryRequirements(nativeUploadBuffer, out memoryRequirements); if (memoryRequirements.Size == 0) { return; } var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, }; PhysicalDeviceMemoryProperties physicalDeviceMemoryProperties; NativePhysicalDevice.GetMemoryProperties(out physicalDeviceMemoryProperties); var typeBits = memoryRequirements.MemoryTypeBits; for (uint i = 0; i < physicalDeviceMemoryProperties.MemoryTypeCount; i++) { if ((typeBits & 1) == 1) { // Type is available, does it match user properties? var memoryType = *((MemoryType *)&physicalDeviceMemoryProperties.MemoryTypes + i); if ((memoryType.PropertyFlags & memoryProperties) == memoryProperties) { allocateInfo.MemoryTypeIndex = i; break; } } typeBits >>= 1; } nativeUploadBufferMemory = NativeDevice.AllocateMemory(ref allocateInfo); NativeDevice.BindBufferMemory(nativeUploadBuffer, nativeUploadBufferMemory, 0); }
public void CreateBufferMemory <T>(string bufName, MemoryProperties props) { if (mDeviceMems.ContainsKey(bufName)) { Misc.SafeInvoke(eErrorSpam, "Buffer " + bufName + " already has a chunk of mem allocated..."); return; } Buffer buf = mBuffers[bufName]; DeviceMemory dm; MemoryRequirements mr = buf.GetMemoryRequirements(); MemoryAllocateInfo mai = new MemoryAllocateInfo(); mai.AllocationSize = mr.Size; mai.MemoryTypeIndex = FindMemoryType(mr.MemoryTypeBits, props); dm = mLogical.AllocateMemory(mai); mDeviceMems.Add(bufName, dm); }
protected VertexData CreateVertexData() { var data = new VertexData(); var triangleVertices = new[, ] { { 0.5f, 0.5f, 0.0f, /* Vertex Color: */ 1.0f, 0.0f, 0.0f }, { -0.5f, 0.5f, 0.0f, /* Vertex Color: */ 0.0f, 1.0f, 0.0f }, { 0.0f, -0.5f, 0.0f, /* Vertex Color: */ 0.0f, 0.0f, 1.0f }, }; DeviceSize memorySize = (ulong)(sizeof(float) * triangleVertices.Length); data.Buffer = CreateBuffer(memorySize, BufferUsageFlags.VertexBuffer); var memoryRequirements = device.GetBufferMemoryRequirements(data.Buffer); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var allocateInfo = new MemoryAllocateInfo(memoryRequirements.Size, memoryIndex); data.DeviceMemory = BindBuffer(data.Buffer, allocateInfo); var mapped = device.MapMemory(data.DeviceMemory, 0, memorySize); VulkanUtils.Copy2DArray(triangleVertices, mapped, memorySize, memorySize); device.UnmapMemory(data.DeviceMemory); data.BindingDescriptions = new[] { new VertexInputBindingDescription(0, (uint)(sizeof(float) * triangleVertices.GetLength(1)), VertexInputRate.Vertex) }; data.AttributeDescriptions = new[] { new VertexInputAttributeDescription(0, 0, Format.R32g32b32Sfloat, 0), new VertexInputAttributeDescription(1, 0, Format.R32g32b32Sfloat, sizeof(float) * 3) }; return(data); }
private void CreateBuffer(DeviceSize size, BufferUsageFlags usageFlags, MemoryPropertyFlags properties, out Vulkan.Buffer buffer, out DeviceMemory bufferMemory) { var bufferInfo = new BufferCreateInfo() { Size = size, Usage = usageFlags, SharingMode = SharingMode.Exclusive, }; buffer = vkDevice.CreateBuffer(bufferInfo); var memRequirements = vkDevice.GetBufferMemoryRequirements(buffer); var allocInfo = new MemoryAllocateInfo() { AllocationSize = memRequirements.Size, MemoryTypeIndex = FindMemoryType(memRequirements.MemoryTypeBits, properties), }; bufferMemory = vkDevice.AllocateMemory(allocInfo); vkDevice.BindBufferMemory(buffer, bufferMemory, 0); }
private void CreateVertexBuffer() { var vertices = new[,] { { 0.0f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f }, { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f }, }; var createInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Usage = BufferUsageFlags.VertexBuffer, Size = (ulong)(sizeof(float) * vertices.Length) }; vertexBuffer = device.CreateBuffer(ref createInfo); MemoryRequirements memoryRequirements; device.GetBufferMemoryRequirements(vertexBuffer, out memoryRequirements); if (memoryRequirements.Size == 0) return; var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, MemoryTypeIndex = MemoryTypeFromProperties(memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible) }; vertexBufferMemory = device.AllocateMemory(ref allocateInfo); var mapped = device.MapMemory(vertexBufferMemory, 0, (ulong)createInfo.Size, MemoryMapFlags.None); fixed (float* source = &vertices[0, 0]) Utilities.CopyMemory(mapped, new IntPtr(source), (int)createInfo.Size); device.UnmapMemory(vertexBufferMemory); device.BindBufferMemory(vertexBuffer, vertexBufferMemory, 0); vertexAttributes = new [] { new VertexInputAttributeDescription { Binding = 0, Location = 0, Format = Format.R32G32B32SFloat, Offset = 0 }, new VertexInputAttributeDescription { Binding = 0, Location = 1, Format = Format.R32G32B32SFloat, Offset = sizeof(float) * 3 }, }; vertexBindings = new [] { new VertexInputBindingDescription { Binding = 0, InputRate = VertexInputRate.Vertex, Stride = (uint)(sizeof(float) * vertices.GetLength(1)) } }; }
ImageData LoadTexture(string filename, Queue queue, CommandPool cmdPool) { // var bmp = new Bitmap(filename); var bitmapFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb; var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); var bitmapData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmapFormat); // uint imageWidth = (uint)bmp.Width; uint imageHeight = (uint)bmp.Height; var imageData = new ImageData(); imageData.Width = imageWidth; imageData.Height = imageHeight; imageData.Image = CreateTextureImage(Format.B8g8r8a8Unorm, imageWidth, imageHeight); imageData.Memory = BindImage(imageData.Image); imageData.View = CreateImageView(imageData.Image, Format.B8g8r8a8Unorm); imageData.Sampler = CreateSampler(); var memRequirements = device.GetImageMemoryRequirements(imageData.Image); var imageBuffer = CreateBuffer(memRequirements.Size, BufferUsageFlags.TransferSrc | BufferUsageFlags.TransferDst); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var memAlloc = new MemoryAllocateInfo(memRequirements.Size, memoryIndex); var bufferMemory = BindBuffer(imageBuffer, memAlloc); CopyBitmapToBuffer(bitmapData.Scan0, (int)(imageWidth * imageHeight * 4), bufferMemory, memRequirements); // var cmdBuffers = AllocateCommandBuffers(cmdPool, 1); var cmdBuffer = cmdBuffers[0]; var beginInfo = new CommandBufferBeginInfo(); cmdBuffer.Begin(beginInfo); PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.Preinitialized, ImageLayout.TransferDstOptimal, AccessFlags.HostWrite, AccessFlags.TransferWrite); CopyBufferToImage(cmdBuffer, imageData, imageBuffer); PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal, AccessFlags.TransferWrite, AccessFlags.ShaderRead); // wait... why does this work? device.DestroyBuffer(imageBuffer); device.FreeMemory(bufferMemory); cmdBuffer.End(); var submitInfo = new SubmitInfo(null, null, new[] { cmdBuffer }, null); queue.Submit(new[] { submitInfo }); submitInfo.Dispose(); queue.WaitIdle(); device.FreeCommandBuffers(cmdPool, new[] { cmdBuffer }); // //CopyBufferToImage(queue, cmdPool, imageData, imageBuffer); // bmp.UnlockBits(bitmapData); bmp.Dispose(); // return(imageData); }
private void CreateVertexBuffer() { var vertices = new[, ] { { 0.0f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f }, { 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f }, { -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f }, }; var createInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Usage = BufferUsageFlags.VertexBuffer, Size = (ulong)(sizeof(float) * vertices.Length) }; vertexBuffer = device.CreateBuffer(ref createInfo); MemoryRequirements memoryRequirements; device.GetBufferMemoryRequirements(vertexBuffer, out memoryRequirements); if (memoryRequirements.Size == 0) { return; } var allocateInfo = new MemoryAllocateInfo { StructureType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, MemoryTypeIndex = MemoryTypeFromProperties(memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible) }; vertexBufferMemory = device.AllocateMemory(ref allocateInfo); var mapped = device.MapMemory(vertexBufferMemory, 0, (ulong)createInfo.Size, MemoryMapFlags.None); fixed(float *source = &vertices[0, 0]) Utilities.CopyMemory(mapped, new IntPtr(source), (int)createInfo.Size); device.UnmapMemory(vertexBufferMemory); device.BindBufferMemory(vertexBuffer, vertexBufferMemory, 0); vertexAttributes = new [] { new VertexInputAttributeDescription { Binding = 0, Location = 0, Format = Format.R32G32B32SFloat, Offset = 0 }, new VertexInputAttributeDescription { Binding = 0, Location = 1, Format = Format.R32G32B32SFloat, Offset = sizeof(float) * 3 }, }; vertexBindings = new [] { new VertexInputBindingDescription { Binding = 0, InputRate = VertexInputRate.Vertex, Stride = (uint)(sizeof(float) * vertices.GetLength(1)) } }; }
public ExampleRenderToDisk() { // The goal of this example is to: // // - Initialize Vulkan // - Create an empty image of size `imageWidth` x `imageHeight` // - Use that image as a render target for a triangle // - Save the render to disk // - Shutdown Vulkan // const string OutputFilename = "./out.bmp"; const Format ImageFormat = Format.R8g8b8a8Unorm; uint imageWidth = 800; uint imageHeight = 600; Instance instance; PhysicalDevice[] physDevices; PhysicalDevice physDevice; QueueFamilyProperties[] queueFamilies; //Device device; Queue queue; CommandPool cmdPool; instance = CreateInstance(); // Create a new Vulkan Instance physDevices = EnumeratePhysicalDevices(instance); // Discover the physical devices attached to the system physDevice = physDevices[0]; // Select the first physical device queueFamilies = physDevice.GetQueueFamilyProperties(); // Get properties about the queues on the physical device physDeviceMem = physDevice.GetMemoryProperties(); // Get properties about the memory on the physical device device = CreateDevice(physDevice, 0); // Create a device from the physical device queue = GetQueue(physDevice, 0); // Get an execution queue from the physical device cmdPool = CreateCommandPool(0); // Create a command pool from which command buffers are created // Now that we have a command pool, we can begin creating command buffers // and recording commands. You will find however that you can't do much of // anything without first initializing a few more dependencies. VertexData vertexData; ImageData imageData; Buffer imageBuffer; RenderPass renderPass; PipelineLayout pipelineLayout; Pipeline[] pipelines; Pipeline pipeline; Framebuffer framebuffer; // This exercise would be pointless if we had nothing to // render, so lets create that data now. vertexData = CreateVertexData(); // Since we didn't enable any extensions, we don't have access to // any display surfaces to render too. Instead we'll create an image // in memory and have Vulkan use it as the render target imageData = new ImageData(); imageData.Width = imageWidth; imageData.Height = imageHeight; imageData.Image = CreateImage(ImageFormat, imageWidth, imageHeight); imageData.Memory = BindImage(imageData.Image); imageData.View = CreateImageView(imageData.Image, ImageFormat); // Allocate device memory to the image so that it can be read from and written to var memRequirements = device.GetImageMemoryRequirements(imageData.Image); imageBuffer = CreateBuffer(memRequirements.Size, BufferUsageFlags.TransferSrc | BufferUsageFlags.TransferDst); var memoryIndex = FindMemoryIndex(MemoryPropertyFlags.HostVisible); var memAlloc = new MemoryAllocateInfo(memRequirements.Size, memoryIndex); var bufferMem = BindBuffer(imageBuffer, memAlloc); // Load shaders from disk and set them up to be passed to `CreatePipeline` var shaderStageCreateInfos = new[] { GetShaderStageCreateInfo(ShaderStageFlags.Vertex, "triangle.vert.spv"), GetShaderStageCreateInfo(ShaderStageFlags.Fragment, "triangle.frag.spv"), }; // Create the render dependencies renderPass = CreateRenderPass(ImageFormat); pipelineLayout = CreatePipelineLayout(); pipelines = CreatePipelines(pipelineLayout, renderPass, shaderStageCreateInfos, vertexData); pipeline = pipelines.First(); framebuffer = CreateFramebuffer(renderPass, imageData); // Render the triangle to the image Render(queue, cmdPool, vertexData, imageData, imageBuffer, renderPass, pipeline, framebuffer); var renderData = CopyBufferToArray(bufferMem, memRequirements); WriteBitmap(renderData, OutputFilename, (int)imageWidth, (int)imageHeight); Console.WriteLine($"Render written to {OutputFilename}"); #region Shutdown // Destroy Vulkan handles in reverse order of creation (roughly) device.DestroyShaderModule(shaderStageCreateInfos[0].Module); device.DestroyShaderModule(shaderStageCreateInfos[1].Module); device.DestroyBuffer(imageBuffer); device.FreeMemory(bufferMem); device.DestroyImageView(imageData.View); device.DestroyImage(imageData.Image); device.FreeMemory(imageData.Memory); device.DestroyBuffer(vertexData.Buffer); device.FreeMemory(vertexData.DeviceMemory); device.DestroyFramebuffer(framebuffer); device.DestroyPipeline(pipeline); device.DestroyPipelineLayout(pipelineLayout); device.DestroyRenderPass(renderPass); device.DestroyCommandPool(cmdPool); device.Destroy(); DebugUtils.DestroyDebugReportCallback(instance, debugCallback); instance.Destroy(); #endregion }
public unsafe DeviceMemory(MemoryAllocateInfo myAllocation, AllocationCallbacks pAllocator = null) : this(VulkanRenderer.SelectedLogicalDevice, myAllocation, pAllocator) { }
internal static unsafe extern Result vkAllocateMemory(Device device, MemoryAllocateInfo* allocateInfo, AllocationCallbacks* allocator, DeviceMemory* memory);
public unsafe void Initialize() { if (!InternalHandle.HasValue) { MipLevels = MipLevels != 0 ? MipLevels : (uint)Math.Floor(Math.Log(Math.Max(Size.Width, Size.Height), 2)); var imageCreateInfo = new ImageCreateInfo { SType = StructureType.ImageCreateInfo, ImageType = ImageType.ImageType2D, Format = Format, Extent = new Extent3D((uint?)Size.Width, (uint?)Size.Height, 1), MipLevels = MipLevels, ArrayLayers = 1, Samples = SampleCountFlags.SampleCount1Bit, Tiling = Tiling, Usage = _imageUsageFlags, SharingMode = SharingMode.Exclusive, InitialLayout = ImageLayout.Undefined, Flags = ImageCreateFlags.ImageCreateMutableFormatBit }; _device.Api.CreateImage(_device.InternalHandle, imageCreateInfo, null, out var image).ThrowOnError(); InternalHandle = image; _device.Api.GetImageMemoryRequirements(_device.InternalHandle, InternalHandle.Value, out var memoryRequirements); var memoryAllocateInfo = new MemoryAllocateInfo { SType = StructureType.MemoryAllocateInfo, AllocationSize = memoryRequirements.Size, MemoryTypeIndex = (uint)VulkanMemoryHelper.FindSuitableMemoryTypeIndex( _physicalDevice, memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit) }; _device.Api.AllocateMemory(_device.InternalHandle, memoryAllocateInfo, null, out var imageMemory); _imageMemory = imageMemory; _device.Api.BindImageMemory(_device.InternalHandle, InternalHandle.Value, _imageMemory, 0); MemorySize = memoryRequirements.Size; var componentMapping = new ComponentMapping( ComponentSwizzle.Identity, ComponentSwizzle.Identity, ComponentSwizzle.Identity, ComponentSwizzle.Identity); AspectFlags = ImageAspectFlags.ImageAspectColorBit; var subresourceRange = new ImageSubresourceRange(AspectFlags, 0, MipLevels, 0, 1); var imageViewCreateInfo = new ImageViewCreateInfo { SType = StructureType.ImageViewCreateInfo, Image = InternalHandle.Value, ViewType = ImageViewType.ImageViewType2D, Format = Format, Components = componentMapping, SubresourceRange = subresourceRange }; _device.Api .CreateImageView(_device.InternalHandle, imageViewCreateInfo, null, out var imageView) .ThrowOnError(); _imageView = imageView; _currentLayout = ImageLayout.Undefined; TransitionLayout(ImageLayout.ColorAttachmentOptimal, AccessFlags.AccessNoneKhr); } }
static public MPointArray ComputeData(MPointArray inPos, float angle, float envolope) { var memorySize = inPos.Count * 4 * sizeof(float); float[] ubo = { inPos.Count, angle, envolope }; // pos to float[] float[] allPos = new float[inPos.Count * 4]; var i = 0; foreach (var point in inPos) { allPos[i * 4 + 0] = (float)point.x; allPos[i * 4 + 1] = (float)point.y; allPos[i * 4 + 2] = (float)point.z; allPos[i * 4 + 3] = (float)point.w; i++; } var instance = new Instance(new InstanceCreateInfo { ApplicationInfo = new ApplicationInfo { ApplicationName = "CSharp Vulkan", ApplicationVersion = Vulkan.Version.Make(1, 0, 0), ApiVersion = Vulkan.Version.Make(1, 0, 0), EngineName = "CSharp Engine", EngineVersion = Vulkan.Version.Make(1, 0, 0) }, //EnabledExtensionCount = 0, //EnabledLayerCount = 0 EnabledExtensionNames = new string[] { "VK_EXT_debug_report" }, EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" } }); var debugCallback = new Instance.DebugReportCallback(DebugReportCallback); instance.EnableDebug(debugCallback, DebugReportFlagsExt.Warning | DebugReportFlagsExt.Error); PhysicalDevice physicalDevice = instance.EnumeratePhysicalDevices()[0]; var queueFamilyIndex = FindBestComputeQueue(physicalDevice); DeviceQueueCreateInfo[] deviceQueueCreateInfo = { new DeviceQueueCreateInfo { QueueFamilyIndex = queueFamilyIndex, QueueCount = 1, QueuePriorities = new float[] { 1.0f } } }; var deviceCreateInfo = new DeviceCreateInfo { QueueCreateInfos = deviceQueueCreateInfo, EnabledFeatures = new PhysicalDeviceFeatures(), EnabledExtensionCount = 0, //EnabledLayerCount = 0 //EnabledExtensionNames = new string[] { "VK_EXT_debug_report" }, EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" } }; var device = physicalDevice.CreateDevice(deviceCreateInfo); //var memProperties = physicalDevice.GetMemoryProperties(); var bufferCreateInfo = new BufferCreateInfo { Size = memorySize, Usage = BufferUsageFlags.StorageBuffer, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queueFamilyIndex } }; var inBuffer = device.CreateBuffer(bufferCreateInfo); var outBuffer = device.CreateBuffer(bufferCreateInfo); var memRequirements = device.GetBufferMemoryRequirements(inBuffer); uint memIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent); var memoryAllocatInfo = new MemoryAllocateInfo { AllocationSize = memRequirements.Size, MemoryTypeIndex = memIndex }; var memory = device.AllocateMemory(memoryAllocatInfo); var dataPtr = device.MapMemory(memory, 0, memorySize); Marshal.Copy(allPos, 0, dataPtr, allPos.Length); device.UnmapMemory(memory); memRequirements = device.GetBufferMemoryRequirements(outBuffer); memoryAllocatInfo.MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent); var outMemory = device.AllocateMemory(memoryAllocatInfo); device.BindBufferMemory(inBuffer, memory, 0); device.BindBufferMemory(outBuffer, outMemory, 0); //var uboSize = Marshal.SizeOf(ubo); var uboSize = 3 * sizeof(float); var uboBufferCreateInfo = new BufferCreateInfo { Size = uboSize, Usage = BufferUsageFlags.UniformBuffer, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { queueFamilyIndex } }; var uboBuffer = device.CreateBuffer(uboBufferCreateInfo); memRequirements = device.GetBufferMemoryRequirements(uboBuffer); var uboMemoryAllocInfo = new MemoryAllocateInfo { AllocationSize = memRequirements.Size, MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent) }; var uboMemory = device.AllocateMemory(uboMemoryAllocInfo); var uboPtr = device.MapMemory(uboMemory, 0, uboSize); Marshal.Copy(ubo, 0, uboPtr, ubo.Length); device.UnmapMemory(uboMemory); device.BindBufferMemory(uboBuffer, uboMemory, 0); //string textureName = string.Format("{0}.comp.spv", typeof(VulankCompute).Namespace); //Stream stream = typeof(VulankCompute).GetTypeInfo().Assembly.GetManifestResourceStream(textureName); string shaderFile = @"E:\coding\CShape\yTwistCSharpVulkan\comp.spv"; Stream stream = File.Open(shaderFile, FileMode.Open); byte[] shaderCode = new byte[stream.Length]; stream.Read(shaderCode, 0, (int)stream.Length); stream.Close(); stream.Dispose(); var shaderModule = device.CreateShaderModule(shaderCode); DescriptorSetLayoutBinding[] descriptorSetLayoutBindings = { new DescriptorSetLayoutBinding { Binding = 0, DescriptorType = DescriptorType.StorageBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute }, new DescriptorSetLayoutBinding { Binding = 1, DescriptorType = DescriptorType.StorageBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute }, new DescriptorSetLayoutBinding { Binding = 2, DescriptorType = DescriptorType.UniformBuffer, DescriptorCount = 1, StageFlags = ShaderStageFlags.Compute } }; var descriporSetLayoutCreateinfo = new DescriptorSetLayoutCreateInfo { Bindings = descriptorSetLayoutBindings }; var descriptorSetLayout = device.CreateDescriptorSetLayout(descriporSetLayoutCreateinfo); var descriptorPool = device.CreateDescriptorPool(new DescriptorPoolCreateInfo { MaxSets = 1, PoolSizes = new DescriptorPoolSize[] { new DescriptorPoolSize { DescriptorCount = 3 } } }); var descriptorSet = device.AllocateDescriptorSets(new DescriptorSetAllocateInfo { DescriptorPool = descriptorPool, SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout } })[0]; var inBufferInfo = new DescriptorBufferInfo { Buffer = inBuffer, Offset = 0, Range = memorySize }; var outBufferInfo = new DescriptorBufferInfo { Buffer = outBuffer, Offset = 0, Range = memorySize }; var uboBufferInfo = new DescriptorBufferInfo { Buffer = uboBuffer, Offset = 0, Range = uboSize }; WriteDescriptorSet[] writeDescriptorSets = { new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 0, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.StorageBuffer, BufferInfo = new DescriptorBufferInfo[] { inBufferInfo } }, new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 1, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.StorageBuffer, BufferInfo = new DescriptorBufferInfo[] { outBufferInfo } }, new WriteDescriptorSet { DstSet = descriptorSet, DstBinding = 2, DstArrayElement = 0, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, BufferInfo = new DescriptorBufferInfo[] { uboBufferInfo } } }; device.UpdateDescriptorSets(writeDescriptorSets, null); var pipelineLayout = device.CreatePipelineLayout(new PipelineLayoutCreateInfo { SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout } }); var shaderStage = new PipelineShaderStageCreateInfo { Stage = ShaderStageFlags.Compute, Module = shaderModule, Name = "main" }; var pipeline = device.CreateComputePipelines(null, new ComputePipelineCreateInfo[] { new ComputePipelineCreateInfo { Stage = shaderStage, Layout = pipelineLayout } })[0]; var commandPool = device.CreateCommandPool(new CommandPoolCreateInfo { QueueFamilyIndex = queueFamilyIndex }); var cmdBuffer = device.AllocateCommandBuffers(new CommandBufferAllocateInfo { CommandPool = commandPool, CommandBufferCount = 1, Level = CommandBufferLevel.Primary })[0]; cmdBuffer.Begin(new CommandBufferBeginInfo { Flags = CommandBufferUsageFlags.OneTimeSubmit }); cmdBuffer.CmdBindPipeline(PipelineBindPoint.Compute, pipeline); cmdBuffer.CmdBindDescriptorSet(PipelineBindPoint.Compute, pipelineLayout, 0, descriptorSet, null); cmdBuffer.CmdDispatch((uint)inPos.Count, 1, 1); cmdBuffer.End(); var queue = device.GetQueue(queueFamilyIndex, 0); //var fence = device.CreateFence(new FenceCreateInfo { Flags=0 }); queue.Submit(new SubmitInfo { WaitSemaphoreCount = 0, CommandBuffers = new CommandBuffer[] { cmdBuffer }, }); queue.WaitIdle(); //device.WaitForFence(fence, true, UInt64.MaxValue); var newDataPtr = device.MapMemory(outMemory, 0, memorySize); Marshal.Copy(newDataPtr, allPos, 0, allPos.Length); device.UnmapMemory(outMemory); var j = 0; foreach (var p in inPos) { p.x = allPos[j * 4 + 0]; p.y = allPos[j * 4 + 1]; p.z = allPos[j * 4 + 2]; p.w = allPos[j * 4 + 3]; j++; } //device.DestroyFence(fence); device.DestroyShaderModule(shaderModule); device.DestroyCommandPool(commandPool); device.DestroyDescriptorSetLayout(descriptorSetLayout); device.DestroyDescriptorPool(descriptorPool); device.DestroyPipelineLayout(pipelineLayout); device.DestroyPipeline(pipeline); device.DestroyBuffer(inBuffer); device.DestroyBuffer(outBuffer); device.DestroyBuffer(uboBuffer); device.FreeMemory(memory); device.FreeMemory(outMemory); device.FreeMemory(uboMemory); device.Destroy(); //instance.Destroy(); return(inPos); }
public unsafe DeviceMemory AllocateMemory(ref MemoryAllocateInfo allocateInfo, AllocationCallbacks* allocator = null) { DeviceMemory memory; fixed (MemoryAllocateInfo* __allocateInfo__ = &allocateInfo) { vkAllocateMemory(this, __allocateInfo__, allocator, &memory).CheckError(); } return memory; }