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 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>(); }
private unsafe CommandBuffer BeginImageCommandBuffer() { Device device = _renderer.Params.Device; Vk vk = _renderer.Vk; CommandBufferAllocateInfo commandBufferAllocateInfo = new() { SType = StructureType.CommandBufferAllocateInfo, CommandBufferCount = 1, CommandPool = _renderer.ImageTransitionPool }; _renderer.AssertVulkan(vk.AllocateCommandBuffers(device, commandBufferAllocateInfo, out CommandBuffer commandBuffer)); CommandBufferBeginInfo commandBufferBeginInfo = new() { SType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.CommandBufferUsageOneTimeSubmitBit, PInheritanceInfo = null }; _renderer.AssertVulkan(vk.BeginCommandBuffer(commandBuffer, commandBufferBeginInfo)); return(commandBuffer); } private unsafe void EndImageCommandBuffer(CommandBuffer commandBuffer) { Device device = _renderer.Params.Device; Vk vk = _renderer.Vk; _renderer.AssertVulkan(vk.EndCommandBuffer(commandBuffer)); SubmitInfo submitInfo = new() { SType = StructureType.SubmitInfo, CommandBufferCount = 1, PCommandBuffers = &commandBuffer, SignalSemaphoreCount = 0, PSignalSemaphores = null, WaitSemaphoreCount = 0, PWaitSemaphores = null, PWaitDstStageMask = null }; _renderer.AssertVulkan(vk.QueueSubmit(_renderer.ImageTransitionQueue, 1, submitInfo, default)); _renderer.AssertVulkan(vk.QueueWaitIdle(_renderer.ImageTransitionQueue)); vk.FreeCommandBuffers(device, _renderer.ImageTransitionPool, 1, commandBuffer); } private unsafe void TransitionImageLayout(ImageLayout oldLayout, ImageLayout newLayout) { Vk vk = _renderer.Vk; CommandBuffer commandBuffer = BeginImageCommandBuffer(); ImageMemoryBarrier imageMemoryBarrier = new() { SType = StructureType.ImageMemoryBarrier, OldLayout = oldLayout, NewLayout = newLayout, SrcQueueFamilyIndex = Vk.QueueFamilyIgnored, DstQueueFamilyIndex = Vk.QueueFamilyIgnored, Image = _image, SubresourceRange = new ImageSubresourceRange() { AspectMask = ImageAspectFlags.ImageAspectColorBit, BaseArrayLayer = 0, LayerCount = 1, BaseMipLevel = 0, LevelCount = _mipLevelCount }, SrcAccessMask = 0, DstAccessMask = 0 }; if ((oldLayout == ImageLayout.Undefined) && (newLayout == ImageLayout.TransferDstOptimal)) { imageMemoryBarrier.SrcAccessMask = 0; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTopOfPipeBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } else if ((oldLayout == ImageLayout.TransferDstOptimal) && (newLayout == ImageLayout.ShaderReadOnlyOptimal)) { imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessTransferWriteBit; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessShaderReadBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageFragmentShaderBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } else if ((oldLayout == ImageLayout.ShaderReadOnlyOptimal) && (newLayout == ImageLayout.TransferDstOptimal)) { imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessShaderReadBit; imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit; vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageFragmentShaderBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier); } EndImageCommandBuffer(commandBuffer); } private void CopyBufferToImage(Buffer <byte> source) { Vk vk = _renderer.Vk; CommandBuffer commandBuffer = BeginImageCommandBuffer(); BufferImageCopy bufferImageCopy = new() { BufferOffset = 0, BufferRowLength = 0, BufferImageHeight = 0, ImageSubresource = new ImageSubresourceLayers() { AspectMask = ImageAspectFlags.ImageAspectColorBit, MipLevel = 0, BaseArrayLayer = 0, LayerCount = 1 }, ImageOffset = new Offset3D() { X = 0, Y = 0, Z = 0 }, ImageExtent = new Extent3D() { Width = Size.X, Height = Size.Y, Depth = 1 } }; vk.CmdCopyBufferToImage(commandBuffer, source.Handle, _image, ImageLayout.TransferDstOptimal, 1, bufferImageCopy); EndImageCommandBuffer(commandBuffer); }
public unsafe void Run(int currentFrameIndex, int imageIndex, Semaphore waitSemaphore, Semaphore signalSemaphore, Fence signal) { var bufferInfo = new DescriptorBufferInfo(_commandBuffers[currentFrameIndex], 0, (ulong)(sizeof(uint) * _commandBufferCapacities[currentFrameIndex])); _vk.UpdateDescriptorSets(_device, 1, new WriteDescriptorSet(dstSet: _targetDescriptorSets[currentFrameIndex], dstBinding: 1, dstArrayElement: 0, descriptorCount: 1, descriptorType: DescriptorType.StorageBuffer, pBufferInfo: &bufferInfo), 0, null); var currentFrame = _frames[currentFrameIndex]; _vk.ResetCommandPool(_device, currentFrame.CommandPool, 0).ThrowCode(); _vk.AllocateCommandBuffers(_device, new CommandBufferAllocateInfo(commandPool: currentFrame.CommandPool, level: CommandBufferLevel.Primary, commandBufferCount: 1), out var commandBuffer).ThrowCode(); Name(ObjectType.CommandBuffer, (ulong)commandBuffer.Handle, $"Command Buffer Frame {currentFrameIndex}"); var renderContext = new RenderContext(_targetImageViews[imageIndex], _targetSize, currentFrameIndex); _vk.BeginCommandBuffer(commandBuffer, new CommandBufferBeginInfo(flags: CommandBufferUsageFlags.CommandBufferUsageOneTimeSubmitBit)) .ThrowCode(); // var memoryBarrier = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2TopOfPipeBitKhr, // srcAccessMask: AccessFlags2KHR.Access2NoneKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2TransferBitKhr, // dstAccessMask: AccessFlags2KHR.Access2TransferWriteBitKhr, // oldLayout: ImageLayout.Undefined, newLayout: ImageLayout.TransferDstOptimal, // srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, // image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1), // sType: StructureType.ImageMemoryBarrier2Khr, pNext: null); // _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1, // pImageMemoryBarriers: &memoryBarrier, dependencyFlags: 0, memoryBarrierCount: 0, pMemoryBarriers: null, bufferMemoryBarrierCount: 0, pBufferMemoryBarriers: null)); _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTopOfPipeBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessNoneKhr, dstAccessMask: AccessFlags.AccessTransferWriteBit, oldLayout: ImageLayout.Undefined, newLayout: ImageLayout.TransferDstOptimal, srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1))); _vk.CmdClearColorImage(commandBuffer, _targetImages.Span[imageIndex], ImageLayout.TransferDstOptimal, new ClearColorValue(0f, 0f, 0f, 1f), 1, new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)); // var memoryBarrier2 = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2TransferBitKhr, // srcAccessMask: AccessFlags2KHR.Access2TransferWriteBitKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2ComputeShaderBitKhr, // dstAccessMask: AccessFlags2KHR.Access2ShaderReadBitKhr | AccessFlags2KHR.Access2ShaderWriteBitKhr, // oldLayout: ImageLayout.TransferDstOptimal, newLayout: ImageLayout.General, // srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, // image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)); // _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1, // pImageMemoryBarriers: &memoryBarrier2)); _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageComputeShaderBit, 0, 0, null, 0, null, 1, new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessTransferWriteBit, dstAccessMask: AccessFlags.AccessShaderReadBit | AccessFlags.AccessShaderWriteBit, oldLayout: ImageLayout.TransferDstOptimal, newLayout: ImageLayout.General, srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1))); Span <uint> pValues = stackalloc uint[] { _targetSize.X, _targetSize.Y }; _vk.CmdPushConstants(commandBuffer, _pipelineLayout, ShaderStageFlags.ShaderStageComputeBit, 0, (uint)pValues.Length * sizeof(uint), pValues); _vk.CmdBindDescriptorSets(commandBuffer, PipelineBindPoint.Compute, _pipelineLayout, 0, 1, _targetDescriptorSets[imageIndex], 0, null); _computeShader.Record(renderContext, commandBuffer); // var memoryBarrier3 = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2ComputeShaderBitKhr, // srcAccessMask: AccessFlags2KHR.Access2ShaderReadBitKhr | AccessFlags2KHR.Access2ShaderWriteBitKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2BottomOfPipeBitKhr, // dstAccessMask: AccessFlags2KHR.Access2NoneKhr, // oldLayout: ImageLayout.General, newLayout: ImageLayout.PresentSrcKhr, // srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, // image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)); // _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1, // pImageMemoryBarriers: &memoryBarrier3)); _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageComputeShaderBit, PipelineStageFlags.PipelineStageBottomOfPipeBit, 0, 0, null, 0, null, 1, new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessShaderReadBit | AccessFlags.AccessShaderWriteBit, dstAccessMask: AccessFlags.AccessNoneKhr, oldLayout: ImageLayout.General, newLayout: ImageLayout.PresentSrcKhr, srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1))); _vk.EndCommandBuffer(commandBuffer); var waitDstStageMask = PipelineStageFlags.PipelineStageTransferBit; _vk.QueueSubmit(Queue, 1, new SubmitInfo(waitSemaphoreCount: 1, pWaitSemaphores: &waitSemaphore, commandBufferCount: 1, pCommandBuffers: &commandBuffer, signalSemaphoreCount: 1, pSignalSemaphores: &signalSemaphore, pWaitDstStageMask: &waitDstStageMask), signal).ThrowCode(); }