0
$\begingroup$

I have two compute shaders that are to be executed one after the other. The first compute shader performs some calculations and stores the number of results in a buffer with VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, which should be the number of workgroups for the second compute shader. After this compute shader, a vkCmdPipelineBarrier should synchronize it. The second compute shader is executed by the vkCmdDispatchIndirect command. Both shader execution commands are located in the same command buffer.

VkMemoryBarrier memoryBarrier; memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memoryBarrier.pNext = NULL; memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader1->getPipeline()); vkCmdBindDescriptorSets(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader1->getPipelineLayout(), 0, 1, &m_descriptorShader1, 0, 0); vkCmdDispatch(m_commandBuffer, 100, 1, 1); vkCmdPipelineBarrier(m_commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0, 1, &memoryBarrier, 0, nullptr, 0, nullptr); vkCmdBindPipeline(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader2->getPipeline()); vkCmdBindDescriptorSets(m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, shader2->getPipelineLayout(), 0, 1, &m_descriptorShader2, 0, 0); vkCmdDispatchIndirect(m_commandBuffer, infoSSBO.getVkBuffer(), 0); 

The following error occurs when attempting to use the VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT flag:

VUID-vkCmdPipelineBarrier-dstAccessMask-02816(ERROR / SPEC): msgNum: 1774732925 - Validation Error: [ VUID-vkCmdPipelineBarrier-dstAccessMask-02816 ] Object 0: handle = 0x1f6932cc430, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x69c8467d | vkCmdPipelineBarrier(): .pMemoryBarriers[0].dstAccessMask bit VK_ACCESS_SHADER_READ_BIT is not supported by stage mask (VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT). The Vulkan spec states: The dstAccessMask member of each element of pMemoryBarriers must only include access flags that are supported by one or more of the pipeline stages in dstStageMask, as specified in the table of supported access types (https://vulkan.lunarg.com/doc/view/1.2.189.2/windows/1.2-extensions/vkspec.html#VUID-vkCmdPipelineBarrier-dstAccessMask-02816) Objects: 1 [0] 0x1f6932cc430, type: 6, name: NULL

If the “VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT” flag is used for both (src and dst), synchronization does not appear to work.

Which flags does the barrier need?

EDIT:

I changed the code to the following:

VkMemoryBarrier memoryBarrierIndirect; memoryBarrierIndirect.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memoryBarrierIndirect.pNext = NULL; memoryBarrierIndirect.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; memoryBarrierIndirect.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT | VK_ACCESS_SHADER_READ_BIT; vkCmdPipelineBarrier(m_coverageRuleCommandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &memoryBarrierIndirect, 0, nullptr, 0, nullptr); 

It seems to work (the correct number of workgroups is executed), but the “VK_LAYER_KHRONOS_validation” is printing:

VUID-vkCmdPipelineBarrier-dstAccessMask-02816(ERROR / SPEC): msgNum: 1774732925 - Validation Error: [ VUID-vkCmdPipelineBarrier-dstAccessMask-02816 ] Object 0: handle = 0x1c85d885f30, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x69c8467d | vkCmdPipelineBarrier(): .pMemoryBarriers[0].dstAccessMask bit VK_ACCESS_INDIRECT_COMMAND_READ_BIT is not supported by stage mask (VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT). The Vulkan spec states: The dstAccessMask member of each element of pMemoryBarriers must only include access flags that are supported by one or more of the pipeline stages in dstStageMask, as specified in the table of supported access types (https://vulkan.lunarg.com/doc/view/1.2.189.2/windows/1.2-extensions/vkspec.html#VUID-vkCmdPipelineBarrier-dstAccessMask-02816) Objects: 1 [0] 0x1c85d885f30, type: 6, name: NULL

I am afraid that it will not work properly on other computers. How can this be fixed?

$\endgroup$
3
  • $\begingroup$ What are the memory barrier settings? Usually both src and dst stage masks are COMPUTE_SHADER_BIT and in the memory barrier src access mask is something like VK_ACCESS_SHADER_WRITE_BIT and the dest access mask is VK_ACCESS_SHADER_READ_BIT. If these are both in the same command buffer no external sync is needed, but if they span command buffers then a semaphore will be need. $\endgroup$ Commented Jun 17 at 11:18
  • $\begingroup$ right now it is like the following: VkMemoryBarrier memoryBarrier; memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; memoryBarrier.pNext = NULL; memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; $\endgroup$ Commented Jun 17 at 11:40
  • $\begingroup$ did you try: memoryBarrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT; $\endgroup$ Commented Jun 18 at 13:08

1 Answer 1

1
$\begingroup$

instead of using the VkMemoryBarrier structure, I found out that the VkBufferMemoryBarrier structure is the right one, and it works well in the following way:

VkBufferMemoryBarrier barrier{}; barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_INDIRECT_COMMAND_READ_BIT; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.buffer = indirectBuffer; barrier.offset = 0; barrier.size = sizeof(VkDispatchIndirectCommand); vkCmdPipelineBarrier( commandBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, // srcStageMask VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // dstStageMask 0, 0, nullptr, 1, &barrier, 0, nullptr ); 
$\endgroup$
2
  • $\begingroup$ Seeing this answer was one of those oh duh moments for me: "of course it should block on the buffer". Knowing which of memory or buffer barrier to use seems ambiguous until it's working at which point it seems obvious. All part of the Vulkan fun. $\endgroup$ Commented Jul 10 at 11:43
  • $\begingroup$ @pmw1234 you are total right :). I'm so happy that there is the VK_LAYER_KHRONOS_validation. Otherwise it would be impossible for me $\endgroup$ Commented Jul 11 at 13:12

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.