ARB_draw_indirect | ARB_multi_draw_indirect | ARB_shader_draw_parameters
Typically "things" bound to draws change at the following different frequencies {per frame, per framebuffer, per shader, per mesh}. Multi-draw-indirect picks up the {per frame, per framebuffer, and per shader} bindings from the legacy path (could be either bindless or non-bindless), and then provides ability to do {per mesh} draws at a high frequency with only the following changes,
typedef struct {
uint32_t indexCountPerInstance;
uint32_t instanceCount;
uint32_t baseIndex; // Start fetching at this index.
uint32_t baseVertex; // Constant to add to index, ie offset in vertex buffer.
uint32_t baseInstance;
} OglDrawParamIndexed;
I roughly take the AZDO model as the application never changes the index buffer or vertex buffer for the lifetime of the game. They just become huge regions of memory which are always bound in which the application self-manages it's own sub-buffers in (can even alias sub-buffers freely there). This is effectively low level memory management.
One possible disadvantage of multi-draw is that just the {per mesh} constants (which would include constants and possibly resource handles) require an extra indirection because the only fast path constant binding is done only at the {per frame, per framebuffer, and per shader} frequency. Majority of the resource bindings would hit the fast path. Only {per mesh} unique textures need the extra indirection (few if any), and only if a texture array wouldn't just work there (the array would be bound on the {per shader} fast path). Leveraging texture arrays just for {per mesh} frequency textures of the same shader sounds practical.
Typically "things" bound to draws change at the following different frequencies {per frame, per framebuffer, per shader, per mesh}. Multi-draw-indirect picks up the {per frame, per framebuffer, and per shader} bindings from the legacy path (could be either bindless or non-bindless), and then provides ability to do {per mesh} draws at a high frequency with only the following changes,
typedef struct {
uint32_t indexCountPerInstance;
uint32_t instanceCount;
uint32_t baseIndex; // Start fetching at this index.
uint32_t baseVertex; // Constant to add to index, ie offset in vertex buffer.
uint32_t baseInstance;
} OglDrawParamIndexed;
I roughly take the AZDO model as the application never changes the index buffer or vertex buffer for the lifetime of the game. They just become huge regions of memory which are always bound in which the application self-manages it's own sub-buffers in (can even alias sub-buffers freely there). This is effectively low level memory management.
One possible disadvantage of multi-draw is that just the {per mesh} constants (which would include constants and possibly resource handles) require an extra indirection because the only fast path constant binding is done only at the {per frame, per framebuffer, and per shader} frequency. Majority of the resource bindings would hit the fast path. Only {per mesh} unique textures need the extra indirection (few if any), and only if a texture array wouldn't just work there (the array would be bound on the {per shader} fast path). Leveraging texture arrays just for {per mesh} frequency textures of the same shader sounds practical.