Shader compiler issue with XCode 12 on iOS 10.1.1

Hello,

So before on XCode 10.3 on MacOS Mojave my code worked without any problems.

However I have since upgraded to XCode 12.4 with MacOS Catalina (10.15.7)

Now when I attempt:

id <MTLRenderPipelineState> pcMTLRenderPipeLineState = [pcMTLDevice newRenderPipelineStateWithDescriptor: pcMTLRenderPipeLineDesc error: &pcError];

I get the following error:

Compiler failed to build request
CMetalPipeLineState::Create: Failed to generate a pipeline state object: Error Domain=AGXMetalA7 Code=1 "Could not resolve texture/samplers references" UserInfo={NSLocalizedDescription=Could not resolve texture/samplers references}

Does anyone have any idea what could be causing this?

The full debug output is shown below:

CMetalPipeLineState::Create: Descriptor: <MTLRenderPipelineDescriptorInternal: 0x1701b5c40>
{
"Alpha to Coverage" = 0;
"Alpha to One" = 0;
"Blend States" = (
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = "MTLPixelFormatBGRA8Unorm_sRGB";
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
},
{
"Alpha Blend Operation" = MTLBlendOperationAdd;
"Blending Enabled" = 0;
"Destination Alpha Blend Factor" = MTLBlendFactorZero;
"Destination RGB Blend Factor" = MTLBlendFactorZero;
"Pixel Format" = MTLPixelFormatInvalid;
"RGB Blend Operation" = MTLBlendOperationAdd;
"Source Alpha Blend Factor" = MTLBlendFactorOne;
"Source RGB Blend Factor" = MTLBlendFactorOne;
"Write Mask" = RGBA;
}
);
"Depth Attachment Format" = MTLPixelFormatDepth32Float;
"Fragment Depth Compare Clamp Mask" = 0x0;
"Fragment Function" = "<MTLDebugFunction: 0x170272200> -> <_MTLFunctionInternal: 0x170196da0>\n{\n attributes = \"<null>\";\n device = \"<AGXA7Device: 0x101728000>\\n{\\n name = \\\"Apple A7 GPU\\\";\\n}\";\n functionType = MTLFunctionTypeFragment;\n name = \"diffuse_main_ps\";\n}";
"Rasterization Enabled" = 1;
"Sample Count" = 1;
"Sample Coverage" = 1;
"Sample Mask" = 0xffffffffffffffff;
"Stencil Attachment Format" = MTLPixelFormatInvalid;
"Vertex Depth Compare Clamp Mask" = 0x0;
"Vertex Array" = "<null>";
"Vertex Enabled" = 1;
"Vertex Function" = "<MTLDebugFunction: 0x170271f40> -> <_MTLFunctionInternal: 0x170196720>\n{\n attributes = \"<null>\";\n device = \"<AGXA7Device: 0x101728000>\\n{\\n name = \\\"Apple A7 GPU\\\";\\n}\";\n functionType = MTLFunctionTypeVertex;\n name = \"diffuse_vp_main_vs\";\n}";
label = "<null>";
maxTessellationFactor = 16;
tessellationControlPointIndexType = MTLTessellationControlPointIndexTypeNone;
tessellationFactorFormat = MTLTessellationFactorFormatHalf;
tessellationFactorScaleEnabled = 0;
tessellationFactorStepFunction = MTLTessellationFactorStepFunctionConstant;
tessellationOutputWindingOrder = MTLWindingClockwise;
tessellationPartitionMode = MTLTessellationPartitionModePow2;
}


Answered by vspyder in 670759022
OK I finally "solved" this.

The issue is that the newly compiled Metal shader library is NOT compatible with the iPhone 5s with iOS version 10.1.1. So calling the method: - (nullable id <MTLLibrary>)newDefaultLibrary; with the compiled Metal library file will not work.

The solution is to run time compile the metal shaders on the target platform with the method:
  • (nullable id <MTLLibrary>)newLibraryWithSource:(NSString *)source options:(nullable MTLCompileOptions *)options error:(__autoreleasing NSError **)error;

With this method I was able to load and run the game. It had negligible impact on the load time of my game.
What do the diffuse_main_ps and diffuse_vp_main_vs functions you're trying to build the pipeline with look like?
The shaders are pretty standard stuff really. Here is the vertex and pixel shaders:

