Mesh is not rendered immediately after updating command buffer

I’m rendering this rough surface. This surface is composed of different sections (each one containing their own vertex, indices, descriptor, uniforms, graphics pipeline…). All these sections put together create the entire surface. The closer to the center of the screen, the more resolution (vertices) these sections have. In some render-loop iterations I have to replace certain sections with other/s with higher or lower resolution, depending where the camera is pointing at that time.

Before rendering all the necessary sections, I have to load them into Vulkan, which I do in a parallel thread asynchronously (except those sections that are already loaded). Once all the necessary sections have been loaded, I update the command buffer (in order to render some new sections, and stop rendering some old sections). Otherwise, I don’t update the command buffer in the current frame.

Loading a particular section is done by calling:

  • createDescriptorSetLayout()
  • createGraphicsPipeline()
  • loadVertex()
  • createVertexBuffer()
  • createIndexBuffer()
  • createUniformBuffers()
  • createDescriptorPool()
  • createDescriptorSets()

The process for each render-loop iterations is:

  1. updateSurface(cameraPosition): Find out which sections are necessary (and order to asynchronously load those that haven’t been loaded yet).
  2. updateUBOs(): Update the UBOs values (i.e., MVP matrices) for each section.
  3. updateModelsState(): Update the command buffer, if necessary.

Problem: After updating the command buffer, some recently loaded sections aren’t rendered right away. Instead, a hole appears (black squares visible in the video) for a fraction of a second, although the section is rendered shortly after. These black squares shouldn’t appear because the command buffer has been updated in a way that the old section is not rendered and the new section is rendered in his place. In other words, the non-rendering of old sections and the rendering of new sections should happen simultaneously, which means that no gaps should appear.

After much consideration, I think this could be a Vulkan-related “problem”. One theory I have is that maybe “model loading into Vulkan” happens asynchronously in Vulkan, so sometimes the corresponding drawing command happens but the model to render is not loaded/ready yet. Could this be possible? This could be similar to vkQueueSubmit, which asynchronously executes a command buffer (which can be managed with vkWaitForFences or vkQueueWaitIdle). Or maybe there is a completely different reason for this bug.

I don’t know where else to look. Maybe there is something I don’t know about how Vulkan works, or I am misinterpreting something. Do you have any clue about this phenomenon? Can you point me in the right/possible direction to check? I don’t want to bother you with tons of code, but don’t hesitate to ask for code or clarifications if you want.

We don’t really have your code here, so I can only guess at what’s going on behind those functions. Step 1 should be to turn on validation layers.

I would suggest looking for synchronization issues. Your CB does wait on any memory transfers associated with whatever those createVertexBuffer and the like functions are doing, yes?