在Metal中反映着色器统一名称

时间:2015-10-04 08:34:54

标签: ios objective-c macos shader metal

假设我的着色器中有以下统一缓冲区:

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

如何在C ++或Objective-C中获得someValue的位置?我想做这样的事情:

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

其中name为'someValue'。

2 个答案:

答案 0 :(得分:3)

我通过检查BGFX的源代码来提出解决方案:

    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);         
            }
        }
    }

答案 1 :(得分:2)

查看Apple Specifying Resources for a Render Command EncoderMetal Programming Guide部分。

作为一个非常基本的解释......

  1. 声明您的uniforms_t结构(通常是包含特定着色器函数的所有制服的单个结构)作为 Metal 着色器函数的参数,并且关联它具有特定的缓冲区索引(例如[[ buffer(0) ]])作为着色器函数声明的一部分。

  2. 从您的应用代码中,将uniforms_t结构的内容复制到MTLBuffer,然后以某种偏移量。

  3. 从您的应用代码中,调用MTLRenderCommandEncoder setVertexBuffer:offset:atIndex:setFragmentBuffer:offset:atIndex:方法关联MTLBuffer的内容(在您复制{的偏移量处{1}}结构),带有在着色器函数中声明的缓冲区索引。这基本上告诉着色器函数uniforms_t查看该函数参数的值(以及该缓冲区中的位置)。