I'm currently moving my game to Vulkan. In my game, I have multiple worker threads to generate drawcalls. Each worker thread has its own command buffer. As render pass begin/end pair need to be within command buffer begin/end pair, so I would think render passes need to be thread local. Is that correct?
If that's the case, my second question is that how can I share pipeline objects among worker threads?
I currently maintain a global pipeline object map, for each drawcall, worker threads generate a key based on render states, shaders and other related information. But because render pass is also needed for creating pipeline object, if render pass is thread local, that would make pipeline object thread local. In this case, how can I share pipeline object among different worker threads?
For sure I've got something wrong, but I can't figure out what that is. please help out.
Making things thread-local is one way to achieve the goal, but you can use Vulkan objects from any thread as long as you properly do your own (i.e. external) synchronization.
Any object that is a parameter to a Vulkan command will be read. Any object marked "externally synchronized" will be written. Rest is just synchronizing write–read\write hazards as is usual in multi-threaded programming.
Many Vulkan objects are constant, and I think VkRenderPass
is one of those, which would simplify things. I.e. only place VkRenderPass
would be marked "externally synchronized" (i.e. write hazard) is its destructor.
If that's the case, my second question is that how can I share pipeline objects among worker threads?
Same rules apply to VkPipeline
objects. Unlike vkCmd*
commands, creation commands (vkCreateGraphicsPipelines
) do not hold on to the VkRenderPass
object:
A VkRenderPass
object passed as a parameter to create another object is not further accessed by that object after the duration of the command it is passed into.
And in any case they only read it (no "externally synchronized"). And read–read "hazard" need no synchronization. So you do not need to worry about VkRenderPass
es when migrating VkPipeline
to a different thread.