Implicit Ordering & Synchronisation

Hello guys,
i am currently implementing post-processing with several shaders. It works fine so far, but without any synchronisation and i dont know exactly why.
The code for doing one post-processing step looks like this:

            
      // Begin renderpass
      // Update dynamic viewport state
      // Update dynamic scissor state
      // Bind vertex buffer containing the fullscreen-quad
      // Update Shader-Descriptor-Set using the image from the previous post-process shader
      // Bind Shader-Pipeline
      // Draw the fullscreen-quad
      // End Renderpass

The above code gets executed for every post-process shader. My question now is why everything works as intended? Does different renderpasses in one command-buffer gets executed one after one?
Why i dont need e.g. a pipeline-barrier here?

Thanks in Advance

My question now is why everything works as intended?

Because undefined behavior doesn’t necessarily mean that something looks wrong. It can come out looking exactly like you expect. Today. What it does tomorrow, or the next day, or on some other hardware, is unknown.

Does different renderpasses in one command-buffer gets executed one after one?

Not without some form of execution dependency between them.

Why i dont need e.g. a pipeline-barrier here?

A pipeline barrier is not possible. Within a renderpass, pipeline barriers can only invoke dependencies within a subpass.

What you should be using is external subpass dependencies.

Oh wait, i am already using Subpass dependencies ._. Could be the reason why everything is working. But tested is without and everything works the same, but i will keep using them!

So to clarify it a bit better for me, i am sync the rendering of the scene with rendering the shadow-maps with a semaphore:

        
        VkSemaphore sceneRenderingWaitSemaphore = NULL;

        // Submit rendering all shadow-maps and wait on the returned wait-semaphore (signaled when rendering all shadow-maps has finished)
        if (settings.renderShadows)
            sceneRenderingWaitSemaphore = shadowRenderer->submit(graphicQueue, frameDataIndex, NULL);

        // Submit primary cmd containing all secondary cmds which rendering the scene
        frameResources[frameDataIndex].primaryCmd.submit(graphicQueue, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
                                                         sceneRenderingWaitSemaphore,
                                                         frameData.semaphores.renderSceneComplete);

When i have a subpass-dependency in the renderpass where i going to render my shadow-maps, which says that MEMORY_READS in VK_EXTERNAL can only occur when COLOR_ATTACHMENT_WRITES in the COLOR_ATTACHMENT_OUTPUT_STAGE has been finished, does that mean i can completely omit this semaphore?

Why are you using a semaphore to synchronize things that are happening on the same queue?

But yes, if you use a semaphore there, it will ensure execution and memory dependencies between the two operations.

Wait, doesnt the spec say that command-buffers submitted to a queue can run in arbitrary order?!

You misunderstood the point of my question: why are you using a semaphore to synchronize things that are happening on the same queue?

Intra-queue operations tend to be synchronized via pipeline barriers, subpass dependencies, or for more complex cases, waiting on events. And by doing it that way, you can issue both command buffers in the same vkQueueSubmit call, thus avoiding needless overhead.

Mmpf i thought this is what semaphores are for. I saw this in so many cases in code-samples. Back to my original question: So i can omit the semaphore there, because the subpass-dependency guarantes that sampling from the shadow-maps occur after rendering right?

Reading other people’s code, given without explanation, is a great way to get the wrong idea about lots of stuff. Yes, semaphores can create dependencies. But they’re not the only way, nor are they the preferred way for dealing with dependencies within a queue.

The only time when you have to use them for something in-queue is when dealing with vkAcquireNextImageKHR. But that’s not strictly “in-queue”, because image acquisition is asynchronous with respect to any VkQueue.

If you have properly set up your subpass dependencies, yes. Pipeline barriers create a dependency between the commands executed before the barrier in the queue and the commands executed after the barrier. Subpass dependencies with a source of SUBPASS_EXTERNAL create a dependency between the commands executed before the renderpass starts and the commands within the first subpass. And so to with the subpass dependencies which use a destination of SUBPASS_EXTERNAL.

If you used an automatic translator for this message, whatever you tried to say didn’t make it. I’d guess that it translated “queue” into “line”, but the rest is fairly inscrutable.