Ray Query Recursion Limits in DirectX Raytracing

Inline ray queries, introduced in DirectX Raytracing (DXR) 1.1, allow developers to traverse acceleration structures directly inside existing shader stages such as compute or pixel shaders. While they offer lower overhead and greater control compared to full DXR state-object pipelines, inline ray queries fundamentally lack native hardware recursion. This article explains the architectural limitations of ray queries regarding recursive ray generation, how multi-bounce effects must be handled instead, and the performance trade-offs involved.

Absence of Native Recursive Dispatch

In a full DXR pipeline, shaders interact with rays dynamically through dedicated stages (Ray Generation, Closest Hit, Any Hit, and Miss shaders). A Closest Hit shader can execute TraceRay() to fire secondary rays directly from the point of intersection. The driver and hardware manage the call stack and execution state up to a maximum declared recursion depth.

Inline ray queries, by contrast, operate via an iterative object-based polling mechanism (RayQuery<Flags>) contained entirely within the caller shader. There is no concept of a runtime-managed call stack that allows a hit point to automatically trigger another shader execution. The query simply returns traversal status flags (such as candidate or committed intersections) back to the originating thread.

Mandatory Iterative Emulation

Because inline ray queries cannot recursively invoke child shaders, any multi-bounce light transport (such as reflections, refractions, or diffuse global illumination) must be manually structured using iterative loops.

To simulate depth:

  • Developers must maintain their own path state (ray origin, direction, throughput, and hit results) in shader local variables.
  • A secondary bounce requires resetting the query object or initializing a new one within a loop.
  • The control flow remains strictly serial per thread, rather than delegating secondary work to separate scheduling queues.

Complexities with Branching Rays

Full raytracing pipelines naturally support branching recursion trees, such as a surface that splits an incoming ray into both a reflected ray and a refracted ray. The pipeline schedules both paths independently across available execution units.

With inline ray queries, true branching requires the developer to manually implement a traversal stack in local shader memory or execute queries sequentially within the same thread. Managing a software stack in registers or thread-group shared memory introduces significant code complexity and inherently limits the practical tree depth.

Register Pressure and Occupancy Degradation

When recursion is flattened into an iterative loop inside an inline ray query, all state for every potential bounce must reside in the host shader's register space. Storing accumulated radiance, surface normals, material properties, and query states across multiple iterations causes high Vector General Purpose Register (VGPR) consumption.

High register pressure limits GPU occupancy by reducing the number of active wavefronts that can run concurrently on a Compute Unit. Full DXR pipelines mitigate this by decoupling hit shading into separate, specialized shaders with smaller, distinct register footprints, allowing the hardware scheduler to interleave ray workloads more efficiently.