Metal: Intersection results unstable when reusing Instance Acceleration Structures

Hi all,

I'm encountering an issue with Metal raytracing on my M5 MacBook Pro regarding Instance Acceleration Structure (IAS).

Intersection tests suddenly stop working after a certain point in the sampling loop.

Situation

  • I implemented an offline GPU path tracer that runs the same kernel multiple times per pixel (sampleCount) using metal::raytracing.
  • Intersection tests are performed using an IAS.
  • Since this is an offline path tracer, geometries inside the IAS never changes across samples (no transforms or updates).
  • As sampleCount increases, there comes a point where the number of intersections drops to zero, and remains zero for all subsequent samples.

Here's a code sketch:

let sampleCount: UInt16 = 1024
for sampleIndex: UInt16 in 0..<sampleCount {
    // ...
    do {
        let commandBuffer = commandQueue.makeCommandBuffer()

        // Dispatch the intersection kernel.

        await commandBuffer.completed()
    }

    do {
        let commandBuffer = commandQueue.makeCommandBuffer()

         // Use the intersection test results from the previous command buffer.

        await commandBuffer.completed()
    }
    // ...
}
kernel void intersectAlongRay(
    const metal::uint32_t threadIndex [[thread_position_in_grid]],
    // ...
    const metal::raytracing::instance_acceleration_structure accelerationStructure [[buffer(2)]],
    // ...
)
{
    // ...
    const auto result = intersector.intersect(ray, accelerationStructure);
    switch (result.type) {
        case metal::raytracing::intersection_type::triangle: {
            // Write intersection result to device buffers.
            break;
        }
        default:
            break;
    }

Observations

  • Encoding both the intersection kernel and the subsequent result usage in the same command buffer does not resolve the problem.
  • Switching from IAS to Primitive Acceleration Structure (PAS) fixes the problem.
  • Rebuilding the IAS for each sample also resolves the issue.
  • Intersections produce inconsistent results even though the IAS and rays are identical — Image 1 shows a hit, while Image 2 shows a miss.

Questions

  • Am I misusing IAS in some way ?
  • Could this be a Metal bug ?

Any guidance or confirmation would be greatly appreciated.

Metal: Intersection results unstable when reusing Instance Acceleration Structures
 
 
Q