title: Vulkan: vkCmdPipelineBarrier for data coherence
body: <p>My question has 2 parts:</p>
  
  <ol>
  <li>What is the difference between memory being available / being visible?</li>
  <li><p>Im learning Vulkan from this tutorial (<a href="https://vulkan-tutorial.com" rel="nofollow noreferrer">https://vulkan-tutorial.com</a>) and currently sneaking around for a different approach to upload uniform data (simple model/view/projection matrices) to a device local memory. The matrices are used in the vertex shader.</p>
  
  <p>In the tutorial the matrices get updated and are copied to a staging buffer (<code>vkMapMemory</code> etc.) and are copied afterwards to the final device local buffer by creating a command buffer, recording <code>vkCmdCopy</code>, submiting it and destroying the buffer. I try to do the last step within the obligatory command buffers for drawing.</p>
  
  <p>While the tutorial way leads to a fluent animation, my experiment misses this feature. I tried to install 2 bufferBarriers to ensure that the copies are done (which seems to be problem), but that didn't help. The resources are properly created and bound - that's working fine.</p>
  
  <pre><code>//update uniform buffer and copy it to the staging buffer
  //(called every frame)
  Tools::UniformBufferObject ubo;
  //set the matrices
  void* data;
  data = device.mapMemory( uniformStagingMemory, 0, sizeof( ubo ), (vk::MemoryMapFlagBits) 0 );
    memcpy( data, &amp;ubo, sizeof( ubo ));
  device.unmapMemory( uniformStagingMemory );
  
  
  //once: create a command buffer for each framebuffer of the swapchain
  //queueFamily struct members set properly
  //1st barrier: make transfer from host memory to staging buffer available / visible
  vk::BufferMemoryBarrier bufMemBarrierStaging;
  bufMemBarrierStaging.srcAccessMask = vk::AccessFlagBits::eHostWrite;
  bufMemBarrierStaging.dstAccessMask = vk::AccessFlagBits::eTransferRead;
  bufMemBarrierStaging.buffer = uniformStagingBuffer;
  bufMemBarrierStaging.offset = 0;
  bufMemBarrierStaging.size = sizeof( Tools::UniformBufferObject );
  
  //2nd barrier: make transfer from staging buffer to device local buffer available / visible
  vk::BufferMemoryBarrier bufMemBarrier;
  bufMemBarrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
  bufMemBarrier.dstAccessMask = vk::AccessFlagBits::eUniformRead | vk::AccessFlagBits::eShaderRead;
  bufMemBarrier.buffer = dataBuffer;
  bufMemBarrier.offset = dataBufferOffsets[2];
  bufMemBarrier.size = sizeof( Tools::UniformBufferObject );
  
  for( size_t i = 0; i &lt; cmdBuffers.size(); i++ ) {
      //begin command buffer
  
      cmdBuffers[i].pipelineBarrier(
          vk::PipelineStageFlagBits::eHost, //srcPipelineStage
          vk::PipelineStageFlagBits::eTransfer, //dstPipelineStage
          (vk::DependencyFlagBits) 0,
          nullptr, //memBarrier
          bufMemBarrierStaging,
          nullptr //imgBarrier
      );
      vk::BufferCopy copyRegion; //filled appropriate
      cmdBuffers[i].copyBuffer( uniformStagingBuffer, dataBuffer, copyRegion );
  
      cmdBuffers[i].pipelineBarrier(
          vk::PipelineStageFlagBits::eTransfer, //srcPipelineStage
          vk::PipelineStageFlagBits::eVertexShader, //dstPipelineStage
          (vk::DependencyFlagBits) 0,
          nullptr, //memBarrier
          bufMemBarrier,
          nullptr //imgBarrier
      );
      //renderpass stuff and drawing etc.
  }
  </code></pre>
  
  <p>with</p>
  
  <pre><code>namespace Tools {
    struct UniformBufferObject {
      glm::mat4 model;
      glm::mat4 view;
      glm::mat4 proj;
    };
  };
  vk::Buffer uniformStagingBuffer;
  vk::DeviceMemory uniformStagingMemory;
  //dataBuffer also contains the vertex and index data, is device local
  vk::Buffer dataBuffer;
  vk::DeviceMemory dataBufferMemory;
  vk::vector&lt;vk::DeviceSize&gt; dataBufferOffsets;
  
  std::vector&lt;vk::CommandBuffer&gt; cmdBuffers;
  </code></pre>
  
  <p>Im using <code>vkcpp</code> (<a href="https://github.com/KhronosGroup/Vulkan-Hpp" rel="nofollow noreferrer">https://github.com/KhronosGroup/Vulkan-Hpp</a>).</p>
  
  <p>Is the reason for this nonfluid animation missing data coherence - and did I a mistake trying to achieve this?</p></li>
  </ol>
  
  <p>Thanks in advance!</p>
  
  <p><strong>Edit:</strong> The problem of part 2 was a missing syncronisation; the staging buffer was (partially) updated before it was read during rendering the frame before.  (Thanks for making clear the difference between memory being available / visible).</p>