Buffers can be used for various purposes. For each buffer, we can upload data to it or copy data from it; we can bind a buffer to a pipeline via descriptor sets and use it inside shaders as a source of data, or we can store data in the buffer from within the shaders.
We must inform a driver about each such usage, not only during buffer creation, but also before the intended usage. When we have been using a buffer for one purpose and from now on we want to use it differently, we must tell the driver about a change in the buffer's usage. This is done through buffer memory barriers. They are set as part of the pipeline barriers during command buffer recording (refer to the Beginning a command buffer recording operation recipe from Chapter 3, Command Buffers and Synchronization).