struct sVertexInput
{
packed_float3 m_cPosition;
packed_float2 m_cTextureCoords;
};


struct sVertexOutput
{
float4 m_cPosition [[position]];
float2 m_cTextureCoords;
};


//==============================================================================
// Diffuse vertex shader
//
// psVertices - input vertices
// rsUniforms - uniforms buffer
// iVertexID - vertex index
//
// Returns: sVertexOutput - vertex output
//==============================================================================

vertex sVertexOutput diffuse_vp_main_vs (const device sVertexInput *psVertices [[buffer (0)]],
constant sVPUniforms &rsUniforms [[buffer (1)]],
uint iVertexID [[vertex_id]])
{
sVertexOutput sVertexOutput;
Code Block
float4 cPosition = float4 (psVertices [iVertexID].m_cPosition, 1.0f);

sVertexOutput.m_cPosition = cPosition * rsUniforms.m_cViewProjection;
Code Block
// pass the texture coordinates through
sVertexOutput.m_cTextureCoords = psVertices [iVertexID].m_cTextureCoords;

return sVertexOutput;
}


//==============================================================================
// Diffuse fragment shader
//
// sVertex - output vertex from vertex shader
// cDiffuseTexture - diffuse texture
// smplDiffuse - diffuse sampler
//
// Returns: half4 - sampled diffuse texture
//==============================================================================

fragment half4 diffuse_main_ps (sVertexOutput sVertex [[stage_in]],
texture2d <float> cDiffuseTexture [[texture (0)]],
sampler smplDiffuse [[sampler (0)]])
{
// sample the diffuse texture
half4 cColor = (half4) (cDiffuseTexture.sample (smplDiffuse, sVertex.m_cTextureCoords));
Code Block
return cColor;
}

Also running the EXACT SAME code on a newer iPhone with iOS 13.6.1 runs perfectly with no crashes.

I also tried the Metal deffered shading demo from Apple and it exhibits the same crash issue:

Could not resolve texture/samplers references

But on the newer phone with iOS 13.6.1 the Deffered shading demo runs without a hitch.
This would be expected with he deferred lighting sample because the deployment target is set to iOS 12. It is not intended to run on iOS 10 because the Metal front end compiler can generate code that the iOS10 drivers will not understand.

Are you sure the deployment target of your app is set to include iOS 10?
Yes the Deferred Lighting demo running on my iPhone 5s with iOS version 10.1.1 will have the same issue and the same error when you create a render pipe line.

I keep an old version of iOS on this phone for compatibility issues. I made sure the deployment target in the Deferred Lighting demo was 10. ie. I changed it to run as the minimum deployment target to be 10.

I will write a report with Feedback Assistant. But it may be hard to debug this if you don't have an iPhone with an old iOS version.

Thanks for helping me!
Sorry, I edited my answer as you were responding. I didn't realize you were running such an old version of iOS (Must have missed it because it was in the title not the body).

Please make sure the deployment target of your app is set to include iOS 10 otherwise the front end compiler in Xcode will likely generate IR code that the iOS 10 drivers will not understand.
I did notice that when I downloaded XCode 12 and loaded my project it "recommended" that I update the deployment target to 12.
Perhaps it is as you state that the Metal Shader compilers are generating code that the drivers on iOS 10 are not compatible with.

I will write the Feedback just the same for completeness. I will try to fix this on my end and if not I guess I will have to upgrade to iOS version on myiPhone5s to 12.

Thanks,
Juan
Accepted Answer
OK I finally "solved" this.

The issue is that the newly compiled Metal shader library is NOT compatible with the iPhone 5s with iOS version 10.1.1. So calling the method: - (nullable id <MTLLibrary>)newDefaultLibrary; with the compiled Metal library file will not work.

The solution is to run time compile the metal shaders on the target platform with the method:
  • (nullable id <MTLLibrary>)newLibraryWithSource:(NSString *)source options:(nullable MTLCompileOptions *)options error:(__autoreleasing NSError **)error;

With this method I was able to load and run the game. It had negligible impact on the load time of my game.

This issue appears to be fixed with XCode 13. Metal libraries compiled in XCode are now working on iOS 10 for us, so you may want to remove your workaround.

Shader compiler issue with XCode 12 on iOS 10.1.1
 
 
Q