Syncing secondary command buffer with another secondary command buffer

Hello guys,

i rendering my scene and my gui both with secondary command buffers.

        // Put secondary cmds in a list for use by the primary cmd
        std::vector<VkCommandBuffer> secondaryCmds;
        secondaryCmds.push_back(frameResources[frameDataIndex].workerCmds[0].get());

        if (renderGUI){
            VkCommandBuffer& guiCmd = guiRenderer->recordCommandBuffer(frameDataIndex, &inheritanceInfo);
            secondaryCmds.push_back(guiCmd);
        }

        vkCmdExecuteCommands(cmd, secondaryCmds.size(), secondaryCmds.data());

That works fine until i have a huge amount of objects in my scene (>200). Then “VkQueuePresent” gives me the “Device is lost” - error.
I guess with many objects the secondary-cmd for rendering the scene takes too long and the secondary-cmd for the gui already starts.
Do i need a Memory-Barrier or sth like this to guarantee that gui-rendering is only allowed to start until the scene-rendering is complete?

Or maybe a better option is to render the gui in a separate framebuffer and just add it to the scene-framebuffer? This way i can easily add post-processing later and add the gui later on.

Edit: Before that i used a separate renderpass / primary-cmd for rendering the gui but thought using a secondary-cmd is better for performance.

Thanks in Advance.

That works fine until i have a huge amount of objects in my scene (>200).

What does it matter if you have 200 objects? You don’t give each object its own command buffer… do you? Because that would be bad.

Command buffers cannot share state. And when the time comes to execute those command buffers, at the beginning of every command buffer will be you setting various state. Which will be duplicate state in a large number of cases. You’d be throwing away huge amounts of performance.

Do i need a Memory-Barrier or sth like this to guarantee that gui-rendering is only allowed to start until the scene-rendering is complete?

That would not be necessary, since writing stuff to the framebuffer as well as depth testing and the like is guaranteed to be in API order.

I have one secondary cmd-buffer for the whole scene.

I did not understand that, can you explain a bit better for me?

Btw here is my code that gets called for every object in the scene:

    if(!isVisible())
        return;

    // Bind vertices
    VkDeviceSize offsets[1] = { 0 };
    vkCmdBindVertexBuffers(cmd, VERTEX_BUFFER_BIND_ID, 1, &VMM::getMeshResource(mesh)->getVertexBuffer(), offsets);

    // Bind indices
    vkCmdBindIndexBuffer(cmd, VMM::getMeshResource(mesh)->getIndexBuffer(), 0, VK_INDEX_TYPE_UINT32);

    // Update per object data through push-constant
    vkCmdPushConstants(cmd, pipeline->getPipelineLayout()->get(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(Mat4f), &getWorldMatrix());

    // Bind uniforms from the material to the shader
    pipeline->getShaders()->bindUniforms(cmd, material);

    // Draw indexed 
    vkCmdDrawIndexed(cmd, mesh->getIndexBufferCount(), 1, 0, 0, 1);