--- include/GLSLANG/ShaderLang.h.orig +++ include/GLSLANG/ShaderLang.h @@ -50,6 +50,10 @@ SH_ESSL_OUTPUT, // GLSL output only supported in some configurations. + SH_GLSL_COMPATIBILITY_OUTPUT, + // Note: GL introduced core profiles in 1.5. + SH_GLSL_130_OUTPUT, + SH_GLSL_140_OUTPUT, SH_GLSL_150_CORE_OUTPUT, SH_GLSL_330_CORE_OUTPUT, SH_GLSL_400_CORE_OUTPUT, --- samples/shader_translator/shader_translator.cpp.orig +++ samples/shader_translator/shader_translator.cpp @@ -441,8 +441,9 @@ " -s=w : use WebGL 1.0 spec\n" " -s=w2 : use WebGL 2.0 spec\n" " -b=e : output GLSL ES code (this is by default)\n" - " -b=g : output GLSL code (version 150)\n" - " -b=g[NUM]: output GLSL code (NUM can be 150, 330, 400, 410, 420, 430, 440, 450)\n" + " -b=g : output GLSL code (compatibility profile)\n" + " -b=g[NUM]: output GLSL code (NUM can be 130, 140, 150, 330, 400, 410, 420, 430, " + "440, 450)\n" " -b=v : output Vulkan SPIR-V code\n" " -b=h11 : output HLSL11 code\n" " -b=m : output MSL code\n" @@ -834,7 +835,7 @@ { if (num.length() == 0) { - *outResult = SH_GLSL_150_CORE_OUTPUT; + *outResult = SH_GLSL_COMPATIBILITY_OUTPUT; return true; } std::istringstream input(num); @@ -846,6 +847,12 @@ switch (value) { + case 130: + *outResult = SH_GLSL_130_OUTPUT; + return true; + case 140: + *outResult = SH_GLSL_140_OUTPUT; + return true; case 150: *outResult = SH_GLSL_150_CORE_OUTPUT; return true; --- src/compiler/fuzz/translator_fuzzer.cpp.orig +++ src/compiler/fuzz/translator_fuzzer.cpp @@ -159,6 +159,9 @@ std::vector validOutputs; validOutputs.push_back(SH_ESSL_OUTPUT); + validOutputs.push_back(SH_GLSL_COMPATIBILITY_OUTPUT); + validOutputs.push_back(SH_GLSL_130_OUTPUT); + validOutputs.push_back(SH_GLSL_140_OUTPUT); validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT); validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT); validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT); --- src/compiler/translator/Compiler.cpp.orig +++ src/compiler/translator/Compiler.cpp @@ -299,9 +299,10 @@ } // anonymous namespace -bool IsGLSL150OrNewer(ShShaderOutput output) +bool IsGLSL130OrNewer(ShShaderOutput output) { - return (output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || + return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT || output == SH_GLSL_420_CORE_OUTPUT || output == SH_GLSL_430_CORE_OUTPUT || output == SH_GLSL_440_CORE_OUTPUT || output == SH_GLSL_450_CORE_OUTPUT); @@ -315,7 +316,8 @@ bool IsGLSL410OrOlder(ShShaderOutput output) { - return (output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || + return (output == SH_GLSL_130_OUTPUT || output == SH_GLSL_140_OUTPUT || + output == SH_GLSL_150_CORE_OUTPUT || output == SH_GLSL_330_CORE_OUTPUT || output == SH_GLSL_400_CORE_OUTPUT || output == SH_GLSL_410_CORE_OUTPUT); } @@ -1193,6 +1195,12 @@ compileOptions.expandFragmentOutputsToVec4 = false; } + // gl_Position should always be written in GLSL compatibility output mode. + if (mOutputType == SH_GLSL_COMPATIBILITY_OUTPUT && mShaderType == GL_VERTEX_SHADER) + { + compileOptions.initGLPosition = true; + } + #if !defined(ANGLE_IR) compileOptions.useIR = false; #endif --- src/compiler/translator/Compiler.h.orig +++ src/compiler/translator/Compiler.h @@ -44,7 +44,7 @@ // // Helper function to check if the shader type is GLSL. // -bool IsGLSL150OrNewer(ShShaderOutput output); +bool IsGLSL130OrNewer(ShShaderOutput output); bool IsGLSL420OrNewer(ShShaderOutput output); bool IsGLSL410OrOlder(ShShaderOutput output); --- src/compiler/translator/glsl/ExtensionGLSL.cpp.orig +++ src/compiler/translator/glsl/ExtensionGLSL.cpp @@ -43,6 +43,11 @@ void TExtensionGLSL::checkOperator(TIntermOperator *node) { + if (mTargetVersion < GLSL_VERSION_130) + { + return; + } + switch (node->getOp()) { case EOpAbs: --- src/compiler/translator/glsl/OutputGLSL.cpp.orig +++ src/compiler/translator/glsl/OutputGLSL.cpp @@ -49,19 +49,17 @@ return; } - ASSERT(sh::IsGLSL150OrNewer(getShaderOutput())); - // Some built-ins get a special translation. const ImmutableString &name = node->getName(); if (name == "gl_FragDepthEXT") { out << "gl_FragDepth"; } - else if (name == "gl_FragColor") + else if (name == "gl_FragColor" && sh::IsGLSL130OrNewer(getShaderOutput())) { out << "webgl_FragColor"; } - else if (name == "gl_FragData") + else if (name == "gl_FragData" && sh::IsGLSL130OrNewer(getShaderOutput())) { out << "webgl_FragData"; } @@ -82,7 +80,20 @@ ImmutableString TOutputGLSL::translateTextureFunction(const ImmutableString &name, const ShCompileOptions &option) { - ASSERT(sh::IsGLSL150OrNewer(getShaderOutput())); + static const char *simpleRename[] = {"texture2DLodEXT", + "texture2DLod", + "texture2DProjLodEXT", + "texture2DProjLod", + "textureCubeLodEXT", + "textureCubeLod", + "texture2DGradEXT", + "texture2DGradARB", + "texture2DProjGradEXT", + "texture2DProjGradARB", + "textureCubeGradEXT", + "textureCubeGradARB", + nullptr, + nullptr}; static const char *legacyToCoreRename[] = { "texture2D", "texture", "texture2DProj", "textureProj", "texture2DLod", "textureLod", "texture2DProjLod", "textureProjLod", "texture2DRect", "texture", "texture2DRectProj", @@ -94,12 +105,14 @@ "texture", "texture3DProj", "textureProj", "texture3DLod", "textureLod", "texture3DProjLod", "textureProjLod", "shadow2DEXT", "texture", "shadow2DProjEXT", "textureProj", nullptr, nullptr}; + const char **mapping = + (sh::IsGLSL130OrNewer(getShaderOutput())) ? legacyToCoreRename : simpleRename; - for (int i = 0; ANGLE_UNSAFE_TODO(legacyToCoreRename[i]) != nullptr; i += 2) + for (int i = 0; ANGLE_UNSAFE_TODO(mapping[i]) != nullptr; i += 2) { - if (name == ANGLE_UNSAFE_TODO(legacyToCoreRename[i])) + if (name == ANGLE_UNSAFE_TODO(mapping[i])) { - return ImmutableString(ANGLE_UNSAFE_TODO(legacyToCoreRename[i + 1])); + return ImmutableString(ANGLE_UNSAFE_TODO(mapping[i + 1])); } } --- src/compiler/translator/glsl/OutputGLSLBase.cpp.orig +++ src/compiler/translator/glsl/OutputGLSLBase.cpp @@ -384,7 +384,7 @@ break; } } - if (sh::IsGLSL150OrNewer(mOutput)) + if (sh::IsGLSL130OrNewer(mOutput)) { switch (qualifier) { @@ -408,7 +408,7 @@ // gl_ClipDistance / gl_CullDistance require different qualifiers based on shader type. case EvqClipDistance: case EvqCullDistance: - return (sh::IsGLSL150OrNewer(mOutput) || mShaderVersion > 100) + return (sh::IsGLSL130OrNewer(mOutput) || mShaderVersion > 100) ? (mShaderType == GL_FRAGMENT_SHADER ? "in" : "out") : "varying"; --- src/compiler/translator/glsl/TranslatorGLSL.cpp.orig +++ src/compiler/translator/glsl/TranslatorGLSL.cpp @@ -32,8 +32,6 @@ const ShCompileOptions &compileOptions, PerformanceDiagnostics * /*perfDiagnostics*/) { - ASSERT(sh::IsGLSL150OrNewer(getOutputType())); - TInfoSinkBase &sink = getInfoSink().obj; // Write GLSL version. @@ -176,6 +174,7 @@ const bool mayHaveESSL1SecondaryOutputs = IsExtensionEnabled(getExtensionBehavior(), TExtension::EXT_blend_func_extended) && getShaderVersion() == 100; + const bool declareGLFragmentOutputs = IsGLSL130OrNewer(getOutputType()); bool hasGLFragColor = false; bool hasGLFragData = false; @@ -184,17 +183,20 @@ for (const auto &outputVar : mOutputVariables) { - if (outputVar.name == "gl_FragColor") - { - ASSERT(!hasGLFragColor); - hasGLFragColor = true; - continue; - } - else if (outputVar.name == "gl_FragData") + if (declareGLFragmentOutputs) { - ASSERT(!hasGLFragData); - hasGLFragData = true; - continue; + if (outputVar.name == "gl_FragColor") + { + ASSERT(!hasGLFragColor); + hasGLFragColor = true; + continue; + } + else if (outputVar.name == "gl_FragData") + { + ASSERT(!hasGLFragData); + hasGLFragData = true; + continue; + } } if (mayHaveESSL1SecondaryOutputs) { @@ -261,18 +263,23 @@ bool TranslatorGLSL::shouldFlattenPragmaStdglInvariantAll() { - // Required when outputting to any GLSL version greater than 1.20, but since ANGLE always - // translates to at least version 1.50, return true. - return true; + // 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()); } void TranslatorGLSL::writeVersion(TIntermNode *root) { - int version = ShaderOutputTypeToGLSLVersion(getOutputType()); - ASSERT(version >= GLSL_VERSION_150); - - TInfoSinkBase &sink = getInfoSink().obj; - sink << "#version " << version << "\n"; + 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. + // If there is no version directive in the shader, 110 is implied. + if (version > 110) + { + TInfoSinkBase &sink = getInfoSink().obj; + sink << "#version " << version << "\n"; + } } void TranslatorGLSL::writeExtensionBehavior(TIntermNode *root, @@ -291,6 +298,30 @@ continue; } + 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::EXT_geometry_shader || + iter.first == TExtension::OES_geometry_shader) + { + sink << "#extension GL_ARB_geometry_shader4 : " << GetBehaviorString(iter.second) + << "\n"; + } + } + const bool isMultiview = (iter.first == TExtension::OVR_multiview) || (iter.first == TExtension::OVR_multiview2); if (isMultiview) @@ -380,7 +411,7 @@ // Need to enable gpu_shader5 to have index constant sampler array indexing if (usesGPUShader5) { - if (getOutputType() >= SH_GLSL_150_CORE_OUTPUT && + if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT && getShaderVersion() == 100) { // Don't use "require" on to avoid breaking WebGL 1 on drivers that silently @@ -400,7 +431,8 @@ if (usesTextureCubeMapArray) { - if (getOutputType() >= SH_GLSL_150_CORE_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT) + if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT && + getOutputType() < SH_GLSL_400_CORE_OUTPUT) { sink << "#extension GL_ARB_texture_cube_map_array : enable\n"; } @@ -413,7 +445,8 @@ if (usesTextureBuffer) { - if (getOutputType() >= SH_GLSL_150_CORE_OUTPUT && getOutputType() < SH_GLSL_400_CORE_OUTPUT) + if (getOutputType() >= SH_GLSL_COMPATIBILITY_OUTPUT && + getOutputType() < SH_GLSL_400_CORE_OUTPUT) { sink << "#extension GL_ARB_texture_buffer_objects : enable\n"; } --- src/compiler/translator/glsl/VersionGLSL.cpp.orig +++ src/compiler/translator/glsl/VersionGLSL.cpp @@ -6,13 +6,25 @@ #include "compiler/translator/glsl/VersionGLSL.h" +#include "angle_gl.h" +#include "compiler/translator/Symbol.h" + namespace sh { +namespace +{ +constexpr const ImmutableString kGlPointCoordString("gl_PointCoord"); +} // anonymous namespace + int ShaderOutputTypeToGLSLVersion(ShShaderOutput output) { switch (output) { + case SH_GLSL_130_OUTPUT: + return GLSL_VERSION_130; + case SH_GLSL_140_OUTPUT: + return GLSL_VERSION_140; case SH_GLSL_150_CORE_OUTPUT: return GLSL_VERSION_150; case SH_GLSL_330_CORE_OUTPUT: @@ -29,10 +41,116 @@ return GLSL_VERSION_440; case SH_GLSL_450_CORE_OUTPUT: return GLSL_VERSION_450; + case SH_GLSL_COMPATIBILITY_OUTPUT: + return GLSL_VERSION_110; default: UNREACHABLE(); return 0; } } +// We need to scan for the following: +// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders +// but only at the global scope. +// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader +// but inside any scope. +// 3. Call to a matrix constructor with another matrix as argument. +// (These constructors were reserved in GLSL version 1.10.) +// 4. Arrays as "out" function parameters. +// GLSL spec section 6.1.1: "When calling a function, expressions that do +// not evaluate to l-values cannot be passed to parameters declared as +// out or inout." +// GLSL 1.1 section 5.8: "Other binary or unary expressions, +// non-dereferenced arrays, function names, swizzles with repeated fields, +// and constants cannot be l-values." +// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that +// are built-in types, entire structures or arrays... are all l-values." +// +TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output) + : TIntermTraverser(true, false, false) +{ + mVersion = ShaderOutputTypeToGLSLVersion(output); + if (pragma.stdgl.invariantAll) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } + if (type == GL_COMPUTE_SHADER) + { + ensureVersionIsAtLeast(GLSL_VERSION_430); + } +} + +void TVersionGLSL::visitSymbol(TIntermSymbol *node) +{ + if (node->variable().symbolType() == SymbolType::BuiltIn && + node->getName() == kGlPointCoordString) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } +} + +bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node) +{ + const TIntermSequence &sequence = *(node->getSequence()); + if (sequence.front()->getAsTyped()->getType().isInvariant()) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } + return true; +} + +bool TVersionGLSL::visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node) +{ + if (node->isPrecise()) + { + ensureVersionIsAtLeast(GLSL_VERSION_420); + } + else + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } + return true; +} + +void TVersionGLSL::visitFunctionPrototype(TIntermFunctionPrototype *node) +{ + size_t paramCount = node->getFunction()->getParamCount(); + for (size_t i = 0; i < paramCount; ++i) + { + const TVariable *param = node->getFunction()->getParam(i); + const TType &type = param->getType(); + if (type.isArray()) + { + TQualifier qualifier = type.getQualifier(); + if ((qualifier == EvqParamOut) || (qualifier == EvqParamInOut)) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + break; + } + } + } +} + +bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node) +{ + if (node->getOp() == EOpConstruct && node->getType().isMatrix()) + { + const TIntermSequence &sequence = *(node->getSequence()); + if (sequence.size() == 1) + { + TIntermTyped *typed = sequence.front()->getAsTyped(); + if (typed && typed->isMatrix()) + { + ensureVersionIsAtLeast(GLSL_VERSION_120); + } + } + } + return true; +} + +void TVersionGLSL::ensureVersionIsAtLeast(int version) +{ + mVersion = std::max(version, mVersion); +} + } // namespace sh --- src/compiler/translator/glsl/VersionGLSL.h.orig +++ src/compiler/translator/glsl/VersionGLSL.h @@ -9,9 +9,15 @@ #include "compiler/translator/tree_util/IntermTraverse.h" +#include "compiler/translator/Pragma.h" + namespace sh { +static const int GLSL_VERSION_110 = 110; +static const int GLSL_VERSION_120 = 120; +static const int GLSL_VERSION_130 = 130; +static const int GLSL_VERSION_140 = 140; static const int GLSL_VERSION_150 = 150; static const int GLSL_VERSION_330 = 330; static const int GLSL_VERSION_400 = 400; @@ -23,6 +29,48 @@ int ShaderOutputTypeToGLSLVersion(ShShaderOutput output); +// Traverses the intermediate tree to return the minimum GLSL version +// required to legally access all built-in features used in the shader. +// GLSL 1.1 which is mandated by OpenGL 2.0 provides: +// - #version and #extension to declare version and extensions. +// - built-in functions refract, exp, and log. +// - updated step() to compare x < edge instead of x <= edge. +// GLSL 1.2 which is mandated by OpenGL 2.1 provides: +// - many changes to reduce differences when compared to the ES specification. +// - invariant keyword and its support. +// - c++ style name hiding rules. +// - built-in variable gl_PointCoord for fragment shaders. +// - matrix constructors taking matrix as argument. +// - array as "out" function parameters +// +// TODO: ES3 equivalent versions of GLSL +class TVersionGLSL : public TIntermTraverser +{ + public: + TVersionGLSL(sh::GLenum type, const TPragma &pragma, ShShaderOutput output); + + // If output is core profile, returns 150. + // If output is legacy profile, + // Returns 120 if the following is used the shader: + // - "invariant", + // - "gl_PointCoord", + // - matrix/matrix constructors + // - array "out" parameters + // Else 110 is returned. + int getVersion() const { return mVersion; } + + void visitSymbol(TIntermSymbol *node) override; + bool visitAggregate(Visit, TIntermAggregate *node) override; + bool visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *node) override; + void visitFunctionPrototype(TIntermFunctionPrototype *node) override; + bool visitDeclaration(Visit, TIntermDeclaration *node) override; + + private: + void ensureVersionIsAtLeast(int version); + + int mVersion; +}; + } // namespace sh #endif // COMPILER_TRANSLATOR_GLSL_VERSIONGLSL_H_ --- src/compiler/translator/ir/src/compile.rs.orig +++ src/compiler/translator/ir/src/compile.rs @@ -18,6 +18,9 @@ enum OutputLanguage { Null, Essl, + GlslCompatibility, + Glsl130, + Glsl140, Glsl150Core, Glsl330Core, Glsl400Core, @@ -418,7 +421,10 @@ #[cfg(not(angle_enable_essl))] panic!("Internal error: ESSL generator is not built"); } - OutputLanguage::Glsl150Core + OutputLanguage::GlslCompatibility + | OutputLanguage::Glsl130 + | OutputLanguage::Glsl140 + | OutputLanguage::Glsl150Core | OutputLanguage::Glsl330Core | OutputLanguage::Glsl400Core | OutputLanguage::Glsl410Core --- src/compiler/translator/util.cpp.orig +++ src/compiler/translator/util.cpp @@ -838,6 +838,8 @@ { switch (output) { + case SH_GLSL_130_OUTPUT: + case SH_GLSL_140_OUTPUT: case SH_GLSL_150_CORE_OUTPUT: case SH_GLSL_330_CORE_OUTPUT: case SH_GLSL_400_CORE_OUTPUT: @@ -846,6 +848,7 @@ case SH_GLSL_430_CORE_OUTPUT: case SH_GLSL_440_CORE_OUTPUT: case SH_GLSL_450_CORE_OUTPUT: + case SH_GLSL_COMPATIBILITY_OUTPUT: return true; default: break; --- src/libANGLE/renderer/gl/FenceNVGL.cpp.orig +++ src/libANGLE/renderer/gl/FenceNVGL.cpp @@ -103,10 +103,8 @@ // static bool FenceNVSyncGL::Supported(const FunctionsGL *functions) { - // GL 3.2 is required for desktop GL - ASSERT(functions->standard != STANDARD_GL_DESKTOP || functions->isAtLeastGL(gl::Version(3, 2))); - return functions->standard == STANDARD_GL_DESKTOP || - functions->isAtLeastGLES(gl::Version(3, 0)); + return functions->isAtLeastGL(gl::Version(3, 2)) || + functions->isAtLeastGLES(gl::Version(3, 0)) || functions->hasGLExtension("GL_ARB_sync"); } } // namespace rx --- src/libANGLE/renderer/gl/renderergl_utils.cpp.orig +++ src/libANGLE/renderer/gl/renderergl_utils.cpp @@ -382,8 +382,19 @@ { return SH_GLSL_330_CORE_OUTPUT; } - ASSERT(functions->isAtLeastGL(gl::Version(3, 2))); - return SH_GLSL_150_CORE_OUTPUT; + if (functions->isAtLeastGL(gl::Version(3, 2))) + { + return SH_GLSL_150_CORE_OUTPUT; + } + if (functions->isAtLeastGL(gl::Version(3, 1))) + { + return SH_GLSL_140_OUTPUT; + } + if (functions->isAtLeastGL(gl::Version(3, 0))) + { + return SH_GLSL_130_OUTPUT; + } + return SH_GLSL_COMPATIBILITY_OUTPUT; } if (functions->standard == STANDARD_GL_ES) { @@ -801,12 +812,6 @@ // Start by assuming ES3.1 support and work down *maxSupportedESVersion = gl::Version(3, 1); - // Desktop GL below 3.2 is not supported - if (functions->standard == STANDARD_GL_DESKTOP && !functions->isAtLeastGL(gl::Version(3, 2))) - { - LimitVersion(maxSupportedESVersion, gl::Version(0, 0)); - } - // Texture format support checks const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); for (GLenum internalFormat : allFormats) @@ -3010,8 +3015,7 @@ } bool SupportsSeparateFramebufferBindings(const FunctionsGL *functions) { - // Note: GL 3.2 is required for desktop GL - return functions->standard == STANDARD_GL_DESKTOP || + return functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)); } --- src/tests/angle_unittests.gni.orig +++ src/tests/angle_unittests.gni @@ -93,6 +93,7 @@ "compiler_tests/CollectVariables_test.cpp", "compiler_tests/ConstructCompiler_test.cpp", "compiler_tests/FloatLex_test.cpp", + "compiler_tests/GLSLCompatibilityOutput_test.cpp", "compiler_tests/GeometryShader_test.cpp", "compiler_tests/GlFragDataNotModified_test.cpp", "compiler_tests/HashNames_test.cpp", --- src/tests/compiler_tests/CollectVariables_test.cpp.orig +++ src/tests/compiler_tests/CollectVariables_test.cpp @@ -54,7 +54,8 @@ virtual void initTranslator(const ShBuiltInResources &resources) { - mTranslator.reset(new TranslatorGLSL(mShaderType, SH_GLES3_SPEC, SH_GLSL_150_CORE_OUTPUT)); + mTranslator.reset( + new TranslatorGLSL(mShaderType, SH_GLES3_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT)); ASSERT_TRUE(mTranslator->Init(resources)); } @@ -175,7 +176,7 @@ void initTranslator(const ShBuiltInResources &resources) override { mTranslator.reset( - new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_150_CORE_OUTPUT)); + new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT)); ASSERT_TRUE(mTranslator->Init(resources)); } }; @@ -231,7 +232,7 @@ void initTranslator(const ShBuiltInResources &resources) { mTranslator.reset( - new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_150_CORE_OUTPUT)); + new TranslatorGLSL(mShaderType, SH_GLES3_1_SPEC, SH_GLSL_COMPATIBILITY_OUTPUT)); ASSERT_TRUE(mTranslator->Init(resources)); } }; --- src/tests/compiler_tests/ConstructCompiler_test.cpp.orig +++ src/tests/compiler_tests/ConstructCompiler_test.cpp @@ -17,7 +17,7 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC, - SH_GLSL_150_CORE_OUTPUT, &resources); + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); ASSERT_NE(nullptr, compiler); sh::Destruct(compiler); } @@ -29,7 +29,7 @@ sh::InitBuiltInResources(&resources); resources.MaxDrawBuffers = 0; ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC, - SH_GLSL_150_CORE_OUTPUT, &resources); + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); ASSERT_EQ(nullptr, compiler); } @@ -41,6 +41,6 @@ resources.EXT_blend_func_extended = 1; resources.MaxDualSourceDrawBuffers = 0; ShHandle compiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC, - SH_GLSL_150_CORE_OUTPUT, &resources); + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); ASSERT_EQ(nullptr, compiler); } --- /dev/null +++ src/tests/compiler_tests/GLSLCompatibilityOutput_test.cpp @@ -0,0 +1,34 @@ +// +// Copyright 2016 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. +// +// GLSLCompatibilityOutputTest.cpp +// Test compiler output for glsl compatibility mode +// + +#include "GLSLANG/ShaderLang.h" +#include "angle_gl.h" +#include "gtest/gtest.h" +#include "tests/test_utils/compiler_test.h" + +using namespace sh; + +class GLSLCompatibilityOutputTest : public MatchOutputCodeTest +{ + public: + GLSLCompatibilityOutputTest() + : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_GLSL_COMPATIBILITY_OUTPUT) + {} +}; + +// Verify gl_Position is written when compiling in compatibility mode +TEST_F(GLSLCompatibilityOutputTest, GLPositionWrittenTest) +{ + const std::string &shaderString = + "precision mediump float;\n" + "void main() {\n" + "}"; + compile(shaderString); + EXPECT_TRUE(foundInCode("gl_Position")); +} --- src/tests/compiler_tests/PruneEmptyCases_test.cpp.orig +++ src/tests/compiler_tests/PruneEmptyCases_test.cpp @@ -21,7 +21,7 @@ class PruneEmptyCasesTest : public MatchOutputCodeTest { public: - PruneEmptyCasesTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_GLSL_150_CORE_OUTPUT) {} + PruneEmptyCasesTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_GLSL_COMPATIBILITY_OUTPUT) {} }; // Test that a switch statement that only contains no-ops is pruned entirely. --- src/tests/compiler_tests/PruneEmptyDeclarations_test.cpp.orig +++ src/tests/compiler_tests/PruneEmptyDeclarations_test.cpp @@ -20,7 +20,9 @@ class PruneEmptyDeclarationsTest : public MatchOutputCodeTest { public: - PruneEmptyDeclarationsTest() : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_GLSL_150_CORE_OUTPUT) {} + PruneEmptyDeclarationsTest() + : MatchOutputCodeTest(GL_VERTEX_SHADER, SH_GLSL_COMPATIBILITY_OUTPUT) + {} }; TEST_F(PruneEmptyDeclarationsTest, EmptyDeclarationStartsDeclaratorList) --- src/tests/compiler_tests/PruneNoOps_test.cpp.orig +++ src/tests/compiler_tests/PruneNoOps_test.cpp @@ -20,7 +20,7 @@ class PruneNoOpsTest : public MatchOutputCodeTest { public: - PruneNoOpsTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_GLSL_150_CORE_OUTPUT) {} + PruneNoOpsTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_GLSL_COMPATIBILITY_OUTPUT) {} }; // Test that a switch statement with a constant expression without a matching case is pruned. --- src/tests/compiler_tests/ShCompile_test.cpp.orig +++ src/tests/compiler_tests/ShCompile_test.cpp @@ -24,7 +24,7 @@ { sh::InitBuiltInResources(&mResources); mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC, - SH_GLSL_150_CORE_OUTPUT, &mResources); + SH_GLSL_COMPATIBILITY_OUTPUT, &mResources); ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed."; } @@ -84,7 +84,7 @@ { sh::InitBuiltInResources(&mResources); mCompiler = sh::ConstructCompiler(GL_COMPUTE_SHADER, SH_GLES3_1_SPEC, - SH_GLSL_150_CORE_OUTPUT, &mResources); + SH_GLSL_COMPATIBILITY_OUTPUT, &mResources); ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed."; } }; --- src/tests/compiler_tests/ShaderVariable_test.cpp.orig +++ src/tests/compiler_tests/ShaderVariable_test.cpp @@ -230,8 +230,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *program[] = { @@ -253,8 +253,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *program1[] = { @@ -288,8 +288,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *program1[] = { @@ -330,8 +330,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *program1[] = { @@ -372,8 +372,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES2_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *program1[] = { @@ -466,8 +466,8 @@ ShBuiltInResources resources; sh::InitBuiltInResources(&resources); - ShHandle compiler = - sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES3_SPEC, SH_GLSL_150_CORE_OUTPUT, &resources); + ShHandle compiler = sh::ConstructCompiler(GL_VERTEX_SHADER, SH_GLES3_SPEC, + SH_GLSL_COMPATIBILITY_OUTPUT, &resources); EXPECT_NE(static_cast(0), compiler); const char *front_underscores[] = { --- src/tests/test_utils/compiler_test.h.orig +++ src/tests/test_utils/compiler_test.h @@ -61,7 +61,7 @@ bool foundInGLSLCode(const char *stringToFind) const { - return foundInCode(SH_GLSL_150_CORE_OUTPUT, stringToFind); + return foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, stringToFind); } bool foundInCode(ShShaderOutput output, const char *stringToFind) const;