protected virtual void CreateCommandBuffer() { // Command pool var commandPoolCreateInfo = new CommandPoolCreateInfo { StructureType = StructureType.CommandPoolCreateInfo, QueueFamilyIndex = 0, Flags = CommandPoolCreateFlags.ResetCommandBuffer }; commandPool = device.CreateCommandPool(ref commandPoolCreateInfo); // Command buffer var commandBufferAllocationInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, Level = CommandBufferLevel.Primary, CommandPool = commandPool, CommandBufferCount = 1 }; CommandBuffer commandBuffer; device.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer); this.commandBuffer = commandBuffer; }
CommandBuffer [] CreateCommandBuffers(Image [] images, Framebuffer [] framebuffers, RenderPass renderPass, SurfaceCapabilitiesKhr surfaceCapabilities) { var createPoolInfo = new CommandPoolCreateInfo { Flags = CommandPoolCreateFlags.ResetCommandBuffer }; var commandPool = device.CreateCommandPool(createPoolInfo); var commandBufferAllocateInfo = new CommandBufferAllocateInfo { Level = CommandBufferLevel.Primary, CommandPool = commandPool, CommandBufferCount = (uint)images.Length }; var buffers = device.AllocateCommandBuffers(commandBufferAllocateInfo); for (int i = 0; i < images.Length; i++) { var commandBufferBeginInfo = new CommandBufferBeginInfo(); buffers [i].Begin(commandBufferBeginInfo); var renderPassBeginInfo = new RenderPassBeginInfo { Framebuffer = framebuffers [i], RenderPass = renderPass, ClearValues = new ClearValue [] { new ClearValue { Color = new ClearColorValue(new float [] { 0.9f, 0.7f, 0.0f, 1.0f }) } }, RenderArea = new Rect2D { Extent = surfaceCapabilities.CurrentExtent } }; buffers [i].CmdBeginRenderPass(renderPassBeginInfo, SubpassContents.Inline); buffers [i].CmdEndRenderPass(); buffers [i].End(); } return(buffers); }
void InitCommandBuffers() { CommandPoolCreateInfo poolCreateInfo = new CommandPoolCreateInfo { QueueFamilyIndex = 0, Flags = CommandPoolCreateFlags.ResetCommandBuffer, }; mainCmdPool = device.CreateCommandPool(poolCreateInfo); CommandBufferAllocateInfo bufferAllocInfo = new CommandBufferAllocateInfo { CommandBufferCount = 1, CommandPool = mainCmdPool, Level = CommandBufferLevel.Primary, }; mainCmd = device.AllocateCommandBuffers(bufferAllocInfo)[0]; cleanupStack.Push(() => { device.FreeCommandBuffer(mainCmdPool, mainCmd); mainCmd = null; device.DestroyCommandPool(mainCmdPool); mainCmdPool = null; }); }
private void CopyBuffer(Vulkan.Buffer srcBuffer, Vulkan.Buffer dstBuffer, DeviceSize size) { var allocInfo = new CommandBufferAllocateInfo() { CommandPool = vkCommandPool, CommandBufferCount = 1, Level = CommandBufferLevel.Primary, }; var commmandBuffer = vkDevice.AllocateCommandBuffers(allocInfo)[0]; commmandBuffer.Begin(new CommandBufferBeginInfo() { Flags = CommandBufferUsageFlags.OneTimeSubmit }); commmandBuffer.CmdCopyBuffer(srcBuffer, dstBuffer, new BufferCopy[] { new BufferCopy() { Size = size } }); commmandBuffer.End(); vkGraphicsQueue.Submit(new SubmitInfo() { CommandBuffers = new CommandBuffer[] { commmandBuffer } }); vkGraphicsQueue.WaitIdle(); vkDevice.FreeCommandBuffer(vkCommandPool, commmandBuffer); }
void CreateCommandBuffer() { /* * We are getting closer to the end. In order to send commands to the device(GPU), * we must first record commands into a command buffer. * To allocate a command buffer, we must first create a command pool. So let us do that. */ CommandPoolCreateInfo commandPoolCreateInfo = new CommandPoolCreateInfo() { Flags = 0, // the queue family of this command pool. All command buffers allocated from this command pool, // must be submitted to queues of this family ONLY. QueueFamilyIndex = computeQueueFamilyIndex }; commandPool = device.CreateCommandPool(commandPoolCreateInfo); /* * Now allocate a command buffer from the command pool. */ CommandBufferAllocateInfo commandBufferAllocateInfo = new CommandBufferAllocateInfo() { //commandBufferAllocateInfo.commandPool = commandPool; // specify the command pool to allocate from. // if the command buffer is primary, it can be directly submitted to queues. // A secondary buffer has to be called from some primary command buffer, and cannot be directly // submitted to a queue. To keep things simple, we use a primary command buffer. Level = CommandBufferLevel.Primary, // VK_COMMAND_BUFFER_LEVEL_PRIMARY; CommandBufferCount = 1 // allocate a single command buffer. }; commandBuffers = commandPool.AllocateBuffers(commandBufferAllocateInfo); // allocate command buffer. /* * Now we shall start recording commands into the newly allocated command buffer. */ CommandBufferBeginInfo beginInfo = new CommandBufferBeginInfo() { Flags = CommandBufferUsages.OneTimeSubmit// VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; // the buffer is only submitted and used once in this application. }; commandBuffers[0].Begin(beginInfo); // start recording commands. /* * We need to bind a pipeline, AND a descriptor set before we dispatch. * The validation layer will NOT give warnings if you forget these, so be very careful not to forget them. */ commandBuffers[0].CmdBindPipeline(PipelineBindPoint.Compute, pipelines[0]); // VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); commandBuffers[0].CmdBindDescriptorSets(PipelineBindPoint.Compute, pipelineLayout, 0, new[] { descriptorSet }); // VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, NULL); /* * Calling vkCmdDispatch basically starts the compute pipeline, and executes the compute shader. * The number of workgroups is specified in the arguments. * If you are already familiar with compute shaders from OpenGL, this should be nothing new to you. */ commandBuffers[0].CmdDispatch((int)Math.Ceiling((double)(WIDTH / WORKGROUP_SIZE)), (int)Math.Ceiling((double)(HEIGHT / WORKGROUP_SIZE)), 1); commandBuffers[0].End(); // end recording commands. }
public void CreateCommandBuffers() { CommandBufferAllocateInfo commandBufferAllocateInfo = VkInit.CommandBufferAllocateInfo(_commandPool, COMMAND_BUFFER_RESET_THRESHOLD); for (int i = 0; i < COMMAND_BUFFER_RESET_THRESHOLD; i++) { VkUtil.AssertVulkan(_vk.AllocateCommandBuffers(_device, commandBufferAllocateInfo, out _commandBuffers[0])); } }
public CommandBuffer[] GimmeCommandBuffers(string queueName) { CommandBufferAllocateInfo cbai = new CommandBufferAllocateInfo(); cbai.Level = CommandBufferLevel.Primary; cbai.CommandBufferCount = mChainBuffers.Length; CommandPool cp = mDevices.GetCommandPool(queueName); return(cp.AllocateBuffers(cbai)); }
protected override void AllocateBuffers(int v) { var commandBufferAllocateInfo = new CommandBufferAllocateInfo { Level = CommandBufferLevel.Secondary, CommandPool = this.CommandPool, CommandBufferCount = (uint)v }; myFreeBuffers.AddRange(LogicalDevice.AllocateCommandBuffers(commandBufferAllocateInfo)); }
protected CommandBuffer[] AllocateCommandBuffers(CommandPool commandPool, uint buffersToAllocate) { var commandBufferAllocationInfo = new CommandBufferAllocateInfo(commandPool, CommandBufferLevel.Primary, buffersToAllocate); var commandBuffers = device.AllocateCommandBuffers(commandBufferAllocationInfo); if (commandBuffers.Length == 0) { throw new InvalidOperationException("Couldn't allocate any command buffers"); } return(commandBuffers); }
protected override void AllocateBuffers(int v) { // var createPoolInfo = new CommandPoolCreateInfo { }; //CommandPool = LogicalDevice.CreateCommandPool(createPoolInfo); var commandBufferAllocateInfo = new CommandBufferAllocateInfo { Level = CommandBufferLevel.Primary, CommandPool = this.CommandPool, CommandBufferCount = (uint)v }; base.myFreeBuffers.AddRange(LogicalDevice.AllocateCommandBuffers(commandBufferAllocateInfo)); }
void AllocateCommandBuffers(CommandPool pool, CommandBuffer[] command_buffers) { var command_buffer_allocate_info = new CommandBufferAllocateInfo { sType = StructureType.CommandBufferAllocateInfo, // VkStructureType sType pNext = IntPtr.Zero, // const void *pNext commandPool = pool, // VkCommandPool commandPool level = CommandBufferLevel.Primary, // VkCommandBufferLevel level commandBufferCount = (uint)command_buffers.Length // uint32_t bufferCount }; fixed(CommandBuffer *ptr = command_buffers) vk.AllocateCommandBuffers(GetDevice, ref command_buffer_allocate_info, ptr); }
public unsafe CommandBuffers(Api api, CommandPool commandPool, uint count) { (_api, _commandPool) = (api, commandPool); var allocInfo = new CommandBufferAllocateInfo(); allocInfo.SType = StructureType.CommandBufferAllocateInfo; allocInfo.CommandPool = _commandPool.VkCommandPool; allocInfo.Level = CommandBufferLevel.Primary; allocInfo.CommandBufferCount = count; _commandBuffers = GC.AllocateArray <CommandBuffer>((int)count, true); Util.Verify(_api.Vk.AllocateCommandBuffers(_api.Device.VkDevice, &allocInfo, (CommandBuffer *)Unsafe.AsPointer(ref _commandBuffers[0])), $"{nameof(CommandBuffers)}: Unable to allocate command buffers"); }
protected CommandBuffer AllocateCommandBuffer(CommandBufferLevel level) { CommandBufferAllocateInfo info = new CommandBufferAllocateInfo(commandPool: this.CommandPool, level: level, commandBufferCount: 1); CommandBuffer buffer; var res = VkApi.AllocateCommandBuffers(Device, &info, &buffer); if (res != Result.Success) { throw new Exception("Unable to allocate command buffers"); } return(buffer); }
public void Initialize(Vk api, Device device, CommandPool pool) { var allocateInfo = new CommandBufferAllocateInfo() { SType = StructureType.CommandBufferAllocateInfo, CommandBufferCount = 1, CommandPool = pool, Level = CommandBufferLevel.Primary }; api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer); Dependants = new List <IAuto>(); Waitables = new HashSet <MultiFenceHolder>(); Dependencies = new HashSet <SemaphoreHolder>(); }
protected override unsafe CommandBuffer CreateObject() { // No allocator ready to be used, let's create a new one var commandBufferAllocationInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, Level = CommandBufferLevel.Primary, CommandPool = commandPool, CommandBufferCount = 1, }; CommandBuffer commandBuffer; GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer); return(commandBuffer); }
public void CopyBuffer(string queue, string src, string dest, int size) { if (!mBuffers.ContainsKey(src)) { Misc.SafeInvoke(eErrorSpam, "No buffer named: " + src + "..."); return; } if (!mBuffers.ContainsKey(dest)) { Misc.SafeInvoke(eErrorSpam, "No buffer named: " + dest + "..."); return; } if (!mCommandPools.ContainsKey(queue)) { Misc.SafeInvoke(eErrorSpam, "No pool named: " + queue + "..."); return; } CommandBufferAllocateInfo cbai = new CommandBufferAllocateInfo(); cbai.Level = CommandBufferLevel.Primary; cbai.CommandBufferCount = 1; CommandBuffer [] bufs = mCommandPools[queue].AllocateBuffers(cbai); CommandBufferBeginInfo cbbi = new CommandBufferBeginInfo( CommandBufferUsages.OneTimeSubmit); bufs[0].Begin(cbbi); BufferCopy bc = new BufferCopy(size, 0, 0); bufs[0].CmdCopyBuffer(mBuffers[src], mBuffers[dest], bc); bufs[0].End(); SubmitInfo si = new SubmitInfo(); si.CommandBuffers = new IntPtr[] { bufs[0].Handle }; SubmitToQueue(si, queue, null); mQueueNames[queue].WaitIdle(); bufs[0].Dispose(); }
private void CreateCommandBuffers() { var allocInfo = new CommandBufferAllocateInfo() { CommandPool = vkCommandPool, Level = CommandBufferLevel.Primary, CommandBufferCount = (uint)vkSwapChainFramebuffers.Length, }; vkCommandBuffers = vkDevice.AllocateCommandBuffers(allocInfo); for (int i = 0; i < vkCommandBuffers.Length; i++) { var beginInfo = new CommandBufferBeginInfo() { Flags = CommandBufferUsageFlags.SimultaneousUse, InheritanceInfo = null, }; var buffer = vkCommandBuffers[i]; buffer.Begin(beginInfo); var renderPassInfo = new RenderPassBeginInfo() { RenderPass = vkRenderPass, Framebuffer = vkSwapChainFramebuffers[i], RenderArea = new Rect2D() { Extent = vkSwapChainExtent }, ClearValues = new ClearValue[] { new ClearValue() { Color = new ClearColorValue(new float[] { 0.0f, 0.0f, 0.0f, 1.0f }) } }, }; buffer.CmdBeginRenderPass(renderPassInfo, SubpassContents.Inline); buffer.CmdBindPipeline(PipelineBindPoint.Graphics, vkGraphicsPipeline); buffer.CmdBindDescriptorSet(PipelineBindPoint.Graphics, vkPipelineLayout, 0, vkDescriptorSet, 0); buffer.CmdBindVertexBuffer(0, vkVertexBuffer, 0); buffer.CmdBindIndexBuffer(vkIndexBuffer, 0, IndexType.Uint16); buffer.CmdDrawIndexed((uint)indices.Length, 1, 0, 0, 0); buffer.CmdEndRenderPass(); buffer.End(); } }
protected CommandBuffer[] AllocateCommandBuffers(int count, CommandBufferLevel level) { CommandBufferAllocateInfo info = new CommandBufferAllocateInfo(commandPool: this.CommandPool, level: level, commandBufferCount: (uint)count); CommandBuffer[] buffers = new CommandBuffer[count]; fixed(CommandBuffer *pbuffers = buffers) { var res = VkApi.AllocateCommandBuffers(Device, &info, pbuffers); if (res != Result.Success) { throw new Exception("Unable to allocate command buffers"); } } return(buffers); }
CommandBuffer [] CreateCommandBuffers(Image [] images, Framebuffer [] framebuffers, Pipeline pipeline, Buffer vertexBuffer, Buffer indexBuffer, uint indexLength) { var createPoolInfo = new CommandPoolCreateInfo { Flags = CommandPoolCreateFlags.ResetCommandBuffer }; var commandPool = device.CreateCommandPool(createPoolInfo); var commandBufferAllocateInfo = new CommandBufferAllocateInfo { Level = CommandBufferLevel.Primary, CommandPool = commandPool, CommandBufferCount = (uint)images.Length }; var buffers = device.AllocateCommandBuffers(commandBufferAllocateInfo); var commandBufferBeginInfo = new CommandBufferBeginInfo(); for (int i = 0; i < images.Length; i++) { buffers [i].Begin(commandBufferBeginInfo); var renderPassBeginInfo = new RenderPassBeginInfo { Framebuffer = framebuffers [i], RenderPass = renderPass, ClearValues = new ClearValue [] { new ClearValue { Color = new ClearColorValue(new float [] { 0.9f, 0.87f, 0.75f, 1.0f }) } }, RenderArea = new Rect2D { Extent = surfaceCapabilities.CurrentExtent } }; buffers [i].CmdBeginRenderPass(renderPassBeginInfo, SubpassContents.Inline); buffers [i].CmdBindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, descriptorSets, null); buffers [i].CmdBindPipeline(PipelineBindPoint.Graphics, pipeline); buffers [i].CmdBindVertexBuffers(0, new Buffer [] { vertexBuffer }, new DeviceSize [] { 0 }); buffers [i].CmdBindIndexBuffer(indexBuffer, 0, IndexType.Uint16); buffers [i].CmdDrawIndexed(indexLength, 1, 0, 0, 0); buffers [i].CmdEndRenderPass(); buffers [i].End(); } return(buffers); }
static void CreateCommandBuffer() { // Command pool var commandPoolCreateInfo = new CommandPoolCreateInfo { QueueFamilyIndex = 0, Flags = (uint)CommandPoolCreateFlags.ResetCommandBuffer, }; commandPool = device.CreateCommandPool(commandPoolCreateInfo, null); Console.WriteLine("[ OK ] Command Pool"); // Command Buffer var commandBufferAllocationInfo = new CommandBufferAllocateInfo { Level = CommandBufferLevel.Primary, CommandPool = commandPool, CommandBufferCount = 1, }; commandBuffer = device.AllocateCommandBuffers(commandBufferAllocationInfo); Console.WriteLine("[ OK ] Command Buffer"); }
CommandBuffer[] AllocateCommandBuffers(CommandPool commandPool, uint buffersToAllocate) { // Command buffers are objects used to record commands which can be subsequently submitted // to a device queue for execution. There are two levels of command buffers - primary // command buffers, which can execute secondary command buffers, and which are submitted to // queues, and secondary command buffers, which can be executed by primary command buffers, // and which are not directly submitted to queues. // // Recorded commands include commands to bind pipelines and descriptor sets to the command // buffer, commands to modify dynamic state, commands to draw (for graphics rendering), // commands to dispatch(for compute), commands to execute secondary command buffers (for // primary command buffers only), commands to copy buffers and images, and other commands. var commandBufferAllocationInfo = new CommandBufferAllocateInfo(commandPool, CommandBufferLevel.Primary, buffersToAllocate); var commandBuffers = device.AllocateCommandBuffers(commandBufferAllocationInfo); if (commandBuffers.Length == 0) { throw new InvalidOperationException("Couldn't allocate any command buffers"); } return(commandBuffers); }
public unsafe void AllocateCommandBuffers(ref CommandBufferAllocateInfo allocateInfo, CommandBuffer* commandBuffers) { fixed (CommandBufferAllocateInfo* __allocateInfo__ = &allocateInfo) { vkAllocateCommandBuffers(this, __allocateInfo__, commandBuffers).CheckError(); } }
/// <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(); } }
/// <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(); } }
/// <summary> /// Allocate command buffers from an existing command pool. /// </summary> /// <param name="allocateInfo">The structure describing parameters of the allocation.</param> /// <returns> /// The resulting command buffer objects returned. Each allocated command buffer begins in /// the initial state. /// </returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public CommandBuffer[] AllocateBuffers(CommandBufferAllocateInfo allocateInfo) { return(CommandBuffer.Allocate(this, &allocateInfo)); }
private unsafe void InitializeImage(DataBox[] dataBoxes) { // 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); if (dataBoxes != null && dataBoxes.Length > 0) { // Buffer-to-image copies need to be aligned to the pixel size and 4 (always a power of 2) var blockSize = Format.IsCompressed() ? NativeFormat.BlockSizeInBytes() : TexturePixelSize; var alignmentMask = (blockSize < 4 ? 4 : blockSize) - 1; int totalSize = dataBoxes.Length * alignmentMask; for (int i = 0; i < dataBoxes.Length; i++) { totalSize += dataBoxes[i].SlicePitch; } SharpVulkan.Buffer uploadResource; int uploadOffset; var uploadMemory = GraphicsDevice.AllocateUploadBuffer(totalSize, out uploadResource, out uploadOffset); // Upload buffer barrier var bufferMemoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)totalSize); // Image barrier var initialBarrier = new ImageMemoryBarrier(NativeImage, ImageLayout.Undefined, ImageLayout.TransferDestinationOptimal, AccessFlags.None, AccessFlags.TransferWrite, new ImageSubresourceRange(NativeImageAspect)); commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 1, &initialBarrier); // Copy data boxes to upload buffer var copies = new BufferImageCopy[dataBoxes.Length]; for (int i = 0; i < copies.Length; i++) { var slicePitch = dataBoxes[i].SlicePitch; int arraySlice = i / MipLevels; int mipSlice = i % MipLevels; var mipMapDescription = GetMipMapDescription(mipSlice); var alignment = ((uploadOffset + alignmentMask) & ~alignmentMask) - uploadOffset; uploadMemory += alignment; uploadOffset += alignment; Utilities.CopyMemory(uploadMemory, dataBoxes[i].DataPointer, slicePitch); // TODO VULKAN: Check if pitches are valid copies[i] = new BufferImageCopy { BufferOffset = (ulong)uploadOffset, ImageSubresource = new ImageSubresourceLayers(ImageAspectFlags.Color, (uint)arraySlice, 1, (uint)mipSlice), BufferRowLength = 0, //(uint)(dataBoxes[i].RowPitch / pixelSize), BufferImageHeight = 0, //(uint)(dataBoxes[i].SlicePitch / dataBoxes[i].RowPitch), ImageOffset = new Offset3D(0, 0, 0), ImageExtent = new Extent3D((uint)mipMapDescription.Width, (uint)mipMapDescription.Height, (uint)mipMapDescription.Depth) }; uploadMemory += slicePitch; uploadOffset += slicePitch; } // Copy from upload buffer to image fixed(BufferImageCopy *copiesPointer = &copies[0]) { commandBuffer.CopyBufferToImage(uploadResource, NativeImage, ImageLayout.TransferDestinationOptimal, (uint)copies.Length, copiesPointer); } IsInitialized = true; } // Transition to default layout var imageMemoryBarrier = new ImageMemoryBarrier(NativeImage, dataBoxes == null || dataBoxes.Length == 0 ? ImageLayout.Undefined : ImageLayout.TransferDestinationOptimal, NativeLayout, dataBoxes == null || dataBoxes.Length == 0 ? AccessFlags.None : AccessFlags.TransferWrite, NativeAccessMask, new ImageSubresourceRange(NativeImageAspect)); commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier); // 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(); GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer); } }
private void SetImageLayout(Image image, ImageAspectFlags imageAspect, ImageLayout oldLayout, ImageLayout newLayout) { if (setupCommanBuffer == CommandBuffer.Null) { // Create command buffer CommandBuffer setupCommandBuffer; var allocateInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, CommandPool = commandPool, Level = CommandBufferLevel.Primary, CommandBufferCount = 1, }; device.AllocateCommandBuffers(ref allocateInfo, &setupCommandBuffer); setupCommanBuffer = setupCommandBuffer; // Begin command buffer var inheritanceInfo = new CommandBufferInheritanceInfo { StructureType = StructureType.CommandBufferInheritanceInfo }; var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo, InheritanceInfo = new IntPtr(&inheritanceInfo) }; setupCommanBuffer.Begin(ref beginInfo); } var imageMemoryBarrier = new ImageMemoryBarrier { StructureType = StructureType.ImageMemoryBarrier, OldLayout = oldLayout, NewLayout = newLayout, Image = image, SubresourceRange = new ImageSubresourceRange(imageAspect, 0, 1, 0, 1) }; switch (newLayout) { case ImageLayout.TransferDestinationOptimal: imageMemoryBarrier.DestinationAccessMask = AccessFlags.TransferRead; break; case ImageLayout.ColorAttachmentOptimal: imageMemoryBarrier.DestinationAccessMask = AccessFlags.ColorAttachmentWrite; break; case ImageLayout.DepthStencilAttachmentOptimal: imageMemoryBarrier.DestinationAccessMask = AccessFlags.DepthStencilAttachmentWrite; break; case ImageLayout.ShaderReadOnlyOptimal: imageMemoryBarrier.DestinationAccessMask = AccessFlags.ShaderRead | AccessFlags.InputAttachmentRead; break; } var sourceStages = PipelineStageFlags.TopOfPipe; var destinationStages = PipelineStageFlags.TopOfPipe; setupCommanBuffer.PipelineBarrier(sourceStages, destinationStages, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier); }
internal static unsafe extern Result vkAllocateCommandBuffers(Device device, CommandBufferAllocateInfo* allocateInfo, CommandBuffer* commandBuffers);
/// <summary> /// Initializes the specified device. /// </summary> /// <param name="graphicsProfiles">The graphics profiles.</param> /// <param name="deviceCreationFlags">The device creation flags.</param> /// <param name="windowHandle">The window handle.</param> private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle) { if (nativeDevice != Device.Null) { // Destroy previous device ReleaseDevice(); } rendererName = Adapter.Description; PhysicalDeviceProperties physicalDeviceProperties; NativePhysicalDevice.GetProperties(out physicalDeviceProperties); ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment; RequestedProfile = graphicsProfiles.Last(); var queueProperties = NativePhysicalDevice.QueueFamilyProperties; // Command lists are thread-safe and execute deferred IsDeferred = true; // TODO VULKAN // Create Vulkan device based on profile uint queuePriorities = 0; var queueCreateInfo = new DeviceQueueCreateInfo { StructureType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = 0, QueueCount = 1, QueuePriorities = new IntPtr(&queuePriorities) }; var enabledFeature = new PhysicalDeviceFeatures { FillModeNonSolid = true, ShaderClipDistance = true, ShaderCullDistance = true, SamplerAnisotropy = true, DepthClamp = true, }; var extensionProperties = NativePhysicalDevice.GetDeviceExtensionProperties(); var availableExtensionNames = new List <string>(); var desiredExtensionNames = new List <string>(); for (int index = 0; index < extensionProperties.Length; index++) { var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName)); var name = Marshal.PtrToStringAnsi(namePointer); availableExtensionNames.Add(name); } desiredExtensionNames.Add("VK_KHR_swapchain"); if (!availableExtensionNames.Contains("VK_KHR_swapchain")) { throw new InvalidOperationException(); } if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode) { desiredExtensionNames.Add("VK_EXT_debug_marker"); IsProfilingSupported = true; } var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray(); try { var deviceCreateInfo = new DeviceCreateInfo { StructureType = StructureType.DeviceCreateInfo, QueueCreateInfoCount = 1, QueueCreateInfos = new IntPtr(&queueCreateInfo), EnabledExtensionCount = (uint)enabledExtensionNames.Length, EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero, EnabledFeatures = new IntPtr(&enabledFeature) }; nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo); } finally { foreach (var enabledExtensionName in enabledExtensionNames) { Marshal.FreeHGlobal(enabledExtensionName); } } NativeCommandQueue = nativeDevice.GetQueue(0, 0); //// Prepare copy command list (start it closed, so that every new use start with a Reset) var commandPoolCreateInfo = new CommandPoolCreateInfo { StructureType = StructureType.CommandPoolCreateInfo, QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex Flags = CommandPoolCreateFlags.ResetCommandBuffer }; NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo); var commandBufferAllocationInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, Level = CommandBufferLevel.Primary, CommandPool = NativeCopyCommandPool, CommandBufferCount = 1 }; CommandBuffer nativeCommandBuffer; NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer); NativeCopyCommandBuffer = nativeCommandBuffer; DescriptorPools = new HeapPool(this); nativeResourceCollector = new NativeResourceCollector(this); graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this); EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float); }