summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp114
1 files changed, 104 insertions, 10 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
index 6acbf7c5a8..aea3f77c4e 100644
--- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp
@@ -6,14 +6,69 @@
#include "compiler/translator/TranslatorGLSL.h"
+#include "angle_gl.h"
+#include "compiler/translator/BuiltInFunctionEmulatorGLSL.h"
+#include "compiler/translator/EmulatePrecision.h"
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/VersionGLSL.h"
-TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
- : TCompiler(type, spec, SH_GLSL_OUTPUT) {
+namespace
+{
+
+// To search for what output variables are used in a fragment shader.
+// We handle gl_FragColor and gl_FragData at the moment.
+class TFragmentOutSearcher : public TIntermTraverser
+{
+ public:
+ TFragmentOutSearcher()
+ : mUsesGlFragColor(false),
+ mUsesGlFragData(false)
+ {
+ }
+
+ bool usesGlFragColor() const
+ {
+ return mUsesGlFragColor;
+ }
+
+ bool usesGlFragData() const
+ {
+ return mUsesGlFragData;
+ }
+
+ protected:
+ virtual void visitSymbol(TIntermSymbol *node) override
+ {
+ if (node->getSymbol() == "gl_FragColor")
+ {
+ mUsesGlFragColor = true;
+ }
+ else if (node->getSymbol() == "gl_FragData")
+ {
+ mUsesGlFragData = true;
+ }
+ }
+
+ private:
+ bool mUsesGlFragColor;
+ bool mUsesGlFragData;
+};
+
+} // namespace anonymous
+
+TranslatorGLSL::TranslatorGLSL(sh::GLenum type,
+ ShShaderSpec spec,
+ ShShaderOutput output)
+ : TCompiler(type, spec, output) {
+}
+
+void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions)
+{
+ if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)
+ InitBuiltInFunctionEmulatorForGLSL(emu, getShaderType());
}
-void TranslatorGLSL::translate(TIntermNode* root) {
+void TranslatorGLSL::translate(TIntermNode *root, int) {
TInfoSinkBase& sink = getInfoSink().obj;
// Write GLSL version.
@@ -24,21 +79,60 @@ void TranslatorGLSL::translate(TIntermNode* root) {
// Write extension behaviour as needed
writeExtensionBehavior();
+ bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision;
+
+ if (precisionEmulation)
+ {
+ EmulatePrecision emulatePrecision;
+ root->traverse(&emulatePrecision);
+ emulatePrecision.updateTree();
+ emulatePrecision.writeEmulationHelpers(sink, getOutputType());
+ }
+
// Write emulated built-in functions if needed.
- getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
- sink, false);
+ if (!getBuiltInFunctionEmulator().IsOutputEmpty())
+ {
+ sink << "// BEGIN: Generated code for built-in function emulation\n\n";
+ sink << "#define webgl_emu_precision\n\n";
+ getBuiltInFunctionEmulator().OutputEmulatedFunctions(sink);
+ sink << "// END: Generated code for built-in function emulation\n\n";
+ }
// Write array bounds clamping emulation if needed.
getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+ // Declare gl_FragColor and glFragData as webgl_FragColor and webgl_FragData
+ // if it's core profile shaders and they are used.
+ if (getShaderType() == GL_FRAGMENT_SHADER &&
+ getOutputType() == SH_GLSL_CORE_OUTPUT)
+ {
+ TFragmentOutSearcher searcher;
+ root->traverse(&searcher);
+ ASSERT(!(searcher.usesGlFragData() && searcher.usesGlFragColor()));
+ if (searcher.usesGlFragColor())
+ {
+ sink << "out vec4 webgl_FragColor;\n";
+ }
+ if (searcher.usesGlFragData())
+ {
+ sink << "out vec4 webgl_FragData[gl_MaxDrawBuffers];\n";
+ }
+ }
+
// Write translated shader.
- TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable(), getShaderVersion());
+ TOutputGLSL outputGLSL(sink,
+ getArrayIndexClampingStrategy(),
+ getHashFunction(),
+ getNameMap(),
+ getSymbolTable(),
+ getShaderVersion(),
+ getOutputType());
root->traverse(&outputGLSL);
}
void TranslatorGLSL::writeVersion(TIntermNode *root)
{
- TVersionGLSL versionGLSL(getShaderType(), getPragma());
+ TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType());
root->traverse(&versionGLSL);
int version = versionGLSL.getVersion();
// We need to write version directive only if it is greater than 110.
@@ -52,9 +146,9 @@ void TranslatorGLSL::writeVersion(TIntermNode *root)
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
- const TExtensionBehavior& extensionBehavior = getExtensionBehavior();
- for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
- iter != extensionBehavior.end(); ++iter) {
+ const TExtensionBehavior& extBehavior = getExtensionBehavior();
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+ iter != extBehavior.end(); ++iter) {
if (iter->second == EBhUndefined)
continue;