Hello,
I'm going into indirect land and this has not been the easiest journey. I'm almost there, but I found a small problem with vertex buffers. As we know, indirect pretty much requires us to not rebind buffers if it's supposed to work. Right now I have interleaved buffers, which works okay but I had to do some weird decisions around meshes that require 2 more attribs (like skinned meshes) and I heard the trend is nowadays towards non-interleaved buffers. The pros of this I see woud be:
- Better management of what is enabled for a given draw - so shadow / depth pass could use smaller amount of attribs (some unknown performance gain for not having to read data that would be discarded anyway?)
- Better way to upload data if only small subset of attributes is dynamic and others are static
- Easier upload of data from file (most of the formats seem to be non-interleaved, but this can be a non-factor if prepared offline)
- Easier debugging (some debuggers are not very clever when it comes to interleaved format possibilities, making it impossible to read buffer contents)
Now, all sounds fun and I could go this way but I just discovered that this may defeat my indirect drawing, because of how I have to specify offsets into buffers (remember - I bind them at the beginning and do not change, so starting offset is 0 and I abuse baseVertex to offset the index into vertex buffer to accomodate that there is a single big buffer having all the meshes rather than one buffer / buffer which is bound as a range to a specific offsets outside of draw call). It would work if all buffers are advanced at the same pace - so if I allocate vertex attrib in POSITION buffer, I do this for all other involved buffers, because if I don't, buffers go out of sync and it's impossible to calculate a single, common baseVertex to provide in indirect call (there it's called "firstIndex").
I tried to visualise this and that's what I created:
As you can see we end up with non-uniform baseVertex if we mix several buffers that are not in sync.
My question is: Is there any way to avoid this problem, other than
a) sticking to interleaved buffers, where problem exists but it's single source of data which means I can provide single baseVertex offset
b) synchronizing buffers so they allocate incrementally and equally among all involved buffers - this pretty much couples all buffers in such "batch" together, so I can't use position buffer for non-skinned meshes anymore - it has to have its own buffer
I see no other solutions that would not defeat the indirect draw, which I think is such a big gain that I'm probably rather going to give up on non-interleaved unless you tell me this is wrong for some reason I don't see.
Has anyone thought about it? Seems like indirect is not yet so popular (and I can see why - implementing it is not exactly feasible if someone has already working engine and don't want to make some sacrifices), so it's not possible to find others with such problems.