Skip to content

Conversation

MarijnS95
Copy link
Contributor

Draft until this becomes more complete, and while I figure out the correct semantics.

Obvious things that should remain unsafe:

  • CPU-side indexing operations (that are not known to be bounds-checked internally).
  • Functions that involve raw pointers and/or data ranges (not translated to slices yet).

Things that are dubious:

  • GPU indices: sampleCountersInBuffer:atSampleIndex:withBarrier:, and also all the calls that set resources on encoders and argument buffers like setBuffer:offset:atIndex:.
  • GPU ranges: executeCommandsInBuffer:withRange:.
  • GPU buffer offsets: executeCommandsInBuffer:indirectBuffer:indirectBufferOffset: (note that MTLBuffer newTextureWithDescriptor:offset:bytesPerRow: was marked safe).

Here I am not sure if Rust's safety model should extend to the GPU, if at least CPU-side encoding is fully safe. It would be more convenient to not have to wrap them in unsafe on the call-side.

Things that seem obviously safe to me:

  • Various object getters and setters with high-level safe types.
  • Especially when they return Option to handle nullability?

Comment on lines 605 to 608
class.MTLBlitPassSampleBufferAttachmentDescriptor.methods.startOfEncoderSampleIndex.unsafe = false
class.MTLBlitPassSampleBufferAttachmentDescriptor.methods."setStartOfEncoderSampleIndex:".unsafe = false
class.MTLBlitPassSampleBufferAttachmentDescriptor.methods.endOfEncoderSampleIndex.unsafe = false
class.MTLBlitPassSampleBufferAttachmentDescriptor.methods."setEndOfEncoderSampleIndex:".unsafe = false
Copy link
Contributor Author

@MarijnS95 MarijnS95 Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More controversial examples of "safe integers" that are most likely only used to index on the GPU... And maybe validated to fit within the length of the currently bounds sample buffer?

MTLRenderPassSampleBufferAttachmentDescriptor doesn't mark the setters safe for example.

Comment on lines 76 to +81
protocol.MTLAccelerationStructureCommandEncoder.methods."buildAccelerationStructure:descriptor:scratchBuffer:scratchBufferOffset:".unsafe = false
protocol.MTLAccelerationStructureCommandEncoder.methods."refitAccelerationStructure:descriptor:destination:scratchBuffer:scratchBufferOffset:".unsafe = false
protocol.MTLAccelerationStructureCommandEncoder.methods."refitAccelerationStructure:descriptor:destination:scratchBuffer:scratchBufferOffset:options:".unsafe = false
protocol.MTLAccelerationStructureCommandEncoder.methods."copyAccelerationStructure:toAccelerationStructure:".unsafe = false
protocol.MTLAccelerationStructureCommandEncoder.methods."writeCompactedAccelerationStructureSize:toBuffer:offset:".unsafe = false
protocol.MTLAccelerationStructureCommandEncoder.methods."writeCompactedAccelerationStructureSize:toBuffer:offset:sizeDataType:".unsafe = false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is quite strange to already see some of these functions that take buffer offsets being marked safe... While not marking all variants as safe.

@madsmtm madsmtm mentioned this pull request Aug 6, 2025
@madsmtm madsmtm added this to the frameworks v0.3.2 milestone Aug 17, 2025
@madsmtm madsmtm added enhancement New feature or request A-framework Affects the framework crates and the translator for them I-unsound A soundness hole, or affecting soundness labels Aug 23, 2025
@madsmtm
Copy link
Owner

madsmtm commented Aug 24, 2025

CPU-side indexing operations (that are not known to be bounds-checked internally).

Pretty sure these are bounds-checked internally. I'll try to add a test that they are.

I am not sure if Rust's safety model should extend to the GPU, if at least CPU-side encoding is fully safe.

What do you think @cwfitzgerald? Should methods that may cause the GPU to execute an out-of-bounds operation be considered UB in objc2-metal?

I'm somewhat leaning towards "yes", but it might not actually be a problem if Metal internally ensures that such accesses cannot touch the data of other applications using the GPU? I.e. if all accesses are sandboxed anyhow?

@madsmtm
Copy link
Owner

madsmtm commented Aug 24, 2025

I guess my problem here is a lack of understanding of how Metal works.

As I understand it, if we are to map safety concerns in normal CPU code to safety concerns when interfacing with the GPU, it would be:

  • Type safety: MTLBuffer seems to be untyped, how do you ensure that you don't cast e.g. MTLPackedFloat3 to a MTLPackedFloatQuaternion (which would be invalid in Rust, since MTLPackedFloat3 has a possibly uninitialized padding field)? Or is this just a valid thing to do everywhere in Metal?
  • Initialization safety: I'm guessing that you're never working with uninitialized memory, but that newly allocated memory is automatically zeroed? Though if that's the case, what happens if you don't initialize e.g. a pointer, and just leave it at 0? And does Metal have the equivalent of NonNull<u32>?
  • Bounds safety: Discussed above.
  • Lifetime safety: If you release a MTLHeap or MTLBuffer before the GPU is done using them, do you get use-after-free? or does Metal hold on to these buffers long enough by itself?
  • Thread safety:
    • To/from-CPU: Accessing the contents of a buffer has to be synchronized. And if using MTLStorageModeShared, reads and writes should probably be volatile?
    • To/from-GPU: Do GPUs have atomics? Would you get torn values if you tried to read something that another GPU "thread" (or whatever it is called) was writing to?
  • Invariants violated by shaders themselves: Should methods like newLibraryWithSource:options:error: even be safe? The shader itself can do most of the above things, right?

Maybe one of you could help clarify these?

@madsmtm
Copy link
Owner

madsmtm commented Aug 25, 2025

Practically, I think we should be able to mark most descriptor methods as safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-framework Affects the framework crates and the translator for them enhancement New feature or request I-unsound A soundness hole, or affecting soundness
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants