Hello AMD,
Lets say an application needs to draws objects by issuing draw commands (vkCmdDraw*) but between them it needs to set new values for various uniform constants
(things like alpha-test ref, matrices, etc.). Virtually for each draw command there is some uniforms that need to be changed.
What is the preferred way to do this in vulkan?
The naive approach would be to use vkCmdCopyBuffer or vkCmdUpdateBuffer before each draw, but this is very problematic:
a) pipeline barriers would be required between each buffer copy/update and the draw command, which could be expensive.
b) neither of those commands (copy and update) can be used inside render pass, so the application would need to enter/leave render pass for basically each draw command.
c) since the vulkan API doesn't guarantee that the draw cmds from different passes will access/update the framebuffer in API order (this is guaranteed only inside single subpass),
explicit barriers will be needed also for all framebuffer attachments between the passes.
All this sounds like brutal overkill to me. Or is it OK to do it this way?
Another approach i thought of would be to write the uniforms needed by each draw cmd in (one or more) sliding buffer(s) - multiple copies of the same logical uniform would be added
in the buffer, one for each draw cmd that uses it. This way, between the draw cmds only vkCmdBindDescriptorSets would be necessary (which can be used inside pass).
This sounds better, but there is a problem when the pipeline uses uniform array(s). Those could be very big. Imagine a skeleton-animated object with 100 bones - that
would need 3*sizeof(vec4)*100 = 4800 bytes. It is probably not good idea to replicate this entire matrix palette each time we want to draw skeletal-animated objects (they may be many).
What would you guys suggest to do in such cases? What would be best for your hardware/drivers.
Can give more cross-vendor info about this, what uniform update strategy is generally preferred at all. Or how the vulkan designers had in mind such task to be handled in this API?
Thanx!