0
votes

Suppose I have the following uniform buffer in my shader:

typedef struct
{
    matrix_float4x4 modelview_projection_matrix;
    float someValue;
} uniforms_t;

How do I get someValue's location in C++ or Objective-C? I want to do something like this:

void Shader::SetFloat( const char* name, float value )

where name would be 'someValue'.

2

2 Answers

4
votes

I came up with a solution by examining BGFX's source code:

    NSError* error = NULL;
    MTLRenderPipelineReflection* reflectionObj;
    MTLPipelineOption option = MTLPipelineOptionBufferTypeInfo | MTLPipelineOptionArgumentInfo;
    id <MTLRenderPipelineState> pso = [device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor options:option reflection:&reflectionObj error:&error];

    for (MTLArgument *arg in reflectionObj.vertexArguments)
    {
        NSLog(@"Found arg: %@\n", arg.name);

        if (arg.bufferDataType == MTLDataTypeStruct)
        {
            for( MTLStructMember* uniform in arg.bufferStructType.members )
            {
                NSLog(@"uniform: %@ type:%lu, location: %lu", uniform.name, (unsigned long)uniform.dataType, (unsigned long)uniform.offset);         
            }
        }
    }
2
votes

Have a look at the Specifying Resources for a Render Command Encoder section of Apple's Metal Programming Guide.

As a very basic explanation...

  1. Declare your uniforms_t structure (which will typically be a single structure containing all the uniforms for a particular shader function) as an argument of a Metal shader function, and associate it with a specific buffer index (eg. [[ buffer(0) ]]) as part of your shader function declaration.

  2. From your app code, copy the contents of your uniforms_t structure into a MTLBuffer, at some offset.

  3. From your app code, invoke the MTLRenderCommandEncoder setVertexBuffer:offset:atIndex: or setFragmentBuffer:offset:atIndex: methods to associate the contents of the MTLBuffer (at the offset where you copied your uniforms_t structure) with the buffer index you declared in your shader function. This basically tells the shader function which MTLBuffer to look in (and where in that buffer) for the value of that function argument.