public override void Update() { initGpuBuffers(); using (CommandPool cmdPoolCompute = new CommandPool(dev, computeQ.qFamIndex)) { CommandBuffer cmd = cmdPoolCompute.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit); pong = false; uint stepSize = imgDim / 2; plCompute.Bind(cmd); cmd.PushConstant(plCompute.Layout, VkShaderStageFlags.Compute, imgDim, sizeof(int)); int pass = 0; while (stepSize > 0 && pass < invocationCount) { cmd.PushConstant(plCompute.Layout, VkShaderStageFlags.Compute, stepSize); if (pong) { plCompute.BindDescriptorSet(cmd, dsetPong); } else { plCompute.BindDescriptorSet(cmd, dsetPing); } cmd.Dispatch(imgDim, imgDim); VkMemoryBarrier memBar = VkMemoryBarrier.New(); memBar.srcAccessMask = VkAccessFlags.ShaderWrite; memBar.dstAccessMask = VkAccessFlags.ShaderRead; Vk.vkCmdPipelineBarrier(cmd.Handle, VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.ComputeShader, VkDependencyFlags.ByRegion, 1, ref memBar, 0, IntPtr.Zero, 0, IntPtr.Zero); pong = !pong; stepSize /= 2; pass++; } plNormalize.Bind(cmd); if (pong) { plNormalize.BindDescriptorSet(cmd, dsetPong); } else { plNormalize.BindDescriptorSet(cmd, dsetPing); } cmd.Dispatch(imgDim, imgDim); pong = !pong; cmd.End(); computeQ.Submit(cmd); computeQ.WaitIdle(); } printResults(); }
public void SetMemoryBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkDependencyFlags dependencyFlags = VkDependencyFlags.ByRegion) { VkMemoryBarrier memoryBarrier = VkMemoryBarrier.New(); memoryBarrier.srcAccessMask = srcAccessMask; memoryBarrier.dstAccessMask = dstAccessMask; Vk.vkCmdPipelineBarrier(Handle, srcStageMask, dstStageMask, dependencyFlags, 1, ref memoryBarrier, 0, IntPtr.Zero, 0, IntPtr.Zero); }
/// <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); } }
public void WaitEvents(List <Event> events, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, List <MemoryBarrier> memoryBarriers, List <BufferMemoryBarrier> bufferMemoryBarriers, List <ImageMemoryBarrier> imageMemoryBarriers) { unsafe { var eventsNative = stackalloc VkEvent[events.Count]; Interop.Marshal <VkEvent, Event>(events, eventsNative); int mbCount = 0; int bbCount = 0; int ibCount = 0; if (memoryBarriers != null) { mbCount = memoryBarriers.Count; } if (bufferMemoryBarriers != null) { bbCount = bufferMemoryBarriers.Count; } if (imageMemoryBarriers != null) ibCount = imageMemoryBarriers.Count; } var mbNative = stackalloc VkMemoryBarrier[mbCount]; var bbNative = stackalloc VkBufferMemoryBarrier[bbCount]; var ibNative = stackalloc VkImageMemoryBarrier[ibCount]; for (int i = 0; i < mbCount; i++) { var mb = memoryBarriers[i]; mbNative[i] = new VkMemoryBarrier(); mbNative[i].sType = VkStructureType.MemoryBarrier; mbNative[i].srcAccessMask = mb.srcAccessMask; mbNative[i].dstAccessMask = mb.dstAccessMask; } for (int i = 0; i < bbCount; i++) { var bb = bufferMemoryBarriers[i]; bbNative[i] = new VkBufferMemoryBarrier(); bbNative[i].sType = VkStructureType.BufferMemoryBarrier; bbNative[i].srcAccessMask = bb.srcAccessMask; bbNative[i].dstAccessMask = bb.dstAccessMask; bbNative[i].srcQueueFamilyIndex = bb.srcQueueFamilyIndex; bbNative[i].dstQueueFamilyIndex = bb.dstQueueFamilyIndex; bbNative[i].buffer = bb.buffer.Native; bbNative[i].offset = bb.offset; bbNative[i].size = bb.size; } for (int i = 0; i < ibCount; i++) { var ib = imageMemoryBarriers[i]; ibNative[i] = new VkImageMemoryBarrier(); ibNative[i].sType = VkStructureType.ImageMemoryBarrier; ibNative[i].srcAccessMask = ib.srcAccessMask; ibNative[i].dstAccessMask = ib.dstAccessMask; ibNative[i].oldLayout = ib.oldLayout; ibNative[i].newLayout = ib.newLayout; ibNative[i].srcQueueFamilyIndex = ib.srcQueueFamilyIndex; ibNative[i].dstQueueFamilyIndex = ib.dstQueueFamilyIndex; ibNative[i].image = ib.image.Native; ibNative[i].subresourceRange = ib.subresourceRange; } Device.Commands.cmdWaitEvents(commandBuffer, (uint)events.Count, (IntPtr)eventsNative, srcStageMask, dstStageMask, (uint)mbCount, (IntPtr)mbNative, (uint)bbCount, (IntPtr)bbNative, (uint)ibCount, (IntPtr)ibNative); }