How to get resource bind point from a structure input ?

I have a simpler fragment shader :


struct PSResources

{

constant ConstantBufferStruct& uniforms [[ buffer(1) ]];

texture2d<float> Texture0 [[texture(0)]];

sampler GlobalSampler [[sampler(0)]];

};


fragment float4 SpritePS(VS_OUT in [[stage_in]],

device PSResources & Resources

)

{

//...

}


This only compiles under Language Version 2.0, however reflection says I have 1 input to my fragment function, the Resources "buffer" and the MTLStructType is non null, so I go into it to find 3 members, a MTLDataTypeTexture, MTLDataTypePointer and MTLDataTypeSampler. This all sounds good, but how do I get the binding points ? The MTLStructMember only has an argument index which starts from 0 and increments by 1 for each member, so for GlobalSampler the index is 2 instead of the binding point I'm looking for which is 0. Same goes for uniforms, I need the 1 but I get 0.


I know I can manually move all inputs into the parameters for the fragment function and that "fixes" the issue by having arguments be present in the MTLRenderPipelineReflection.fragmentArguments, but I enjoy having my inputs in a nice structure in case I need to pass resources to functions and having just a single function parameter is way cleaner than having a ton of arguments for all functions.

Accepted Reply

I think what you may actually want is:


fragment float4 SpritePS(VS_OUT in [[stage_in]],
                         PSResources Resources)
{
  //...
}


This syntax is described in Section 2.11.2 of the Metal Shading Language Specification (v 2.2).


The syntax that you are using is that of Argument Buffers described in Section 2.12. In that syntax, the binding point attributes [[ buffer(1) ]], [[texture(1)]], etc. are ignored by the compiler and it automatically assigns the [[ id(n) ]] attribute for the members of the PSResources struct.

Replies

I think what you may actually want is:


fragment float4 SpritePS(VS_OUT in [[stage_in]],
                         PSResources Resources)
{
  //...
}


This syntax is described in Section 2.11.2 of the Metal Shading Language Specification (v 2.2).


The syntax that you are using is that of Argument Buffers described in Section 2.12. In that syntax, the binding point attributes [[ buffer(1) ]], [[texture(1)]], etc. are ignored by the compiler and it automatically assigns the [[ id(n) ]] attribute for the members of the PSResources struct.

Thanks for the fix, that was it. It made the arguments be all 3 resources instead of the structure. I did have an issue though as initially I only changed the fragment function and I had similar code for the vertex function, and with that on I was getting this

Execution of the command buffer was aborted due to an error during execution. Caused GPU Hang Error (IOAF code 3)

Seems like validation is not capturing this error. The flags being ignored is also very misleading.