Hash :
4888ceb6
Author :
Date :
2010-10-01T21:13:12
Made the API of shader translator library consistent. - We recently started using OpenGL-type enums. This CL makes all old enums consistent with the new scheme. - Renamed TBuiltInResource to ShBuiltInResources to have a consistent prefix BUG=46 Review URL: http://codereview.appspot.com/2328041 git-svn-id: https://angleproject.googlecode.com/svn/trunk@443 736b8ea6-26fd-11df-bfd4-992fa37f6226
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "compiler/Initialize.h"
#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
static bool InitializeSymbolTable(
const TBuiltInStrings& builtInStrings,
ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
TInfoSink& infoSink, TSymbolTable& symbolTable)
{
TIntermediate intermediate(infoSink);
TExtensionBehavior extBehavior;
TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
GlobalParseContext = &parseContext;
setInitialState();
assert(symbolTable.isEmpty());
//
// Parse the built-ins. This should only happen once per
// language symbol table.
//
// Push the symbol table to give it an initial scope. This
// push should not have a corresponding pop, so that built-ins
// are preserved, and the test for an empty table fails.
//
symbolTable.push();
//Initialize the Preprocessor
if (InitPreprocessor())
{
infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
return false;
}
for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
{
const char* builtInShaders = i->c_str();
int builtInLengths = static_cast<int>(i->size());
if (builtInLengths <= 0)
continue;
if (PaParseStrings(&builtInShaders, &builtInLengths, 1, parseContext) != 0)
{
infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
return false;
}
}
IdentifyBuiltIns(type, spec, resources, symbolTable);
FinalizePreprocessor();
return true;
}
static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
{
for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
iter != extBehavior.end(); ++iter) {
PredefineIntMacro(iter->first.c_str(), 1);
}
}
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec)
{
}
TCompiler::~TCompiler()
{
}
bool TCompiler::Init(const ShBuiltInResources& resources)
{
// Generate built-in symbol table.
if (!InitBuiltInSymbolTable(resources))
return false;
InitExtensionBehavior(resources, extensionBehavior);
return true;
}
bool TCompiler::compile(const char* const shaderStrings[],
const int numStrings,
int compileOptions)
{
clearResults();
if (numStrings == 0)
return true;
TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, infoSink);
GlobalParseContext = &parseContext;
setInitialState();
// Initialize preprocessor.
InitPreprocessor();
DefineExtensionMacros(extensionBehavior);
// We preserve symbols at the built-in level from compile-to-compile.
// Start pushing the user-defined symbols at global level.
symbolTable.push();
if (!symbolTable.atGlobalLevel())
infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
// Parse shader.
bool success =
(PaParseStrings(shaderStrings, 0, numStrings, parseContext) == 0) &&
(parseContext.treeRoot != NULL);
if (success) {
success = intermediate.postProcess(parseContext.treeRoot);
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
intermediate.outputTree(parseContext.treeRoot);
if (success && (compileOptions & SH_OBJECT_CODE))
translate(parseContext.treeRoot);
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
collectAttribsUniforms(parseContext.treeRoot);
}
// Cleanup memory.
intermediate.remove(parseContext.treeRoot);
// Ensure symbol table is returned to the built-in level,
// throwing away all but the built-ins.
while (!symbolTable.atBuiltInLevel())
symbolTable.pop();
FinalizePreprocessor();
return success;
}
bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
{
TBuiltIns builtIns;
builtIns.initialize(shaderType, shaderSpec, resources);
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
shaderType, shaderSpec, resources, infoSink, symbolTable);
}
void TCompiler::clearResults()
{
infoSink.info.erase();
infoSink.obj.erase();
infoSink.debug.erase();
attribs.clear();
uniforms.clear();
}
void TCompiler::collectAttribsUniforms(TIntermNode* root)
{
CollectAttribsUniforms collect(attribs, uniforms);
root->traverse(&collect);
}