diff options
author | Steve Block <steveblock@google.com> | 2010-08-27 17:00:52 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-08-27 17:00:52 +0100 |
commit | a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579 (patch) | |
tree | d69bc189eb2ea23d5cb9fa0a1d89320515f3788c /ANGLE/src/compiler/ShaderLang.cpp | |
parent | 7dbefbd5e0e191ea647b8af3581382d04a073fe5 (diff) | |
download | external_webkit-a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579.zip external_webkit-a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579.tar.gz external_webkit-a9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579.tar.bz2 |
Add ANGLE at r65615
ANGLE is now required for the Mac build, so should have been added
as part of the merge to r65615.
Change-Id: I048185d196cf3150651fff0e3761fc57928f18ce
Diffstat (limited to 'ANGLE/src/compiler/ShaderLang.cpp')
-rw-r--r-- | ANGLE/src/compiler/ShaderLang.cpp | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/ANGLE/src/compiler/ShaderLang.cpp b/ANGLE/src/compiler/ShaderLang.cpp new file mode 100644 index 0000000..3c36ef8 --- /dev/null +++ b/ANGLE/src/compiler/ShaderLang.cpp @@ -0,0 +1,289 @@ +// +// 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. +// + +// +// Implement the top-level of interface to the compiler, +// as defined in ShaderLang.h +// + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/Initialize.h" +#include "compiler/InitializeDll.h" +#include "compiler/ParseHelper.h" +#include "compiler/ShHandle.h" +#include "compiler/SymbolTable.h" + +static bool InitializeSymbolTable( + const TBuiltInStrings& builtInStrings, + EShLanguage language, EShSpec spec, const TBuiltInResource& resources, + TInfoSink& infoSink, TSymbolTable& symbolTable) +{ + TIntermediate intermediate(infoSink); + TParseContext parseContext(symbolTable, intermediate, language, 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[1]; + int builtInLengths[1]; + + builtInShaders[0] = (*i).c_str(); + builtInLengths[0] = (int) (*i).size(); + + if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) + { + infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); + return false; + } + } + + IdentifyBuiltIns(language, spec, resources, symbolTable); + + FinalizePreprocessor(); + + return true; +} + +static bool GenerateBuiltInSymbolTable( + EShLanguage language, EShSpec spec, const TBuiltInResource& resources, + TInfoSink& infoSink, TSymbolTable& symbolTable) +{ + TBuiltIns builtIns; + + builtIns.initialize(language, spec, resources); + return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable); +} + +// +// This is the platform independent interface between an OGL driver +// and the shading language compiler. +// + +// +// Driver must call this first, once, before doing any other +// compiler operations. +// +int ShInitialize() +{ + bool ret = InitProcess(); + + return ret ? 1 : 0; +} + +// +// Driver calls these to create and destroy compiler objects. +// + +ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources) +{ + if (!InitThread()) + return 0; + + TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec)); + TCompiler* compiler = base->getAsCompiler(); + if (compiler == 0) + return 0; + + // Generate built-in symbol table. + if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) { + ShDestruct(base); + return 0; + } + + return reinterpret_cast<void*>(base); +} + +void ShDestruct(ShHandle handle) +{ + if (handle == 0) + return; + + TShHandleBase* base = static_cast<TShHandleBase*>(handle); + + if (base->getAsCompiler()) + DeleteCompiler(base->getAsCompiler()); +} + +// +// Cleanup symbol tables +// +int ShFinalize() +{ + return 1; +} + +// +// Do an actual compile on the given strings. The result is left +// in the given compile object. +// +// Return: The return value of ShCompile is really boolean, indicating +// success or failure. +// +int ShCompile( + const ShHandle handle, + const char* const shaderStrings[], + const int numStrings, + const EShOptimizationLevel optLevel, + int debugOptions + ) +{ + if (!InitThread()) + return 0; + + if (handle == 0) + return 0; + + TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle); + TCompiler* compiler = base->getAsCompiler(); + if (compiler == 0) + return 0; + + GlobalPoolAllocator.push(); + TInfoSink& infoSink = compiler->getInfoSink(); + infoSink.info.erase(); + infoSink.debug.erase(); + infoSink.obj.erase(); + + if (numStrings == 0) + return 1; + + TIntermediate intermediate(infoSink); + TSymbolTable& symbolTable = compiler->getSymbolTable(); + + TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink); + parseContext.initializeExtensionBehavior(); + GlobalParseContext = &parseContext; + + setInitialState(); + + InitPreprocessor(); + // + // Parse the application's shaders. All the following symbol table + // work will be throw-away, so push a new allocation scope that can + // be thrown away, then push a scope for the current shader's globals. + // + bool success = true; + + symbolTable.push(); + if (!symbolTable.atGlobalLevel()) + parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level"); + + int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext); + if (ret) + success = false; + + if (success && parseContext.treeRoot) { + if (optLevel == EShOptNoGeneration) + parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation was requested."); + else { + success = intermediate.postProcess(parseContext.treeRoot, parseContext.language); + + if (success) { + + if (debugOptions & EDebugOpIntermediate) + intermediate.outputTree(parseContext.treeRoot); + + // + // Call the machine dependent compiler + // + if (!compiler->compile(parseContext.treeRoot)) + success = false; + } + } + } else if (!success) { + parseContext.infoSink.info.prefix(EPrefixError); + parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; + success = false; + if (debugOptions & EDebugOpIntermediate) + intermediate.outputTree(parseContext.treeRoot); + } else if (!parseContext.treeRoot) { + parseContext.error(1, "Unexpected end of file.", "", ""); + parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n"; + success = false; + if (debugOptions & EDebugOpIntermediate) + intermediate.outputTree(parseContext.treeRoot); + } + + 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(); + // + // Throw away all the temporary memory used by the compilation process. + // + GlobalPoolAllocator.pop(); + + return success ? 1 : 0; +} + +// +// Return any compiler log of messages for the application. +// +const char* ShGetInfoLog(const ShHandle handle) +{ + if (!InitThread()) + return 0; + + if (handle == 0) + return 0; + + TShHandleBase* base = static_cast<TShHandleBase*>(handle); + TInfoSink* infoSink = 0; + + if (base->getAsCompiler()) + infoSink = &(base->getAsCompiler()->getInfoSink()); + + infoSink->info << infoSink->debug.c_str(); + return infoSink->info.c_str(); +} + +// +// Return any object code. +// +const char* ShGetObjectCode(const ShHandle handle) +{ + if (!InitThread()) + return 0; + + if (handle == 0) + return 0; + + TShHandleBase* base = static_cast<TShHandleBase*>(handle); + TInfoSink* infoSink; + + if (base->getAsCompiler()) + infoSink = &(base->getAsCompiler()->getInfoSink()); + + return infoSink->obj.c_str(); +} |