Comment #62 on issue 5505 by
k...@chromium.org: Upstream Apple's direct-to-Metal backend
https://bugs.chromium.org/p/angleproject/issues/detail?id=5505#c62Changing the generated variables to EvqSpecConst and turning on the direct-to-Metal backend produces the next failure here, in the first test run with the Metal backend:
$ out/Debug/angle_end2end_tests --gtest_filter=\*ES\*Metal\*
-----
[ RUN ] EGLBlobCacheTest.Functional/ES2_Metal
fopen("/var/folders/4j/b231sqks3ts88_ls1h2069jm002z4b/C//com.apple.metal/31001/libraries.data", "r+") is skipped
fopen("/var/folders/4j/b231sqks3ts88_ls1h2069jm002z4b/C//com.apple.metal/31001/libraries.data", "w+") is skipped
AST validation error(s):
ERROR: 0:6: 'aTest' : Found reference to undeclared or inconsistently transformed variable <validateVariableReferences>
ERROR: 0:7: 'aPosition' : Found reference to undeclared or inconsistently transformed variable <validateVariableReferences>
../../third_party/angle/src/tests/test_utils/ANGLETest.cpp:64: Failure
Compiler.cpp:559 (validateAST): ! Assert failed in validateAST (../../third_party/angle/src/compiler/translator/Compiler.cpp:559): valid
Stack trace:
0 angle_end2end_tests 0x000000010fb1ecdd angle::(anonymous namespace)::TestPlatform_logError(angle::PlatformMethods*, char const*) + 125
1 libGLESv2.dylib 0x000000011f517bd1 angle::LoggingAnnotator::logMessage(gl::LogMessage const&) const + 241
2 libGLESv2.dylib 0x00000001202e2196 gl::LogMessage::~LogMessage() + 166
3 libGLESv2.dylib 0x00000001202e1b35 gl::LogMessage::~LogMessage() + 21
4 libGLESv2.dylib 0x000000012031b253 sh::TCompiler::validateAST(sh::TIntermNode*) + 483
5 libGLESv2.dylib 0x000000012054eeb3 sh::TIntermRebuild::rebuildRoot(sh::TIntermBlock&) + 67
6 libGLESv2.dylib 0x00000001205aac31 (anonymous namespace)::GeneratePipelineStruct::exec(sh::TIntermBlock&) + 65
7 libGLESv2.dylib 0x00000001205a9a5e (anonymous namespace)::GeneratePipelineStruct::Exec((anonymous namespace)::PipelineStructInfo&, sh::TCompiler&, sh::TIntermBlock&, sh::IdGen&, sh::Pipeline const&, sh::SymbolEnv&, sh::Invariants&) + 158
8 libGLESv2.dylib 0x00000001205a9631 (anonymous namespace)::RewritePipeline(sh::TCompiler&, sh::TIntermBlock&, sh::IdGen&, sh::Pipeline const&, sh::SymbolEnv&, sh::Invariants&, sh::PipelineScoped<sh::TStructure>&) + 497
9 libGLESv2.dylib 0x00000001205a93a0 sh::RewritePipelines(sh::TCompiler&, sh::TIntermBlock&, sh::IdGen&, sh::DriverUniform&, sh::SymbolEnv&, sh::Invariants&, sh::PipelineStructs&) + 768
10 libGLESv2.dylib 0x000000012051be3d sh::TranslatorMetalDirect::translateImpl(sh::TInfoSinkBase&, sh::TIntermBlock*, unsigned long long, sh::PerformanceDiagnostics*, sh::SpecConst*, sh::DriverUniform*) + 6957
...
-----
Disabling AST validation in TIntermRebuild causes a crash which needs to be caught in the debugger to be useful:
-----
(lldb) bt
* thread #6, stop reason = signal SIGABRT
* frame #0: 0x00007fff2044e92e libsystem_kernel.dylib`__pthread_kill + 10
frame #1: 0x00007fff2047d5bd libsystem_pthread.dylib`pthread_kill + 263
frame #2: 0x00007fff203d2411 libsystem_c.dylib`abort + 120
frame #3: 0x0000000112f31971 libGLESv2.dylib`std::__1::__throw_out_of_range(__msg="unordered_map::at: key not found") at stdexcept:270:5
frame #4: 0x0000000114095631 libGLESv2.dylib`std::__1::unordered_map<unsigned long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<unsigned long>, std::__1::equal_to<unsigned long>, std::__1::allocator<std::__1::pair<unsigned long const, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::at(this=0x000000010b08d048 size=2, __k=0x0000700003891510) at unordered_map:1789:9
frame #5: 0x000000011409484e libGLESv2.dylib`sh::TranslatorMetalReflection::getOriginalName(this=0x000000010b08d040, id=3096) at TranslatorMetalDirect.h:72:73
frame #6: 0x00000001140209dd libGLESv2.dylib`(anonymous namespace)::GenMetalTraverser::emitUniformBufferDeclaration(this=0x0000700003892df8, field=0x000000010b8a7900, annotationIndices=0x0000700003891808)::GenMetalTraverser::FieldAnnotationIndices&) at EmitMetal.cpp:1165:50
frame #7: 0x000000011401e65c libGLESv2.dylib`(anonymous namespace)::GenMetalTraverser::emitStructDeclaration(this=0x0000700003892df8, type=0x000000010b8a9510) at EmitMetal.cpp:1225:13
frame #8: 0x000000011401d466 libGLESv2.dylib`(anonymous namespace)::GenMetalTraverser::emitVariableDeclaration(this=0x0000700003892df8, decl=0x0000700003892678, evdConfig=0x00007000038922b8)::VarDecl const&, (anonymous namespace)::GenMetalTraverser::EmitVariableDeclarationConfig const&) at EmitMetal.cpp:1282:17
frame #9: 0x0000000114013cb5 libGLESv2.dylib`(anonymous namespace)::GenMetalTraverser::visitDeclaration(this=0x0000700003892df8, (null)=PreVisit, declNode=0x000000010b8a9490) at EmitMetal.cpp:2211:9
frame #10: 0x0000000113f29a37 libGLESv2.dylib`sh::TIntermDeclaration::visit(this=0x000000010b8a9490, visit=PreVisit, it=0x0000700003892df8) at IntermTraverse.cpp:169:16
frame #11: 0x0000000113f2935c libGLESv2.dylib`void sh::TIntermTraverser::traverse<sh::TIntermNode>(this=0x0000700003892df8, node=0x000000010b8a9490) at IntermTraverse.cpp:32:23
frame #12: 0x0000000113f2954d libGLESv2.dylib`sh::TIntermNode::traverse(this=0x000000010b8a9490, it=0x0000700003892df8) at IntermTraverse.cpp:63:9
frame #13: 0x0000000114013596 libGLESv2.dylib`(anonymous namespace)::GenMetalTraverser::visitBlock(this=0x0000700003892df8, (null)=PreVisit, blockNode=0x000000010b86c480) at EmitMetal.cpp:2165:18
frame #14: 0x0000000113f29aa4 libGLESv2.dylib`sh::TIntermBlock::visit(this=0x000000010b86c480, visit=PreVisit, it=0x0000700003892df8) at IntermTraverse.cpp:179:16
frame #15: 0x0000000113f2c07a libGLESv2.dylib`sh::TIntermTraverser::traverseBlock(this=0x0000700003892df8, node=0x000000010b86c480) at IntermTraverse.cpp:466:23
frame #16: 0x0000000113f297c1 libGLESv2.dylib`sh::TIntermBlock::traverse(this=0x000000010b86c480, it=0x0000700003892df8) at IntermTraverse.cpp:101:9
frame #17: 0x000000011400f5ea libGLESv2.dylib`sh::EmitMetal(compiler=0x000000010b08c400, root=0x000000010b86c480, idGen=0x0000700003893560, pipelineStructs=0x00007000038933e8, invariants=0x00007000038936a0, symbolEnv=0x00007000038937e8, ppc=0x0000700003893558, symbolTable=0x000000010b08c7e0) at EmitMetal.cpp:2485:14
frame #18: 0x0000000113ff9082 libGLESv2.dylib`sh::TranslatorMetalDirect::translateImpl(this=0x000000010b08c400, sink=0x000000010b08cf88, root=0x000000010b86c480, compileOptions=36594225705386060, (null)=0x0000700003893b08, specConst=0x0000700003893a38, driverUniforms=0x0000700003893a18) at TranslatorMetalDirect.cpp:1153:10
frame #19: 0x0000000113ffbe0b libGLESv2.dylib`sh::TranslatorMetalDirect::translate(this=0x000000010b08c400, root=0x000000010b86c480, compileOptions=36594225705386060, perfDiagnostics=0x0000700003893b08) at TranslatorMetalDirect.cpp:1200:10
-----
The TranslatorMetalDirect path is producing invalid variable references - I assume it's moving global variables into a top-level struct and failing to update those variables to refer to the struct's fields, or something similar.