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.
Blockquote
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:
https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
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.