@@ -99,22 +99,85 @@ class.MTLLinkedFunctions.methods."setPrivateFunctions:".unsafe = false
9999# nothing. Metal enables this by default, so we must assume that their
100100# configuration of it is sound (?), and that we don't need to mark compilation
101101# as unsafe.
102+ #
102103# class.MTLCompileOptions.methods."setMathMode:".unsafe = false
103104# class.MTLCompileOptions.methods."setFastMathEnabled:".unsafe = false
104105
106+ # SAFETY: Mark any accesses to the contents of `MTLResource`s as unsafe.
107+ #
108+ # Reading or writing to resources is unsynchronized and effectively equivalent
109+ # to (non-atomically?) sharing these between threads. The user needs to
110+ # explicitly synchronize accesses to these. (Explicit synchronization could
111+ # maybe in some cases be avoided with `MTLStorageModeShared` and
112+ # `MTLHazardTrackingModeTracked`, but that's dangerous to solely rely on).
113+ #
114+ # In `header-translator`, subprotocols of `MTLResource` is marked as unsafe in
115+ # argument position to ensure that any accesses to these on the GPU side are
116+ # properly synchronized.
117+ #
118+ # Here, we mark all inherent methods that read/write on these as `unsafe` to
119+ # also make things unsafe on the CPU side.
120+ protocol.MTLBuffer.methods.contents.unsafe = false # Raw pointer, unsafe in itself.
121+ protocol.MTLTensor.methods."getBytes:strides:fromSliceOrigin:sliceDimensions:".unsafe = true
122+ protocol.MTLTensor.methods."replaceSliceOrigin:sliceDimensions:withBytes:strides:".unsafe = true
123+ protocol.MTLTexture.methods."getBytes:bytesPerRow:bytesPerImage:fromRegion:mipmapLevel:slice:".unsafe = true
124+ protocol.MTLTexture.methods."getBytes:bytesPerRow:fromRegion:mipmapLevel:".unsafe = true
125+ protocol.MTLTexture.methods."replaceRegion:mipmapLevel:slice:withBytes:bytesPerRow:bytesPerImage:".unsafe = true
126+ protocol.MTLTexture.methods."replaceRegion:mipmapLevel:withBytes:bytesPerRow:".unsafe = true
127+ protocol.MTLAccelerationStructure.unsafe = true
128+ protocol.MTLAccelerationStructure.methods.gpuResourceID.unsafe = false
129+ protocol.MTLAccelerationStructure.methods.size.unsafe = false
130+ protocol.MTLIndirectCommandBuffer.unsafe = true
131+ protocol.MTLIndirectCommandBuffer.methods.gpuResourceID.unsafe = false
132+ protocol.MTLIndirectCommandBuffer.methods.size.unsafe = false
133+ protocol.MTLIntersectionFunctionTable.unsafe = true
134+ protocol.MTLIntersectionFunctionTable.methods.gpuResourceID.unsafe = false
135+ protocol.MTLVisibleFunctionTable.unsafe = true
136+ protocol.MTLVisibleFunctionTable.methods.gpuResourceID.unsafe = false
137+
138+ # TODO(breaking): Mark these as unsafe, they probably require synchronization.
139+ class.MTLRenderPassAttachmentDescriptor.methods."setTexture:".unsafe = false
140+ class.MTLRenderPassAttachmentDescriptor.methods."setResolveTexture:".unsafe = false
141+ class.MTLAccelerationStructureBoundingBoxGeometryDescriptor.methods."setBoundingBoxBuffer:".unsafe = false
142+ class.MTLRenderPassDescriptor.methods."setVisibilityResultBuffer:".unsafe = false
143+ class.MTLInstanceAccelerationStructureDescriptor.methods."setInstanceDescriptorBuffer:".unsafe = false
144+ class.MTLInstanceAccelerationStructureDescriptor.methods."setInstancedAccelerationStructures:".unsafe = false
145+ class.MTLAccelerationStructureGeometryDescriptor.methods."setPrimitiveDataBuffer:".unsafe = false
146+ class.MTLAccelerationStructureTriangleGeometryDescriptor.methods."setVertexBuffer:".unsafe = false
147+ protocol.MTLRenderCommandEncoder.methods."useResource:usage:".unsafe = false
148+ protocol.MTLRenderCommandEncoder.methods."useResource:usage:stages:".unsafe = false
149+ protocol.MTLComputeCommandEncoder.methods."useResource:usage:".unsafe = false
150+ protocol.MTLBlitCommandEncoder.methods."synchronizeResource:".unsafe = false
151+ protocol.MTLBlitCommandEncoder.methods."generateMipmapsForTexture:".unsafe = false
152+ protocol.MTLBlitCommandEncoder.methods."optimizeContentsForGPUAccess:".unsafe = false
153+ protocol.MTLAccelerationStructureCommandEncoder.methods."copyAndCompactAccelerationStructure:toAccelerationStructure:".unsafe = false
154+
155+ # SAFETY: Resource options are safe to specify:
156+ # - Hazard tracking and storage modes change the required synchronization, but
157+ # we handle that above. Also, we wouldn't really be able to prevent
158+ # untracked resources, these are the only option in Metal 4.
159+ # - The CPU cache mode is safe, it should only affect performance, not
160+ # correctness.
161+ #
162+ # class.*.methods."setResourceOptions:".unsafe = false
163+
164+ # TODO(breaking): Mark these as unsafe, setting `MTLPurgeableState::Volatile)`
165+ # is probably not safe, as you have to lock resources to prevent them from
166+ # being purged while in use.
167+ # TODO: How would you do such locking?
168+ protocol.MTLResource.methods."setPurgeableState:".unsafe = false
169+ protocol.MTLHeap.methods."setPurgeableState:".unsafe = false
170+
105171# Using the resource's contents in a memory-safe manner is very difficult
106172# after this is called.
107173protocol.MTLResource.methods.makeAliasable.unsafe = true
108174
109- # Using `MTLHazardTrackingModeUntracked` requires extra synchronization.
110- # TODO(breaking): Mark all of these as unsafe.
111- class.MTLTensorDescriptor.methods."setHazardTrackingMode:".unsafe = true
112- class.MTLTextureDescriptor.methods."setHazardTrackingMode:".unsafe = false
113- # TODO: MTLHeap should maybe be unsafe by default, since it has untracked
114- # by default?
115- class.MTLHeapDescriptor.methods."setHazardTrackingMode:".unsafe = false
175+ # SAFETY: Modifying residency is safe, it's effectively the same as
176+ # controlling what's in the L1/L2/L3 cache on the CPU.
177+ # protocol.MTLResidencySet.methods.requestResidency.unsafe = false
178+ # protocol.MTLResidencySet.methods.endResidency.unsafe = false
116179
117- # TODO(breaking): Mark this as unsafe.
180+ # TODO(breaking): Mark this as unsafe?
118181class.MTLHeapDescriptor.methods."setType:".unsafe = false
119182
120183# These affect lifetime safety, and can cause use-after-free if used incorrectly.
0 commit comments