-->

Is rebinding a graphics pipeline in Vulkan a guara

2019-05-21 03:18发布

问题:

In the simplified scenario where each object to be rendered is translated into a secondary command buffer and each of those command buffers bind a graphics pipeline initially: is a guaranteed no-op to bind the pipeline that was immediately bound before? Or the order of execution of the secondary command buffers is not guaranteed at all?

回答1:

is a guaranteed no-op to bind the pipeline that was immediately bound before?

No. In fact, in the case you're outlining, you should assume precisely the opposite. Why?

Since each of your CBs is isolated from the others, the vkCmdBindPipeline function has no way to know what was bound beforehand. Remember: the state of a command buffer that has started recording is undefined. Which means that the command buffer building code cannot make any assumptions about any state which you did not set within this CB.

In order for the driver to implement the optimization you're talking about, it would have to, at vkCmdExecuteCommands time, introspect into each secondary command buffer and start ripping out anything that is duplicated across CB boundaries.

That might be viable if vkCmdExecuteCommands has to copy all of the commands out of secondary CBs into primary ones. But that would only be reasonable for systems where secondary CBs don't exist at a hardware level and thus have to be implemented by copying their commands into the primary CB. But even in this case, implementing such culling would make the command take longer to execute compared to simply copying some tokens into the primary CB's storage.

When dealing with a low-level API, do not assume that the driver is going to use information outside of its immediate purview to optimize your code. Especially when you have the tools for doing that optimization yourself.

This is (yet another) a reason why you should not give each individual object its own CB.

Or the order of execution of the secondary command buffers is not guaranteed at all?

The order of execution of commands is unchanged by their presence in CBs. However, the well-defined nature of the state these commands use is affected.

Outside of state inherited by secondary CBs, every secondary CB's state begins undefined. That's why you have to bind a pipeline for each one. Commands that rely on previously issued state only have well-defined behavior if that previously issued state is within the CB containing that command (or is inherited state).



标签: c++ vulkan