Arguments to Graphics Functions

Hello - I am trying to understand why some arguments to the vertex and fragment shaders are sent as pointers while others are sent as a reference. Can someone help me understand the rationale? For example, in the code below, v_in is a pointer while mvp_matrix is a reference.

render_vertex(const device VertexInput* v_in [[buffer(0)]],
constant float4x4& mvp_matrix [[buffer(1)]], constant LightDesc& light_desc [[buffer(2)]], device VertexOutput* xform_output [[buffer(3)]], uint v_id [[vertex_id]] )

Take a look at section 2.7 in the Metal Shading Language Specification:

MSL implements a buffer as a pointer . So they’re saying that any MTLBuffer s that you send to the GPU should be *buffer in the shader function arguments.

That would be if you’re using:

renderEncoder.setFragmentBuffer(_ buffer: MTLBuffer?...)

However, when you’re using:

renderEncoder.setFragmentBytes(_ bytes: UnsafeRawPointer...)

the documentation says you’re also creating an MTLBuffer behind the scenes.

If the bytes are an array, that’s a pointer to the first object in the array, so you’d access that array with a pointer in the shader function.

If the bytes are a single item, such as a struct or a float4x4, then you access the item by reference with &.

Btw, on the Swift side, MTLBuffer.contents() returns an UnsafeMutableRawPointer to the actual data.

Brilliant! Thank you

1 Like