Advanced API Performance: Descriptors

A graphic of a computer sending code to multiple stacks.

By using descriptor types, you can bind resources to shaders and specify how those resources are accessed. This creates efficient communication between the CPU…

By using descriptor types, you can bind resources to shaders and specify how those resources are accessed. This creates efficient communication between the CPU and GPU and enables shaders to access the necessary data during rendering.

Recommended

  • Prefer a “bindless” design.
    • Use unbounded array descriptors pointing to big descriptor tables or sets with all known textures, buffers, and acceleration structures needed for the frame.
    • Upload as much data upfront as possible (textures, per-draw constants, and per-frame constants) and make them accessible through these descriptor arrays.
    • This design also makes it easier to implement ray tracing; that is, allowing access to every texture and buffers from each shader.
    • Cache descriptors on GPU-visible descriptor heaps (DirectX 12) or sets (Vulkan) with a known offset. This lowers the CPU overhead and virtually eliminates the need for copying descriptors.
    • Use multiple copies of the heap to handle descriptor changes gracefully, such as streaming textures and buffers. But don’t exceed the 1M and 2K limits. For more information, see the Not Recommended section later in this post.
  • Use root (DirectX 12) or push (Vulkan) constants. They are the fastest way to transfer per-draw varying constants.
  • On Pascal: Prefer CBVs over SRVs for constant data.
    • Generally, SRV buffers are slower than CBV buffers on

      Source:: NVIDIA