In my Vulkan app I'm using a single command buffer and I'm prerecording everything in it, right now I have a bug and one of the places that I'm suspicious about it, is where I copying a region of data from a staging buffer to GPU(device local) buffer, and then I do my operations on that buffer.
The Question is, should I do synchronization even when I'm using a single command buffer?
My question is not specific to only copy buffer it is a general question, Is there any case that even in a single command buffer app you should do synchronization?
In Vulkan, you have to almost synchronize everything.
It is not because you are using only one command buffer that commands can not be run asynchronously.
Let's say for example that you are copying a buffer, and after you want to read this buffer as a Vertex Buffer.
You must issue a memory barrier from the
TRANSFER_STAGE
to theVERTEX_INPUT_STAGE
and with a srcAccessTRANSFER_WRITE
and a dstAccessVERTEX_ATTRIBUTE_READ
.Going that way, the barrier ensure the transfer is finished AND that the memory is both available and visible.
It could be red like that : When the second command reach the
VERTEX_INPUT_STAGE
, please wait for the prior command finish theTRANSFER_STAGE
(It is the execution barrier). And flush theTRANSFER_WRITE
cache for theTRANSFER_STAGE
and invalidate theVERTEX_ATTRIBUTE_READ
cache for theVERTEX_INPUT_STAGE
(it is the memory barrier). I used the word flush / invalidate for a specific stage here because some stagesTOP
andBOTTOM
does not access memory, so it is useless to try to perform a memory barrier on them.However, I read that you are using a staging buffer, when you WRITE into your staging buffer, the memoryBarrier from the HOST are made by the submission of the command buffer. However, if you do not use COHERENT memory, you must use
vkFlushMappedMemoryRanges
.A good idea could be to use the barrier JUST before you will use the datas :
You could have more informations here