public static void vkCmdPipelineBarrier(VkCommandBuffer commandBuffer, VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask, int dependencyFlags, int memoryBarrierCount, VkMemoryBarrier[] pMemoryBarriers, int bufferMemoryBarrierCount, VkBufferMemoryBarrier[] pBufferMemoryBarriers, int imageMemoryBarrierCount, VkImageMemoryBarrier[] pImageMemoryBarriers) { bool hasBarrier = false; VkPreconditions.CheckNull(commandBuffer, nameof(commandBuffer)); if (memoryBarrierCount != 0) { hasBarrier = true; VkPreconditions.CheckNull(pMemoryBarriers, nameof(pMemoryBarriers)); VkPreconditions.CheckRange(memoryBarrierCount, 1, pMemoryBarriers.Length, nameof(memoryBarrierCount)); } if (bufferMemoryBarrierCount != 0) { hasBarrier = true; VkPreconditions.CheckNull(pBufferMemoryBarriers, nameof(pBufferMemoryBarriers)); VkPreconditions.CheckRange(bufferMemoryBarrierCount, 1, pBufferMemoryBarriers.Length, nameof(bufferMemoryBarrierCount)); } if (imageMemoryBarrierCount != 0) { hasBarrier = true; VkPreconditions.CheckNull(pImageMemoryBarriers, nameof(pImageMemoryBarriers)); VkPreconditions.CheckRange(imageMemoryBarrierCount, 1, pImageMemoryBarriers.Length, nameof(imageMemoryBarrierCount)); } VkPreconditions.CheckOperation(!hasBarrier, ("At least one type of barrier must be informed on the command")); GetCommandBuffer(commandBuffer).CmdPipelineBarrier(srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); }
public void CmdPipelineBarrier(VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask, int dependencyFlags, int memoryBarrierCount, VkMemoryBarrier[] pMemoryBarriers, int bufferMemoryBarrierCount, VkBufferMemoryBarrier[] pBufferMemoryBarriers, int imageMemoryBarrierCount, VkImageMemoryBarrier[] pImageMemoryBarriers) { if (m_State != CommandBufferState.Recording) { return; } m_Commands.Add(new Cmd_PipelineBarrier(srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers)); }
public Cmd_PipelineBarrier(VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask, int dependencyFlags, int memoryBarrierCount, VkMemoryBarrier[] pMemoryBarriers, int bufferMemoryBarrierCount, VkBufferMemoryBarrier[] pBufferMemoryBarriers, int imageMemoryBarrierCount, VkImageMemoryBarrier[] pImageMemoryBarriers) { this.srcStageMask = srcStageMask; this.dstStageMask = dstStageMask; this.dependencyFlags = dependencyFlags; this.memoryBarrierCount = memoryBarrierCount; this.pMemoryBarriers = pMemoryBarriers; this.bufferMemoryBarrierCount = bufferMemoryBarrierCount; this.pBufferMemoryBarriers = pBufferMemoryBarriers; this.imageMemoryBarrierCount = imageMemoryBarrierCount; this.pImageMemoryBarriers = pImageMemoryBarriers; }
void drawFrame() { int imageIndex; Vulkan.vkAcquireNextImageKHR(device, swapChain, long.MaxValue, imageAvailableSemaphore, null, out imageIndex); VkSubmitInfo submitInfo = new VkSubmitInfo(); submitInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SUBMIT_INFO; VkSemaphore[] waitSemaphores = new VkSemaphore[] { imageAvailableSemaphore }; VkPipelineStageFlagBits[] waitStages = new VkPipelineStageFlagBits[] { VkPipelineStageFlagBits.VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = new VkCommandBuffer[] { commandBuffers[imageIndex] }; VkSemaphore[] signalSemaphores = new VkSemaphore[] { renderFinishedSemaphore }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; fpsSubmitQueue.Begin(); VkResult result = Vulkan.vkQueueSubmit(graphicsQueue, 1, new VkSubmitInfo[] { submitInfo }, null); fpsSubmitQueue.End(); fpsSubmitQueue.DebugPeriodicReport(); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo = new VkPresentInfoKHR(); presentInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR[] swapChains = new VkSwapchainKHR[] { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = new int[] { imageIndex }; fpsPresentQueue.Begin(); Vulkan.vkQueuePresentKHR(presentQueue, presentInfo); fpsPresentQueue.End(); fpsPresentQueue.DebugPeriodicReport(); Vulkan.vkQueueWaitIdle(presentQueue); }
// Fixed sub resource on first mip level and layer public static void setImageLayout( VkCommandBuffer cmdbuffer, VkImage image, VkImageAspectFlagBits aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkPipelineStageFlagBits srcStageMask = VkPipelineStageFlagBits.AllCommands, VkPipelineStageFlagBits dstStageMask = VkPipelineStageFlagBits.AllCommands) { VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange(); subresourceRange.aspectMask = aspectMask; subresourceRange.baseMipLevel = 0; subresourceRange.levelCount = 1; subresourceRange.layerCount = 1; setImageLayout(cmdbuffer, image, aspectMask, oldImageLayout, newImageLayout, subresourceRange); }
// Create an image memory barrier for changing the layout of // an image and put it into an active command buffer // See chapter 11.4 "Image Layout" for details public static void setImageLayout( VkCommandBuffer cmdbuffer, VkImage image, VkImageAspectFlagBits aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkImageSubresourceRange subresourceRange, VkPipelineStageFlagBits srcStageMask = VkPipelineStageFlagBits.AllCommands, VkPipelineStageFlagBits dstStageMask = VkPipelineStageFlagBits.AllCommands) { // Create an image barrier object VkImageMemoryBarrier imageMemoryBarrier = new VkImageMemoryBarrier(); imageMemoryBarrier.sType = ImageMemoryBarrier; imageMemoryBarrier.oldLayout = oldImageLayout; imageMemoryBarrier.newLayout = newImageLayout; imageMemoryBarrier.image = image; imageMemoryBarrier.subresourceRange = subresourceRange; // Source layouts (old) // Source access mask controls actions that have to be finished on the old layout // before it will be transitioned to the new layout switch (oldImageLayout) { case VkImageLayout.Undefined: // Image layout is undefined (or does not matter) // Only valid as initial layout // No flags required, listed only for completeness imageMemoryBarrier.srcAccessMask = 0; break; case VkImageLayout.Preinitialized: // Image is preinitialized // Only valid as initial layout for linear images, preserves memory contents // Make sure host writes have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.HostWrite; break; case VkImageLayout.ColorAttachmentOptimal: // Image is a color attachment // Make sure any writes to the color buffer have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.ColorAttachmentWrite; break; case VkImageLayout.DepthStencilAttachmentOptimal: // Image is a depth/stencil attachment // Make sure any writes to the depth/stencil buffer have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.DepthStencilAttachmentWrite; break; case VkImageLayout.TransferSrcOptimal: // Image is a transfer source // Make sure any reads from the image have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.TransferRead; break; case VkImageLayout.TransferDstOptimal: // Image is a transfer destination // Make sure any writes to the image have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.TransferWrite; break; case VkImageLayout.ShaderReadOnlyOptimal: // Image is read by a shader // Make sure any shader reads from the image have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.ShaderRead; break; } // Target layouts (new) // Destination access mask controls the dependency for the new image layout switch (newImageLayout) { case VkImageLayout.TransferDstOptimal: // Image will be used as a transfer destination // Make sure any writes to the image have been finished imageMemoryBarrier.dstAccessMask = VkAccessFlagBits.TransferWrite; break; case VkImageLayout.TransferSrcOptimal: // Image will be used as a transfer source // Make sure any reads from and writes to the image have been finished imageMemoryBarrier.srcAccessMask = imageMemoryBarrier.srcAccessMask | VkAccessFlagBits.TransferRead; imageMemoryBarrier.dstAccessMask = VkAccessFlagBits.TransferRead; break; case VkImageLayout.ColorAttachmentOptimal: // Image will be used as a color attachment // Make sure any writes to the color buffer have been finished imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.TransferRead; imageMemoryBarrier.dstAccessMask = VkAccessFlagBits.ColorAttachmentWrite; break; case VkImageLayout.DepthStencilAttachmentOptimal: // Image layout will be used as a depth/stencil attachment // Make sure any writes to depth/stencil buffer have been finished imageMemoryBarrier.dstAccessMask = imageMemoryBarrier.dstAccessMask | VkAccessFlagBits.DepthStencilAttachmentWrite; break; case VkImageLayout.ShaderReadOnlyOptimal: // Image will be read in a shader (sampler, input attachment) // Make sure any writes to the image have been finished if (imageMemoryBarrier.srcAccessMask == 0) { imageMemoryBarrier.srcAccessMask = VkAccessFlagBits.HostWrite | VkAccessFlagBits.TransferWrite; } imageMemoryBarrier.dstAccessMask = VkAccessFlagBits.ShaderRead; break; } // Put barrier inside setup command buffer vkCmdPipelineBarrier( cmdbuffer, srcStageMask, dstStageMask, 0, 0, null, 0, null, 1, &imageMemoryBarrier); }
// Create an image memory barrier for changing the layout of // an image and put it into an active command buffer void setImageLayout( VkCommandBuffer cmdBuffer, VkImage image, VkImageAspectFlagBits aspectMask, VkImageLayout oldImageLayout, VkImageLayout newImageLayout, VkImageSubresourceRange subresourceRange) { // Create an image barrier object var barrier = VkImageMemoryBarrier.Alloc(); barrier[0].oldLayout = oldImageLayout; barrier[0].newLayout = newImageLayout; barrier[0].image = image; barrier[0].subresourceRange = subresourceRange; // Only sets masks for layouts used in this example // For a more complete version that can be used with other layouts see vks::tools::setImageLayout // Source layouts (old) switch (oldImageLayout) { case VkImageLayout.Undefined: // Only valid as initial layout, memory contents are not preserved // Can be accessed directly, no source dependency required barrier[0].srcAccessMask = 0; break; case VkImageLayout.Preinitialized: // Only valid as initial layout for linear images, preserves memory contents // Make sure host writes to the image have been finished barrier[0].srcAccessMask = VkAccessFlagBits.HostWrite; break; case VkImageLayout.TransferDstOptimal: // Old layout is transfer destination // Make sure any writes to the image have been finished barrier[0].srcAccessMask = VkAccessFlagBits.TransferWrite; break; } // Target layouts (new) switch (newImageLayout) { case VkImageLayout.TransferSrcOptimal: // Transfer source (copy, blit) // Make sure any reads from the image have been finished barrier[0].dstAccessMask = VkAccessFlagBits.TransferRead; break; case VkImageLayout.TransferDstOptimal: // Transfer destination (copy, blit) // Make sure any writes to the image have been finished barrier[0].dstAccessMask = VkAccessFlagBits.TransferWrite; break; case VkImageLayout.ShaderReadOnlyOptimal: // Shader read (sampler, input attachment) barrier[0].dstAccessMask = VkAccessFlagBits.ShaderRead; break; } // Put barrier on top of pipeline VkPipelineStageFlagBits srcStageFlags = VkPipelineStageFlagBits.TopOfPipe; VkPipelineStageFlagBits destStageFlags = VkPipelineStageFlagBits.TopOfPipe; // Put barrier inside setup command buffer vkCmdPipelineBarrier( cmdBuffer, srcStageFlags, destStageFlags, 0,//VkDependencyFlagBits.None, 0, null, 0, null, 1, barrier); }
internal void CmdPipelineBarrier(VkPipelineStageFlagBits srcStageMask, VkPipelineStageFlagBits dstStageMask, int dependencyFlags, int memoryBarrierCount, VkMemoryBarrier[] pMemoryBarriers, int bufferMemoryBarrierCount, VkBufferMemoryBarrier[] pBufferMemoryBarriers, int imageMemoryBarrierCount, VkImageMemoryBarrier[] pImageMemoryBarriers) { }