public void Submit(CommandBuffer buffer, VkSemaphore?wait = null, VkPipelineStageFlag waitStage = 0, VkSemaphore?signal = null, VkFence?submit = null) { buffer.AssertBuilt(); var buff = buffer.Handle; unsafe { var waitH = wait ?? VkSemaphore.Null; var signalH = signal ?? VkSemaphore.Null; var submitH = submit ?? VkFence.Null; var info = new VkSubmitInfo() { SType = VkStructureType.SubmitInfo, PNext = IntPtr.Zero, CommandBufferCount = 1, PCommandBuffers = &buff, SignalSemaphoreCount = signalH != VkSemaphore.Null ? 1u : 0u, PSignalSemaphores = &signalH, WaitSemaphoreCount = waitH != VkSemaphore.Null ? 1u : 0u, PWaitSemaphores = &waitH, PWaitDstStageMask = &waitStage, }; if (buffer is CommandBufferPooledExclusiveUse peu) { Debug.Assert(submitH == VkFence.Null, "Can't use a submit fence on a pooled handle"); peu.DoSubmit(Handle, info); } else { VkException.Check(VkQueue.vkQueueSubmit(Handle, 1, &info, submitH)); } } }
/// <summary> /// Records a buffer image barrier /// </summary> /// <returns>this</returns> public void BufferMemoryBarrier(Buffer buffer, VkAccessFlag srcAccess, uint srcQueue, VkAccessFlag dstAccess, uint dstQueue = Vulkan.QueueFamilyIgnored, VkPipelineStageFlag srcStage = VkPipelineStageFlag.AllCommands, VkPipelineStageFlag dstStage = VkPipelineStageFlag.AllCommands, VkDependencyFlag depFlag = VkDependencyFlag.None, ulong offset = 0, ulong size = 0) { var temp = new VkBufferMemoryBarrier() { SType = VkStructureType.BufferMemoryBarrier, PNext = IntPtr.Zero, SrcAccessMask = srcAccess, DstAccessMask = dstAccess, Buffer = buffer.Handle, SrcQueueFamilyIndex = srcQueue, DstQueueFamilyIndex = dstQueue, Offset = offset, Size = size == 0 ? buffer.Size - offset : size }; PipelineBarrier(srcStage, dstStage, depFlag, default(VkMemoryBarrier), temp, default(VkImageMemoryBarrier)); }
/// <summary> /// Sets the destination stage mask for this dependency. /// <seealso cref="VkSubpassDependency.DstStageMask"/> /// </summary> /// <param name="dst">destination stage mask</param> /// <returns>this</returns> public TBuilder DstStage(VkPipelineStageFlag dst) { _desc.DstStageMask = dst; Debug.Assert(_desc.DstSubpass == Vulkan.SubpassExternal || (_desc.DstStageMask & VkPipelineStageFlag.Host) == 0); return((TBuilder)this); }
/// <summary> /// Sets the source stage mask for this dependency. /// <seealso cref="VkSubpassDependency.SrcStageMask"/> /// </summary> /// <param name="src">source stage mask</param> /// <returns>this</returns> public TBuilder SrcStage(VkPipelineStageFlag src) { _desc.SrcStageMask = src; Debug.Assert(_desc.SrcSubpass == Vulkan.SubpassExternal || (_desc.SrcStageMask & VkPipelineStageFlag.Host) == 0); return((TBuilder)this); }
/// <summary> /// To record a pipeline barrier, call: /// </summary> /// <param name="srcStageMask">is a bitmask of <c>VkPipelineStageFlagBits</c> specifying the <a href='https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-pipeline-stages-masks'> source stage mask</a>.</param> /// <param name="dstStageMask">is a bitmask of <c>VkPipelineStageFlagBits</c> specifying the <a href='https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-pipeline-stages-masks'> destination stage mask</a>.</param> /// <param name="dependencyFlags">is a bitmask of <c>VkDependencyFlagBits</c> specifying how execution and memory dependencies are formed.</param> /// <param name="barrier">is a pointer to an array of <see cref="VkMemoryBarrier"/> structures.</param> /// <param name="bufferBarrier">is a pointer to an array of <see cref="VkBufferMemoryBarrier"/> structures.</param> /// <param name="imageBarrier">is a pointer to an array of <see cref="VkImageMemoryBarrier"/> structures.</param> public void PipelineBarrier(VkPipelineStageFlag srcStageMask, VkPipelineStageFlag dstStageMask, VkDependencyFlag dependencyFlags, Span <VkMemoryBarrier> barrier, Span <VkBufferMemoryBarrier> bufferBarrier, Span <VkImageMemoryBarrier> imageBarrier) { Handle.PipelineBarrier(srcStageMask, dstStageMask, dependencyFlags, barrier, bufferBarrier, imageBarrier); }
public void Submit(CommandBuffer buffer, Semaphore wait, VkPipelineStageFlag waitStage, Semaphore signal, Fence submit) { wait?.AssertValid(); signal?.AssertValid(); submit?.AssertValid(); Submit(buffer, wait?.Handle, waitStage, signal?.Handle, submit?.Handle); }
private static void GetStageInfo(VkImageLayout layout, out VkPipelineStageFlag pipelineStage, out VkAccessFlag accessMask) { accessMask = VkAccessFlag.None; pipelineStage = 0; switch (layout) { case VkImageLayout.ColorAttachmentOptimal: pipelineStage = VkPipelineStageFlag.AllGraphics; accessMask |= VkAccessFlag.ColorAttachmentRead | VkAccessFlag.ColorAttachmentWrite; break; case VkImageLayout.DepthStencilAttachmentOptimal: case VkImageLayout.DepthReadOnlyStencilAttachmentOptimalKhr: pipelineStage = VkPipelineStageFlag.AllGraphics; accessMask |= VkAccessFlag.DepthStencilAttachmentRead | VkAccessFlag.DepthStencilAttachmentWrite; break; case VkImageLayout.DepthStencilReadOnlyOptimal: case VkImageLayout.DepthAttachmentStencilReadOnlyOptimalKhr: pipelineStage = VkPipelineStageFlag.AllGraphics; accessMask |= VkAccessFlag.DepthStencilAttachmentRead; break; case VkImageLayout.ShaderReadOnlyOptimal: pipelineStage = VkPipelineStageFlag.AllGraphics; accessMask |= VkAccessFlag.ShaderRead; break; case VkImageLayout.TransferSrcOptimal: pipelineStage = VkPipelineStageFlag.Transfer; accessMask |= VkAccessFlag.TransferRead; break; case VkImageLayout.TransferDstOptimal: pipelineStage = VkPipelineStageFlag.Transfer; accessMask |= VkAccessFlag.TransferWrite; break; case VkImageLayout.Undefined: pipelineStage = VkPipelineStageFlag.AllCommands; accessMask |= VkAccessFlag.None; break; case VkImageLayout.SharedPresentKhr: case VkImageLayout.PresentSrcKhr: case VkImageLayout.Preinitialized: case VkImageLayout.General: pipelineStage = VkPipelineStageFlag.AllCommands; accessMask |= VkAccessFlag.AllExceptExt; break; } }
/// <summary> /// To record a pipeline barrier, call: /// </summary> /// <param name="srcStageMask">is a bitmask of <c>VkPipelineStageFlagBits</c> specifying the <a href='https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-pipeline-stages-masks'> source stage mask</a>.</param> /// <param name="dstStageMask">is a bitmask of <c>VkPipelineStageFlagBits</c> specifying the <a href='https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#synchronization-pipeline-stages-masks'> destination stage mask</a>.</param> /// <param name="dependencyFlags">is a bitmask of <c>VkDependencyFlagBits</c> specifying how execution and memory dependencies are formed.</param> /// <param name="barrier">is a pointer to an array of <see cref="VkMemoryBarrier"/> structures.</param> /// <param name="bufferBarrier">is a pointer to an array of <see cref="VkBufferMemoryBarrier"/> structures.</param> /// <param name="imageBarrier">is a pointer to an array of <see cref="VkImageMemoryBarrier"/> structures.</param> public void PipelineBarrier(VkPipelineStageFlag srcStageMask, VkPipelineStageFlag dstStageMask, VkDependencyFlag dependencyFlags, VkMemoryBarrier barrier = default(VkMemoryBarrier), VkBufferMemoryBarrier bufferBarrier = default(VkBufferMemoryBarrier), VkImageMemoryBarrier imageBarrier = default(VkImageMemoryBarrier)) { unsafe { VkCommandBuffer.vkCmdPipelineBarrier(Handle, srcStageMask, dstStageMask, dependencyFlags, barrier.SType != VkStructureType.BufferMemoryBarrier ? 0 : 1u, &barrier, bufferBarrier.SType != VkStructureType.BufferMemoryBarrier ? 0 : 1u, &bufferBarrier, imageBarrier.SType != VkStructureType.ImageMemoryBarrier ? 0 : 1u, &imageBarrier); } }
/// <summary> /// Sets the source and destination stage masks for this dependency. /// <seealso cref="VkSubpassDependency.SrcStageMask"/> /// <seealso cref="VkSubpassDependency.DstStageMask"/> /// </summary> /// <param name="src">source stage mask</param> /// <param name="dst">destination stage mask</param> /// <returns>this</returns> public TBuilder Stage(VkPipelineStageFlag src, VkPipelineStageFlag dst) { return(SrcStage(src).DstStage(dst)); }