public unsafe BufferHolder Create(VulkanGraphicsDevice gd, int size, bool forConditionalRendering = false) { var usage = DefaultBufferUsageFlags; if (forConditionalRendering && gd.Capabilities.SupportsConditionalRendering) { usage |= BufferUsageFlags.BufferUsageConditionalRenderingBitExt; } var bufferCreateInfo = new BufferCreateInfo() { SType = StructureType.BufferCreateInfo, Size = (ulong)size, Usage = usage, SharingMode = SharingMode.Exclusive }; gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError(); gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements); var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, DefaultBufferMemoryFlags); if (allocation.Memory.Handle == 0UL) { gd.Api.DestroyBuffer(_device, buffer, null); return(null); } gd.Api.BindBufferMemory(_device, buffer, allocation.Memory, allocation.Offset); return(new BufferHolder(gd, _device, buffer, allocation, size)); }
public void CreateBuffer() { var createInfo = new BufferCreateInfo(32, BufferUsages.VertexBuffer); using (Device.CreateBuffer(createInfo)) { } using (Device.CreateBuffer(createInfo, CustomAllocator)) { } }
private unsafe void CreateBuffer() { var createInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Flags = BufferCreateFlags.None }; for (int i = 0; i < MipLevels; i++) { var mipmap = GetMipMapDescription(i); createInfo.Size += (uint)(mipmap.DepthStride * mipmap.Depth * ArraySize); } createInfo.Usage = BufferUsageFlags.TransferSource | BufferUsageFlags.TransferDestination; // Create buffer NativeBuffer = GraphicsDevice.NativeDevice.CreateBuffer(ref createInfo); // Allocate and bind memory MemoryRequirements memoryRequirements; GraphicsDevice.NativeDevice.GetBufferMemoryRequirements(NativeBuffer, out memoryRequirements); AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements); if (NativeMemory != DeviceMemory.Null) { GraphicsDevice.NativeDevice.BindBufferMemory(NativeBuffer, NativeMemory, 0); } }
public UniformBuffer() { int mySize = Marshal.SizeOf(typeof(T)); BufferCreateInfo myBuffer = new BufferCreateInfo { Size = mySize, Usage = BufferUsageFlags.UniformBuffer, SharingMode = SharingMode.Exclusive, QueueFamilyIndices = new uint[] { VulkanRenderer.ActiveGraphicsFamilyQueueIndex } }; //TODO: Fix this in the buffers -_- CreateBuffer(VulkanRenderer.SelectedPhysicalDevice, myBuffer, null); }
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); }
/* public Vulkan.Buffer CreateUniformBuffer() * { * var uniformBufferData = new AreaUniformBuffer * { * width = SurfaceCapabilities.CurrentExtent.Width, * height = SurfaceCapabilities.CurrentExtent.Height * }; * * return CreateBuffer(uniformBufferData, BufferUsageFlags.UniformBuffer, typeof(AreaUniformBuffer)); * } * private Vulkan.Buffer CreateBuffer( 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 } * }; * return CreateBufferBufferCreateInfoCanBeSet(values, type, length, size, createBufferInfo); * } * * private Vulkan.Buffer CreateBufferBufferCreateInfoCanBeSet(object values, Type type, int length, int size, BufferCreateInfo createBufferInfo) * { * var buffer = LogicalDevice.CreateBuffer(createBufferInfo); * var memoryReq = LogicalDevice.GetBufferMemoryRequirements(buffer); * var allocInfo = new MemoryAllocateInfo { AllocationSize = memoryReq.Size }; * var memoryProperties = myPhysicalDevice.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 = LogicalDevice.AllocateMemory(allocInfo); * var memPtr = LogicalDevice.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); * * LogicalDevice.UnmapMemory(deviceMemory); * LogicalDevice.BindBufferMemory(buffer, deviceMemory, 0); * * return buffer; * } * VertextBuffer VertBuffer = */ public unsafe VulkanBuffer(VulkanPhysicalDevice myDevice, BufferCreateInfo createBufferInfo, AllocationCallbacks pAllocator = null) //Tested { if (myDevice == null) { throw new VULKANDEVICE_NO_ACTIVE_DEVICE(); } this.Allocator = pAllocator; this.myActiveDevice = myDevice; CreateBuffer(myDevice, createBufferInfo, pAllocator); }
public unsafe VertexBuffer(T[] myManagedArray, uint[] QueueFamilyIndices, SharingMode myMode = SharingMode.Exclusive, AllocationCallbacks pAllocator = null) { int mySize = Marshal.SizeOf(typeof(T)); BufferCreateInfo myBuffer = new BufferCreateInfo { Size = myManagedArray.Length * mySize, Usage = BufferUsageFlags.VertexBuffer, SharingMode = myMode, QueueFamilyIndices = QueueFamilyIndices }; CreateBuffer(VulkanRenderer.SelectedPhysicalDevice, myBuffer, pAllocator); CopyFromMemory <T>(myManagedArray); }
public unsafe UniformBuffer(T myManagedArray, SharingMode myMode = SharingMode.Exclusive, AllocationCallbacks pAllocator = null) { int mySize = Marshal.SizeOf(typeof(T)); BufferCreateInfo myBuffer = new BufferCreateInfo { Size = mySize, Usage = BufferUsageFlags.UniformBuffer, SharingMode = myMode, QueueFamilyIndices = new uint[] { VulkanRenderer.ActiveGraphicsFamilyQueueIndex } }; CreateBuffer(VulkanRenderer.SelectedPhysicalDevice, myBuffer, pAllocator); CopyFromMemory <T>(myManagedArray); }
public unsafe StagingBuffer(T[] myManagedArray, VulkanPhysicalDevice myDevice, uint[] VisibleToQueueFamilyIndices, SharingMode myMode = SharingMode.Exclusive, AllocationCallbacks pAllocator = null) { int mySize = Marshal.SizeOf(typeof(T)); BufferCreateInfo myBuffer = new BufferCreateInfo { Size = myManagedArray.Length * mySize, Usage = BufferUsageFlags.TransferSrc, SharingMode = myMode, QueueFamilyIndices = VisibleToQueueFamilyIndices }; CreateBuffer(myDevice, myBuffer, pAllocator); CopyFromMemory <T>(myManagedArray); }
public unsafe UniformBuffer(T myManagedArray, VulkanPhysicalDevice myDevice, uint[] QueueFamilyIndices, SharingMode myMode = SharingMode.Exclusive, AllocationCallbacks pAllocator = null) { int mySize = Marshal.SizeOf(typeof(T)); BufferCreateInfo myBuffer = new BufferCreateInfo { Size = mySize, Usage = BufferUsageFlags.UniformBuffer, SharingMode = myMode, QueueFamilyIndices = QueueFamilyIndices }; CreateBuffer(myDevice, myBuffer, pAllocator); CopyFromMemory <T>(myManagedArray); }
public void CreateBuffer(int sizeInBytes, string name, BufferUsages usage, SharingMode sm, int [] famIndexes = null) { BufferCreateInfo bci = new BufferCreateInfo(sizeInBytes, usage, BufferCreateFlags.None, sm, famIndexes); Buffer buf = mLogical.CreateBuffer(bci); mBuffers.Add(name, buf); }
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); }
private unsafe void CreateUniformBuffer() //Simpler setup from the Vertex buffer because there is no staging or device copying { BufferCreateInfo bufferInfo = new BufferCreateInfo { SType = StructureType.BufferCreateInfo, Size = this.UniformBufferSize, Usage = BufferUsageFlags.BufferUsageUniformBufferBit, SharingMode = SharingMode.Exclusive }; // Allow this to be updated every frame var allocInfo = new AllocationCreateInfo( usage: MemoryUsage.CPU_To_GPU, requiredFlags: MemoryPropertyFlags.MemoryPropertyHostVisibleBit); // Binds buffer to allocation for you var buffer = this.Allocator.CreateBuffer(in bufferInfo, in allocInfo, out var allocation); // Camera/MVP Matrix calculation Camera.LookAt(new Vector3(2f, 2f, -5f), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); var radFov = MathF.PI / 180f * 45f; var aspect = (float)this.SwapchainExtent.Width / this.SwapchainExtent.Height; Camera.Perspective(radFov, aspect, 0.5f, 100f); Camera.UpdateMVP(); allocation.Map(); Matrix4x4 *ptr = (Matrix4x4 *)allocation.MappedData; ptr[0] = Camera.MVPMatrix; // Camera Matrix ptr[1] = Matrix4x4.Identity; // Model Matrix allocation.Unmap(); this.UniformBuffer = buffer; this.UniformAllocation = allocation; }
protected unsafe void CreateBuffer(VulkanPhysicalDevice myDevice, BufferCreateInfo createBufferInfo, AllocationCallbacks pAllocator = null) { if (myDevice == null) { throw new VULKANDEVICE_NO_ACTIVE_DEVICE(); } this.Allocator = pAllocator; this.myActiveDevice = myDevice; SizeOfInternalStructure = createBufferInfo.Size; Result result; fixed(UInt64 *ptrpBuffer = &this.m) { result = Interop.NativeMethods.vkCreateBuffer(myDevice.LogicalDevice.m, createBufferInfo != null ? createBufferInfo.m : (Interop.BufferCreateInfo *) default(IntPtr), pAllocator != null ? pAllocator.m : null, ptrpBuffer); } if (result != Result.Success) { throw new ResultException(result); } }
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); }
internal unsafe IntPtr AllocateUploadBuffer(int size, out SharpVulkan.Buffer resource, out int offset) { // TODO D3D12 thread safety, should we simply use locks? if (nativeUploadBuffer == SharpVulkan.Buffer.Null || nativeUploadBufferOffset + size > nativeUploadBufferSize) { if (nativeUploadBuffer != SharpVulkan.Buffer.Null) { NativeDevice.UnmapMemory(nativeUploadBufferMemory); Collect(nativeUploadBuffer); Collect(nativeUploadBufferMemory); } // Allocate new buffer // TODO D3D12 recycle old ones (using fences to know when GPU is done with them) // TODO D3D12 ResourceStates.CopySource not working? nativeUploadBufferSize = Math.Max(4 * 1024 * 1024, size); var bufferCreateInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Size = (ulong)nativeUploadBufferSize, Flags = BufferCreateFlags.None, Usage = BufferUsageFlags.TransferSource, }; nativeUploadBuffer = NativeDevice.CreateBuffer(ref bufferCreateInfo); AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent); nativeUploadBufferStart = NativeDevice.MapMemory(nativeUploadBufferMemory, 0, (ulong)nativeUploadBufferSize, MemoryMapFlags.None); nativeUploadBufferOffset = 0; } // Bump allocate resource = nativeUploadBuffer; offset = nativeUploadBufferOffset; nativeUploadBufferOffset += size; return(nativeUploadBufferStart + offset); }
Buffer CreateBuffer(DeviceSize size, BufferUsageFlags flags) { var bufferCreateInfo = new BufferCreateInfo(size, flags, SharingMode.Exclusive, null); return(device.CreateBuffer(bufferCreateInfo)); }
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)) } }; }
private unsafe void CreatePipelineLayout() { var binding = new DescriptorSetLayoutBinding { Binding = 0, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, StageFlags = ShaderStageFlags.Vertex }; var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo { StructureType = StructureType.DescriptorSetLayoutCreateInfo, BindingCount = 1, Bindings = new IntPtr(&binding) }; descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo); var localDescriptorSetLayout = descriptorSetLayout; var createInfo = new PipelineLayoutCreateInfo { StructureType = StructureType.PipelineLayoutCreateInfo, SetLayoutCount = 1, SetLayouts = new IntPtr(&localDescriptorSetLayout) }; pipelineLayout = device.CreatePipelineLayout(ref createInfo); var poolSize = new DescriptorPoolSize { DescriptorCount = 2, Type = DescriptorType.UniformBuffer }; var descriptorPoolCreateinfo = new DescriptorPoolCreateInfo { StructureType = StructureType.DescriptorPoolCreateInfo, PoolSizeCount = 1, PoolSizes = new IntPtr(&poolSize), MaxSets = 2 }; descriptorPool = device.CreateDescriptorPool(ref descriptorPoolCreateinfo); var bufferCreateInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Usage = BufferUsageFlags.UniformBuffer, Size = 64, }; uniformBuffer = device.CreateBuffer(ref bufferCreateInfo); MemoryRequirements memoryRequirements; device.GetBufferMemoryRequirements(uniformBuffer, out memoryRequirements); var memory = AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements); device.BindBufferMemory(uniformBuffer, memory, 0); var mappedMemory = device.MapMemory(memory, 0, 64, MemoryMapFlags.None); var data = new[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; Utilities.Write(mappedMemory, data, 0, data.Length); device.UnmapMemory(memory); }
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)) } }; }
/// <summary> /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataPointer"></param> public unsafe void Recreate(IntPtr dataPointer) { var createInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Size = (ulong)bufferDescription.SizeInBytes, Flags = BufferCreateFlags.None, }; createInfo.Usage |= BufferUsageFlags.TransferSource; // We always fill using transfer //if (bufferDescription.Usage != GraphicsResourceUsage.Immutable) createInfo.Usage |= BufferUsageFlags.TransferDestination; if ((ViewFlags & BufferFlags.VertexBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.VertexBuffer; NativeAccessMask |= AccessFlags.VertexAttributeRead; NativePipelineStageMask |= PipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.IndexBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.IndexBuffer; NativeAccessMask |= AccessFlags.IndexRead; NativePipelineStageMask |= PipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.ConstantBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.UniformBuffer; NativeAccessMask |= AccessFlags.UniformRead; NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader; } if ((ViewFlags & BufferFlags.ShaderResource) != 0) { createInfo.Usage |= BufferUsageFlags.UniformTexelBuffer; NativeAccessMask |= AccessFlags.ShaderRead; NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader; if ((ViewFlags & BufferFlags.UnorderedAccess) != 0) { createInfo.Usage |= BufferUsageFlags.StorageTexelBuffer; NativeAccessMask |= AccessFlags.ShaderWrite; } } // Create buffer NativeBuffer = GraphicsDevice.NativeDevice.CreateBuffer(ref createInfo); // Allocate memory var memoryProperties = MemoryPropertyFlags.DeviceLocal; if (bufferDescription.Usage == GraphicsResourceUsage.Staging) { throw new NotImplementedException(); } else if (Usage == GraphicsResourceUsage.Dynamic) { memoryProperties = MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent; } MemoryRequirements memoryRequirements; GraphicsDevice.NativeDevice.GetBufferMemoryRequirements(NativeBuffer, out memoryRequirements); AllocateMemory(memoryProperties, memoryRequirements); if (NativeMemory != DeviceMemory.Null) { GraphicsDevice.NativeDevice.BindBufferMemory(NativeBuffer, NativeMemory, 0); } if (SizeInBytes > 0) { // Begin copy command buffer var commandBufferAllocateInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, CommandPool = GraphicsDevice.NativeCopyCommandPool, CommandBufferCount = 1, Level = CommandBufferLevel.Primary }; CommandBuffer commandBuffer; GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocateInfo, &commandBuffer); var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.OneTimeSubmit }; commandBuffer.Begin(ref beginInfo); // Copy to upload buffer if (dataPointer != IntPtr.Zero) { if (Usage == GraphicsResourceUsage.Dynamic) { var uploadMemory = GraphicsDevice.NativeDevice.MapMemory(NativeMemory, 0, (ulong)SizeInBytes, MemoryMapFlags.None); Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes); GraphicsDevice.NativeDevice.UnmapMemory(NativeMemory); } else { var sizeInBytes = bufferDescription.SizeInBytes; SharpVulkan.Buffer uploadResource; int uploadOffset; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(sizeInBytes, out uploadResource, out uploadOffset); Utilities.CopyMemory(uploadMemory, dataPointer, sizeInBytes); // Barrier var memoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)sizeInBytes); commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &memoryBarrier, 0, null); // Copy var bufferCopy = new BufferCopy { SourceOffset = (uint)uploadOffset, DestinationOffset = 0, Size = (uint)sizeInBytes }; commandBuffer.CopyBuffer(uploadResource, NativeBuffer, 1, &bufferCopy); } } else { commandBuffer.FillBuffer(NativeBuffer, 0, (uint)bufferDescription.SizeInBytes, 0); } // Barrier var bufferMemoryBarrier = new BufferMemoryBarrier(NativeBuffer, AccessFlags.TransferWrite, NativeAccessMask); commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 0, null); // Close and submit commandBuffer.End(); var submitInfo = new SubmitInfo { StructureType = StructureType.SubmitInfo, CommandBufferCount = 1, CommandBuffers = new IntPtr(&commandBuffer), }; lock (GraphicsDevice.QueueLock) { GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null); GraphicsDevice.NativeCommandQueue.WaitIdle(); //commandBuffer.Reset(CommandBufferResetFlags.None); GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer); } InitializeViews(); } }
protected unsafe VulkanBuffer(BufferCreateInfo createBufferInfo, AllocationCallbacks pAllocator) : this(VulkanRenderer.SelectedPhysicalDevice, createBufferInfo, pAllocator) { }
/// <summary> /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="dataPointer"></param> public unsafe void Recreate(IntPtr dataPointer) { var createInfo = new BufferCreateInfo { StructureType = StructureType.BufferCreateInfo, Size = (ulong)bufferDescription.SizeInBytes, Flags = BufferCreateFlags.None, }; createInfo.Usage |= BufferUsageFlags.TransferSource; // We always fill using transfer //if (bufferDescription.Usage != GraphicsResourceUsage.Immutable) createInfo.Usage |= BufferUsageFlags.TransferDestination; if (Usage == GraphicsResourceUsage.Staging) { NativeAccessMask = AccessFlags.HostRead | AccessFlags.HostWrite; NativePipelineStageMask |= PipelineStageFlags.Host; } else { if ((ViewFlags & BufferFlags.VertexBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.VertexBuffer; NativeAccessMask |= AccessFlags.VertexAttributeRead; NativePipelineStageMask |= PipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.IndexBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.IndexBuffer; NativeAccessMask |= AccessFlags.IndexRead; NativePipelineStageMask |= PipelineStageFlags.VertexInput; } if ((ViewFlags & BufferFlags.ConstantBuffer) != 0) { createInfo.Usage |= BufferUsageFlags.UniformBuffer; NativeAccessMask |= AccessFlags.UniformRead; NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader; } if ((ViewFlags & BufferFlags.ShaderResource) != 0) { createInfo.Usage |= BufferUsageFlags.UniformTexelBuffer; NativeAccessMask |= AccessFlags.ShaderRead; NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader; if ((ViewFlags & BufferFlags.UnorderedAccess) != 0) { createInfo.Usage |= BufferUsageFlags.StorageTexelBuffer; NativeAccessMask |= AccessFlags.ShaderWrite; } } } // Create buffer NativeBuffer = GraphicsDevice.NativeDevice.CreateBuffer(ref createInfo); // Allocate memory var memoryProperties = MemoryPropertyFlags.DeviceLocal; if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic) { memoryProperties = MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent; } MemoryRequirements memoryRequirements; GraphicsDevice.NativeDevice.GetBufferMemoryRequirements(NativeBuffer, out memoryRequirements); AllocateMemory(memoryProperties, memoryRequirements); if (NativeMemory != DeviceMemory.Null) { GraphicsDevice.NativeDevice.BindBufferMemory(NativeBuffer, NativeMemory, 0); } if (SizeInBytes > 0) { // Begin copy command buffer var commandBufferAllocateInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, CommandPool = GraphicsDevice.NativeCopyCommandPool, CommandBufferCount = 1, Level = CommandBufferLevel.Primary }; CommandBuffer commandBuffer; lock (GraphicsDevice.QueueLock) { GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocateInfo, &commandBuffer); } var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.OneTimeSubmit }; commandBuffer.Begin(ref beginInfo); // Copy to upload buffer if (dataPointer != IntPtr.Zero) { if (Usage == GraphicsResourceUsage.Dynamic) { var uploadMemory = GraphicsDevice.NativeDevice.MapMemory(NativeMemory, 0, (ulong)SizeInBytes, MemoryMapFlags.None); Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes); GraphicsDevice.NativeDevice.UnmapMemory(NativeMemory); } else { var sizeInBytes = bufferDescription.SizeInBytes; SharpVulkan.Buffer uploadResource; int uploadOffset; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(sizeInBytes, out uploadResource, out uploadOffset); Utilities.CopyMemory(uploadMemory, dataPointer, sizeInBytes); // Barrier var memoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)sizeInBytes); commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &memoryBarrier, 0, null); // Copy var bufferCopy = new BufferCopy { SourceOffset = (uint)uploadOffset, DestinationOffset = 0, Size = (uint)sizeInBytes }; commandBuffer.CopyBuffer(uploadResource, NativeBuffer, 1, &bufferCopy); } } else { commandBuffer.FillBuffer(NativeBuffer, 0, (uint)bufferDescription.SizeInBytes, 0); } // Barrier var bufferMemoryBarrier = new BufferMemoryBarrier(NativeBuffer, AccessFlags.TransferWrite, NativeAccessMask); commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 0, null); // Close and submit commandBuffer.End(); var submitInfo = new SubmitInfo { StructureType = StructureType.SubmitInfo, CommandBufferCount = 1, CommandBuffers = new IntPtr(&commandBuffer), }; lock (GraphicsDevice.QueueLock) { GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null); GraphicsDevice.NativeCommandQueue.WaitIdle(); //commandBuffer.Reset(CommandBufferResetFlags.None); GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer); } InitializeViews(); } }
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); }
internal static unsafe extern Result vkCreateBuffer(Device device, BufferCreateInfo* createInfo, AllocationCallbacks* allocator, Buffer* buffer);
private Buffer CreateBuffer() { var bufferCreateInfo = new BufferCreateInfo(DefaultBufferSize, BufferUsages.UniformTexelBuffer); return(Device.CreateBuffer(bufferCreateInfo)); }
public unsafe Buffer CreateBuffer(ref BufferCreateInfo createInfo, AllocationCallbacks* allocator = null) { Buffer buffer; fixed (BufferCreateInfo* __createInfo__ = &createInfo) { vkCreateBuffer(this, __createInfo__, allocator, &buffer).CheckError(); } return buffer; }