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.