I'm working on a UI that uses Vulkan for rendering. I've come across a conundrum of sorts. The general structure as it stands is:
- Window class handles interfacing with OS. Each Window contains a number of Frame's (5-10'ish range, not a large number).
- Frame classes serve as containers for controls. Frame's are mostly there to facilitate different rendering techniques (different shaders, descriptors sets, etc...), as well as differences in update frequency.
- Controls, the buttons, menus, etc... you actually see/work with, are contained in Frame's.
I had ideas for 3 different ways to approach this:
1) Have each Frame record a secondary command buffer. To render the Window a primary commmand buffer would be created executing the secondary buffers within a render pass. That way I'd only have to update the secondary command buffers when their corresponding Frame changes, the Frame secondary buffers would be VkFrameBuffer independent, and leads itself to easy multi-threading. The downside is that the entire window would need to be rendered every frame. For a video game this isn't a problem, but for apps/utilities this is unnecessary most of the time.
2) Store a 'dirty' rect/area. When rendering simply create one large primary framebuffer that contains all necessary rendering. This has the advantage of only rendering what actually changes, but means there would be almost no re-use of the command buffers. Every change would almost always necessitate a completely new command buffer.
3) Have each Frame create its own primary command buffer. This would make 'dirty' rect/area updates relatively easy, as well as allow command buffer reuse for some situations. The downside is there would still be much less command buffer reuse than option 1, and rendering would not occur within a single render pass. The docs aren't entirely clear, and since each GPU is different, its hard to gauge how much slower splitting the rendering across 5-10 separate command buffers/render passes would be than having one large one.
How would you guys go about this? What method is better and/or what are you guys using?