summaryrefslogtreecommitdiffstats
path: root/ANGLE/src/compiler/ShaderLang.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-08-27 17:00:52 +0100
committerSteve Block <steveblock@google.com>2010-08-27 17:00:52 +0100
commita9bfd6c4a32dfd9cc032cb67c6ccb8d09c16f579 (patch)
treed69bc189eb2ea23d5cb9fa0a1d89320515f3788c /ANGLE/src/compiler/ShaderLang.cpp
parent7dbefbd5e0e191ea647b8af3581382d04a073fe5 (diff)
downloadexternal_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.cpp289
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();
+}