Metal 4 & Acceleration Structures

I have really enjoyed looking through the code and videos related to Metal 4. Currently, my interest is to update a ReSTIR Project and take advantage of more robust ways to refit acceleration Structures and more powerful ways to access resources.

I am working in Swift and have encountered a couple of puzzles:

What is the 'accepted' way to create a MTL4BufferRange to store indices and vertices?

How do I properly rewrite Swift code to build and compact an Acceleration Structure?

I do realize that this is all in Beta and will happily look through Code Samples this Fall. If other guidance is available earlier, that would be fabulous!

Thank you

Hello,

That makes at least two of us who really enjoyed the Metal 4 sessions. :)

Give us some time to determine answers for your questions about Swift and Metal. Documentation is expected to be available in both Obj-C and Swift so that's a start.

Please clarify "How do I properly rewrite Swift code to build and compact an Acceleration Structure?"

Are you asking how to use copyAndCompact(sourceAccelerationStructure:destinationAccelerationStructure:) or how would write your own equivalent in Swift (for use with ReSTIR)?

Re: sample code, it looks like we're continuing to publish samples primarily in Obj-C. Please let us know if you'd like more samples written with Swift by sending us an enhancement request using the Feedback Assistant.

Thanks for your reply.

My first issue came up when trying to use a MTL4ComputeCommandEncoder to build an AccelerationStructure:

func build(destinationAccelerationStructure: any MTLAccelerationStructure, descriptor: MTL4AccelerationStructureDescriptor, scratchBuffer: MTL4BufferRange)

The setup of the scratch buffer ( MTL4BufferRangeMake(::) ) is unfamiliar to me although I have looked through the documentation

I am accustomed to using the MTLDevice and Acceleration Structure Sizes to build an old-school scratch buffer. Any naive attempts to use the gpuAddress value from such an existing MTLBuffer have predictably failed with the message:

__buildAccelerationStructure:descriptor:scratchBuffer:]:2450: failed assertion `Compute Command Encoder Build Acceleration Structure Validation Metal 4 does not support raytracing with software emulation __

So, I guess my initial question is how do I properly create a MTL4BufferRange to use in the build function?

Short answer is how you would use it in Obj-C, where scratchBuffer is a MTLBuffer e.g.

[commandEncoder buildAccelerationStructure:accelerationStructure
descriptor:desc
scratchBuffer:MTL4BufferRange(scratchBuffer.gpuAddress, scratchBuffer.length)];

Can you provide more of your setup code or an Xcode project?

I'm uncertain of what to think of the error message.

What kind of Apple Silicon Mac are you using for development?

Hi again and thank you for your thoughts,

I am using an M1 Mac Studio. I have included as simple and linear code sample as possible, borrowing the bare minimum geometry from a sample project. I get the error message mentioned earlier at the last line:

let commandBuffer: MTL4CommandBuffer = device.makeCommandBuffer()!
let commandAllocator: MTL4CommandAllocator = device.makeCommandAllocator()!
       
commandBuffer.beginCommandBuffer( allocator: commandAllocator )

let commandEncoder: MTL4ComputeCommandEncoder = commandBuffer.makeComputeCommandEncoder()!
            
// Create a Plane Object
let planeVertices: [vector_float3] = [ vector_float3( -4.5, -1.1,  0.0 ), vector_float3( -4.5, -1.1,  5.0 ), vector_float3( 4.5, -1.1,  5.0 ), vector_float3( 4.5, -1.1,  0.0 ) ]
            
var vertexIndices: [UInt16]
var vertexPositions: [vector_float3]
                
let v0 = planeVertices[0]
let v1 = planeVertices[1]
let v2 = planeVertices[2]
let v3 = planeVertices[3]
          
vertexIndices = [ 0, 1, 2, 0, 2, 3 ]
vertexPositions = [ v0, v1, v2, v3 ]
                
let indexBuffer = device.makeBuffer( length: MemoryLayout<UInt16>.stride * vertexIndices.count, options: .storageModeShared )!
var ptr = indexBuffer.contents()
let indexPointer = ptr.bindMemory( to: UInt16.self, capacity: 1 )
for i in 0..<( vertexIndices.count )
       {
       indexPointer[i] = vertexIndices[i]
       }

let indexBufferRange = MTL4BufferRangeMake( indexBuffer.gpuAddress, UInt64(indexBuffer.length ) )
            
let positionBuffer = device.makeBuffer( length: MemoryLayout<vector_float3>.stride * vertexPositions.count, options: .storageModeShared )!
ptr = positionBuffer.contents()
let positionPointer = ptr.bindMemory( to: vector_float3.self, capacity: 1 )
for i in 0..<( vertexPositions.count )
       {
       positionPointer[i] = vertexPositions[i]
       }
            
let positionBufferRange = MTL4BufferRangeMake( positionBuffer.gpuAddress, UInt64( positionBuffer.length ) )

let geometryDescriptor: MTL4AccelerationStructureTriangleGeometryDescriptor = MTL4AccelerationStructureTriangleGeometryDescriptor()

   geometryDescriptor.indexBuffer = indexBufferRange
   geometryDescriptor.indexType = MTLIndexType.uint16
   geometryDescriptor.vertexBuffer = positionBufferRange
   geometryDescriptor.vertexStride = MemoryLayout<vector_float3>.stride
   geometryDescriptor.triangleCount = vertexIndices.count / 3

let accelerationDescriptor: MTL4PrimitiveAccelerationStructureDescriptor = MTL4PrimitiveAccelerationStructureDescriptor()
accelerationDescriptor.geometryDescriptors = [geometryDescriptor]
             
let accelerationStructureSizes = device.accelerationStructureSizes( descriptor: accelerationDescriptor )
                
let accelerationStructure = (device.makeAccelerationStructure( size: accelerationStructureSizes.accelerationStructureSize ))!
        
let scratchBuffer = device.makeBuffer( length: accelerationStructureSizes.buildScratchBufferSize, options: .storageModePrivate )
                
let scratchBufferRange = MTL4BufferRangeMake( scratchBuffer!.gpuAddress, UInt64( scratchBuffer!.length ) )

commandEncoder.build( destinationAccelerationStructure: accelerationStructure, descriptor: accelerationDescriptor, scratchBuffer: scratchBufferRange )

Metal 4 & Acceleration Structures
 
 
Q