Search code examples
vulkan

What happens if I use an access mask with top of pipe bit as stage?


Let's say that I record a transfer command in a command buffer data that needs to be read from the shader. Also assume that a transfer has been made of vertices and indices to the buffers bound. I don't want any drawing operations to begin until the transfers have completed. So I put a global memory barrier:

cmd_buffer->placeGlobalMemoryBarrier(
/* src_stage */ VK_PIPELINE_STAGE_TRANSFER_BIT, 
/* dst_stage */ VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 
/* src_access_mask */ VK_ACCESS_TRANSFER_WRITE_BIT, 
/* dst_access_mask */ VK_ACCESS_SHADER_READ_BIT);

The VK_ACCESS_SHADER_READ_BIT is supposed to say make all memory visible before reading from the shader. But is this not enough to ensure that the vertices and indices are visible?

Furthermore, let's say I want to read the uniform from BOTH the vertex and fragment shader, the access mask of VK_ACCESS_SHADER_READ_BIT mask is enough, right? I don't need VK_ACCESS_UNIFORM_READ_BIT, right?


Solution

  • What happens if you use an access mask with VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT is undefined behavior. It is not allowed:

    An application must not specify an access flag in a synchronization command if it does not include a pipeline stage in the corresponding stage mask that is able to perform accesses of that type.

    If you want to cover everything, you need to use VK_PIPELINE_STAGE_ALL_COMMANDS_BIT instead.


    VK_ACCESS_SHADER_READ_BIT is not enough to make vertices and indices visible-to. This mask only covers the things listed in its descriptions, e.g. per non-extended Vulkan 1.0 specification:

    VK_ACCESS_SHADER_READ_BIT specifies read access to a uniform texel buffer, sampled image, storage buffer, physical storage buffer, shader binding table, storage texel buffer, or storage image in any shader pipeline stage.

    VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT and VK_ACCESS_INDEX_READ_BIT are for vertex and index buffer, respectively. Both related to the VK_PIPELINE_STAGE_VERTEX_INPUT_BIT stage.


    VK_ACCESS_UNIFORM_READ_BIT is a subset of VK_ACCESS_SHADER_READ_BIT. Either bit covers uniform reads, and can be used with any VK_PIPELINE_STAGE_*_SHADER_BIT stage.

    Nevertheless you hurt nothing by including that access mask bit explicitly.

    Correction: VK_ACCESS_SHADER_READ_BIT does not include VK_ACCESS_UNIFORM_READ_BIT per KhronosGroup/Vulkan-Docs#2169.