1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/Compiler.h"
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker #include "common/BinaryStream.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "common/CompiledShaderState.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/angle_version_info.h"
17*8975f5c5SAndroid Build Coastguard Worker
18*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/CallDAG.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/CollectVariables.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/Initialize.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/IsASTDepthBelowLimit.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/OutputTree.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ParseContext.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateBarrierFunctionCall.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateClipCullDistance.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateLimitations.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateMaxParameters.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateOutputs.h"
29*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateTypeSizeLimitations.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/ValidateVaryingLocations.h"
31*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/VariablePacker.h"
32*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/ClampFragDepth.h"
33*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/ClampIndirectIndices.h"
34*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/ClampPointSize.h"
35*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/DeclareAndInitBuiltinsForInstancedMultiview.h"
36*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/DeferGlobalInitializers.h"
37*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/EmulateGLFragColorBroadcast.h"
38*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/EmulateMultiDrawShaderBuiltins.h"
39*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/FoldExpressions.h"
40*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/ForcePrecisionQualifier.h"
41*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/InitializeVariables.h"
42*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/MonomorphizeUnsupportedFunctions.h"
43*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/PruneEmptyCases.h"
44*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/PruneInfiniteLoops.h"
45*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/PruneNoOps.h"
46*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RemoveArrayLengthMethod.h"
47*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RemoveDynamicIndexing.h"
48*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RemoveInvariantDeclaration.h"
49*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RemoveUnreferencedVariables.h"
50*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RescopeGlobalVariables.h"
51*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/RewritePixelLocalStorage.h"
52*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/SeparateDeclarations.h"
53*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/SimplifyLoopConditions.h"
54*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/SplitSequenceOperator.h"
55*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/RegenerateStructNames.h"
56*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/RewriteRepeatedAssignToSwizzled.h"
57*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/ScalarizeVecAndMatConstructorArgs.h"
58*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/UseInterfaceBlockFields.h"
59*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/apple/AddAndTrueToLoopCondition.h"
60*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/apple/RewriteDoWhile.h"
61*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_ops/glsl/apple/UnfoldShortCircuitAST.h"
62*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/BuiltIn.h"
63*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/IntermNodePatternMatcher.h"
64*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/ReplaceShadowingVariables.h"
65*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/tree_util/ReplaceVariable.h"
66*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/util.h"
67*8975f5c5SAndroid Build Coastguard Worker
68*8975f5c5SAndroid Build Coastguard Worker // #define ANGLE_FUZZER_CORPUS_OUTPUT_DIR "corpus/"
69*8975f5c5SAndroid Build Coastguard Worker
70*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
71*8975f5c5SAndroid Build Coastguard Worker # include "common/hash_utils.h"
72*8975f5c5SAndroid Build Coastguard Worker # include "common/mathutil.h"
73*8975f5c5SAndroid Build Coastguard Worker #endif
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker namespace sh
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker namespace
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker // Helper that returns if a top-level node is unused. If it's a function, the function prototype is
81*8975f5c5SAndroid Build Coastguard Worker // returned as well.
IsTopLevelNodeUnusedFunction(const CallDAG & callDag,const std::vector<TFunctionMetadata> & metadata,TIntermNode * node,const TFunction ** functionOut)82*8975f5c5SAndroid Build Coastguard Worker bool IsTopLevelNodeUnusedFunction(const CallDAG &callDag,
83*8975f5c5SAndroid Build Coastguard Worker const std::vector<TFunctionMetadata> &metadata,
84*8975f5c5SAndroid Build Coastguard Worker TIntermNode *node,
85*8975f5c5SAndroid Build Coastguard Worker const TFunction **functionOut)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker const TIntermFunctionPrototype *asFunctionPrototype = node->getAsFunctionPrototypeNode();
88*8975f5c5SAndroid Build Coastguard Worker const TIntermFunctionDefinition *asFunctionDefinition = node->getAsFunctionDefinition();
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker *functionOut = nullptr;
91*8975f5c5SAndroid Build Coastguard Worker
92*8975f5c5SAndroid Build Coastguard Worker if (asFunctionDefinition)
93*8975f5c5SAndroid Build Coastguard Worker {
94*8975f5c5SAndroid Build Coastguard Worker *functionOut = asFunctionDefinition->getFunction();
95*8975f5c5SAndroid Build Coastguard Worker }
96*8975f5c5SAndroid Build Coastguard Worker else if (asFunctionPrototype)
97*8975f5c5SAndroid Build Coastguard Worker {
98*8975f5c5SAndroid Build Coastguard Worker *functionOut = asFunctionPrototype->getFunction();
99*8975f5c5SAndroid Build Coastguard Worker }
100*8975f5c5SAndroid Build Coastguard Worker if (*functionOut == nullptr)
101*8975f5c5SAndroid Build Coastguard Worker {
102*8975f5c5SAndroid Build Coastguard Worker return false;
103*8975f5c5SAndroid Build Coastguard Worker }
104*8975f5c5SAndroid Build Coastguard Worker
105*8975f5c5SAndroid Build Coastguard Worker size_t callDagIndex = callDag.findIndex((*functionOut)->uniqueId());
106*8975f5c5SAndroid Build Coastguard Worker if (callDagIndex == CallDAG::InvalidIndex)
107*8975f5c5SAndroid Build Coastguard Worker {
108*8975f5c5SAndroid Build Coastguard Worker // This happens only for unimplemented prototypes which are thus unused
109*8975f5c5SAndroid Build Coastguard Worker ASSERT(asFunctionPrototype);
110*8975f5c5SAndroid Build Coastguard Worker return true;
111*8975f5c5SAndroid Build Coastguard Worker }
112*8975f5c5SAndroid Build Coastguard Worker
113*8975f5c5SAndroid Build Coastguard Worker ASSERT(callDagIndex < metadata.size());
114*8975f5c5SAndroid Build Coastguard Worker return !metadata[callDagIndex].used;
115*8975f5c5SAndroid Build Coastguard Worker }
116*8975f5c5SAndroid Build Coastguard Worker
117*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
DumpFuzzerCase(char const * const * shaderStrings,size_t numStrings,uint32_t type,uint32_t spec,uint32_t output,const ShCompileOptions & options)118*8975f5c5SAndroid Build Coastguard Worker void DumpFuzzerCase(char const *const *shaderStrings,
119*8975f5c5SAndroid Build Coastguard Worker size_t numStrings,
120*8975f5c5SAndroid Build Coastguard Worker uint32_t type,
121*8975f5c5SAndroid Build Coastguard Worker uint32_t spec,
122*8975f5c5SAndroid Build Coastguard Worker uint32_t output,
123*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &options)
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker ShaderDumpHeader header{};
126*8975f5c5SAndroid Build Coastguard Worker header.type = type;
127*8975f5c5SAndroid Build Coastguard Worker header.spec = spec;
128*8975f5c5SAndroid Build Coastguard Worker header.output = output;
129*8975f5c5SAndroid Build Coastguard Worker memcpy(&header.basicCompileOptions, &options, offsetof(ShCompileOptions, metal));
130*8975f5c5SAndroid Build Coastguard Worker static_assert(offsetof(ShCompileOptions, metal) <= sizeof(header.basicCompileOptions));
131*8975f5c5SAndroid Build Coastguard Worker memcpy(&header.metalCompileOptions, &options.metal, sizeof(options.metal));
132*8975f5c5SAndroid Build Coastguard Worker static_assert(sizeof(options.metal) <= sizeof(header.metalCompileOptions));
133*8975f5c5SAndroid Build Coastguard Worker memcpy(&header.plsCompileOptions, &options.pls, sizeof(options.pls));
134*8975f5c5SAndroid Build Coastguard Worker static_assert(sizeof(options.pls) <= sizeof(header.plsCompileOptions));
135*8975f5c5SAndroid Build Coastguard Worker size_t contentsLength = sizeof(header) + 1; // Extra: header + nul terminator.
136*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < numStrings; i++)
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker contentsLength += strlen(shaderStrings[i]);
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker std::vector<uint8_t> contents(rx::roundUp<size_t>(contentsLength, 4), 0);
141*8975f5c5SAndroid Build Coastguard Worker memcpy(&contents[0], &header, sizeof(header));
142*8975f5c5SAndroid Build Coastguard Worker uint8_t *data = &contents[sizeof(header)];
143*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < numStrings; i++)
144*8975f5c5SAndroid Build Coastguard Worker {
145*8975f5c5SAndroid Build Coastguard Worker auto length = strlen(shaderStrings[i]);
146*8975f5c5SAndroid Build Coastguard Worker memcpy(data, shaderStrings[i], length);
147*8975f5c5SAndroid Build Coastguard Worker data += length;
148*8975f5c5SAndroid Build Coastguard Worker }
149*8975f5c5SAndroid Build Coastguard Worker auto hash = angle::ComputeGenericHash(contents.data(), contents.size());
150*8975f5c5SAndroid Build Coastguard Worker
151*8975f5c5SAndroid Build Coastguard Worker std::ostringstream o = sh::InitializeStream<std::ostringstream>();
152*8975f5c5SAndroid Build Coastguard Worker o << ANGLE_FUZZER_CORPUS_OUTPUT_DIR << std::hex << std::setw(16) << std::setfill('0') << hash
153*8975f5c5SAndroid Build Coastguard Worker << ".sample";
154*8975f5c5SAndroid Build Coastguard Worker std::string s = o.str();
155*8975f5c5SAndroid Build Coastguard Worker
156*8975f5c5SAndroid Build Coastguard Worker // Must match the input format of the fuzzer
157*8975f5c5SAndroid Build Coastguard Worker FILE *f = fopen(s.c_str(), "w");
158*8975f5c5SAndroid Build Coastguard Worker fwrite(contents.data(), sizeof(char), contentsLength, f);
159*8975f5c5SAndroid Build Coastguard Worker fclose(f);
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker #endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
162*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
163*8975f5c5SAndroid Build Coastguard Worker
IsGLSL130OrNewer(ShShaderOutput output)164*8975f5c5SAndroid Build Coastguard Worker bool IsGLSL130OrNewer(ShShaderOutput output)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
167*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
168*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT ||
169*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
170*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
171*8975f5c5SAndroid Build Coastguard Worker }
172*8975f5c5SAndroid Build Coastguard Worker
IsGLSL420OrNewer(ShShaderOutput output)173*8975f5c5SAndroid Build Coastguard Worker bool IsGLSL420OrNewer(ShShaderOutput output)
174*8975f5c5SAndroid Build Coastguard Worker {
175*8975f5c5SAndroid Build Coastguard Worker return (output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT ||
176*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT);
177*8975f5c5SAndroid Build Coastguard Worker }
178*8975f5c5SAndroid Build Coastguard Worker
IsGLSL410OrOlder(ShShaderOutput output)179*8975f5c5SAndroid Build Coastguard Worker bool IsGLSL410OrOlder(ShShaderOutput output)
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT ||
182*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT ||
183*8975f5c5SAndroid Build Coastguard Worker output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT);
184*8975f5c5SAndroid Build Coastguard Worker }
185*8975f5c5SAndroid Build Coastguard Worker
RemoveInvariant(sh::GLenum shaderType,int shaderVersion,ShShaderOutput outputType,const ShCompileOptions & compileOptions)186*8975f5c5SAndroid Build Coastguard Worker bool RemoveInvariant(sh::GLenum shaderType,
187*8975f5c5SAndroid Build Coastguard Worker int shaderVersion,
188*8975f5c5SAndroid Build Coastguard Worker ShShaderOutput outputType,
189*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker if (shaderType == GL_FRAGMENT_SHADER &&
192*8975f5c5SAndroid Build Coastguard Worker (IsGLSL420OrNewer(outputType) || IsOutputSPIRV(outputType)))
193*8975f5c5SAndroid Build Coastguard Worker return true;
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.removeInvariantAndCentroidForESSL3 && shaderVersion >= 300 &&
196*8975f5c5SAndroid Build Coastguard Worker shaderType == GL_VERTEX_SHADER)
197*8975f5c5SAndroid Build Coastguard Worker return true;
198*8975f5c5SAndroid Build Coastguard Worker
199*8975f5c5SAndroid Build Coastguard Worker return false;
200*8975f5c5SAndroid Build Coastguard Worker }
201*8975f5c5SAndroid Build Coastguard Worker
GetGlobalMaxTokenSize(ShShaderSpec spec)202*8975f5c5SAndroid Build Coastguard Worker size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
203*8975f5c5SAndroid Build Coastguard Worker {
204*8975f5c5SAndroid Build Coastguard Worker // WebGL defines a max token length of 256, while ES2 leaves max token
205*8975f5c5SAndroid Build Coastguard Worker // size undefined. ES3 defines a max size of 1024 characters.
206*8975f5c5SAndroid Build Coastguard Worker switch (spec)
207*8975f5c5SAndroid Build Coastguard Worker {
208*8975f5c5SAndroid Build Coastguard Worker case SH_WEBGL_SPEC:
209*8975f5c5SAndroid Build Coastguard Worker return 256;
210*8975f5c5SAndroid Build Coastguard Worker default:
211*8975f5c5SAndroid Build Coastguard Worker return 1024;
212*8975f5c5SAndroid Build Coastguard Worker }
213*8975f5c5SAndroid Build Coastguard Worker }
214*8975f5c5SAndroid Build Coastguard Worker
GetMaxUniformVectorsForShaderType(GLenum shaderType,const ShBuiltInResources & resources)215*8975f5c5SAndroid Build Coastguard Worker int GetMaxUniformVectorsForShaderType(GLenum shaderType, const ShBuiltInResources &resources)
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker switch (shaderType)
218*8975f5c5SAndroid Build Coastguard Worker {
219*8975f5c5SAndroid Build Coastguard Worker case GL_VERTEX_SHADER:
220*8975f5c5SAndroid Build Coastguard Worker return resources.MaxVertexUniformVectors;
221*8975f5c5SAndroid Build Coastguard Worker case GL_FRAGMENT_SHADER:
222*8975f5c5SAndroid Build Coastguard Worker return resources.MaxFragmentUniformVectors;
223*8975f5c5SAndroid Build Coastguard Worker
224*8975f5c5SAndroid Build Coastguard Worker // TODO ([email protected]): check if we need finer-grained component counting
225*8975f5c5SAndroid Build Coastguard Worker case GL_COMPUTE_SHADER:
226*8975f5c5SAndroid Build Coastguard Worker return resources.MaxComputeUniformComponents / 4;
227*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_SHADER_EXT:
228*8975f5c5SAndroid Build Coastguard Worker return resources.MaxGeometryUniformComponents / 4;
229*8975f5c5SAndroid Build Coastguard Worker default:
230*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
231*8975f5c5SAndroid Build Coastguard Worker return -1;
232*8975f5c5SAndroid Build Coastguard Worker }
233*8975f5c5SAndroid Build Coastguard Worker }
234*8975f5c5SAndroid Build Coastguard Worker
235*8975f5c5SAndroid Build Coastguard Worker namespace
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker
238*8975f5c5SAndroid Build Coastguard Worker class [[nodiscard]] TScopedPoolAllocator
239*8975f5c5SAndroid Build Coastguard Worker {
240*8975f5c5SAndroid Build Coastguard Worker public:
TScopedPoolAllocator(angle::PoolAllocator * allocator)241*8975f5c5SAndroid Build Coastguard Worker TScopedPoolAllocator(angle::PoolAllocator *allocator) : mAllocator(allocator)
242*8975f5c5SAndroid Build Coastguard Worker {
243*8975f5c5SAndroid Build Coastguard Worker mAllocator->push();
244*8975f5c5SAndroid Build Coastguard Worker SetGlobalPoolAllocator(mAllocator);
245*8975f5c5SAndroid Build Coastguard Worker }
~TScopedPoolAllocator()246*8975f5c5SAndroid Build Coastguard Worker ~TScopedPoolAllocator()
247*8975f5c5SAndroid Build Coastguard Worker {
248*8975f5c5SAndroid Build Coastguard Worker SetGlobalPoolAllocator(nullptr);
249*8975f5c5SAndroid Build Coastguard Worker mAllocator->pop(angle::PoolAllocator::ReleaseStrategy::All);
250*8975f5c5SAndroid Build Coastguard Worker }
251*8975f5c5SAndroid Build Coastguard Worker
252*8975f5c5SAndroid Build Coastguard Worker private:
253*8975f5c5SAndroid Build Coastguard Worker angle::PoolAllocator *mAllocator;
254*8975f5c5SAndroid Build Coastguard Worker };
255*8975f5c5SAndroid Build Coastguard Worker
256*8975f5c5SAndroid Build Coastguard Worker class [[nodiscard]] TScopedSymbolTableLevel
257*8975f5c5SAndroid Build Coastguard Worker {
258*8975f5c5SAndroid Build Coastguard Worker public:
TScopedSymbolTableLevel(TSymbolTable * table)259*8975f5c5SAndroid Build Coastguard Worker TScopedSymbolTableLevel(TSymbolTable *table) : mTable(table)
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker ASSERT(mTable->isEmpty());
262*8975f5c5SAndroid Build Coastguard Worker mTable->push();
263*8975f5c5SAndroid Build Coastguard Worker }
~TScopedSymbolTableLevel()264*8975f5c5SAndroid Build Coastguard Worker ~TScopedSymbolTableLevel()
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker while (!mTable->isEmpty())
267*8975f5c5SAndroid Build Coastguard Worker mTable->pop();
268*8975f5c5SAndroid Build Coastguard Worker }
269*8975f5c5SAndroid Build Coastguard Worker
270*8975f5c5SAndroid Build Coastguard Worker private:
271*8975f5c5SAndroid Build Coastguard Worker TSymbolTable *mTable;
272*8975f5c5SAndroid Build Coastguard Worker };
273*8975f5c5SAndroid Build Coastguard Worker
GetMaxShaderVersionForSpec(ShShaderSpec spec)274*8975f5c5SAndroid Build Coastguard Worker int GetMaxShaderVersionForSpec(ShShaderSpec spec)
275*8975f5c5SAndroid Build Coastguard Worker {
276*8975f5c5SAndroid Build Coastguard Worker switch (spec)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker case SH_GLES2_SPEC:
279*8975f5c5SAndroid Build Coastguard Worker case SH_WEBGL_SPEC:
280*8975f5c5SAndroid Build Coastguard Worker return 100;
281*8975f5c5SAndroid Build Coastguard Worker case SH_GLES3_SPEC:
282*8975f5c5SAndroid Build Coastguard Worker case SH_WEBGL2_SPEC:
283*8975f5c5SAndroid Build Coastguard Worker return 300;
284*8975f5c5SAndroid Build Coastguard Worker case SH_GLES3_1_SPEC:
285*8975f5c5SAndroid Build Coastguard Worker case SH_WEBGL3_SPEC:
286*8975f5c5SAndroid Build Coastguard Worker return 310;
287*8975f5c5SAndroid Build Coastguard Worker case SH_GLES3_2_SPEC:
288*8975f5c5SAndroid Build Coastguard Worker return 320;
289*8975f5c5SAndroid Build Coastguard Worker default:
290*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
291*8975f5c5SAndroid Build Coastguard Worker return 0;
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker }
294*8975f5c5SAndroid Build Coastguard Worker
ValidateFragColorAndFragData(GLenum shaderType,int shaderVersion,const TSymbolTable & symbolTable,TDiagnostics * diagnostics)295*8975f5c5SAndroid Build Coastguard Worker bool ValidateFragColorAndFragData(GLenum shaderType,
296*8975f5c5SAndroid Build Coastguard Worker int shaderVersion,
297*8975f5c5SAndroid Build Coastguard Worker const TSymbolTable &symbolTable,
298*8975f5c5SAndroid Build Coastguard Worker TDiagnostics *diagnostics)
299*8975f5c5SAndroid Build Coastguard Worker {
300*8975f5c5SAndroid Build Coastguard Worker if (shaderVersion > 100 || shaderType != GL_FRAGMENT_SHADER)
301*8975f5c5SAndroid Build Coastguard Worker {
302*8975f5c5SAndroid Build Coastguard Worker return true;
303*8975f5c5SAndroid Build Coastguard Worker }
304*8975f5c5SAndroid Build Coastguard Worker
305*8975f5c5SAndroid Build Coastguard Worker bool usesFragColor = false;
306*8975f5c5SAndroid Build Coastguard Worker bool usesFragData = false;
307*8975f5c5SAndroid Build Coastguard Worker // This validation is a bit stricter than the spec - it's only an error to write to
308*8975f5c5SAndroid Build Coastguard Worker // both FragData and FragColor. But because it's better not to have reads from undefined
309*8975f5c5SAndroid Build Coastguard Worker // variables, we always return an error if they are both referenced, rather than only if they
310*8975f5c5SAndroid Build Coastguard Worker // are written.
311*8975f5c5SAndroid Build Coastguard Worker if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_FragColor()) ||
312*8975f5c5SAndroid Build Coastguard Worker symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()))
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker usesFragColor = true;
315*8975f5c5SAndroid Build Coastguard Worker }
316*8975f5c5SAndroid Build Coastguard Worker // Extension variables may not always be initialized (saves some time at symbol table init).
317*8975f5c5SAndroid Build Coastguard Worker bool secondaryFragDataUsed =
318*8975f5c5SAndroid Build Coastguard Worker symbolTable.gl_SecondaryFragDataEXT() != nullptr &&
319*8975f5c5SAndroid Build Coastguard Worker symbolTable.isStaticallyUsed(*symbolTable.gl_SecondaryFragDataEXT());
320*8975f5c5SAndroid Build Coastguard Worker if (symbolTable.isStaticallyUsed(*symbolTable.gl_FragData()) || secondaryFragDataUsed)
321*8975f5c5SAndroid Build Coastguard Worker {
322*8975f5c5SAndroid Build Coastguard Worker usesFragData = true;
323*8975f5c5SAndroid Build Coastguard Worker }
324*8975f5c5SAndroid Build Coastguard Worker if (usesFragColor && usesFragData)
325*8975f5c5SAndroid Build Coastguard Worker {
326*8975f5c5SAndroid Build Coastguard Worker const char *errorMessage = "cannot use both gl_FragData and gl_FragColor";
327*8975f5c5SAndroid Build Coastguard Worker if (symbolTable.isStaticallyUsed(*BuiltInVariable::gl_SecondaryFragColorEXT()) ||
328*8975f5c5SAndroid Build Coastguard Worker secondaryFragDataUsed)
329*8975f5c5SAndroid Build Coastguard Worker {
330*8975f5c5SAndroid Build Coastguard Worker errorMessage =
331*8975f5c5SAndroid Build Coastguard Worker "cannot use both output variable sets (gl_FragData, gl_SecondaryFragDataEXT)"
332*8975f5c5SAndroid Build Coastguard Worker " and (gl_FragColor, gl_SecondaryFragColorEXT)";
333*8975f5c5SAndroid Build Coastguard Worker }
334*8975f5c5SAndroid Build Coastguard Worker diagnostics->globalError(errorMessage);
335*8975f5c5SAndroid Build Coastguard Worker return false;
336*8975f5c5SAndroid Build Coastguard Worker }
337*8975f5c5SAndroid Build Coastguard Worker return true;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker
340*8975f5c5SAndroid Build Coastguard Worker } // namespace
341*8975f5c5SAndroid Build Coastguard Worker
TShHandleBase()342*8975f5c5SAndroid Build Coastguard Worker TShHandleBase::TShHandleBase()
343*8975f5c5SAndroid Build Coastguard Worker {
344*8975f5c5SAndroid Build Coastguard Worker allocator.push();
345*8975f5c5SAndroid Build Coastguard Worker SetGlobalPoolAllocator(&allocator);
346*8975f5c5SAndroid Build Coastguard Worker }
347*8975f5c5SAndroid Build Coastguard Worker
~TShHandleBase()348*8975f5c5SAndroid Build Coastguard Worker TShHandleBase::~TShHandleBase()
349*8975f5c5SAndroid Build Coastguard Worker {
350*8975f5c5SAndroid Build Coastguard Worker SetGlobalPoolAllocator(nullptr);
351*8975f5c5SAndroid Build Coastguard Worker allocator.popAll();
352*8975f5c5SAndroid Build Coastguard Worker }
353*8975f5c5SAndroid Build Coastguard Worker
TCompiler(sh::GLenum type,ShShaderSpec spec,ShShaderOutput output)354*8975f5c5SAndroid Build Coastguard Worker TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
355*8975f5c5SAndroid Build Coastguard Worker : mVariablesCollected(false),
356*8975f5c5SAndroid Build Coastguard Worker mGLPositionInitialized(false),
357*8975f5c5SAndroid Build Coastguard Worker mShaderType(type),
358*8975f5c5SAndroid Build Coastguard Worker mShaderSpec(spec),
359*8975f5c5SAndroid Build Coastguard Worker mOutputType(output),
360*8975f5c5SAndroid Build Coastguard Worker mBuiltInFunctionEmulator(),
361*8975f5c5SAndroid Build Coastguard Worker mDiagnostics(mInfoSink.info),
362*8975f5c5SAndroid Build Coastguard Worker mSourcePath(nullptr),
363*8975f5c5SAndroid Build Coastguard Worker mComputeShaderLocalSizeDeclared(false),
364*8975f5c5SAndroid Build Coastguard Worker mComputeShaderLocalSize(1),
365*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderMaxVertices(-1),
366*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInvocations(0),
367*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInputPrimitiveType(EptUndefined),
368*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderOutputPrimitiveType(EptUndefined),
369*8975f5c5SAndroid Build Coastguard Worker mTessControlShaderOutputVertices(0),
370*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPrimitiveType(EtetUndefined),
371*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputVertexSpacingType(EtetUndefined),
372*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputOrderingType(EtetUndefined),
373*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPointType(EtetUndefined),
374*8975f5c5SAndroid Build Coastguard Worker mHasAnyPreciseType(false),
375*8975f5c5SAndroid Build Coastguard Worker mAdvancedBlendEquations(0),
376*8975f5c5SAndroid Build Coastguard Worker mUsesDerivatives(false),
377*8975f5c5SAndroid Build Coastguard Worker mCompileOptions{}
378*8975f5c5SAndroid Build Coastguard Worker {}
379*8975f5c5SAndroid Build Coastguard Worker
~TCompiler()380*8975f5c5SAndroid Build Coastguard Worker TCompiler::~TCompiler() {}
381*8975f5c5SAndroid Build Coastguard Worker
isHighPrecisionSupported() const382*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::isHighPrecisionSupported() const
383*8975f5c5SAndroid Build Coastguard Worker {
384*8975f5c5SAndroid Build Coastguard Worker return mShaderVersion > 100 || mShaderType != GL_FRAGMENT_SHADER ||
385*8975f5c5SAndroid Build Coastguard Worker mResources.FragmentPrecisionHigh == 1;
386*8975f5c5SAndroid Build Coastguard Worker }
387*8975f5c5SAndroid Build Coastguard Worker
shouldRunLoopAndIndexingValidation(const ShCompileOptions & compileOptions) const388*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const
389*8975f5c5SAndroid Build Coastguard Worker {
390*8975f5c5SAndroid Build Coastguard Worker // If compiling an ESSL 1.00 shader for WebGL, or if its been requested through the API,
391*8975f5c5SAndroid Build Coastguard Worker // validate loop and indexing as well (to verify that the shader only uses minimal functionality
392*8975f5c5SAndroid Build Coastguard Worker // of ESSL 1.00 as in Appendix A of the spec).
393*8975f5c5SAndroid Build Coastguard Worker return (IsWebGLBasedSpec(mShaderSpec) && mShaderVersion == 100) ||
394*8975f5c5SAndroid Build Coastguard Worker compileOptions.validateLoopIndexing;
395*8975f5c5SAndroid Build Coastguard Worker }
396*8975f5c5SAndroid Build Coastguard Worker
shouldLimitTypeSizes() const397*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::shouldLimitTypeSizes() const
398*8975f5c5SAndroid Build Coastguard Worker {
399*8975f5c5SAndroid Build Coastguard Worker // Prevent unrealistically large variable sizes in shaders. This works around driver bugs
400*8975f5c5SAndroid Build Coastguard Worker // around int-size limits (such as 2GB). The limits are generously large enough that no real
401*8975f5c5SAndroid Build Coastguard Worker // shader should ever hit it.
402*8975f5c5SAndroid Build Coastguard Worker //
403*8975f5c5SAndroid Build Coastguard Worker // The size check does not take std430 into account, so this is limited to WebGL and shaders
404*8975f5c5SAndroid Build Coastguard Worker // up to ES3.
405*8975f5c5SAndroid Build Coastguard Worker return mShaderVersion <= 300;
406*8975f5c5SAndroid Build Coastguard Worker }
407*8975f5c5SAndroid Build Coastguard Worker
Init(const ShBuiltInResources & resources)408*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::Init(const ShBuiltInResources &resources)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker SetGlobalPoolAllocator(&allocator);
411*8975f5c5SAndroid Build Coastguard Worker
412*8975f5c5SAndroid Build Coastguard Worker // Generate built-in symbol table.
413*8975f5c5SAndroid Build Coastguard Worker if (!initBuiltInSymbolTable(resources))
414*8975f5c5SAndroid Build Coastguard Worker return false;
415*8975f5c5SAndroid Build Coastguard Worker
416*8975f5c5SAndroid Build Coastguard Worker mResources = resources;
417*8975f5c5SAndroid Build Coastguard Worker setResourceString();
418*8975f5c5SAndroid Build Coastguard Worker
419*8975f5c5SAndroid Build Coastguard Worker InitExtensionBehavior(resources, mExtensionBehavior);
420*8975f5c5SAndroid Build Coastguard Worker return true;
421*8975f5c5SAndroid Build Coastguard Worker }
422*8975f5c5SAndroid Build Coastguard Worker
compileTreeForTesting(const char * const shaderStrings[],size_t numStrings,const ShCompileOptions & compileOptions)423*8975f5c5SAndroid Build Coastguard Worker TIntermBlock *TCompiler::compileTreeForTesting(const char *const shaderStrings[],
424*8975f5c5SAndroid Build Coastguard Worker size_t numStrings,
425*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions)
426*8975f5c5SAndroid Build Coastguard Worker {
427*8975f5c5SAndroid Build Coastguard Worker return compileTreeImpl(shaderStrings, numStrings, compileOptions);
428*8975f5c5SAndroid Build Coastguard Worker }
429*8975f5c5SAndroid Build Coastguard Worker
compileTreeImpl(const char * const shaderStrings[],size_t numStrings,const ShCompileOptions & compileOptions)430*8975f5c5SAndroid Build Coastguard Worker TIntermBlock *TCompiler::compileTreeImpl(const char *const shaderStrings[],
431*8975f5c5SAndroid Build Coastguard Worker size_t numStrings,
432*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions)
433*8975f5c5SAndroid Build Coastguard Worker {
434*8975f5c5SAndroid Build Coastguard Worker // Remember the compile options for helper functions such as validateAST.
435*8975f5c5SAndroid Build Coastguard Worker mCompileOptions = compileOptions;
436*8975f5c5SAndroid Build Coastguard Worker
437*8975f5c5SAndroid Build Coastguard Worker clearResults();
438*8975f5c5SAndroid Build Coastguard Worker
439*8975f5c5SAndroid Build Coastguard Worker ASSERT(numStrings > 0);
440*8975f5c5SAndroid Build Coastguard Worker ASSERT(GetGlobalPoolAllocator());
441*8975f5c5SAndroid Build Coastguard Worker
442*8975f5c5SAndroid Build Coastguard Worker // Reset the extension behavior for each compilation unit.
443*8975f5c5SAndroid Build Coastguard Worker ResetExtensionBehavior(mResources, mExtensionBehavior, compileOptions);
444*8975f5c5SAndroid Build Coastguard Worker
445*8975f5c5SAndroid Build Coastguard Worker // If gl_DrawID is not supported, remove it from the available extensions
446*8975f5c5SAndroid Build Coastguard Worker // Currently we only allow emulation of gl_DrawID
447*8975f5c5SAndroid Build Coastguard Worker const bool glDrawIDSupported = compileOptions.emulateGLDrawID;
448*8975f5c5SAndroid Build Coastguard Worker if (!glDrawIDSupported)
449*8975f5c5SAndroid Build Coastguard Worker {
450*8975f5c5SAndroid Build Coastguard Worker auto it = mExtensionBehavior.find(TExtension::ANGLE_multi_draw);
451*8975f5c5SAndroid Build Coastguard Worker if (it != mExtensionBehavior.end())
452*8975f5c5SAndroid Build Coastguard Worker {
453*8975f5c5SAndroid Build Coastguard Worker mExtensionBehavior.erase(it);
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker }
456*8975f5c5SAndroid Build Coastguard Worker
457*8975f5c5SAndroid Build Coastguard Worker const bool glBaseVertexBaseInstanceSupported = compileOptions.emulateGLBaseVertexBaseInstance;
458*8975f5c5SAndroid Build Coastguard Worker if (!glBaseVertexBaseInstanceSupported)
459*8975f5c5SAndroid Build Coastguard Worker {
460*8975f5c5SAndroid Build Coastguard Worker auto it =
461*8975f5c5SAndroid Build Coastguard Worker mExtensionBehavior.find(TExtension::ANGLE_base_vertex_base_instance_shader_builtin);
462*8975f5c5SAndroid Build Coastguard Worker if (it != mExtensionBehavior.end())
463*8975f5c5SAndroid Build Coastguard Worker {
464*8975f5c5SAndroid Build Coastguard Worker mExtensionBehavior.erase(it);
465*8975f5c5SAndroid Build Coastguard Worker }
466*8975f5c5SAndroid Build Coastguard Worker }
467*8975f5c5SAndroid Build Coastguard Worker
468*8975f5c5SAndroid Build Coastguard Worker // First string is path of source file if flag is set. The actual source follows.
469*8975f5c5SAndroid Build Coastguard Worker size_t firstSource = 0;
470*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.sourcePath)
471*8975f5c5SAndroid Build Coastguard Worker {
472*8975f5c5SAndroid Build Coastguard Worker mSourcePath = shaderStrings[0];
473*8975f5c5SAndroid Build Coastguard Worker ++firstSource;
474*8975f5c5SAndroid Build Coastguard Worker }
475*8975f5c5SAndroid Build Coastguard Worker
476*8975f5c5SAndroid Build Coastguard Worker TParseContext parseContext(mSymbolTable, mExtensionBehavior, mShaderType, mShaderSpec,
477*8975f5c5SAndroid Build Coastguard Worker compileOptions, &mDiagnostics, getResources(), getOutputType());
478*8975f5c5SAndroid Build Coastguard Worker
479*8975f5c5SAndroid Build Coastguard Worker parseContext.setFragmentPrecisionHighOnESSL1(mResources.FragmentPrecisionHigh == 1);
480*8975f5c5SAndroid Build Coastguard Worker
481*8975f5c5SAndroid Build Coastguard Worker // We preserve symbols at the built-in level from compile-to-compile.
482*8975f5c5SAndroid Build Coastguard Worker // Start pushing the user-defined symbols at global level.
483*8975f5c5SAndroid Build Coastguard Worker TScopedSymbolTableLevel globalLevel(&mSymbolTable);
484*8975f5c5SAndroid Build Coastguard Worker ASSERT(mSymbolTable.atGlobalLevel());
485*8975f5c5SAndroid Build Coastguard Worker
486*8975f5c5SAndroid Build Coastguard Worker // Parse shader.
487*8975f5c5SAndroid Build Coastguard Worker if (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], nullptr,
488*8975f5c5SAndroid Build Coastguard Worker &parseContext) != 0)
489*8975f5c5SAndroid Build Coastguard Worker {
490*8975f5c5SAndroid Build Coastguard Worker return nullptr;
491*8975f5c5SAndroid Build Coastguard Worker }
492*8975f5c5SAndroid Build Coastguard Worker
493*8975f5c5SAndroid Build Coastguard Worker if (!postParseChecks(parseContext))
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker return nullptr;
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker
498*8975f5c5SAndroid Build Coastguard Worker setASTMetadata(parseContext);
499*8975f5c5SAndroid Build Coastguard Worker
500*8975f5c5SAndroid Build Coastguard Worker if (!checkShaderVersion(&parseContext))
501*8975f5c5SAndroid Build Coastguard Worker {
502*8975f5c5SAndroid Build Coastguard Worker return nullptr;
503*8975f5c5SAndroid Build Coastguard Worker }
504*8975f5c5SAndroid Build Coastguard Worker
505*8975f5c5SAndroid Build Coastguard Worker TIntermBlock *root = parseContext.getTreeRoot();
506*8975f5c5SAndroid Build Coastguard Worker if (!checkAndSimplifyAST(root, parseContext, compileOptions))
507*8975f5c5SAndroid Build Coastguard Worker {
508*8975f5c5SAndroid Build Coastguard Worker return nullptr;
509*8975f5c5SAndroid Build Coastguard Worker }
510*8975f5c5SAndroid Build Coastguard Worker
511*8975f5c5SAndroid Build Coastguard Worker return root;
512*8975f5c5SAndroid Build Coastguard Worker }
513*8975f5c5SAndroid Build Coastguard Worker
checkShaderVersion(TParseContext * parseContext)514*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::checkShaderVersion(TParseContext *parseContext)
515*8975f5c5SAndroid Build Coastguard Worker {
516*8975f5c5SAndroid Build Coastguard Worker if (GetMaxShaderVersionForSpec(mShaderSpec) < mShaderVersion)
517*8975f5c5SAndroid Build Coastguard Worker {
518*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("unsupported shader version");
519*8975f5c5SAndroid Build Coastguard Worker return false;
520*8975f5c5SAndroid Build Coastguard Worker }
521*8975f5c5SAndroid Build Coastguard Worker
522*8975f5c5SAndroid Build Coastguard Worker ASSERT(parseContext);
523*8975f5c5SAndroid Build Coastguard Worker switch (mShaderType)
524*8975f5c5SAndroid Build Coastguard Worker {
525*8975f5c5SAndroid Build Coastguard Worker case GL_COMPUTE_SHADER:
526*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion < 310)
527*8975f5c5SAndroid Build Coastguard Worker {
528*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("Compute shader is not supported in this shader version.");
529*8975f5c5SAndroid Build Coastguard Worker return false;
530*8975f5c5SAndroid Build Coastguard Worker }
531*8975f5c5SAndroid Build Coastguard Worker break;
532*8975f5c5SAndroid Build Coastguard Worker
533*8975f5c5SAndroid Build Coastguard Worker case GL_GEOMETRY_SHADER_EXT:
534*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion < 310)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError(
537*8975f5c5SAndroid Build Coastguard Worker "Geometry shader is not supported in this shader version.");
538*8975f5c5SAndroid Build Coastguard Worker return false;
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker else if (mShaderVersion == 310)
541*8975f5c5SAndroid Build Coastguard Worker {
542*8975f5c5SAndroid Build Coastguard Worker if (!parseContext->checkCanUseOneOfExtensions(
543*8975f5c5SAndroid Build Coastguard Worker sh::TSourceLoc(),
544*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 2u>{
545*8975f5c5SAndroid Build Coastguard Worker {TExtension::EXT_geometry_shader, TExtension::OES_geometry_shader}}))
546*8975f5c5SAndroid Build Coastguard Worker {
547*8975f5c5SAndroid Build Coastguard Worker return false;
548*8975f5c5SAndroid Build Coastguard Worker }
549*8975f5c5SAndroid Build Coastguard Worker }
550*8975f5c5SAndroid Build Coastguard Worker break;
551*8975f5c5SAndroid Build Coastguard Worker
552*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_CONTROL_SHADER_EXT:
553*8975f5c5SAndroid Build Coastguard Worker case GL_TESS_EVALUATION_SHADER_EXT:
554*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion < 310)
555*8975f5c5SAndroid Build Coastguard Worker {
556*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError(
557*8975f5c5SAndroid Build Coastguard Worker "Tessellation shaders are not supported in this shader version.");
558*8975f5c5SAndroid Build Coastguard Worker return false;
559*8975f5c5SAndroid Build Coastguard Worker }
560*8975f5c5SAndroid Build Coastguard Worker else if (mShaderVersion == 310)
561*8975f5c5SAndroid Build Coastguard Worker {
562*8975f5c5SAndroid Build Coastguard Worker if (!parseContext->checkCanUseOneOfExtensions(
563*8975f5c5SAndroid Build Coastguard Worker sh::TSourceLoc(),
564*8975f5c5SAndroid Build Coastguard Worker std::array<TExtension, 2u>{{TExtension::EXT_tessellation_shader,
565*8975f5c5SAndroid Build Coastguard Worker TExtension::OES_tessellation_shader}}))
566*8975f5c5SAndroid Build Coastguard Worker {
567*8975f5c5SAndroid Build Coastguard Worker return false;
568*8975f5c5SAndroid Build Coastguard Worker }
569*8975f5c5SAndroid Build Coastguard Worker }
570*8975f5c5SAndroid Build Coastguard Worker break;
571*8975f5c5SAndroid Build Coastguard Worker
572*8975f5c5SAndroid Build Coastguard Worker default:
573*8975f5c5SAndroid Build Coastguard Worker break;
574*8975f5c5SAndroid Build Coastguard Worker }
575*8975f5c5SAndroid Build Coastguard Worker
576*8975f5c5SAndroid Build Coastguard Worker return true;
577*8975f5c5SAndroid Build Coastguard Worker }
578*8975f5c5SAndroid Build Coastguard Worker
setASTMetadata(const TParseContext & parseContext)579*8975f5c5SAndroid Build Coastguard Worker void TCompiler::setASTMetadata(const TParseContext &parseContext)
580*8975f5c5SAndroid Build Coastguard Worker {
581*8975f5c5SAndroid Build Coastguard Worker mShaderVersion = parseContext.getShaderVersion();
582*8975f5c5SAndroid Build Coastguard Worker
583*8975f5c5SAndroid Build Coastguard Worker mPragma = parseContext.pragma();
584*8975f5c5SAndroid Build Coastguard Worker mSymbolTable.setGlobalInvariant(mPragma.stdgl.invariantAll);
585*8975f5c5SAndroid Build Coastguard Worker
586*8975f5c5SAndroid Build Coastguard Worker mEarlyFragmentTestsSpecified = parseContext.isEarlyFragmentTestsSpecified();
587*8975f5c5SAndroid Build Coastguard Worker
588*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasDiscard] = parseContext.hasDiscard();
589*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::EnablesPerSampleShading] =
590*8975f5c5SAndroid Build Coastguard Worker parseContext.isSampleQualifierSpecified();
591*8975f5c5SAndroid Build Coastguard Worker
592*8975f5c5SAndroid Build Coastguard Worker mComputeShaderLocalSizeDeclared = parseContext.isComputeShaderLocalSizeDeclared();
593*8975f5c5SAndroid Build Coastguard Worker mComputeShaderLocalSize = parseContext.getComputeShaderLocalSize();
594*8975f5c5SAndroid Build Coastguard Worker
595*8975f5c5SAndroid Build Coastguard Worker mNumViews = parseContext.getNumViews();
596*8975f5c5SAndroid Build Coastguard Worker
597*8975f5c5SAndroid Build Coastguard Worker mHasAnyPreciseType = parseContext.hasAnyPreciseType();
598*8975f5c5SAndroid Build Coastguard Worker
599*8975f5c5SAndroid Build Coastguard Worker mUsesDerivatives = parseContext.usesDerivatives();
600*8975f5c5SAndroid Build Coastguard Worker
601*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_FRAGMENT_SHADER)
602*8975f5c5SAndroid Build Coastguard Worker {
603*8975f5c5SAndroid Build Coastguard Worker mAdvancedBlendEquations = parseContext.getAdvancedBlendEquations();
604*8975f5c5SAndroid Build Coastguard Worker const std::map<int, ShPixelLocalStorageFormat> &plsFormats =
605*8975f5c5SAndroid Build Coastguard Worker parseContext.pixelLocalStorageFormats();
606*8975f5c5SAndroid Build Coastguard Worker // std::map keys are in sorted order, so the PLS uniform with the largest binding will be at
607*8975f5c5SAndroid Build Coastguard Worker // rbegin().
608*8975f5c5SAndroid Build Coastguard Worker mPixelLocalStorageFormats.resize(plsFormats.empty() ? 0 : plsFormats.rbegin()->first + 1,
609*8975f5c5SAndroid Build Coastguard Worker ShPixelLocalStorageFormat::NotPLS);
610*8975f5c5SAndroid Build Coastguard Worker for (auto [binding, format] : parseContext.pixelLocalStorageFormats())
611*8975f5c5SAndroid Build Coastguard Worker {
612*8975f5c5SAndroid Build Coastguard Worker mPixelLocalStorageFormats[binding] = format;
613*8975f5c5SAndroid Build Coastguard Worker }
614*8975f5c5SAndroid Build Coastguard Worker }
615*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_GEOMETRY_SHADER_EXT)
616*8975f5c5SAndroid Build Coastguard Worker {
617*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInputPrimitiveType = parseContext.getGeometryShaderInputPrimitiveType();
618*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderOutputPrimitiveType = parseContext.getGeometryShaderOutputPrimitiveType();
619*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderMaxVertices = parseContext.getGeometryShaderMaxVertices();
620*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInvocations = parseContext.getGeometryShaderInvocations();
621*8975f5c5SAndroid Build Coastguard Worker
622*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidGeometryShaderInputPrimitiveType] =
623*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInputPrimitiveType != EptUndefined;
624*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidGeometryShaderOutputPrimitiveType] =
625*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderOutputPrimitiveType != EptUndefined;
626*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidGeometryShaderMaxVertices] =
627*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderMaxVertices >= 0;
628*8975f5c5SAndroid Build Coastguard Worker }
629*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_TESS_CONTROL_SHADER_EXT)
630*8975f5c5SAndroid Build Coastguard Worker {
631*8975f5c5SAndroid Build Coastguard Worker mTessControlShaderOutputVertices = parseContext.getTessControlShaderOutputVertices();
632*8975f5c5SAndroid Build Coastguard Worker }
633*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_TESS_EVALUATION_SHADER_EXT)
634*8975f5c5SAndroid Build Coastguard Worker {
635*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPrimitiveType =
636*8975f5c5SAndroid Build Coastguard Worker parseContext.getTessEvaluationShaderInputPrimitiveType();
637*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputVertexSpacingType =
638*8975f5c5SAndroid Build Coastguard Worker parseContext.getTessEvaluationShaderInputVertexSpacingType();
639*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputOrderingType =
640*8975f5c5SAndroid Build Coastguard Worker parseContext.getTessEvaluationShaderInputOrderingType();
641*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPointType = parseContext.getTessEvaluationShaderInputPointType();
642*8975f5c5SAndroid Build Coastguard Worker
643*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidTessGenMode] =
644*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPrimitiveType != EtetUndefined;
645*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidTessGenSpacing] =
646*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputVertexSpacingType != EtetUndefined;
647*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidTessGenVertexOrder] =
648*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputOrderingType != EtetUndefined;
649*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasValidTessGenPointMode] =
650*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPointType != EtetUndefined;
651*8975f5c5SAndroid Build Coastguard Worker }
652*8975f5c5SAndroid Build Coastguard Worker }
653*8975f5c5SAndroid Build Coastguard Worker
getSharedMemorySize() const654*8975f5c5SAndroid Build Coastguard Worker unsigned int TCompiler::getSharedMemorySize() const
655*8975f5c5SAndroid Build Coastguard Worker {
656*8975f5c5SAndroid Build Coastguard Worker unsigned int sharedMemSize = 0;
657*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &var : mSharedVariables)
658*8975f5c5SAndroid Build Coastguard Worker {
659*8975f5c5SAndroid Build Coastguard Worker sharedMemSize += var.getExternalSize();
660*8975f5c5SAndroid Build Coastguard Worker }
661*8975f5c5SAndroid Build Coastguard Worker
662*8975f5c5SAndroid Build Coastguard Worker return sharedMemSize;
663*8975f5c5SAndroid Build Coastguard Worker }
664*8975f5c5SAndroid Build Coastguard Worker
getShaderBinary(const ShHandle compilerHandle,const char * const shaderStrings[],size_t numStrings,const ShCompileOptions & compileOptions,ShaderBinaryBlob * const binaryOut)665*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::getShaderBinary(const ShHandle compilerHandle,
666*8975f5c5SAndroid Build Coastguard Worker const char *const shaderStrings[],
667*8975f5c5SAndroid Build Coastguard Worker size_t numStrings,
668*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions,
669*8975f5c5SAndroid Build Coastguard Worker ShaderBinaryBlob *const binaryOut)
670*8975f5c5SAndroid Build Coastguard Worker {
671*8975f5c5SAndroid Build Coastguard Worker if (!compile(shaderStrings, numStrings, compileOptions))
672*8975f5c5SAndroid Build Coastguard Worker {
673*8975f5c5SAndroid Build Coastguard Worker return false;
674*8975f5c5SAndroid Build Coastguard Worker }
675*8975f5c5SAndroid Build Coastguard Worker
676*8975f5c5SAndroid Build Coastguard Worker gl::BinaryOutputStream stream;
677*8975f5c5SAndroid Build Coastguard Worker gl::ShaderType shaderType = gl::FromGLenum<gl::ShaderType>(mShaderType);
678*8975f5c5SAndroid Build Coastguard Worker gl::CompiledShaderState state(shaderType);
679*8975f5c5SAndroid Build Coastguard Worker state.buildCompiledShaderState(compilerHandle, IsOutputSPIRV(mOutputType));
680*8975f5c5SAndroid Build Coastguard Worker
681*8975f5c5SAndroid Build Coastguard Worker stream.writeBytes(
682*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<const unsigned char *>(angle::GetANGLEShaderProgramVersion()),
683*8975f5c5SAndroid Build Coastguard Worker angle::GetANGLEShaderProgramVersionHashSize());
684*8975f5c5SAndroid Build Coastguard Worker stream.writeEnum(shaderType);
685*8975f5c5SAndroid Build Coastguard Worker stream.writeEnum(mOutputType);
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker // Serialize the full source string for the shader. Ignore the source path if it is provided.
688*8975f5c5SAndroid Build Coastguard Worker std::string sourceString;
689*8975f5c5SAndroid Build Coastguard Worker size_t startingIndex = compileOptions.sourcePath ? 1 : 0;
690*8975f5c5SAndroid Build Coastguard Worker for (size_t i = startingIndex; i < numStrings; ++i)
691*8975f5c5SAndroid Build Coastguard Worker {
692*8975f5c5SAndroid Build Coastguard Worker sourceString.append(shaderStrings[i]);
693*8975f5c5SAndroid Build Coastguard Worker }
694*8975f5c5SAndroid Build Coastguard Worker stream.writeString(sourceString);
695*8975f5c5SAndroid Build Coastguard Worker
696*8975f5c5SAndroid Build Coastguard Worker stream.writeBytes(reinterpret_cast<const uint8_t *>(&compileOptions), sizeof(compileOptions));
697*8975f5c5SAndroid Build Coastguard Worker stream.writeBytes(reinterpret_cast<const uint8_t *>(&mResources), sizeof(mResources));
698*8975f5c5SAndroid Build Coastguard Worker
699*8975f5c5SAndroid Build Coastguard Worker state.serialize(stream);
700*8975f5c5SAndroid Build Coastguard Worker
701*8975f5c5SAndroid Build Coastguard Worker ASSERT(binaryOut);
702*8975f5c5SAndroid Build Coastguard Worker *binaryOut = std::move(stream.getData());
703*8975f5c5SAndroid Build Coastguard Worker return true;
704*8975f5c5SAndroid Build Coastguard Worker }
705*8975f5c5SAndroid Build Coastguard Worker
validateAST(TIntermNode * root)706*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::validateAST(TIntermNode *root)
707*8975f5c5SAndroid Build Coastguard Worker {
708*8975f5c5SAndroid Build Coastguard Worker if (mCompileOptions.validateAST)
709*8975f5c5SAndroid Build Coastguard Worker {
710*8975f5c5SAndroid Build Coastguard Worker bool valid = ValidateAST(root, &mDiagnostics, mValidateASTOptions);
711*8975f5c5SAndroid Build Coastguard Worker
712*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
713*8975f5c5SAndroid Build Coastguard Worker if (!valid)
714*8975f5c5SAndroid Build Coastguard Worker {
715*8975f5c5SAndroid Build Coastguard Worker OutputTree(root, mInfoSink.info);
716*8975f5c5SAndroid Build Coastguard Worker fprintf(stderr, "AST validation error(s):\n%s\n", mInfoSink.info.c_str());
717*8975f5c5SAndroid Build Coastguard Worker }
718*8975f5c5SAndroid Build Coastguard Worker #endif
719*8975f5c5SAndroid Build Coastguard Worker // In debug, assert validation. In release, validation errors will be returned back to the
720*8975f5c5SAndroid Build Coastguard Worker // application as internal ANGLE errors.
721*8975f5c5SAndroid Build Coastguard Worker ASSERT(valid);
722*8975f5c5SAndroid Build Coastguard Worker
723*8975f5c5SAndroid Build Coastguard Worker return valid;
724*8975f5c5SAndroid Build Coastguard Worker }
725*8975f5c5SAndroid Build Coastguard Worker return true;
726*8975f5c5SAndroid Build Coastguard Worker }
727*8975f5c5SAndroid Build Coastguard Worker
disableValidateFunctionCall()728*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::disableValidateFunctionCall()
729*8975f5c5SAndroid Build Coastguard Worker {
730*8975f5c5SAndroid Build Coastguard Worker bool wasEnabled = mValidateASTOptions.validateFunctionCall;
731*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateFunctionCall = false;
732*8975f5c5SAndroid Build Coastguard Worker return wasEnabled;
733*8975f5c5SAndroid Build Coastguard Worker }
734*8975f5c5SAndroid Build Coastguard Worker
restoreValidateFunctionCall(bool enable)735*8975f5c5SAndroid Build Coastguard Worker void TCompiler::restoreValidateFunctionCall(bool enable)
736*8975f5c5SAndroid Build Coastguard Worker {
737*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mValidateASTOptions.validateFunctionCall);
738*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateFunctionCall = enable;
739*8975f5c5SAndroid Build Coastguard Worker }
740*8975f5c5SAndroid Build Coastguard Worker
disableValidateVariableReferences()741*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::disableValidateVariableReferences()
742*8975f5c5SAndroid Build Coastguard Worker {
743*8975f5c5SAndroid Build Coastguard Worker bool wasEnabled = mValidateASTOptions.validateVariableReferences;
744*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateVariableReferences = false;
745*8975f5c5SAndroid Build Coastguard Worker return wasEnabled;
746*8975f5c5SAndroid Build Coastguard Worker }
747*8975f5c5SAndroid Build Coastguard Worker
restoreValidateVariableReferences(bool enable)748*8975f5c5SAndroid Build Coastguard Worker void TCompiler::restoreValidateVariableReferences(bool enable)
749*8975f5c5SAndroid Build Coastguard Worker {
750*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mValidateASTOptions.validateVariableReferences);
751*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateVariableReferences = enable;
752*8975f5c5SAndroid Build Coastguard Worker }
753*8975f5c5SAndroid Build Coastguard Worker
enableValidateNoMoreTransformations()754*8975f5c5SAndroid Build Coastguard Worker void TCompiler::enableValidateNoMoreTransformations()
755*8975f5c5SAndroid Build Coastguard Worker {
756*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateNoMoreTransformations = true;
757*8975f5c5SAndroid Build Coastguard Worker }
758*8975f5c5SAndroid Build Coastguard Worker
checkAndSimplifyAST(TIntermBlock * root,const TParseContext & parseContext,const ShCompileOptions & compileOptions)759*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
760*8975f5c5SAndroid Build Coastguard Worker const TParseContext &parseContext,
761*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptions)
762*8975f5c5SAndroid Build Coastguard Worker {
763*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions = {};
764*8975f5c5SAndroid Build Coastguard Worker
765*8975f5c5SAndroid Build Coastguard Worker // Disallow expressions deemed too complex.
766*8975f5c5SAndroid Build Coastguard Worker // This needs to be checked before other functions that will traverse the AST
767*8975f5c5SAndroid Build Coastguard Worker // to prevent potential stack overflow crashes.
768*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.limitExpressionComplexity && !limitExpressionComplexity(root))
769*8975f5c5SAndroid Build Coastguard Worker {
770*8975f5c5SAndroid Build Coastguard Worker return false;
771*8975f5c5SAndroid Build Coastguard Worker }
772*8975f5c5SAndroid Build Coastguard Worker
773*8975f5c5SAndroid Build Coastguard Worker if (!validateAST(root))
774*8975f5c5SAndroid Build Coastguard Worker {
775*8975f5c5SAndroid Build Coastguard Worker return false;
776*8975f5c5SAndroid Build Coastguard Worker }
777*8975f5c5SAndroid Build Coastguard Worker
778*8975f5c5SAndroid Build Coastguard Worker // For now, rewrite pixel local storage before collecting variables or any operations on images.
779*8975f5c5SAndroid Build Coastguard Worker //
780*8975f5c5SAndroid Build Coastguard Worker // TODO(anglebug.com/40096838):
781*8975f5c5SAndroid Build Coastguard Worker // Should this actually run after collecting variables?
782*8975f5c5SAndroid Build Coastguard Worker // Do we need more introspection?
783*8975f5c5SAndroid Build Coastguard Worker // Do we want to hide rewritten shader image uniforms from glGetActiveUniform?
784*8975f5c5SAndroid Build Coastguard Worker if (hasPixelLocalStorageUniforms())
785*8975f5c5SAndroid Build Coastguard Worker {
786*8975f5c5SAndroid Build Coastguard Worker ASSERT(
787*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage));
788*8975f5c5SAndroid Build Coastguard Worker if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions,
789*8975f5c5SAndroid Build Coastguard Worker getShaderVersion()))
790*8975f5c5SAndroid Build Coastguard Worker {
791*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("internal compiler error translating pixel local storage");
792*8975f5c5SAndroid Build Coastguard Worker return false;
793*8975f5c5SAndroid Build Coastguard Worker }
794*8975f5c5SAndroid Build Coastguard Worker }
795*8975f5c5SAndroid Build Coastguard Worker
796*8975f5c5SAndroid Build Coastguard Worker if (shouldRunLoopAndIndexingValidation(compileOptions) &&
797*8975f5c5SAndroid Build Coastguard Worker !ValidateLimitations(root, mShaderType, &mSymbolTable, &mDiagnostics))
798*8975f5c5SAndroid Build Coastguard Worker {
799*8975f5c5SAndroid Build Coastguard Worker return false;
800*8975f5c5SAndroid Build Coastguard Worker }
801*8975f5c5SAndroid Build Coastguard Worker
802*8975f5c5SAndroid Build Coastguard Worker if (!ValidateFragColorAndFragData(mShaderType, mShaderVersion, mSymbolTable, &mDiagnostics))
803*8975f5c5SAndroid Build Coastguard Worker {
804*8975f5c5SAndroid Build Coastguard Worker return false;
805*8975f5c5SAndroid Build Coastguard Worker }
806*8975f5c5SAndroid Build Coastguard Worker
807*8975f5c5SAndroid Build Coastguard Worker // Fold expressions that could not be folded before validation that was done as a part of
808*8975f5c5SAndroid Build Coastguard Worker // parsing.
809*8975f5c5SAndroid Build Coastguard Worker if (!FoldExpressions(this, root, &mDiagnostics))
810*8975f5c5SAndroid Build Coastguard Worker {
811*8975f5c5SAndroid Build Coastguard Worker return false;
812*8975f5c5SAndroid Build Coastguard Worker }
813*8975f5c5SAndroid Build Coastguard Worker // Folding should only be able to generate warnings.
814*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDiagnostics.numErrors() == 0);
815*8975f5c5SAndroid Build Coastguard Worker
816*8975f5c5SAndroid Build Coastguard Worker // gl_ClipDistance and gl_CullDistance built-in arrays have unique semantics.
817*8975f5c5SAndroid Build Coastguard Worker // They are pre-declared as unsized and must be sized by the shader either
818*8975f5c5SAndroid Build Coastguard Worker // redeclaring them or indexing them only with integral constant expressions.
819*8975f5c5SAndroid Build Coastguard Worker // The translator treats them as having the maximum allowed size and this pass
820*8975f5c5SAndroid Build Coastguard Worker // detects the actual sizes resizing the variables if needed.
821*8975f5c5SAndroid Build Coastguard Worker if (parseContext.isExtensionEnabled(TExtension::ANGLE_clip_cull_distance) ||
822*8975f5c5SAndroid Build Coastguard Worker parseContext.isExtensionEnabled(TExtension::EXT_clip_cull_distance) ||
823*8975f5c5SAndroid Build Coastguard Worker parseContext.isExtensionEnabled(TExtension::APPLE_clip_distance))
824*8975f5c5SAndroid Build Coastguard Worker {
825*8975f5c5SAndroid Build Coastguard Worker bool isClipDistanceUsed = false;
826*8975f5c5SAndroid Build Coastguard Worker if (!ValidateClipCullDistance(this, root, &mDiagnostics,
827*8975f5c5SAndroid Build Coastguard Worker mResources.MaxCombinedClipAndCullDistances,
828*8975f5c5SAndroid Build Coastguard Worker &mClipDistanceSize, &mCullDistanceSize, &isClipDistanceUsed))
829*8975f5c5SAndroid Build Coastguard Worker {
830*8975f5c5SAndroid Build Coastguard Worker return false;
831*8975f5c5SAndroid Build Coastguard Worker }
832*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags[MetadataFlags::HasClipDistance] = isClipDistanceUsed;
833*8975f5c5SAndroid Build Coastguard Worker }
834*8975f5c5SAndroid Build Coastguard Worker
835*8975f5c5SAndroid Build Coastguard Worker // Validate no barrier() after return before prunning it in |PruneNoOps()| below.
836*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_TESS_CONTROL_SHADER && !ValidateBarrierFunctionCall(root, &mDiagnostics))
837*8975f5c5SAndroid Build Coastguard Worker {
838*8975f5c5SAndroid Build Coastguard Worker return false;
839*8975f5c5SAndroid Build Coastguard Worker }
840*8975f5c5SAndroid Build Coastguard Worker
841*8975f5c5SAndroid Build Coastguard Worker // We prune no-ops to work around driver bugs and to keep AST processing and output simple.
842*8975f5c5SAndroid Build Coastguard Worker // The following kinds of no-ops are pruned:
843*8975f5c5SAndroid Build Coastguard Worker // 1. Empty declarations "int;".
844*8975f5c5SAndroid Build Coastguard Worker // 2. Literal statements: "1.0;". The ESSL output doesn't define a default precision
845*8975f5c5SAndroid Build Coastguard Worker // for float, so float literal statements would end up with no precision which is
846*8975f5c5SAndroid Build Coastguard Worker // invalid ESSL.
847*8975f5c5SAndroid Build Coastguard Worker // 3. Any unreachable statement after a discard, return, break or continue.
848*8975f5c5SAndroid Build Coastguard Worker // After this empty declarations are not allowed in the AST.
849*8975f5c5SAndroid Build Coastguard Worker if (!PruneNoOps(this, root, &mSymbolTable))
850*8975f5c5SAndroid Build Coastguard Worker {
851*8975f5c5SAndroid Build Coastguard Worker return false;
852*8975f5c5SAndroid Build Coastguard Worker }
853*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateNoStatementsAfterBranch = true;
854*8975f5c5SAndroid Build Coastguard Worker
855*8975f5c5SAndroid Build Coastguard Worker // We need to generate globals early if we have non constant initializers enabled
856*8975f5c5SAndroid Build Coastguard Worker bool initializeLocalsAndGlobals =
857*8975f5c5SAndroid Build Coastguard Worker compileOptions.initializeUninitializedLocals && !IsOutputHLSL(getOutputType());
858*8975f5c5SAndroid Build Coastguard Worker bool canUseLoopsToInitialize = !compileOptions.dontUseLoopsToInitializeVariables;
859*8975f5c5SAndroid Build Coastguard Worker bool highPrecisionSupported = isHighPrecisionSupported();
860*8975f5c5SAndroid Build Coastguard Worker bool enableNonConstantInitializers = IsExtensionEnabled(
861*8975f5c5SAndroid Build Coastguard Worker mExtensionBehavior, TExtension::EXT_shader_non_constant_global_initializers);
862*8975f5c5SAndroid Build Coastguard Worker // forceDeferNonConstGlobalInitializers is needed for MSL
863*8975f5c5SAndroid Build Coastguard Worker // to convert a non-const global. For example:
864*8975f5c5SAndroid Build Coastguard Worker //
865*8975f5c5SAndroid Build Coastguard Worker // int someGlobal = 123;
866*8975f5c5SAndroid Build Coastguard Worker //
867*8975f5c5SAndroid Build Coastguard Worker // to
868*8975f5c5SAndroid Build Coastguard Worker //
869*8975f5c5SAndroid Build Coastguard Worker // int someGlobal;
870*8975f5c5SAndroid Build Coastguard Worker // void main() {
871*8975f5c5SAndroid Build Coastguard Worker // someGlobal = 123;
872*8975f5c5SAndroid Build Coastguard Worker //
873*8975f5c5SAndroid Build Coastguard Worker // This is because MSL doesn't allow statically initialized non-const globals.
874*8975f5c5SAndroid Build Coastguard Worker bool forceDeferNonConstGlobalInitializers = getOutputType() == SH_MSL_METAL_OUTPUT;
875*8975f5c5SAndroid Build Coastguard Worker
876*8975f5c5SAndroid Build Coastguard Worker if (enableNonConstantInitializers &&
877*8975f5c5SAndroid Build Coastguard Worker !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
878*8975f5c5SAndroid Build Coastguard Worker highPrecisionSupported, forceDeferNonConstGlobalInitializers,
879*8975f5c5SAndroid Build Coastguard Worker &mSymbolTable))
880*8975f5c5SAndroid Build Coastguard Worker {
881*8975f5c5SAndroid Build Coastguard Worker return false;
882*8975f5c5SAndroid Build Coastguard Worker }
883*8975f5c5SAndroid Build Coastguard Worker
884*8975f5c5SAndroid Build Coastguard Worker // Create the function DAG and check there is no recursion
885*8975f5c5SAndroid Build Coastguard Worker if (!initCallDag(root))
886*8975f5c5SAndroid Build Coastguard Worker {
887*8975f5c5SAndroid Build Coastguard Worker return false;
888*8975f5c5SAndroid Build Coastguard Worker }
889*8975f5c5SAndroid Build Coastguard Worker
890*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.limitCallStackDepth && !checkCallDepth())
891*8975f5c5SAndroid Build Coastguard Worker {
892*8975f5c5SAndroid Build Coastguard Worker return false;
893*8975f5c5SAndroid Build Coastguard Worker }
894*8975f5c5SAndroid Build Coastguard Worker
895*8975f5c5SAndroid Build Coastguard Worker // Checks which functions are used and if "main" exists
896*8975f5c5SAndroid Build Coastguard Worker mFunctionMetadata.clear();
897*8975f5c5SAndroid Build Coastguard Worker mFunctionMetadata.resize(mCallDag.size());
898*8975f5c5SAndroid Build Coastguard Worker if (!tagUsedFunctions())
899*8975f5c5SAndroid Build Coastguard Worker {
900*8975f5c5SAndroid Build Coastguard Worker return false;
901*8975f5c5SAndroid Build Coastguard Worker }
902*8975f5c5SAndroid Build Coastguard Worker
903*8975f5c5SAndroid Build Coastguard Worker if (!pruneUnusedFunctions(root))
904*8975f5c5SAndroid Build Coastguard Worker {
905*8975f5c5SAndroid Build Coastguard Worker return false;
906*8975f5c5SAndroid Build Coastguard Worker }
907*8975f5c5SAndroid Build Coastguard Worker
908*8975f5c5SAndroid Build Coastguard Worker if (IsSpecWithFunctionBodyNewScope(mShaderSpec, mShaderVersion))
909*8975f5c5SAndroid Build Coastguard Worker {
910*8975f5c5SAndroid Build Coastguard Worker if (!ReplaceShadowingVariables(this, root, &mSymbolTable))
911*8975f5c5SAndroid Build Coastguard Worker {
912*8975f5c5SAndroid Build Coastguard Worker return false;
913*8975f5c5SAndroid Build Coastguard Worker }
914*8975f5c5SAndroid Build Coastguard Worker }
915*8975f5c5SAndroid Build Coastguard Worker
916*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion >= 310 && !ValidateVaryingLocations(root, &mDiagnostics, mShaderType))
917*8975f5c5SAndroid Build Coastguard Worker {
918*8975f5c5SAndroid Build Coastguard Worker return false;
919*8975f5c5SAndroid Build Coastguard Worker }
920*8975f5c5SAndroid Build Coastguard Worker
921*8975f5c5SAndroid Build Coastguard Worker // anglebug.com/42265954: The ESSL spec has a bug with images as function arguments. The
922*8975f5c5SAndroid Build Coastguard Worker // recommended workaround is to inline functions that accept image arguments.
923*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion >= 310 && !MonomorphizeUnsupportedFunctions(
924*8975f5c5SAndroid Build Coastguard Worker this, root, &mSymbolTable,
925*8975f5c5SAndroid Build Coastguard Worker UnsupportedFunctionArgsBitSet{UnsupportedFunctionArgs::Image}))
926*8975f5c5SAndroid Build Coastguard Worker {
927*8975f5c5SAndroid Build Coastguard Worker return false;
928*8975f5c5SAndroid Build Coastguard Worker }
929*8975f5c5SAndroid Build Coastguard Worker
930*8975f5c5SAndroid Build Coastguard Worker if (mShaderVersion >= 300 && mShaderType == GL_FRAGMENT_SHADER &&
931*8975f5c5SAndroid Build Coastguard Worker !ValidateOutputs(root, getExtensionBehavior(), mResources, hasPixelLocalStorageUniforms(),
932*8975f5c5SAndroid Build Coastguard Worker IsWebGLBasedSpec(mShaderSpec), &mDiagnostics))
933*8975f5c5SAndroid Build Coastguard Worker {
934*8975f5c5SAndroid Build Coastguard Worker return false;
935*8975f5c5SAndroid Build Coastguard Worker }
936*8975f5c5SAndroid Build Coastguard Worker
937*8975f5c5SAndroid Build Coastguard Worker // Clamping uniform array bounds needs to happen after validateLimitations pass.
938*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.clampIndirectArrayBounds)
939*8975f5c5SAndroid Build Coastguard Worker {
940*8975f5c5SAndroid Build Coastguard Worker if (!ClampIndirectIndices(this, root, &mSymbolTable))
941*8975f5c5SAndroid Build Coastguard Worker {
942*8975f5c5SAndroid Build Coastguard Worker return false;
943*8975f5c5SAndroid Build Coastguard Worker }
944*8975f5c5SAndroid Build Coastguard Worker }
945*8975f5c5SAndroid Build Coastguard Worker
946*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.initializeBuiltinsForInstancedMultiview &&
947*8975f5c5SAndroid Build Coastguard Worker (parseContext.isExtensionEnabled(TExtension::OVR_multiview2) ||
948*8975f5c5SAndroid Build Coastguard Worker parseContext.isExtensionEnabled(TExtension::OVR_multiview)) &&
949*8975f5c5SAndroid Build Coastguard Worker getShaderType() != GL_COMPUTE_SHADER)
950*8975f5c5SAndroid Build Coastguard Worker {
951*8975f5c5SAndroid Build Coastguard Worker if (!DeclareAndInitBuiltinsForInstancedMultiview(
952*8975f5c5SAndroid Build Coastguard Worker this, root, mNumViews, mShaderType, compileOptions, mOutputType, &mSymbolTable))
953*8975f5c5SAndroid Build Coastguard Worker {
954*8975f5c5SAndroid Build Coastguard Worker return false;
955*8975f5c5SAndroid Build Coastguard Worker }
956*8975f5c5SAndroid Build Coastguard Worker }
957*8975f5c5SAndroid Build Coastguard Worker
958*8975f5c5SAndroid Build Coastguard Worker // This pass might emit short circuits so keep it before the short circuit unfolding
959*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.rewriteDoWhileLoops)
960*8975f5c5SAndroid Build Coastguard Worker {
961*8975f5c5SAndroid Build Coastguard Worker if (!RewriteDoWhile(this, root, &mSymbolTable))
962*8975f5c5SAndroid Build Coastguard Worker {
963*8975f5c5SAndroid Build Coastguard Worker return false;
964*8975f5c5SAndroid Build Coastguard Worker }
965*8975f5c5SAndroid Build Coastguard Worker }
966*8975f5c5SAndroid Build Coastguard Worker
967*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.addAndTrueToLoopCondition)
968*8975f5c5SAndroid Build Coastguard Worker {
969*8975f5c5SAndroid Build Coastguard Worker if (!AddAndTrueToLoopCondition(this, root))
970*8975f5c5SAndroid Build Coastguard Worker {
971*8975f5c5SAndroid Build Coastguard Worker return false;
972*8975f5c5SAndroid Build Coastguard Worker }
973*8975f5c5SAndroid Build Coastguard Worker }
974*8975f5c5SAndroid Build Coastguard Worker
975*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.unfoldShortCircuit)
976*8975f5c5SAndroid Build Coastguard Worker {
977*8975f5c5SAndroid Build Coastguard Worker if (!UnfoldShortCircuitAST(this, root))
978*8975f5c5SAndroid Build Coastguard Worker {
979*8975f5c5SAndroid Build Coastguard Worker return false;
980*8975f5c5SAndroid Build Coastguard Worker }
981*8975f5c5SAndroid Build Coastguard Worker }
982*8975f5c5SAndroid Build Coastguard Worker
983*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.regenerateStructNames)
984*8975f5c5SAndroid Build Coastguard Worker {
985*8975f5c5SAndroid Build Coastguard Worker if (!RegenerateStructNames(this, root, &mSymbolTable))
986*8975f5c5SAndroid Build Coastguard Worker {
987*8975f5c5SAndroid Build Coastguard Worker return false;
988*8975f5c5SAndroid Build Coastguard Worker }
989*8975f5c5SAndroid Build Coastguard Worker }
990*8975f5c5SAndroid Build Coastguard Worker
991*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER &&
992*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw))
993*8975f5c5SAndroid Build Coastguard Worker {
994*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.emulateGLDrawID)
995*8975f5c5SAndroid Build Coastguard Worker {
996*8975f5c5SAndroid Build Coastguard Worker if (!EmulateGLDrawID(this, root, &mSymbolTable, &mUniforms))
997*8975f5c5SAndroid Build Coastguard Worker {
998*8975f5c5SAndroid Build Coastguard Worker return false;
999*8975f5c5SAndroid Build Coastguard Worker }
1000*8975f5c5SAndroid Build Coastguard Worker }
1001*8975f5c5SAndroid Build Coastguard Worker }
1002*8975f5c5SAndroid Build Coastguard Worker
1003*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER &&
1004*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior,
1005*8975f5c5SAndroid Build Coastguard Worker TExtension::ANGLE_base_vertex_base_instance_shader_builtin))
1006*8975f5c5SAndroid Build Coastguard Worker {
1007*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.emulateGLBaseVertexBaseInstance)
1008*8975f5c5SAndroid Build Coastguard Worker {
1009*8975f5c5SAndroid Build Coastguard Worker if (!EmulateGLBaseVertexBaseInstance(this, root, &mSymbolTable, &mUniforms,
1010*8975f5c5SAndroid Build Coastguard Worker compileOptions.addBaseVertexToVertexID))
1011*8975f5c5SAndroid Build Coastguard Worker {
1012*8975f5c5SAndroid Build Coastguard Worker return false;
1013*8975f5c5SAndroid Build Coastguard Worker }
1014*8975f5c5SAndroid Build Coastguard Worker }
1015*8975f5c5SAndroid Build Coastguard Worker }
1016*8975f5c5SAndroid Build Coastguard Worker
1017*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_FRAGMENT_SHADER && mShaderVersion == 100 && mResources.EXT_draw_buffers &&
1018*8975f5c5SAndroid Build Coastguard Worker mResources.MaxDrawBuffers > 1 &&
1019*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior, TExtension::EXT_draw_buffers))
1020*8975f5c5SAndroid Build Coastguard Worker {
1021*8975f5c5SAndroid Build Coastguard Worker if (!EmulateGLFragColorBroadcast(this, root, mResources.MaxDrawBuffers,
1022*8975f5c5SAndroid Build Coastguard Worker mResources.MaxDualSourceDrawBuffers, &mOutputVariables,
1023*8975f5c5SAndroid Build Coastguard Worker &mSymbolTable, mShaderVersion))
1024*8975f5c5SAndroid Build Coastguard Worker {
1025*8975f5c5SAndroid Build Coastguard Worker return false;
1026*8975f5c5SAndroid Build Coastguard Worker }
1027*8975f5c5SAndroid Build Coastguard Worker }
1028*8975f5c5SAndroid Build Coastguard Worker
1029*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.simplifyLoopConditions)
1030*8975f5c5SAndroid Build Coastguard Worker {
1031*8975f5c5SAndroid Build Coastguard Worker if (!SimplifyLoopConditions(this, root, &getSymbolTable()))
1032*8975f5c5SAndroid Build Coastguard Worker {
1033*8975f5c5SAndroid Build Coastguard Worker return false;
1034*8975f5c5SAndroid Build Coastguard Worker }
1035*8975f5c5SAndroid Build Coastguard Worker }
1036*8975f5c5SAndroid Build Coastguard Worker else
1037*8975f5c5SAndroid Build Coastguard Worker {
1038*8975f5c5SAndroid Build Coastguard Worker // Split multi declarations and remove calls to array length().
1039*8975f5c5SAndroid Build Coastguard Worker // Note that SimplifyLoopConditions needs to be run before any other AST transformations
1040*8975f5c5SAndroid Build Coastguard Worker // that may need to generate new statements from loop conditions or loop expressions.
1041*8975f5c5SAndroid Build Coastguard Worker if (!SimplifyLoopConditions(this, root,
1042*8975f5c5SAndroid Build Coastguard Worker IntermNodePatternMatcher::kMultiDeclaration |
1043*8975f5c5SAndroid Build Coastguard Worker IntermNodePatternMatcher::kArrayLengthMethod,
1044*8975f5c5SAndroid Build Coastguard Worker &getSymbolTable()))
1045*8975f5c5SAndroid Build Coastguard Worker {
1046*8975f5c5SAndroid Build Coastguard Worker return false;
1047*8975f5c5SAndroid Build Coastguard Worker }
1048*8975f5c5SAndroid Build Coastguard Worker }
1049*8975f5c5SAndroid Build Coastguard Worker
1050*8975f5c5SAndroid Build Coastguard Worker // Note that separate declarations need to be run before other AST transformations that
1051*8975f5c5SAndroid Build Coastguard Worker // generate new statements from expressions.
1052*8975f5c5SAndroid Build Coastguard Worker if (!SeparateDeclarations(*this, *root, mCompileOptions.separateCompoundStructDeclarations))
1053*8975f5c5SAndroid Build Coastguard Worker {
1054*8975f5c5SAndroid Build Coastguard Worker return false;
1055*8975f5c5SAndroid Build Coastguard Worker }
1056*8975f5c5SAndroid Build Coastguard Worker
1057*8975f5c5SAndroid Build Coastguard Worker if (IsWebGLBasedSpec(mShaderSpec))
1058*8975f5c5SAndroid Build Coastguard Worker {
1059*8975f5c5SAndroid Build Coastguard Worker // Remove infinite loops, they are not supposed to exist in shaders.
1060*8975f5c5SAndroid Build Coastguard Worker bool anyInfiniteLoops = false;
1061*8975f5c5SAndroid Build Coastguard Worker if (!PruneInfiniteLoops(this, root, &mSymbolTable, &anyInfiniteLoops))
1062*8975f5c5SAndroid Build Coastguard Worker {
1063*8975f5c5SAndroid Build Coastguard Worker return false;
1064*8975f5c5SAndroid Build Coastguard Worker }
1065*8975f5c5SAndroid Build Coastguard Worker
1066*8975f5c5SAndroid Build Coastguard Worker // If requested, reject shaders with infinite loops. If not requested, the same loops are
1067*8975f5c5SAndroid Build Coastguard Worker // removed from the shader as a fallback.
1068*8975f5c5SAndroid Build Coastguard Worker if (anyInfiniteLoops && mCompileOptions.rejectWebglShadersWithUndefinedBehavior)
1069*8975f5c5SAndroid Build Coastguard Worker {
1070*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("Infinite loop detected in the shader");
1071*8975f5c5SAndroid Build Coastguard Worker return false;
1072*8975f5c5SAndroid Build Coastguard Worker }
1073*8975f5c5SAndroid Build Coastguard Worker }
1074*8975f5c5SAndroid Build Coastguard Worker
1075*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.rescopeGlobalVariables)
1076*8975f5c5SAndroid Build Coastguard Worker {
1077*8975f5c5SAndroid Build Coastguard Worker if (!RescopeGlobalVariables(*this, *root))
1078*8975f5c5SAndroid Build Coastguard Worker {
1079*8975f5c5SAndroid Build Coastguard Worker return false;
1080*8975f5c5SAndroid Build Coastguard Worker }
1081*8975f5c5SAndroid Build Coastguard Worker }
1082*8975f5c5SAndroid Build Coastguard Worker
1083*8975f5c5SAndroid Build Coastguard Worker mValidateASTOptions.validateMultiDeclarations = true;
1084*8975f5c5SAndroid Build Coastguard Worker
1085*8975f5c5SAndroid Build Coastguard Worker if (!SplitSequenceOperator(this, root, IntermNodePatternMatcher::kArrayLengthMethod,
1086*8975f5c5SAndroid Build Coastguard Worker &getSymbolTable()))
1087*8975f5c5SAndroid Build Coastguard Worker {
1088*8975f5c5SAndroid Build Coastguard Worker return false;
1089*8975f5c5SAndroid Build Coastguard Worker }
1090*8975f5c5SAndroid Build Coastguard Worker
1091*8975f5c5SAndroid Build Coastguard Worker if (!RemoveArrayLengthMethod(this, root))
1092*8975f5c5SAndroid Build Coastguard Worker {
1093*8975f5c5SAndroid Build Coastguard Worker return false;
1094*8975f5c5SAndroid Build Coastguard Worker }
1095*8975f5c5SAndroid Build Coastguard Worker // Fold the expressions again, because |RemoveArrayLengthMethod| can introduce new constants.
1096*8975f5c5SAndroid Build Coastguard Worker if (!FoldExpressions(this, root, &mDiagnostics))
1097*8975f5c5SAndroid Build Coastguard Worker {
1098*8975f5c5SAndroid Build Coastguard Worker return false;
1099*8975f5c5SAndroid Build Coastguard Worker }
1100*8975f5c5SAndroid Build Coastguard Worker
1101*8975f5c5SAndroid Build Coastguard Worker if (!RemoveUnreferencedVariables(this, root, &mSymbolTable))
1102*8975f5c5SAndroid Build Coastguard Worker {
1103*8975f5c5SAndroid Build Coastguard Worker return false;
1104*8975f5c5SAndroid Build Coastguard Worker }
1105*8975f5c5SAndroid Build Coastguard Worker
1106*8975f5c5SAndroid Build Coastguard Worker // In case the last case inside a switch statement is a certain type of no-op, GLSL compilers in
1107*8975f5c5SAndroid Build Coastguard Worker // drivers may not accept it. In this case we clean up the dead code from the end of switch
1108*8975f5c5SAndroid Build Coastguard Worker // statements. This is also required because PruneNoOps or RemoveUnreferencedVariables may have
1109*8975f5c5SAndroid Build Coastguard Worker // left switch statements that only contained an empty declaration inside the final case in an
1110*8975f5c5SAndroid Build Coastguard Worker // invalid state. Relies on that PruneNoOps and RemoveUnreferencedVariables have already been
1111*8975f5c5SAndroid Build Coastguard Worker // run.
1112*8975f5c5SAndroid Build Coastguard Worker if (!PruneEmptyCases(this, root))
1113*8975f5c5SAndroid Build Coastguard Worker {
1114*8975f5c5SAndroid Build Coastguard Worker return false;
1115*8975f5c5SAndroid Build Coastguard Worker }
1116*8975f5c5SAndroid Build Coastguard Worker
1117*8975f5c5SAndroid Build Coastguard Worker // Run after RemoveUnreferencedVariables, validate that the shader does not have excessively
1118*8975f5c5SAndroid Build Coastguard Worker // large variables.
1119*8975f5c5SAndroid Build Coastguard Worker if (shouldLimitTypeSizes() && !ValidateTypeSizeLimitations(root, &mSymbolTable, &mDiagnostics))
1120*8975f5c5SAndroid Build Coastguard Worker {
1121*8975f5c5SAndroid Build Coastguard Worker return false;
1122*8975f5c5SAndroid Build Coastguard Worker }
1123*8975f5c5SAndroid Build Coastguard Worker
1124*8975f5c5SAndroid Build Coastguard Worker // Built-in function emulation needs to happen after validateLimitations pass.
1125*8975f5c5SAndroid Build Coastguard Worker GetGlobalPoolAllocator()->lock();
1126*8975f5c5SAndroid Build Coastguard Worker initBuiltInFunctionEmulator(&mBuiltInFunctionEmulator, compileOptions);
1127*8975f5c5SAndroid Build Coastguard Worker GetGlobalPoolAllocator()->unlock();
1128*8975f5c5SAndroid Build Coastguard Worker mBuiltInFunctionEmulator.markBuiltInFunctionsForEmulation(root);
1129*8975f5c5SAndroid Build Coastguard Worker
1130*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.scalarizeVecAndMatConstructorArgs)
1131*8975f5c5SAndroid Build Coastguard Worker {
1132*8975f5c5SAndroid Build Coastguard Worker if (!ScalarizeVecAndMatConstructorArgs(this, root, &mSymbolTable))
1133*8975f5c5SAndroid Build Coastguard Worker {
1134*8975f5c5SAndroid Build Coastguard Worker return false;
1135*8975f5c5SAndroid Build Coastguard Worker }
1136*8975f5c5SAndroid Build Coastguard Worker }
1137*8975f5c5SAndroid Build Coastguard Worker
1138*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.forceShaderPrecisionHighpToMediump)
1139*8975f5c5SAndroid Build Coastguard Worker {
1140*8975f5c5SAndroid Build Coastguard Worker if (!ForceShaderPrecisionToMediump(root, &mSymbolTable, mShaderType))
1141*8975f5c5SAndroid Build Coastguard Worker {
1142*8975f5c5SAndroid Build Coastguard Worker return false;
1143*8975f5c5SAndroid Build Coastguard Worker }
1144*8975f5c5SAndroid Build Coastguard Worker }
1145*8975f5c5SAndroid Build Coastguard Worker
1146*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mVariablesCollected);
1147*8975f5c5SAndroid Build Coastguard Worker CollectVariables(root, &mAttributes, &mOutputVariables, &mUniforms, &mInputVaryings,
1148*8975f5c5SAndroid Build Coastguard Worker &mOutputVaryings, &mSharedVariables, &mUniformBlocks, &mShaderStorageBlocks,
1149*8975f5c5SAndroid Build Coastguard Worker mResources.HashFunction, &mSymbolTable, mShaderType, mExtensionBehavior,
1150*8975f5c5SAndroid Build Coastguard Worker mResources, mTessControlShaderOutputVertices);
1151*8975f5c5SAndroid Build Coastguard Worker collectInterfaceBlocks();
1152*8975f5c5SAndroid Build Coastguard Worker mVariablesCollected = true;
1153*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.useUnusedStandardSharedBlocks)
1154*8975f5c5SAndroid Build Coastguard Worker {
1155*8975f5c5SAndroid Build Coastguard Worker if (!useAllMembersInUnusedStandardAndSharedBlocks(root))
1156*8975f5c5SAndroid Build Coastguard Worker {
1157*8975f5c5SAndroid Build Coastguard Worker return false;
1158*8975f5c5SAndroid Build Coastguard Worker }
1159*8975f5c5SAndroid Build Coastguard Worker }
1160*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.enforcePackingRestrictions)
1161*8975f5c5SAndroid Build Coastguard Worker {
1162*8975f5c5SAndroid Build Coastguard Worker int maxUniformVectors = GetMaxUniformVectorsForShaderType(mShaderType, mResources);
1163*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER && compileOptions.emulateClipOrigin)
1164*8975f5c5SAndroid Build Coastguard Worker {
1165*8975f5c5SAndroid Build Coastguard Worker --maxUniformVectors;
1166*8975f5c5SAndroid Build Coastguard Worker }
1167*8975f5c5SAndroid Build Coastguard Worker // Returns true if, after applying the packing rules in the GLSL ES 1.00.17 spec
1168*8975f5c5SAndroid Build Coastguard Worker // Appendix A, section 7, the shader does not use too many uniforms.
1169*8975f5c5SAndroid Build Coastguard Worker if (!CheckVariablesInPackingLimits(maxUniformVectors, mUniforms))
1170*8975f5c5SAndroid Build Coastguard Worker {
1171*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("too many uniforms");
1172*8975f5c5SAndroid Build Coastguard Worker return false;
1173*8975f5c5SAndroid Build Coastguard Worker }
1174*8975f5c5SAndroid Build Coastguard Worker }
1175*8975f5c5SAndroid Build Coastguard Worker bool needInitializeOutputVariables =
1176*8975f5c5SAndroid Build Coastguard Worker compileOptions.initOutputVariables && mShaderType != GL_COMPUTE_SHADER;
1177*8975f5c5SAndroid Build Coastguard Worker needInitializeOutputVariables |=
1178*8975f5c5SAndroid Build Coastguard Worker compileOptions.initFragmentOutputVariables && mShaderType == GL_FRAGMENT_SHADER;
1179*8975f5c5SAndroid Build Coastguard Worker if (needInitializeOutputVariables)
1180*8975f5c5SAndroid Build Coastguard Worker {
1181*8975f5c5SAndroid Build Coastguard Worker if (!initializeOutputVariables(root))
1182*8975f5c5SAndroid Build Coastguard Worker {
1183*8975f5c5SAndroid Build Coastguard Worker return false;
1184*8975f5c5SAndroid Build Coastguard Worker }
1185*8975f5c5SAndroid Build Coastguard Worker }
1186*8975f5c5SAndroid Build Coastguard Worker
1187*8975f5c5SAndroid Build Coastguard Worker // Removing invariant declarations must be done after collecting variables.
1188*8975f5c5SAndroid Build Coastguard Worker // Otherwise, built-in invariant declarations don't apply.
1189*8975f5c5SAndroid Build Coastguard Worker if (RemoveInvariant(mShaderType, mShaderVersion, mOutputType, compileOptions))
1190*8975f5c5SAndroid Build Coastguard Worker {
1191*8975f5c5SAndroid Build Coastguard Worker if (!RemoveInvariantDeclaration(this, root))
1192*8975f5c5SAndroid Build Coastguard Worker {
1193*8975f5c5SAndroid Build Coastguard Worker return false;
1194*8975f5c5SAndroid Build Coastguard Worker }
1195*8975f5c5SAndroid Build Coastguard Worker }
1196*8975f5c5SAndroid Build Coastguard Worker
1197*8975f5c5SAndroid Build Coastguard Worker // gl_Position is always written in compatibility output mode.
1198*8975f5c5SAndroid Build Coastguard Worker // It may have been already initialized among other output variables, in that case we don't
1199*8975f5c5SAndroid Build Coastguard Worker // need to initialize it twice.
1200*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER && !mGLPositionInitialized &&
1201*8975f5c5SAndroid Build Coastguard Worker (compileOptions.initGLPosition || mOutputType == SH_GLSL_COMPATIBILITY_OUTPUT))
1202*8975f5c5SAndroid Build Coastguard Worker {
1203*8975f5c5SAndroid Build Coastguard Worker if (!initializeGLPosition(root))
1204*8975f5c5SAndroid Build Coastguard Worker {
1205*8975f5c5SAndroid Build Coastguard Worker return false;
1206*8975f5c5SAndroid Build Coastguard Worker }
1207*8975f5c5SAndroid Build Coastguard Worker mGLPositionInitialized = true;
1208*8975f5c5SAndroid Build Coastguard Worker }
1209*8975f5c5SAndroid Build Coastguard Worker
1210*8975f5c5SAndroid Build Coastguard Worker // DeferGlobalInitializers needs to be run before other AST transformations that generate new
1211*8975f5c5SAndroid Build Coastguard Worker // statements from expressions. But it's fine to run DeferGlobalInitializers after the above
1212*8975f5c5SAndroid Build Coastguard Worker // SplitSequenceOperator and RemoveArrayLengthMethod since they only have an effect on the AST
1213*8975f5c5SAndroid Build Coastguard Worker // on ESSL >= 3.00, and the initializers that need to be deferred can only exist in ESSL < 3.00.
1214*8975f5c5SAndroid Build Coastguard Worker // Exception: if EXT_shader_non_constant_global_initializers is enabled, we must generate global
1215*8975f5c5SAndroid Build Coastguard Worker // initializers before we generate the DAG, since initializers may call functions which must not
1216*8975f5c5SAndroid Build Coastguard Worker // be optimized out
1217*8975f5c5SAndroid Build Coastguard Worker if (!enableNonConstantInitializers &&
1218*8975f5c5SAndroid Build Coastguard Worker !DeferGlobalInitializers(this, root, initializeLocalsAndGlobals, canUseLoopsToInitialize,
1219*8975f5c5SAndroid Build Coastguard Worker highPrecisionSupported, forceDeferNonConstGlobalInitializers,
1220*8975f5c5SAndroid Build Coastguard Worker &mSymbolTable))
1221*8975f5c5SAndroid Build Coastguard Worker {
1222*8975f5c5SAndroid Build Coastguard Worker return false;
1223*8975f5c5SAndroid Build Coastguard Worker }
1224*8975f5c5SAndroid Build Coastguard Worker
1225*8975f5c5SAndroid Build Coastguard Worker if (initializeLocalsAndGlobals)
1226*8975f5c5SAndroid Build Coastguard Worker {
1227*8975f5c5SAndroid Build Coastguard Worker // Initialize uninitialized local variables.
1228*8975f5c5SAndroid Build Coastguard Worker // In some cases initializing can generate extra statements in the parent block, such as
1229*8975f5c5SAndroid Build Coastguard Worker // when initializing nameless structs or initializing arrays in ESSL 1.00. In that case
1230*8975f5c5SAndroid Build Coastguard Worker // we need to first simplify loop conditions. We've already separated declarations
1231*8975f5c5SAndroid Build Coastguard Worker // earlier, which is also required. If we don't follow the Appendix A limitations, loop
1232*8975f5c5SAndroid Build Coastguard Worker // init statements can declare arrays or nameless structs and have multiple
1233*8975f5c5SAndroid Build Coastguard Worker // declarations.
1234*8975f5c5SAndroid Build Coastguard Worker
1235*8975f5c5SAndroid Build Coastguard Worker if (!shouldRunLoopAndIndexingValidation(compileOptions))
1236*8975f5c5SAndroid Build Coastguard Worker {
1237*8975f5c5SAndroid Build Coastguard Worker if (!SimplifyLoopConditions(this, root,
1238*8975f5c5SAndroid Build Coastguard Worker IntermNodePatternMatcher::kArrayDeclaration |
1239*8975f5c5SAndroid Build Coastguard Worker IntermNodePatternMatcher::kNamelessStructDeclaration,
1240*8975f5c5SAndroid Build Coastguard Worker &getSymbolTable()))
1241*8975f5c5SAndroid Build Coastguard Worker {
1242*8975f5c5SAndroid Build Coastguard Worker return false;
1243*8975f5c5SAndroid Build Coastguard Worker }
1244*8975f5c5SAndroid Build Coastguard Worker }
1245*8975f5c5SAndroid Build Coastguard Worker
1246*8975f5c5SAndroid Build Coastguard Worker if (!InitializeUninitializedLocals(this, root, getShaderVersion(), canUseLoopsToInitialize,
1247*8975f5c5SAndroid Build Coastguard Worker highPrecisionSupported, &getSymbolTable()))
1248*8975f5c5SAndroid Build Coastguard Worker {
1249*8975f5c5SAndroid Build Coastguard Worker return false;
1250*8975f5c5SAndroid Build Coastguard Worker }
1251*8975f5c5SAndroid Build Coastguard Worker }
1252*8975f5c5SAndroid Build Coastguard Worker
1253*8975f5c5SAndroid Build Coastguard Worker if (getShaderType() == GL_VERTEX_SHADER && compileOptions.clampPointSize)
1254*8975f5c5SAndroid Build Coastguard Worker {
1255*8975f5c5SAndroid Build Coastguard Worker if (!ClampPointSize(this, root, mResources.MinPointSize, mResources.MaxPointSize,
1256*8975f5c5SAndroid Build Coastguard Worker &getSymbolTable()))
1257*8975f5c5SAndroid Build Coastguard Worker {
1258*8975f5c5SAndroid Build Coastguard Worker return false;
1259*8975f5c5SAndroid Build Coastguard Worker }
1260*8975f5c5SAndroid Build Coastguard Worker }
1261*8975f5c5SAndroid Build Coastguard Worker
1262*8975f5c5SAndroid Build Coastguard Worker if (getShaderType() == GL_FRAGMENT_SHADER && compileOptions.clampFragDepth)
1263*8975f5c5SAndroid Build Coastguard Worker {
1264*8975f5c5SAndroid Build Coastguard Worker if (!ClampFragDepth(this, root, &getSymbolTable()))
1265*8975f5c5SAndroid Build Coastguard Worker {
1266*8975f5c5SAndroid Build Coastguard Worker return false;
1267*8975f5c5SAndroid Build Coastguard Worker }
1268*8975f5c5SAndroid Build Coastguard Worker }
1269*8975f5c5SAndroid Build Coastguard Worker
1270*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.rewriteRepeatedAssignToSwizzled)
1271*8975f5c5SAndroid Build Coastguard Worker {
1272*8975f5c5SAndroid Build Coastguard Worker if (!sh::RewriteRepeatedAssignToSwizzled(this, root))
1273*8975f5c5SAndroid Build Coastguard Worker {
1274*8975f5c5SAndroid Build Coastguard Worker return false;
1275*8975f5c5SAndroid Build Coastguard Worker }
1276*8975f5c5SAndroid Build Coastguard Worker }
1277*8975f5c5SAndroid Build Coastguard Worker
1278*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.removeDynamicIndexingOfSwizzledVector)
1279*8975f5c5SAndroid Build Coastguard Worker {
1280*8975f5c5SAndroid Build Coastguard Worker if (!sh::RemoveDynamicIndexingOfSwizzledVector(this, root, &getSymbolTable(), nullptr))
1281*8975f5c5SAndroid Build Coastguard Worker {
1282*8975f5c5SAndroid Build Coastguard Worker return false;
1283*8975f5c5SAndroid Build Coastguard Worker }
1284*8975f5c5SAndroid Build Coastguard Worker }
1285*8975f5c5SAndroid Build Coastguard Worker
1286*8975f5c5SAndroid Build Coastguard Worker return true;
1287*8975f5c5SAndroid Build Coastguard Worker }
1288*8975f5c5SAndroid Build Coastguard Worker
postParseChecks(const TParseContext & parseContext)1289*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::postParseChecks(const TParseContext &parseContext)
1290*8975f5c5SAndroid Build Coastguard Worker {
1291*8975f5c5SAndroid Build Coastguard Worker std::stringstream errorMessage;
1292*8975f5c5SAndroid Build Coastguard Worker
1293*8975f5c5SAndroid Build Coastguard Worker if (parseContext.getTreeRoot() == nullptr)
1294*8975f5c5SAndroid Build Coastguard Worker {
1295*8975f5c5SAndroid Build Coastguard Worker errorMessage << "Shader parsing failed (mTreeRoot == nullptr)";
1296*8975f5c5SAndroid Build Coastguard Worker }
1297*8975f5c5SAndroid Build Coastguard Worker
1298*8975f5c5SAndroid Build Coastguard Worker for (TType *type : parseContext.getDeferredArrayTypesToSize())
1299*8975f5c5SAndroid Build Coastguard Worker {
1300*8975f5c5SAndroid Build Coastguard Worker errorMessage << "Unsized global array type: " << type->getBasicString();
1301*8975f5c5SAndroid Build Coastguard Worker }
1302*8975f5c5SAndroid Build Coastguard Worker
1303*8975f5c5SAndroid Build Coastguard Worker if (!errorMessage.str().empty())
1304*8975f5c5SAndroid Build Coastguard Worker {
1305*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError(errorMessage.str().c_str());
1306*8975f5c5SAndroid Build Coastguard Worker return false;
1307*8975f5c5SAndroid Build Coastguard Worker }
1308*8975f5c5SAndroid Build Coastguard Worker
1309*8975f5c5SAndroid Build Coastguard Worker return true;
1310*8975f5c5SAndroid Build Coastguard Worker }
1311*8975f5c5SAndroid Build Coastguard Worker
compile(const char * const shaderStrings[],size_t numStrings,const ShCompileOptions & compileOptionsIn)1312*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::compile(const char *const shaderStrings[],
1313*8975f5c5SAndroid Build Coastguard Worker size_t numStrings,
1314*8975f5c5SAndroid Build Coastguard Worker const ShCompileOptions &compileOptionsIn)
1315*8975f5c5SAndroid Build Coastguard Worker {
1316*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
1317*8975f5c5SAndroid Build Coastguard Worker DumpFuzzerCase(shaderStrings, numStrings, mShaderType, mShaderSpec, mOutputType,
1318*8975f5c5SAndroid Build Coastguard Worker compileOptionsIn);
1319*8975f5c5SAndroid Build Coastguard Worker #endif // defined(ANGLE_FUZZER_CORPUS_OUTPUT_DIR)
1320*8975f5c5SAndroid Build Coastguard Worker
1321*8975f5c5SAndroid Build Coastguard Worker if (numStrings == 0)
1322*8975f5c5SAndroid Build Coastguard Worker return true;
1323*8975f5c5SAndroid Build Coastguard Worker
1324*8975f5c5SAndroid Build Coastguard Worker ShCompileOptions compileOptions = compileOptionsIn;
1325*8975f5c5SAndroid Build Coastguard Worker
1326*8975f5c5SAndroid Build Coastguard Worker // Apply key workarounds.
1327*8975f5c5SAndroid Build Coastguard Worker if (shouldFlattenPragmaStdglInvariantAll())
1328*8975f5c5SAndroid Build Coastguard Worker {
1329*8975f5c5SAndroid Build Coastguard Worker // This should be harmless to do in all cases, but for the moment, do it only conditionally.
1330*8975f5c5SAndroid Build Coastguard Worker compileOptions.flattenPragmaSTDGLInvariantAll = true;
1331*8975f5c5SAndroid Build Coastguard Worker }
1332*8975f5c5SAndroid Build Coastguard Worker
1333*8975f5c5SAndroid Build Coastguard Worker TScopedPoolAllocator scopedAlloc(&allocator);
1334*8975f5c5SAndroid Build Coastguard Worker TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
1335*8975f5c5SAndroid Build Coastguard Worker
1336*8975f5c5SAndroid Build Coastguard Worker if (root)
1337*8975f5c5SAndroid Build Coastguard Worker {
1338*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.intermediateTree)
1339*8975f5c5SAndroid Build Coastguard Worker {
1340*8975f5c5SAndroid Build Coastguard Worker OutputTree(root, mInfoSink.info);
1341*8975f5c5SAndroid Build Coastguard Worker }
1342*8975f5c5SAndroid Build Coastguard Worker
1343*8975f5c5SAndroid Build Coastguard Worker if (compileOptions.objectCode)
1344*8975f5c5SAndroid Build Coastguard Worker {
1345*8975f5c5SAndroid Build Coastguard Worker PerformanceDiagnostics perfDiagnostics(&mDiagnostics);
1346*8975f5c5SAndroid Build Coastguard Worker if (!translate(root, compileOptions, &perfDiagnostics))
1347*8975f5c5SAndroid Build Coastguard Worker {
1348*8975f5c5SAndroid Build Coastguard Worker return false;
1349*8975f5c5SAndroid Build Coastguard Worker }
1350*8975f5c5SAndroid Build Coastguard Worker }
1351*8975f5c5SAndroid Build Coastguard Worker
1352*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER)
1353*8975f5c5SAndroid Build Coastguard Worker {
1354*8975f5c5SAndroid Build Coastguard Worker bool lookForDrawID =
1355*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_multi_draw) &&
1356*8975f5c5SAndroid Build Coastguard Worker compileOptions.emulateGLDrawID;
1357*8975f5c5SAndroid Build Coastguard Worker bool lookForBaseVertexBaseInstance =
1358*8975f5c5SAndroid Build Coastguard Worker IsExtensionEnabled(mExtensionBehavior,
1359*8975f5c5SAndroid Build Coastguard Worker TExtension::ANGLE_base_vertex_base_instance_shader_builtin) &&
1360*8975f5c5SAndroid Build Coastguard Worker compileOptions.emulateGLBaseVertexBaseInstance;
1361*8975f5c5SAndroid Build Coastguard Worker
1362*8975f5c5SAndroid Build Coastguard Worker if (lookForDrawID || lookForBaseVertexBaseInstance)
1363*8975f5c5SAndroid Build Coastguard Worker {
1364*8975f5c5SAndroid Build Coastguard Worker for (auto &uniform : mUniforms)
1365*8975f5c5SAndroid Build Coastguard Worker {
1366*8975f5c5SAndroid Build Coastguard Worker if (lookForDrawID && uniform.name == "angle_DrawID" &&
1367*8975f5c5SAndroid Build Coastguard Worker uniform.mappedName == "angle_DrawID")
1368*8975f5c5SAndroid Build Coastguard Worker {
1369*8975f5c5SAndroid Build Coastguard Worker uniform.name = "gl_DrawID";
1370*8975f5c5SAndroid Build Coastguard Worker }
1371*8975f5c5SAndroid Build Coastguard Worker else if (lookForBaseVertexBaseInstance && uniform.name == "angle_BaseVertex" &&
1372*8975f5c5SAndroid Build Coastguard Worker uniform.mappedName == "angle_BaseVertex")
1373*8975f5c5SAndroid Build Coastguard Worker {
1374*8975f5c5SAndroid Build Coastguard Worker uniform.name = "gl_BaseVertex";
1375*8975f5c5SAndroid Build Coastguard Worker }
1376*8975f5c5SAndroid Build Coastguard Worker else if (lookForBaseVertexBaseInstance &&
1377*8975f5c5SAndroid Build Coastguard Worker uniform.name == "angle_BaseInstance" &&
1378*8975f5c5SAndroid Build Coastguard Worker uniform.mappedName == "angle_BaseInstance")
1379*8975f5c5SAndroid Build Coastguard Worker {
1380*8975f5c5SAndroid Build Coastguard Worker uniform.name = "gl_BaseInstance";
1381*8975f5c5SAndroid Build Coastguard Worker }
1382*8975f5c5SAndroid Build Coastguard Worker }
1383*8975f5c5SAndroid Build Coastguard Worker }
1384*8975f5c5SAndroid Build Coastguard Worker }
1385*8975f5c5SAndroid Build Coastguard Worker
1386*8975f5c5SAndroid Build Coastguard Worker // The IntermNode tree doesn't need to be deleted here, since the
1387*8975f5c5SAndroid Build Coastguard Worker // memory will be freed in a big chunk by the PoolAllocator.
1388*8975f5c5SAndroid Build Coastguard Worker return true;
1389*8975f5c5SAndroid Build Coastguard Worker }
1390*8975f5c5SAndroid Build Coastguard Worker return false;
1391*8975f5c5SAndroid Build Coastguard Worker }
1392*8975f5c5SAndroid Build Coastguard Worker
initBuiltInSymbolTable(const ShBuiltInResources & resources)1393*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::initBuiltInSymbolTable(const ShBuiltInResources &resources)
1394*8975f5c5SAndroid Build Coastguard Worker {
1395*8975f5c5SAndroid Build Coastguard Worker if (resources.MaxDrawBuffers < 1)
1396*8975f5c5SAndroid Build Coastguard Worker {
1397*8975f5c5SAndroid Build Coastguard Worker return false;
1398*8975f5c5SAndroid Build Coastguard Worker }
1399*8975f5c5SAndroid Build Coastguard Worker if (resources.EXT_blend_func_extended && resources.MaxDualSourceDrawBuffers < 1)
1400*8975f5c5SAndroid Build Coastguard Worker {
1401*8975f5c5SAndroid Build Coastguard Worker return false;
1402*8975f5c5SAndroid Build Coastguard Worker }
1403*8975f5c5SAndroid Build Coastguard Worker
1404*8975f5c5SAndroid Build Coastguard Worker mSymbolTable.initializeBuiltIns(mShaderType, mShaderSpec, resources);
1405*8975f5c5SAndroid Build Coastguard Worker
1406*8975f5c5SAndroid Build Coastguard Worker return true;
1407*8975f5c5SAndroid Build Coastguard Worker }
1408*8975f5c5SAndroid Build Coastguard Worker
setResourceString()1409*8975f5c5SAndroid Build Coastguard Worker void TCompiler::setResourceString()
1410*8975f5c5SAndroid Build Coastguard Worker {
1411*8975f5c5SAndroid Build Coastguard Worker std::ostringstream strstream = sh::InitializeStream<std::ostringstream>();
1412*8975f5c5SAndroid Build Coastguard Worker
1413*8975f5c5SAndroid Build Coastguard Worker // clang-format off
1414*8975f5c5SAndroid Build Coastguard Worker strstream << ":MaxVertexAttribs:" << mResources.MaxVertexAttribs
1415*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexUniformVectors:" << mResources.MaxVertexUniformVectors
1416*8975f5c5SAndroid Build Coastguard Worker << ":MaxVaryingVectors:" << mResources.MaxVaryingVectors
1417*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexTextureImageUnits:" << mResources.MaxVertexTextureImageUnits
1418*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedTextureImageUnits:" << mResources.MaxCombinedTextureImageUnits
1419*8975f5c5SAndroid Build Coastguard Worker << ":MaxTextureImageUnits:" << mResources.MaxTextureImageUnits
1420*8975f5c5SAndroid Build Coastguard Worker << ":MaxFragmentUniformVectors:" << mResources.MaxFragmentUniformVectors
1421*8975f5c5SAndroid Build Coastguard Worker << ":MaxDrawBuffers:" << mResources.MaxDrawBuffers
1422*8975f5c5SAndroid Build Coastguard Worker << ":OES_standard_derivatives:" << mResources.OES_standard_derivatives
1423*8975f5c5SAndroid Build Coastguard Worker << ":OES_EGL_image_external:" << mResources.OES_EGL_image_external
1424*8975f5c5SAndroid Build Coastguard Worker << ":OES_EGL_image_external_essl3:" << mResources.OES_EGL_image_external_essl3
1425*8975f5c5SAndroid Build Coastguard Worker << ":NV_EGL_stream_consumer_external:" << mResources.NV_EGL_stream_consumer_external
1426*8975f5c5SAndroid Build Coastguard Worker << ":ARB_texture_rectangle:" << mResources.ARB_texture_rectangle
1427*8975f5c5SAndroid Build Coastguard Worker << ":EXT_draw_buffers:" << mResources.EXT_draw_buffers
1428*8975f5c5SAndroid Build Coastguard Worker << ":FragmentPrecisionHigh:" << mResources.FragmentPrecisionHigh
1429*8975f5c5SAndroid Build Coastguard Worker << ":MaxExpressionComplexity:" << mResources.MaxExpressionComplexity
1430*8975f5c5SAndroid Build Coastguard Worker << ":MaxStatementDepth:" << mResources.MaxStatementDepth
1431*8975f5c5SAndroid Build Coastguard Worker << ":MaxCallStackDepth:" << mResources.MaxCallStackDepth
1432*8975f5c5SAndroid Build Coastguard Worker << ":MaxFunctionParameters:" << mResources.MaxFunctionParameters
1433*8975f5c5SAndroid Build Coastguard Worker << ":EXT_blend_func_extended:" << mResources.EXT_blend_func_extended
1434*8975f5c5SAndroid Build Coastguard Worker << ":EXT_conservative_depth:" << mResources.EXT_conservative_depth
1435*8975f5c5SAndroid Build Coastguard Worker << ":EXT_frag_depth:" << mResources.EXT_frag_depth
1436*8975f5c5SAndroid Build Coastguard Worker << ":EXT_primitive_bounding_box:" << mResources.EXT_primitive_bounding_box
1437*8975f5c5SAndroid Build Coastguard Worker << ":OES_primitive_bounding_box:" << mResources.OES_primitive_bounding_box
1438*8975f5c5SAndroid Build Coastguard Worker << ":EXT_separate_shader_objects:" << mResources.EXT_separate_shader_objects
1439*8975f5c5SAndroid Build Coastguard Worker << ":EXT_shader_texture_lod:" << mResources.EXT_shader_texture_lod
1440*8975f5c5SAndroid Build Coastguard Worker << ":EXT_shader_framebuffer_fetch:" << mResources.EXT_shader_framebuffer_fetch
1441*8975f5c5SAndroid Build Coastguard Worker << ":EXT_shader_framebuffer_fetch_non_coherent:" << mResources.EXT_shader_framebuffer_fetch_non_coherent
1442*8975f5c5SAndroid Build Coastguard Worker << ":NV_shader_framebuffer_fetch:" << mResources.NV_shader_framebuffer_fetch
1443*8975f5c5SAndroid Build Coastguard Worker << ":ARM_shader_framebuffer_fetch:" << mResources.ARM_shader_framebuffer_fetch
1444*8975f5c5SAndroid Build Coastguard Worker << ":ARM_shader_framebuffer_fetch_depth_stencil:" << mResources.ARM_shader_framebuffer_fetch_depth_stencil
1445*8975f5c5SAndroid Build Coastguard Worker << ":OVR_multiview2:" << mResources.OVR_multiview2
1446*8975f5c5SAndroid Build Coastguard Worker << ":OVR_multiview:" << mResources.OVR_multiview
1447*8975f5c5SAndroid Build Coastguard Worker << ":EXT_YUV_target:" << mResources.EXT_YUV_target
1448*8975f5c5SAndroid Build Coastguard Worker << ":EXT_geometry_shader:" << mResources.EXT_geometry_shader
1449*8975f5c5SAndroid Build Coastguard Worker << ":OES_geometry_shader:" << mResources.OES_geometry_shader
1450*8975f5c5SAndroid Build Coastguard Worker << ":OES_shader_io_blocks:" << mResources.OES_shader_io_blocks
1451*8975f5c5SAndroid Build Coastguard Worker << ":EXT_shader_io_blocks:" << mResources.EXT_shader_io_blocks
1452*8975f5c5SAndroid Build Coastguard Worker << ":EXT_gpu_shader5:" << mResources.EXT_gpu_shader5
1453*8975f5c5SAndroid Build Coastguard Worker << ":OES_texture_3D:" << mResources.OES_texture_3D
1454*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexOutputVectors:" << mResources.MaxVertexOutputVectors
1455*8975f5c5SAndroid Build Coastguard Worker << ":MaxFragmentInputVectors:" << mResources.MaxFragmentInputVectors
1456*8975f5c5SAndroid Build Coastguard Worker << ":MinProgramTexelOffset:" << mResources.MinProgramTexelOffset
1457*8975f5c5SAndroid Build Coastguard Worker << ":MaxProgramTexelOffset:" << mResources.MaxProgramTexelOffset
1458*8975f5c5SAndroid Build Coastguard Worker << ":MaxDualSourceDrawBuffers:" << mResources.MaxDualSourceDrawBuffers
1459*8975f5c5SAndroid Build Coastguard Worker << ":MaxViewsOVR:" << mResources.MaxViewsOVR
1460*8975f5c5SAndroid Build Coastguard Worker << ":NV_draw_buffers:" << mResources.NV_draw_buffers
1461*8975f5c5SAndroid Build Coastguard Worker << ":ANGLE_multi_draw:" << mResources.ANGLE_multi_draw
1462*8975f5c5SAndroid Build Coastguard Worker << ":ANGLE_base_vertex_base_instance_shader_builtin:" << mResources.ANGLE_base_vertex_base_instance_shader_builtin
1463*8975f5c5SAndroid Build Coastguard Worker << ":APPLE_clip_distance:" << mResources.APPLE_clip_distance
1464*8975f5c5SAndroid Build Coastguard Worker << ":OES_texture_cube_map_array:" << mResources.OES_texture_cube_map_array
1465*8975f5c5SAndroid Build Coastguard Worker << ":EXT_texture_cube_map_array:" << mResources.EXT_texture_cube_map_array
1466*8975f5c5SAndroid Build Coastguard Worker << ":EXT_texture_query_lod:" << mResources.EXT_texture_query_lod
1467*8975f5c5SAndroid Build Coastguard Worker << ":EXT_texture_shadow_lod:" << mResources.EXT_texture_shadow_lod
1468*8975f5c5SAndroid Build Coastguard Worker << ":EXT_shadow_samplers:" << mResources.EXT_shadow_samplers
1469*8975f5c5SAndroid Build Coastguard Worker << ":OES_shader_multisample_interpolation:" << mResources.OES_shader_multisample_interpolation
1470*8975f5c5SAndroid Build Coastguard Worker << ":OES_shader_image_atomic:" << mResources.OES_shader_image_atomic
1471*8975f5c5SAndroid Build Coastguard Worker << ":EXT_tessellation_shader:" << mResources.EXT_tessellation_shader
1472*8975f5c5SAndroid Build Coastguard Worker << ":OES_tessellation_shader:" << mResources.OES_tessellation_shader
1473*8975f5c5SAndroid Build Coastguard Worker << ":OES_texture_buffer:" << mResources.OES_texture_buffer
1474*8975f5c5SAndroid Build Coastguard Worker << ":EXT_texture_buffer:" << mResources.EXT_texture_buffer
1475*8975f5c5SAndroid Build Coastguard Worker << ":OES_sample_variables:" << mResources.OES_sample_variables
1476*8975f5c5SAndroid Build Coastguard Worker << ":EXT_clip_cull_distance:" << mResources.EXT_clip_cull_distance
1477*8975f5c5SAndroid Build Coastguard Worker << ":ANGLE_clip_cull_distance:" << mResources.ANGLE_clip_cull_distance
1478*8975f5c5SAndroid Build Coastguard Worker << ":MinProgramTextureGatherOffset:" << mResources.MinProgramTextureGatherOffset
1479*8975f5c5SAndroid Build Coastguard Worker << ":MaxProgramTextureGatherOffset:" << mResources.MaxProgramTextureGatherOffset
1480*8975f5c5SAndroid Build Coastguard Worker << ":MaxImageUnits:" << mResources.MaxImageUnits
1481*8975f5c5SAndroid Build Coastguard Worker << ":MaxSamples:" << mResources.MaxSamples
1482*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexImageUniforms:" << mResources.MaxVertexImageUniforms
1483*8975f5c5SAndroid Build Coastguard Worker << ":MaxFragmentImageUniforms:" << mResources.MaxFragmentImageUniforms
1484*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeImageUniforms:" << mResources.MaxComputeImageUniforms
1485*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedImageUniforms:" << mResources.MaxCombinedImageUniforms
1486*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedShaderOutputResources:" << mResources.MaxCombinedShaderOutputResources
1487*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupCountX:" << mResources.MaxComputeWorkGroupCount[0]
1488*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupCountY:" << mResources.MaxComputeWorkGroupCount[1]
1489*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupCountZ:" << mResources.MaxComputeWorkGroupCount[2]
1490*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupSizeX:" << mResources.MaxComputeWorkGroupSize[0]
1491*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupSizeY:" << mResources.MaxComputeWorkGroupSize[1]
1492*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeWorkGroupSizeZ:" << mResources.MaxComputeWorkGroupSize[2]
1493*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeUniformComponents:" << mResources.MaxComputeUniformComponents
1494*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeTextureImageUnits:" << mResources.MaxComputeTextureImageUnits
1495*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeAtomicCounters:" << mResources.MaxComputeAtomicCounters
1496*8975f5c5SAndroid Build Coastguard Worker << ":MaxComputeAtomicCounterBuffers:" << mResources.MaxComputeAtomicCounterBuffers
1497*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexAtomicCounters:" << mResources.MaxVertexAtomicCounters
1498*8975f5c5SAndroid Build Coastguard Worker << ":MaxFragmentAtomicCounters:" << mResources.MaxFragmentAtomicCounters
1499*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedAtomicCounters:" << mResources.MaxCombinedAtomicCounters
1500*8975f5c5SAndroid Build Coastguard Worker << ":MaxAtomicCounterBindings:" << mResources.MaxAtomicCounterBindings
1501*8975f5c5SAndroid Build Coastguard Worker << ":MaxVertexAtomicCounterBuffers:" << mResources.MaxVertexAtomicCounterBuffers
1502*8975f5c5SAndroid Build Coastguard Worker << ":MaxFragmentAtomicCounterBuffers:" << mResources.MaxFragmentAtomicCounterBuffers
1503*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedAtomicCounterBuffers:" << mResources.MaxCombinedAtomicCounterBuffers
1504*8975f5c5SAndroid Build Coastguard Worker << ":MaxAtomicCounterBufferSize:" << mResources.MaxAtomicCounterBufferSize
1505*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryUniformComponents:" << mResources.MaxGeometryUniformComponents
1506*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryUniformBlocks:" << mResources.MaxGeometryUniformBlocks
1507*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryInputComponents:" << mResources.MaxGeometryInputComponents
1508*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryOutputComponents:" << mResources.MaxGeometryOutputComponents
1509*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryOutputVertices:" << mResources.MaxGeometryOutputVertices
1510*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryTotalOutputComponents:" << mResources.MaxGeometryTotalOutputComponents
1511*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryTextureImageUnits:" << mResources.MaxGeometryTextureImageUnits
1512*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryAtomicCounterBuffers:" << mResources.MaxGeometryAtomicCounterBuffers
1513*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryAtomicCounters:" << mResources.MaxGeometryAtomicCounters
1514*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryShaderStorageBlocks:" << mResources.MaxGeometryShaderStorageBlocks
1515*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryShaderInvocations:" << mResources.MaxGeometryShaderInvocations
1516*8975f5c5SAndroid Build Coastguard Worker << ":MaxGeometryImageUniforms:" << mResources.MaxGeometryImageUniforms
1517*8975f5c5SAndroid Build Coastguard Worker << ":MaxClipDistances" << mResources.MaxClipDistances
1518*8975f5c5SAndroid Build Coastguard Worker << ":MaxCullDistances" << mResources.MaxCullDistances
1519*8975f5c5SAndroid Build Coastguard Worker << ":MaxCombinedClipAndCullDistances" << mResources.MaxCombinedClipAndCullDistances
1520*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlInputComponents:" << mResources.MaxTessControlInputComponents
1521*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlOutputComponents:" << mResources.MaxTessControlOutputComponents
1522*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlTextureImageUnits:" << mResources.MaxTessControlTextureImageUnits
1523*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlUniformComponents:" << mResources.MaxTessControlUniformComponents
1524*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlTotalOutputComponents:" << mResources.MaxTessControlTotalOutputComponents
1525*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlImageUniforms:" << mResources.MaxTessControlImageUniforms
1526*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlAtomicCounters:" << mResources.MaxTessControlAtomicCounters
1527*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessControlAtomicCounterBuffers:" << mResources.MaxTessControlAtomicCounterBuffers
1528*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessPatchComponents:" << mResources.MaxTessPatchComponents
1529*8975f5c5SAndroid Build Coastguard Worker << ":MaxPatchVertices:" << mResources.MaxPatchVertices
1530*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessGenLevel:" << mResources.MaxTessGenLevel
1531*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationInputComponents:" << mResources.MaxTessEvaluationInputComponents
1532*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationOutputComponents:" << mResources.MaxTessEvaluationOutputComponents
1533*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationTextureImageUnits:" << mResources.MaxTessEvaluationTextureImageUnits
1534*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationUniformComponents:" << mResources.MaxTessEvaluationUniformComponents
1535*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationImageUniforms:" << mResources.MaxTessEvaluationImageUniforms
1536*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationAtomicCounters:" << mResources.MaxTessEvaluationAtomicCounters
1537*8975f5c5SAndroid Build Coastguard Worker << ":MaxTessEvaluationAtomicCounterBuffers:" << mResources.MaxTessEvaluationAtomicCounterBuffers;
1538*8975f5c5SAndroid Build Coastguard Worker // clang-format on
1539*8975f5c5SAndroid Build Coastguard Worker
1540*8975f5c5SAndroid Build Coastguard Worker mBuiltInResourcesString = strstream.str();
1541*8975f5c5SAndroid Build Coastguard Worker }
1542*8975f5c5SAndroid Build Coastguard Worker
collectInterfaceBlocks()1543*8975f5c5SAndroid Build Coastguard Worker void TCompiler::collectInterfaceBlocks()
1544*8975f5c5SAndroid Build Coastguard Worker {
1545*8975f5c5SAndroid Build Coastguard Worker ASSERT(mInterfaceBlocks.empty());
1546*8975f5c5SAndroid Build Coastguard Worker mInterfaceBlocks.reserve(mUniformBlocks.size() + mShaderStorageBlocks.size());
1547*8975f5c5SAndroid Build Coastguard Worker mInterfaceBlocks.insert(mInterfaceBlocks.end(), mUniformBlocks.begin(), mUniformBlocks.end());
1548*8975f5c5SAndroid Build Coastguard Worker mInterfaceBlocks.insert(mInterfaceBlocks.end(), mShaderStorageBlocks.begin(),
1549*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks.end());
1550*8975f5c5SAndroid Build Coastguard Worker }
1551*8975f5c5SAndroid Build Coastguard Worker
clearResults()1552*8975f5c5SAndroid Build Coastguard Worker void TCompiler::clearResults()
1553*8975f5c5SAndroid Build Coastguard Worker {
1554*8975f5c5SAndroid Build Coastguard Worker mInfoSink.info.erase();
1555*8975f5c5SAndroid Build Coastguard Worker mInfoSink.obj.erase();
1556*8975f5c5SAndroid Build Coastguard Worker mInfoSink.debug.erase();
1557*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.resetErrorCount();
1558*8975f5c5SAndroid Build Coastguard Worker
1559*8975f5c5SAndroid Build Coastguard Worker mMetadataFlags.reset();
1560*8975f5c5SAndroid Build Coastguard Worker mSpecConstUsageBits.reset();
1561*8975f5c5SAndroid Build Coastguard Worker
1562*8975f5c5SAndroid Build Coastguard Worker mAttributes.clear();
1563*8975f5c5SAndroid Build Coastguard Worker mOutputVariables.clear();
1564*8975f5c5SAndroid Build Coastguard Worker mUniforms.clear();
1565*8975f5c5SAndroid Build Coastguard Worker mInputVaryings.clear();
1566*8975f5c5SAndroid Build Coastguard Worker mOutputVaryings.clear();
1567*8975f5c5SAndroid Build Coastguard Worker mSharedVariables.clear();
1568*8975f5c5SAndroid Build Coastguard Worker mInterfaceBlocks.clear();
1569*8975f5c5SAndroid Build Coastguard Worker mUniformBlocks.clear();
1570*8975f5c5SAndroid Build Coastguard Worker mShaderStorageBlocks.clear();
1571*8975f5c5SAndroid Build Coastguard Worker mVariablesCollected = false;
1572*8975f5c5SAndroid Build Coastguard Worker mGLPositionInitialized = false;
1573*8975f5c5SAndroid Build Coastguard Worker
1574*8975f5c5SAndroid Build Coastguard Worker mNumViews = -1;
1575*8975f5c5SAndroid Build Coastguard Worker
1576*8975f5c5SAndroid Build Coastguard Worker mClipDistanceSize = 0;
1577*8975f5c5SAndroid Build Coastguard Worker mCullDistanceSize = 0;
1578*8975f5c5SAndroid Build Coastguard Worker
1579*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInputPrimitiveType = EptUndefined;
1580*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderOutputPrimitiveType = EptUndefined;
1581*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderInvocations = 0;
1582*8975f5c5SAndroid Build Coastguard Worker mGeometryShaderMaxVertices = -1;
1583*8975f5c5SAndroid Build Coastguard Worker
1584*8975f5c5SAndroid Build Coastguard Worker mTessControlShaderOutputVertices = 0;
1585*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPrimitiveType = EtetUndefined;
1586*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputVertexSpacingType = EtetUndefined;
1587*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputOrderingType = EtetUndefined;
1588*8975f5c5SAndroid Build Coastguard Worker mTessEvaluationShaderInputPointType = EtetUndefined;
1589*8975f5c5SAndroid Build Coastguard Worker
1590*8975f5c5SAndroid Build Coastguard Worker mBuiltInFunctionEmulator.cleanup();
1591*8975f5c5SAndroid Build Coastguard Worker
1592*8975f5c5SAndroid Build Coastguard Worker mNameMap.clear();
1593*8975f5c5SAndroid Build Coastguard Worker
1594*8975f5c5SAndroid Build Coastguard Worker mSourcePath = nullptr;
1595*8975f5c5SAndroid Build Coastguard Worker
1596*8975f5c5SAndroid Build Coastguard Worker mSymbolTable.clearCompilationResults();
1597*8975f5c5SAndroid Build Coastguard Worker }
1598*8975f5c5SAndroid Build Coastguard Worker
initCallDag(TIntermNode * root)1599*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::initCallDag(TIntermNode *root)
1600*8975f5c5SAndroid Build Coastguard Worker {
1601*8975f5c5SAndroid Build Coastguard Worker mCallDag.clear();
1602*8975f5c5SAndroid Build Coastguard Worker
1603*8975f5c5SAndroid Build Coastguard Worker switch (mCallDag.init(root, &mDiagnostics))
1604*8975f5c5SAndroid Build Coastguard Worker {
1605*8975f5c5SAndroid Build Coastguard Worker case CallDAG::INITDAG_SUCCESS:
1606*8975f5c5SAndroid Build Coastguard Worker return true;
1607*8975f5c5SAndroid Build Coastguard Worker case CallDAG::INITDAG_RECURSION:
1608*8975f5c5SAndroid Build Coastguard Worker case CallDAG::INITDAG_UNDEFINED:
1609*8975f5c5SAndroid Build Coastguard Worker // Error message has already been written out.
1610*8975f5c5SAndroid Build Coastguard Worker ASSERT(mDiagnostics.numErrors() > 0);
1611*8975f5c5SAndroid Build Coastguard Worker return false;
1612*8975f5c5SAndroid Build Coastguard Worker }
1613*8975f5c5SAndroid Build Coastguard Worker
1614*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE();
1615*8975f5c5SAndroid Build Coastguard Worker return true;
1616*8975f5c5SAndroid Build Coastguard Worker }
1617*8975f5c5SAndroid Build Coastguard Worker
checkCallDepth()1618*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::checkCallDepth()
1619*8975f5c5SAndroid Build Coastguard Worker {
1620*8975f5c5SAndroid Build Coastguard Worker std::vector<int> depths(mCallDag.size());
1621*8975f5c5SAndroid Build Coastguard Worker
1622*8975f5c5SAndroid Build Coastguard Worker for (size_t i = 0; i < mCallDag.size(); i++)
1623*8975f5c5SAndroid Build Coastguard Worker {
1624*8975f5c5SAndroid Build Coastguard Worker int depth = 0;
1625*8975f5c5SAndroid Build Coastguard Worker const CallDAG::Record &record = mCallDag.getRecordFromIndex(i);
1626*8975f5c5SAndroid Build Coastguard Worker
1627*8975f5c5SAndroid Build Coastguard Worker for (int calleeIndex : record.callees)
1628*8975f5c5SAndroid Build Coastguard Worker {
1629*8975f5c5SAndroid Build Coastguard Worker depth = std::max(depth, depths[calleeIndex] + 1);
1630*8975f5c5SAndroid Build Coastguard Worker }
1631*8975f5c5SAndroid Build Coastguard Worker
1632*8975f5c5SAndroid Build Coastguard Worker depths[i] = depth;
1633*8975f5c5SAndroid Build Coastguard Worker
1634*8975f5c5SAndroid Build Coastguard Worker if (depth >= mResources.MaxCallStackDepth)
1635*8975f5c5SAndroid Build Coastguard Worker {
1636*8975f5c5SAndroid Build Coastguard Worker // Trace back the function chain to have a meaningful info log.
1637*8975f5c5SAndroid Build Coastguard Worker std::stringstream errorStream = sh::InitializeStream<std::stringstream>();
1638*8975f5c5SAndroid Build Coastguard Worker errorStream << "Call stack too deep (larger than " << mResources.MaxCallStackDepth
1639*8975f5c5SAndroid Build Coastguard Worker << ") with the following call chain: "
1640*8975f5c5SAndroid Build Coastguard Worker << record.node->getFunction()->name();
1641*8975f5c5SAndroid Build Coastguard Worker
1642*8975f5c5SAndroid Build Coastguard Worker int currentFunction = static_cast<int>(i);
1643*8975f5c5SAndroid Build Coastguard Worker int currentDepth = depth;
1644*8975f5c5SAndroid Build Coastguard Worker
1645*8975f5c5SAndroid Build Coastguard Worker while (currentFunction != -1)
1646*8975f5c5SAndroid Build Coastguard Worker {
1647*8975f5c5SAndroid Build Coastguard Worker errorStream
1648*8975f5c5SAndroid Build Coastguard Worker << " -> "
1649*8975f5c5SAndroid Build Coastguard Worker << mCallDag.getRecordFromIndex(currentFunction).node->getFunction()->name();
1650*8975f5c5SAndroid Build Coastguard Worker
1651*8975f5c5SAndroid Build Coastguard Worker int nextFunction = -1;
1652*8975f5c5SAndroid Build Coastguard Worker for (const int &calleeIndex : mCallDag.getRecordFromIndex(currentFunction).callees)
1653*8975f5c5SAndroid Build Coastguard Worker {
1654*8975f5c5SAndroid Build Coastguard Worker if (depths[calleeIndex] == currentDepth - 1)
1655*8975f5c5SAndroid Build Coastguard Worker {
1656*8975f5c5SAndroid Build Coastguard Worker currentDepth--;
1657*8975f5c5SAndroid Build Coastguard Worker nextFunction = calleeIndex;
1658*8975f5c5SAndroid Build Coastguard Worker }
1659*8975f5c5SAndroid Build Coastguard Worker }
1660*8975f5c5SAndroid Build Coastguard Worker
1661*8975f5c5SAndroid Build Coastguard Worker currentFunction = nextFunction;
1662*8975f5c5SAndroid Build Coastguard Worker }
1663*8975f5c5SAndroid Build Coastguard Worker
1664*8975f5c5SAndroid Build Coastguard Worker std::string errorStr = errorStream.str();
1665*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError(errorStr.c_str());
1666*8975f5c5SAndroid Build Coastguard Worker
1667*8975f5c5SAndroid Build Coastguard Worker return false;
1668*8975f5c5SAndroid Build Coastguard Worker }
1669*8975f5c5SAndroid Build Coastguard Worker }
1670*8975f5c5SAndroid Build Coastguard Worker
1671*8975f5c5SAndroid Build Coastguard Worker return true;
1672*8975f5c5SAndroid Build Coastguard Worker }
1673*8975f5c5SAndroid Build Coastguard Worker
tagUsedFunctions()1674*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::tagUsedFunctions()
1675*8975f5c5SAndroid Build Coastguard Worker {
1676*8975f5c5SAndroid Build Coastguard Worker // Search from main, starting from the end of the DAG as it usually is the root.
1677*8975f5c5SAndroid Build Coastguard Worker for (size_t i = mCallDag.size(); i-- > 0;)
1678*8975f5c5SAndroid Build Coastguard Worker {
1679*8975f5c5SAndroid Build Coastguard Worker if (mCallDag.getRecordFromIndex(i).node->getFunction()->isMain())
1680*8975f5c5SAndroid Build Coastguard Worker {
1681*8975f5c5SAndroid Build Coastguard Worker internalTagUsedFunction(i);
1682*8975f5c5SAndroid Build Coastguard Worker return true;
1683*8975f5c5SAndroid Build Coastguard Worker }
1684*8975f5c5SAndroid Build Coastguard Worker }
1685*8975f5c5SAndroid Build Coastguard Worker
1686*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("Missing main()");
1687*8975f5c5SAndroid Build Coastguard Worker return false;
1688*8975f5c5SAndroid Build Coastguard Worker }
1689*8975f5c5SAndroid Build Coastguard Worker
internalTagUsedFunction(size_t index)1690*8975f5c5SAndroid Build Coastguard Worker void TCompiler::internalTagUsedFunction(size_t index)
1691*8975f5c5SAndroid Build Coastguard Worker {
1692*8975f5c5SAndroid Build Coastguard Worker if (mFunctionMetadata[index].used)
1693*8975f5c5SAndroid Build Coastguard Worker {
1694*8975f5c5SAndroid Build Coastguard Worker return;
1695*8975f5c5SAndroid Build Coastguard Worker }
1696*8975f5c5SAndroid Build Coastguard Worker
1697*8975f5c5SAndroid Build Coastguard Worker mFunctionMetadata[index].used = true;
1698*8975f5c5SAndroid Build Coastguard Worker
1699*8975f5c5SAndroid Build Coastguard Worker for (int calleeIndex : mCallDag.getRecordFromIndex(index).callees)
1700*8975f5c5SAndroid Build Coastguard Worker {
1701*8975f5c5SAndroid Build Coastguard Worker internalTagUsedFunction(calleeIndex);
1702*8975f5c5SAndroid Build Coastguard Worker }
1703*8975f5c5SAndroid Build Coastguard Worker }
1704*8975f5c5SAndroid Build Coastguard Worker
pruneUnusedFunctions(TIntermBlock * root)1705*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::pruneUnusedFunctions(TIntermBlock *root)
1706*8975f5c5SAndroid Build Coastguard Worker {
1707*8975f5c5SAndroid Build Coastguard Worker TIntermSequence *sequence = root->getSequence();
1708*8975f5c5SAndroid Build Coastguard Worker
1709*8975f5c5SAndroid Build Coastguard Worker size_t writeIndex = 0;
1710*8975f5c5SAndroid Build Coastguard Worker for (size_t readIndex = 0; readIndex < sequence->size(); ++readIndex)
1711*8975f5c5SAndroid Build Coastguard Worker {
1712*8975f5c5SAndroid Build Coastguard Worker TIntermNode *node = sequence->at(readIndex);
1713*8975f5c5SAndroid Build Coastguard Worker
1714*8975f5c5SAndroid Build Coastguard Worker // Keep anything that's not unused.
1715*8975f5c5SAndroid Build Coastguard Worker const TFunction *function = nullptr;
1716*8975f5c5SAndroid Build Coastguard Worker const bool shouldPrune =
1717*8975f5c5SAndroid Build Coastguard Worker IsTopLevelNodeUnusedFunction(mCallDag, mFunctionMetadata, node, &function);
1718*8975f5c5SAndroid Build Coastguard Worker if (!shouldPrune)
1719*8975f5c5SAndroid Build Coastguard Worker {
1720*8975f5c5SAndroid Build Coastguard Worker (*sequence)[writeIndex++] = node;
1721*8975f5c5SAndroid Build Coastguard Worker continue;
1722*8975f5c5SAndroid Build Coastguard Worker }
1723*8975f5c5SAndroid Build Coastguard Worker
1724*8975f5c5SAndroid Build Coastguard Worker // If a function is unused, it may have a struct declaration in its return value which
1725*8975f5c5SAndroid Build Coastguard Worker // shouldn't be pruned. In that case, replace the function definition with the struct
1726*8975f5c5SAndroid Build Coastguard Worker // definition.
1727*8975f5c5SAndroid Build Coastguard Worker ASSERT(function != nullptr);
1728*8975f5c5SAndroid Build Coastguard Worker const TType &returnType = function->getReturnType();
1729*8975f5c5SAndroid Build Coastguard Worker if (!returnType.isStructSpecifier())
1730*8975f5c5SAndroid Build Coastguard Worker {
1731*8975f5c5SAndroid Build Coastguard Worker continue;
1732*8975f5c5SAndroid Build Coastguard Worker }
1733*8975f5c5SAndroid Build Coastguard Worker
1734*8975f5c5SAndroid Build Coastguard Worker TVariable *structVariable =
1735*8975f5c5SAndroid Build Coastguard Worker new TVariable(&mSymbolTable, kEmptyImmutableString, &returnType, SymbolType::Empty);
1736*8975f5c5SAndroid Build Coastguard Worker TIntermSymbol *structSymbol = new TIntermSymbol(structVariable);
1737*8975f5c5SAndroid Build Coastguard Worker TIntermDeclaration *structDeclaration = new TIntermDeclaration;
1738*8975f5c5SAndroid Build Coastguard Worker structDeclaration->appendDeclarator(structSymbol);
1739*8975f5c5SAndroid Build Coastguard Worker
1740*8975f5c5SAndroid Build Coastguard Worker structSymbol->setLine(node->getLine());
1741*8975f5c5SAndroid Build Coastguard Worker structDeclaration->setLine(node->getLine());
1742*8975f5c5SAndroid Build Coastguard Worker
1743*8975f5c5SAndroid Build Coastguard Worker (*sequence)[writeIndex++] = structDeclaration;
1744*8975f5c5SAndroid Build Coastguard Worker }
1745*8975f5c5SAndroid Build Coastguard Worker
1746*8975f5c5SAndroid Build Coastguard Worker sequence->resize(writeIndex);
1747*8975f5c5SAndroid Build Coastguard Worker
1748*8975f5c5SAndroid Build Coastguard Worker return validateAST(root);
1749*8975f5c5SAndroid Build Coastguard Worker }
1750*8975f5c5SAndroid Build Coastguard Worker
limitExpressionComplexity(TIntermBlock * root)1751*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
1752*8975f5c5SAndroid Build Coastguard Worker {
1753*8975f5c5SAndroid Build Coastguard Worker if (!IsASTDepthBelowLimit(root, mResources.MaxExpressionComplexity))
1754*8975f5c5SAndroid Build Coastguard Worker {
1755*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("Expression too complex.");
1756*8975f5c5SAndroid Build Coastguard Worker return false;
1757*8975f5c5SAndroid Build Coastguard Worker }
1758*8975f5c5SAndroid Build Coastguard Worker
1759*8975f5c5SAndroid Build Coastguard Worker if (!ValidateMaxParameters(root, mResources.MaxFunctionParameters))
1760*8975f5c5SAndroid Build Coastguard Worker {
1761*8975f5c5SAndroid Build Coastguard Worker mDiagnostics.globalError("Function has too many parameters.");
1762*8975f5c5SAndroid Build Coastguard Worker return false;
1763*8975f5c5SAndroid Build Coastguard Worker }
1764*8975f5c5SAndroid Build Coastguard Worker
1765*8975f5c5SAndroid Build Coastguard Worker return true;
1766*8975f5c5SAndroid Build Coastguard Worker }
1767*8975f5c5SAndroid Build Coastguard Worker
initializeGLPosition(TIntermBlock * root)1768*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::initializeGLPosition(TIntermBlock *root)
1769*8975f5c5SAndroid Build Coastguard Worker {
1770*8975f5c5SAndroid Build Coastguard Worker sh::ShaderVariable var(GL_FLOAT_VEC4);
1771*8975f5c5SAndroid Build Coastguard Worker var.name = "gl_Position";
1772*8975f5c5SAndroid Build Coastguard Worker return InitializeVariables(this, root, {var}, &mSymbolTable, mShaderVersion, mExtensionBehavior,
1773*8975f5c5SAndroid Build Coastguard Worker false, false);
1774*8975f5c5SAndroid Build Coastguard Worker }
1775*8975f5c5SAndroid Build Coastguard Worker
useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock * root)1776*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root)
1777*8975f5c5SAndroid Build Coastguard Worker {
1778*8975f5c5SAndroid Build Coastguard Worker sh::InterfaceBlockList list;
1779*8975f5c5SAndroid Build Coastguard Worker
1780*8975f5c5SAndroid Build Coastguard Worker for (const sh::InterfaceBlock &block : mUniformBlocks)
1781*8975f5c5SAndroid Build Coastguard Worker {
1782*8975f5c5SAndroid Build Coastguard Worker if (!block.staticUse &&
1783*8975f5c5SAndroid Build Coastguard Worker (block.layout == sh::BLOCKLAYOUT_STD140 || block.layout == sh::BLOCKLAYOUT_SHARED))
1784*8975f5c5SAndroid Build Coastguard Worker {
1785*8975f5c5SAndroid Build Coastguard Worker list.push_back(block);
1786*8975f5c5SAndroid Build Coastguard Worker }
1787*8975f5c5SAndroid Build Coastguard Worker }
1788*8975f5c5SAndroid Build Coastguard Worker
1789*8975f5c5SAndroid Build Coastguard Worker return sh::UseInterfaceBlockFields(this, root, list, mSymbolTable);
1790*8975f5c5SAndroid Build Coastguard Worker }
1791*8975f5c5SAndroid Build Coastguard Worker
initializeOutputVariables(TIntermBlock * root)1792*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::initializeOutputVariables(TIntermBlock *root)
1793*8975f5c5SAndroid Build Coastguard Worker {
1794*8975f5c5SAndroid Build Coastguard Worker InitVariableList list;
1795*8975f5c5SAndroid Build Coastguard Worker list.reserve(mOutputVaryings.size());
1796*8975f5c5SAndroid Build Coastguard Worker if (mShaderType == GL_VERTEX_SHADER || mShaderType == GL_GEOMETRY_SHADER_EXT ||
1797*8975f5c5SAndroid Build Coastguard Worker mShaderType == GL_TESS_CONTROL_SHADER_EXT || mShaderType == GL_TESS_EVALUATION_SHADER_EXT)
1798*8975f5c5SAndroid Build Coastguard Worker {
1799*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &var : mOutputVaryings)
1800*8975f5c5SAndroid Build Coastguard Worker {
1801*8975f5c5SAndroid Build Coastguard Worker list.push_back(var);
1802*8975f5c5SAndroid Build Coastguard Worker if (var.name == "gl_Position")
1803*8975f5c5SAndroid Build Coastguard Worker {
1804*8975f5c5SAndroid Build Coastguard Worker ASSERT(!mGLPositionInitialized);
1805*8975f5c5SAndroid Build Coastguard Worker mGLPositionInitialized = true;
1806*8975f5c5SAndroid Build Coastguard Worker }
1807*8975f5c5SAndroid Build Coastguard Worker }
1808*8975f5c5SAndroid Build Coastguard Worker }
1809*8975f5c5SAndroid Build Coastguard Worker else
1810*8975f5c5SAndroid Build Coastguard Worker {
1811*8975f5c5SAndroid Build Coastguard Worker ASSERT(mShaderType == GL_FRAGMENT_SHADER);
1812*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &var : mOutputVariables)
1813*8975f5c5SAndroid Build Coastguard Worker {
1814*8975f5c5SAndroid Build Coastguard Worker // in-out variables represent the context of the framebuffer
1815*8975f5c5SAndroid Build Coastguard Worker // when the draw call starts, so they have to be considered
1816*8975f5c5SAndroid Build Coastguard Worker // as already initialized.
1817*8975f5c5SAndroid Build Coastguard Worker if (!var.isFragmentInOut)
1818*8975f5c5SAndroid Build Coastguard Worker {
1819*8975f5c5SAndroid Build Coastguard Worker list.push_back(var);
1820*8975f5c5SAndroid Build Coastguard Worker }
1821*8975f5c5SAndroid Build Coastguard Worker }
1822*8975f5c5SAndroid Build Coastguard Worker }
1823*8975f5c5SAndroid Build Coastguard Worker return InitializeVariables(this, root, list, &mSymbolTable, mShaderVersion, mExtensionBehavior,
1824*8975f5c5SAndroid Build Coastguard Worker false, false);
1825*8975f5c5SAndroid Build Coastguard Worker }
1826*8975f5c5SAndroid Build Coastguard Worker
getExtensionBehavior() const1827*8975f5c5SAndroid Build Coastguard Worker const TExtensionBehavior &TCompiler::getExtensionBehavior() const
1828*8975f5c5SAndroid Build Coastguard Worker {
1829*8975f5c5SAndroid Build Coastguard Worker return mExtensionBehavior;
1830*8975f5c5SAndroid Build Coastguard Worker }
1831*8975f5c5SAndroid Build Coastguard Worker
getSourcePath() const1832*8975f5c5SAndroid Build Coastguard Worker const char *TCompiler::getSourcePath() const
1833*8975f5c5SAndroid Build Coastguard Worker {
1834*8975f5c5SAndroid Build Coastguard Worker return mSourcePath;
1835*8975f5c5SAndroid Build Coastguard Worker }
1836*8975f5c5SAndroid Build Coastguard Worker
getResources() const1837*8975f5c5SAndroid Build Coastguard Worker const ShBuiltInResources &TCompiler::getResources() const
1838*8975f5c5SAndroid Build Coastguard Worker {
1839*8975f5c5SAndroid Build Coastguard Worker return mResources;
1840*8975f5c5SAndroid Build Coastguard Worker }
1841*8975f5c5SAndroid Build Coastguard Worker
getBuiltInFunctionEmulator() const1842*8975f5c5SAndroid Build Coastguard Worker const BuiltInFunctionEmulator &TCompiler::getBuiltInFunctionEmulator() const
1843*8975f5c5SAndroid Build Coastguard Worker {
1844*8975f5c5SAndroid Build Coastguard Worker return mBuiltInFunctionEmulator;
1845*8975f5c5SAndroid Build Coastguard Worker }
1846*8975f5c5SAndroid Build Coastguard Worker
isVaryingDefined(const char * varyingName)1847*8975f5c5SAndroid Build Coastguard Worker bool TCompiler::isVaryingDefined(const char *varyingName)
1848*8975f5c5SAndroid Build Coastguard Worker {
1849*8975f5c5SAndroid Build Coastguard Worker ASSERT(mVariablesCollected);
1850*8975f5c5SAndroid Build Coastguard Worker for (size_t ii = 0; ii < mInputVaryings.size(); ++ii)
1851*8975f5c5SAndroid Build Coastguard Worker {
1852*8975f5c5SAndroid Build Coastguard Worker if (mInputVaryings[ii].name == varyingName)
1853*8975f5c5SAndroid Build Coastguard Worker {
1854*8975f5c5SAndroid Build Coastguard Worker return true;
1855*8975f5c5SAndroid Build Coastguard Worker }
1856*8975f5c5SAndroid Build Coastguard Worker }
1857*8975f5c5SAndroid Build Coastguard Worker for (size_t ii = 0; ii < mOutputVaryings.size(); ++ii)
1858*8975f5c5SAndroid Build Coastguard Worker {
1859*8975f5c5SAndroid Build Coastguard Worker if (mOutputVaryings[ii].name == varyingName)
1860*8975f5c5SAndroid Build Coastguard Worker {
1861*8975f5c5SAndroid Build Coastguard Worker return true;
1862*8975f5c5SAndroid Build Coastguard Worker }
1863*8975f5c5SAndroid Build Coastguard Worker }
1864*8975f5c5SAndroid Build Coastguard Worker
1865*8975f5c5SAndroid Build Coastguard Worker return false;
1866*8975f5c5SAndroid Build Coastguard Worker }
1867*8975f5c5SAndroid Build Coastguard Worker
1868*8975f5c5SAndroid Build Coastguard Worker } // namespace sh
1869