Metal Question About Pointer or Reference

Doctor Caroline:

     I have finished Chapter 5 Light Fundament. I collect some question to ask. I find reference and pointer in fragment shader argument table like this your sample code:

fragment float4 fragment_main(VertexOut in [[stage_in]],
// 1
constant Light *lights [[buffer(2)]],
constant FragmentUniforms &fragmentUniforms [[ buffer(3)]]) {…}

And would you please tell me what time I would use pointer or reference? (I have C++ fundament)

As a general rule:

If the bytes are an array in an MTLBuffer, you’d access that array with a pointer in the shader function.

If the bytes are a single item (and they are not stored in an MTLBuffer), then you access the item by reference with &.

Here lights is an array of structs, and fragmentUniforms is a single struct.

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

MSL implements a buffer as a pointer. So Apple are saying that any MTLBuffers 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...)

even though the documentation says you’re also creating an MTLBuffer behind the scenes, you still use a reference in the shader.

1 Like
Thank you for your help.  Do you mean the lights is in MTLBuffer and fragmentUniforms is not?

I think I may have answered misleadingly.

lights is an array of struct Light. fragmentUniforms is a single struct FragmentUniforms.

When you are accessing an array, you use a pointer. When you are accessing a single element, you use the reference.