VisionOS 26 - threadsPerThreadgroup limit causing crash on device (but not in simulator)

Hi all,

I'm running into an issue with an app that previously worked fine on device using visionOS 2.0. After updating to visionOS 26, the same code runs fine in the simulator but crashes on the device with the following error:

-[MTLDebugComputeCommandEncoder _validateThreadsPerThreadgroup:]:1330: 
failed assertion `(threadsPerThreadgroup.width(32) * threadsPerThreadgroup.height(32) * threadsPerThreadgroup.depth(1))(1024) must be <= 832. (kernel threadgroup size limit)`

Is there any documented way to check or increase the allowed threadsPerThreadgroup size on Apple Vision Pro? Or any recommended workaround for this regression?

Thanks in advance!

Hi Kamlofsky,

The number of threads per threadgroup is a property of the pipeline state you use. You can query the maximum number of threads per threadgroup that your compute pipeline state supports by checking the value of property:

computePipeline.maxTotalThreadsPerThreadgroup, with computePipeline being an instance of MTLComputePipelineState.

https://developer.apple.com/documentation/metal/mtlcomputepipelinestate/maxtotalthreadsperthreadgroup

Hi @Kamlofsky

As my colleague mentioned, the maxTotalThreadsPerThreadgroup property of your MTLComputePipelineState is the way to go for checking the maximum number of threads that can be dispatched per threadgroup. I suggest using that value along with threadExecutionWidth to determine the correct number of threads and thread groups to dispatch, as described in Calculating Threadgroup and Grid Sizes.

Alternatively, you can also specify a value for maxTotalThreadsPerThreadgroup yourself by creating a MTLComputePipelineDescriptor and setting its maxTotalThreadsPerThreadgroup property to your desired value. You can then use that descriptor to create a compute pipeline state via the makeComputePipelineState(descriptor:options:reflection:) method.

Let me know if you have any further questions!

Thanks for your detailed responses.

After reviewing this closely, I realize the issue arises specifically from a compute pipeline implicitly dispatching threadgroups with a dimension of (32,32,1), exceeding the maximum allowed (832 threads per threadgroup) on Vision Pro devices.

Following your suggestions, I've explicitly checked all compute pipelines in my project and verified the maxTotalThreadsPerThreadgroup property. However, I am not using MTLComputePipelineDescriptor; instead, I'm using MTLRenderPipelineDescriptor and MTLTileRenderPipelineDescriptor. I've ensured all my render shaders explicitly define threadgroup dimensions that comply with the maxTotalThreadsPerThreadgroup constraint, adjusting them to (16,16,1) to stay within safe limits.

Despite these adjustments, the problem persists intermittently. Is there any known caching behavior or implicit threadgroup sizing performed by visionOS or Metal that could be causing the default value of (32,32,1) to resurface? Additionally, are there specific considerations or constraints for tile-based shaders or render pipelines in visionOS 26 compared to visionOS 2.0?

Thanks again for your support!

VisionOS 26 - threadsPerThreadgroup limit causing crash on device (but not in simulator)
 
 
Q