From 0a7aebadfbb3534284546aa3ca8612314c08f136 Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 26 Jun 2018 16:56:45 +0200 Subject: Update ANGLE to chromium/3280 Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint --- .../src/compiler/translator/TranslatorGLSL.cpp | 214 +++++++++++++++++---- 1 file changed, 178 insertions(+), 36 deletions(-) (limited to 'src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp') diff --git a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp index 05e9eb310b..a14e69e5d5 100644 --- a/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp +++ b/src/3rdparty/angle/src/compiler/translator/TranslatorGLSL.cpp @@ -11,53 +11,116 @@ #include "compiler/translator/EmulatePrecision.h" #include "compiler/translator/ExtensionGLSL.h" #include "compiler/translator/OutputGLSL.h" +#include "compiler/translator/RewriteTexelFetchOffset.h" +#include "compiler/translator/RewriteUnaryMinusOperatorFloat.h" #include "compiler/translator/VersionGLSL.h" -TranslatorGLSL::TranslatorGLSL(sh::GLenum type, - ShShaderSpec spec, - ShShaderOutput output) - : TCompiler(type, spec, output) { +namespace sh +{ + +TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output) + : TCompiler(type, spec, output) +{ } -void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) +void TranslatorGLSL::initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, + ShCompileOptions compileOptions) { - if (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS) + if (compileOptions & SH_EMULATE_ABS_INT_FUNCTION) + { + InitBuiltInAbsFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + } + + if (compileOptions & SH_EMULATE_ISNAN_FLOAT_FUNCTION) { - InitBuiltInFunctionEmulatorForGLSLWorkarounds(emu, getShaderType()); + InitBuiltInIsnanFunctionEmulatorForGLSLWorkarounds(emu, getShaderVersion()); + } + + if (compileOptions & SH_EMULATE_ATAN2_FLOAT_FUNCTION) + { + InitBuiltInAtanFunctionEmulatorForGLSLWorkarounds(emu); } int targetGLSLVersion = ShaderOutputTypeToGLSLVersion(getOutputType()); InitBuiltInFunctionEmulatorForGLSLMissingFunctions(emu, getShaderType(), targetGLSLVersion); } -void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) +void TranslatorGLSL::translate(TIntermBlock *root, + ShCompileOptions compileOptions, + PerformanceDiagnostics * /*perfDiagnostics*/) { - TInfoSinkBase& sink = getInfoSink().obj; + TInfoSinkBase &sink = getInfoSink().obj; // Write GLSL version. writeVersion(root); - writePragma(); - // Write extension behaviour as needed - writeExtensionBehavior(root); + writeExtensionBehavior(root, compileOptions); + + // Write pragmas after extensions because some drivers consider pragmas + // like non-preprocessor tokens. + writePragma(compileOptions); + + // If flattening the global invariant pragma, write invariant declarations for built-in + // variables. It should be harmless to do this twice in the case that the shader also explicitly + // did this. However, it's important to emit invariant qualifiers only for those built-in + // variables that are actually used, to avoid affecting the behavior of the shader. + if ((compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) != 0 && + getPragma().stdgl.invariantAll && + !sh::RemoveInvariant(getShaderType(), getShaderVersion(), getOutputType(), compileOptions)) + { + ASSERT(wereVariablesCollected()); + + switch (getShaderType()) + { + case GL_VERTEX_SHADER: + sink << "invariant gl_Position;\n"; - bool precisionEmulation = getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; + // gl_PointSize should be declared invariant in both ESSL 1.00 and 3.00 fragment + // shaders if it's statically referenced. + conditionallyOutputInvariantDeclaration("gl_PointSize"); + break; + case GL_FRAGMENT_SHADER: + // The preprocessor will reject this pragma if it's used in ESSL 3.00 fragment + // shaders, so we can use simple logic to determine whether to declare these + // variables invariant. + conditionallyOutputInvariantDeclaration("gl_FragCoord"); + conditionallyOutputInvariantDeclaration("gl_PointCoord"); + break; + default: + // Currently not reached, but leave this in for future expansion. + ASSERT(false); + break; + } + } + + if ((compileOptions & SH_REWRITE_TEXELFETCHOFFSET_TO_TEXELFETCH) != 0) + { + sh::RewriteTexelFetchOffset(root, getSymbolTable(), getShaderVersion()); + } + + if ((compileOptions & SH_REWRITE_FLOAT_UNARY_MINUS_OPERATOR) != 0) + { + sh::RewriteUnaryMinusOperatorFloat(root); + } + + bool precisionEmulation = + getResources().WEBGL_debug_shader_precision && getPragma().debugShaderPrecision; if (precisionEmulation) { - EmulatePrecision emulatePrecision(getSymbolTable(), getShaderVersion()); + EmulatePrecision emulatePrecision(&getSymbolTable(), getShaderVersion()); root->traverse(&emulatePrecision); emulatePrecision.updateTree(); - emulatePrecision.writeEmulationHelpers(sink, getOutputType()); + emulatePrecision.writeEmulationHelpers(sink, getShaderVersion(), getOutputType()); } // Write emulated built-in functions if needed. - if (!getBuiltInFunctionEmulator().IsOutputEmpty()) + 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 << "#define emu_precision\n\n"; + getBuiltInFunctionEmulator().outputEmulatedFunctions(sink); sink << "// END: Generated code for built-in function emulation\n\n"; } @@ -69,7 +132,7 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) if (getShaderType() == GL_FRAGMENT_SHADER) { const bool mayHaveESSL1SecondaryOutputs = - IsExtensionEnabled(getExtensionBehavior(), "GL_EXT_blend_func_extended") && + IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_blend_func_extended) && getShaderVersion() == 100; const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType()); @@ -132,17 +195,48 @@ void TranslatorGLSL::translate(TIntermNode *root, int compileOptions) } } + if (getShaderType() == GL_COMPUTE_SHADER && isComputeShaderLocalSizeDeclared()) + { + const sh::WorkGroupSize &localSize = getComputeShaderLocalSize(); + sink << "layout (local_size_x=" << localSize[0] << ", local_size_y=" << localSize[1] + << ", local_size_z=" << localSize[2] << ") in;\n"; + } + + if (getShaderType() == GL_GEOMETRY_SHADER_OES) + { + WriteGeometryShaderLayoutQualifiers( + sink, getGeometryShaderInputPrimitiveType(), getGeometryShaderInvocations(), + getGeometryShaderOutputPrimitiveType(), getGeometryShaderMaxVertices()); + } + // Write translated shader. - TOutputGLSL outputGLSL(sink, - getArrayIndexClampingStrategy(), - getHashFunction(), - getNameMap(), - getSymbolTable(), - getShaderVersion(), - getOutputType()); + TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), + &getSymbolTable(), getShaderType(), getShaderVersion(), getOutputType(), + compileOptions); + + if (compileOptions & SH_TRANSLATE_VIEWID_OVR_TO_UNIFORM) + { + TName uniformName(TString("ViewID_OVR")); + uniformName.setInternal(true); + sink << "uniform int " << outputGLSL.hashName(uniformName) << ";\n"; + } + root->traverse(&outputGLSL); } +bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll() +{ + // Required when outputting to any GLSL version greater than 1.20, but since ANGLE doesn't + // translate to that version, return true for the next higher version. + return IsGLSL130OrNewer(getOutputType()); +} + +bool TranslatorGLSL::shouldCollectVariables(ShCompileOptions compileOptions) +{ + return (compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL) || + TCompiler::shouldCollectVariables(compileOptions); +} + void TranslatorGLSL::writeVersion(TIntermNode *root) { TVersionGLSL versionGLSL(getShaderType(), getPragma(), getOutputType()); @@ -152,15 +246,15 @@ void TranslatorGLSL::writeVersion(TIntermNode *root) // If there is no version directive in the shader, 110 is implied. if (version > 110) { - TInfoSinkBase& sink = getInfoSink().obj; + TInfoSinkBase &sink = getInfoSink().obj; sink << "#version " << version << "\n"; } } -void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) +void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root, ShCompileOptions compileOptions) { - TInfoSinkBase& sink = getInfoSink().obj; - const TExtensionBehavior& extBehavior = getExtensionBehavior(); + TInfoSinkBase &sink = getInfoSink().obj; + const TExtensionBehavior &extBehavior = getExtensionBehavior(); for (const auto &iter : extBehavior) { if (iter.second == EBhUndefined) @@ -168,21 +262,58 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) continue; } - // For GLSL output, we don't need to emit most extensions explicitly, - // but some we need to translate. - if (iter.first == "GL_EXT_shader_texture_lod") + if (getOutputType() == SH_GLSL_COMPATIBILITY_OUTPUT) + { + // For GLSL output, we don't need to emit most extensions explicitly, + // but some we need to translate in GL compatibility profile. + if (iter.first == TExtension::EXT_shader_texture_lod) + { + sink << "#extension GL_ARB_shader_texture_lod : " << GetBehaviorString(iter.second) + << "\n"; + } + + if (iter.first == TExtension::EXT_draw_buffers) + { + sink << "#extension GL_ARB_draw_buffers : " << GetBehaviorString(iter.second) + << "\n"; + } + + if (iter.first == TExtension::OES_geometry_shader) + { + sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second) + << "\n"; + } + } + + const bool isMultiview = (iter.first == TExtension::OVR_multiview); + if (isMultiview && getShaderType() == GL_VERTEX_SHADER && + (compileOptions & SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER) != 0u) { - sink << "#extension GL_ARB_shader_texture_lod : " << getBehaviorString(iter.second) - << "\n"; + // Emit the NV_viewport_array2 extension in a vertex shader if the + // SH_SELECT_VIEW_IN_NV_GLSL_VERTEX_SHADER option is set and the OVR_multiview(2) + // extension is requested. + sink << "#extension GL_NV_viewport_array2 : require\n"; } } // GLSL ES 3 explicit location qualifiers need to use an extension before GLSL 330 - if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT) + if (getShaderVersion() >= 300 && getOutputType() < SH_GLSL_330_CORE_OUTPUT && + getShaderType() != GL_COMPUTE_SHADER) { sink << "#extension GL_ARB_explicit_attrib_location : require\n"; } + // Need to enable gpu_shader5 to have index constant sampler array indexing + if (getOutputType() != SH_ESSL_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT && + getShaderVersion() == 100) + { + // Don't use "require" on to avoid breaking WebGL 1 on drivers that silently + // support index constant sampler array indexing, but don't have the extension or + // on drivers that don't have the extension at all as it would break WebGL 1 for + // some users. + sink << "#extension GL_ARB_gpu_shader5 : enable\n"; + } + TExtensionGLSL extensionGLSL(getOutputType()); root->traverse(&extensionGLSL); @@ -195,3 +326,14 @@ void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root) sink << "#extension " << ext << " : require\n"; } } + +void TranslatorGLSL::conditionallyOutputInvariantDeclaration(const char *builtinVaryingName) +{ + if (isVaryingDefined(builtinVaryingName)) + { + TInfoSinkBase &sink = getInfoSink().obj; + sink << "invariant " << builtinVaryingName << ";\n"; + } +} + +} // namespace sh -- cgit v1.2.3