Description

This sample demonstrates how to use extensions to OpenGL to offload the CPU in generating rendering work when you have a large number of objects in a scene. The extensions and core features used are a subset of the features commonly known as 'AZDO' (For Approaching Zero Driver Overhead)

Screenshot

APIs Used

  • GL_ARB_multi_draw_indirect

Technical Details

The MultiDrawIndirect sample shows how to use core OpenGL 4.4 behavior, along with several extensions to minimize driver-related CPU overhead. Modern applications frequently run into bottlenecks regarding the sheer number of draw calls needed per frame. In order to reduce this overhead, a set of core features and extensions referred to as "Approaching Zero Driver Overhead" ("AZDO") were developed to process multiple draw commands, using vertex and index data sourced from arbitrary buffers in a single function call. If your scene is bottlenecked by draw calls and contains a large number of similar models, then you should look at whether the MultiDrawIndirect extensions can be of use. This is a much more generally applicable method than strict instancing.

As a visual, the samples shows a grid of windmills. Each windmill is an instance selected from a set of twenty randomly-scaled models. The interface allows you to adjust the number of instances rendered, and to select between a single call to MultiDrawIndirect, or to display the grid as a number of single draw calls.

While these instances are (in the case of this sample) manual copies of the sample model for ease of loading, the models could each be any of a wide range of geometries. Using MultiDrawIndirect, the rendering of each object is declared in the GL_DRAW_INDIRECT_BUFFER array, with each set of instances being represented by a copy of the structure DrawElementsIndirectCommand. This structure is defined in the extension GL_ARB_draw_indirect, and includes the primitive count, the number of instances to be drawn, the first index to use for drawing, and any vertex array offsets or instance offsets. This allows a single sub-command in the array to draw either a single object or any number of classic instances. Thus, MultiDrawIndirect improves upon — rather than replaces — classic instancing.

The time taken by the GPU and CPU is displayed for both the MultiDraw call and single draw calls. In general, even if the frame rate rises only slightly when MultiDrawIndirect is selected (e.g. if the scene is fill-limited), the CPU time should be seen to fall significantly when using MultiDrawIndirect. The main goal of MultiDrawIndirect and other AZDO features is to reduce driver overhead; while they may not always increase frame rate directly, they can generally reduce the CPU load, providing more CPU "headroom" for the application itself.

This sample uses the following extensions to enable functionalities that may not be available in base OpenGL:

  • GL_ARB_multi_draw_indirect: Allows the parameters of each draw to be stored in a buffer.