blob: dc5a8a194c30b76531390a264987e7a9e3674397 [file] [log] [blame]
alokp@chromium.org07620a52010-09-23 17:53:56 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "compiler/Initialize.h"
8#include "compiler/ParseHelper.h"
9#include "compiler/ShHandle.h"
10
11static bool InitializeSymbolTable(
12 const TBuiltInStrings& builtInStrings,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000013 ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
alokp@chromium.org07620a52010-09-23 17:53:56 +000014 TInfoSink& infoSink, TSymbolTable& symbolTable)
15{
16 TIntermediate intermediate(infoSink);
17 TExtensionBehavior extBehavior;
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000018 TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
alokp@chromium.org07620a52010-09-23 17:53:56 +000019
20 GlobalParseContext = &parseContext;
21
alokp@chromium.org07620a52010-09-23 17:53:56 +000022 assert(symbolTable.isEmpty());
23 //
24 // Parse the built-ins. This should only happen once per
25 // language symbol table.
26 //
27 // Push the symbol table to give it an initial scope. This
28 // push should not have a corresponding pop, so that built-ins
29 // are preserved, and the test for an empty table fails.
30 //
31 symbolTable.push();
alokp@chromium.org07620a52010-09-23 17:53:56 +000032
33 for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
34 {
alokp@chromium.org570bfc72010-09-24 17:19:25 +000035 const char* builtInShaders = i->c_str();
36 int builtInLengths = static_cast<int>(i->size());
37 if (builtInLengths <= 0)
38 continue;
alokp@chromium.org07620a52010-09-23 17:53:56 +000039
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000040 if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
alokp@chromium.org07620a52010-09-23 17:53:56 +000041 {
42 infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
43 return false;
44 }
45 }
46
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000047 IdentifyBuiltIns(type, spec, resources, symbolTable);
alokp@chromium.org07620a52010-09-23 17:53:56 +000048
alokp@chromium.org07620a52010-09-23 17:53:56 +000049 return true;
50}
51
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000052TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
53 : shaderType(type),
54 shaderSpec(spec)
55{
56}
57
58TCompiler::~TCompiler()
59{
60}
61
62bool TCompiler::Init(const ShBuiltInResources& resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +000063{
64 // Generate built-in symbol table.
65 if (!InitBuiltInSymbolTable(resources))
66 return false;
67
68 InitExtensionBehavior(resources, extensionBehavior);
69 return true;
70}
71
72bool TCompiler::compile(const char* const shaderStrings[],
73 const int numStrings,
74 int compileOptions)
75{
76 clearResults();
77
78 if (numStrings == 0)
79 return true;
80
81 TIntermediate intermediate(infoSink);
82 TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000083 shaderType, shaderSpec, infoSink);
alokp@chromium.org07620a52010-09-23 17:53:56 +000084 GlobalParseContext = &parseContext;
alokp@chromium.org07620a52010-09-23 17:53:56 +000085
86 // We preserve symbols at the built-in level from compile-to-compile.
87 // Start pushing the user-defined symbols at global level.
88 symbolTable.push();
89 if (!symbolTable.atGlobalLevel())
90 infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
91
92 // Parse shader.
93 bool success =
alokp@chromium.org044a5cf2010-11-12 15:42:16 +000094 (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) &&
alokp@chromium.org07620a52010-09-23 17:53:56 +000095 (parseContext.treeRoot != NULL);
96 if (success) {
97 success = intermediate.postProcess(parseContext.treeRoot);
98
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000099 if (success && (compileOptions & SH_INTERMEDIATE_TREE))
alokp@chromium.org07620a52010-09-23 17:53:56 +0000100 intermediate.outputTree(parseContext.treeRoot);
101
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000102 if (success && (compileOptions & SH_OBJECT_CODE))
alokp@chromium.org07620a52010-09-23 17:53:56 +0000103 translate(parseContext.treeRoot);
104
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000105 if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
alokp@chromium.org07620a52010-09-23 17:53:56 +0000106 collectAttribsUniforms(parseContext.treeRoot);
107 }
108
109 // Cleanup memory.
110 intermediate.remove(parseContext.treeRoot);
111 // Ensure symbol table is returned to the built-in level,
112 // throwing away all but the built-ins.
113 while (!symbolTable.atBuiltInLevel())
114 symbolTable.pop();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000115
116 return success;
117}
118
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000119bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000120{
121 TBuiltIns builtIns;
122
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000123 builtIns.initialize(shaderType, shaderSpec, resources);
124 return InitializeSymbolTable(builtIns.getBuiltInStrings(),
125 shaderType, shaderSpec, resources, infoSink, symbolTable);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000126}
127
128void TCompiler::clearResults()
129{
130 infoSink.info.erase();
131 infoSink.obj.erase();
132 infoSink.debug.erase();
133
134 attribs.clear();
135 uniforms.clear();
136}
137
138void TCompiler::collectAttribsUniforms(TIntermNode* root)
139{
140 CollectAttribsUniforms collect(attribs, uniforms);
141 root->traverse(&collect);
142}
143