1
votes

In this example where we copy some buffer into vertex buffer and we want to quickly to start rendering using this buffer in two submissions without waiting over some fence:

vkBeginCommandBuffer(tansferCommandBuffer)
  vkCmdCopyBuffer(tansferCommandBuffer, hostVisibleBuffer, vertexBuffer)
vkEndCommandBuffer(tansferCommandBuffer)

vkQueueSubmit(queue, tansferCommandBuffer)


vkBeginCommandBuffer(renderCommandBuffer)
  ...
  vkCmdBindVertexBuffers(vertexBuffer)
  vkCmdDraw()
  ...
vkEndCommandBuffer(renderCommandBuffer)

vkQueueSubmit(queue, renderCommandBuffer)

From what I understand is that tansferCommandBuffer might not have been finished when renderCommandBuffer is submitted, and renderCommandBuffer may get scheduled and reads form floating data in vertexBuffer.

We could attach a semaphore while submitting tansferCommandBuffer to be singled after completion and forward this semaphore to renderCommandBuffer to wait for before execution. The issue here is that it blocks the second batch commands that do not depend on the buffer.

Or we could insert a barrier after the copy command or before the bind vertex command, which seems to be much better since we can specify that the access to the buffer is our main concerned and possibly keep part of the batch to be executed.

Is there any good reason for using semaphores instead of barriers for similar cases (single queue, multiple submissions)?

1

1 Answers

2
votes

Barriers are necessary whenever you change the way in which resources are used to inform the driver/hardware about that change. So in your example the barrier is probably needed too, nevertheless.

But as for the semaphores. When you submit a command buffer, you specify both semaphore handles and pipeline stages at which wait should occur on a corresponding semaphore. You do this through the following members of the VkSubmitInfo structure:

  • pWaitSemaphores is a pointer to an array of semaphores upon which to wait before the command buffers for this batch begin execution. If semaphores to wait on are provided, they define a semaphore wait operation.
  • pWaitDstStageMask is a pointer to an array of pipeline stages at which each corresponding semaphore wait will occur.

So when you submit a command buffer, all commands up to the specified stage can be executed by the hardware.