diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp | 114 |
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; |