Are Vulkan renderpasses thread local in multi-thre

2019-07-17 05:53发布

问题:

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.

回答1:

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 VkRenderPasses when migrating VkPipeline to a different thread.