diff --git a/Install/Windows/glslangValidator.exe b/Install/Windows/glslangValidator.exe
index 792c066a197e623d26101c08e13faba247bee5d7..b64716382f8e0a2032fd5bfb4a1bbd6cb5431b5a 100644
Binary files a/Install/Windows/glslangValidator.exe and b/Install/Windows/glslangValidator.exe differ
diff --git a/Test/100.frag b/Test/100.frag
index 57c5c88e2da1848aa09aa096b60bfff4010ab7ce..a4dc7982235a6b5ad2d1081611b411eca6b0639e 100644
--- a/Test/100.frag
+++ b/Test/100.frag
@@ -110,4 +110,31 @@ void foo239()
 {
     gl_FragDepth = f13;    // ERROR
     gl_FragDepthEXT = f13;
-}
\ No newline at end of file
+}
+
+#extension GL_OES_EGL_image_external : enable
+
+uniform samplerExternalOES sExt;
+
+void foo245()
+{
+    texture2D(sExt, vec2(0.2));
+    texture2DProj(sExt, vec3(f13));
+    texture2DProj(sExt, v[2]);
+}
+
+precision mediump samplerExternalOES;
+uniform samplerExternalOES mediumExt;
+uniform highp samplerExternalOES highExt;
+
+void foo246()
+{
+    texture2D(mediumExt, vec2(0.2));
+    texture2DProj(highExt, v[2]);
+    texture3D(sExt, vec3(f13));   // ERROR
+    texture2DProjLod(sExt, vec3(f13), f13);  // ERROR
+}
+
+#extension GL_OES_EGL_image_external : disable
+
+uniform samplerExternalOES badExt;  // syntax ERROR
diff --git a/Test/baseResults/100.frag.out b/Test/baseResults/100.frag.out
index db43e6a74244833164815682874aaeebb7f901f7..07dc9871a1db39b8d6ba7ac02bac2fd6860356f6 100644
--- a/Test/baseResults/100.frag.out
+++ b/Test/baseResults/100.frag.out
@@ -48,7 +48,10 @@ ERROR: 0:93: 'fwidth' : required extension not requested: GL_OES_standard_deriva
 ERROR: 0:103: 'gl_FragDepth' : undeclared identifier 
 ERROR: 0:104: 'gl_FragDepthEXT' : required extension not requested: GL_EXT_frag_depth
 ERROR: 0:111: 'gl_FragDepth' : undeclared identifier 
-ERROR: 43 compilation errors.  No code generated.
+ERROR: 0:134: 'texture3D' : no matching overloaded function found 
+ERROR: 0:135: 'texture2DProjLod' : no matching overloaded function found 
+ERROR: 0:140: '' :  syntax error
+ERROR: 46 compilation errors.  No code generated.
 
 ERROR: node is still EOpNull!
 0:3  Sequence
@@ -184,6 +187,42 @@ ERROR: node is still EOpNull!
 0:112      move second child to first child (highp float)
 0:112        'gl_FragDepthEXT' (gl_FragDepth highp float)
 0:112        'f13' (invariant mediump float)
+0:119  Function Definition: foo245( (void)
+0:119    Function Parameters: 
+0:121    Sequence
+0:121      Function Call: texture2D(sE21;vf2; (lowp 4-component vector of float)
+0:121        'sExt' (uniform lowp samplerExternalOES)
+0:121        Constant:
+0:121          0.200000
+0:121          0.200000
+0:122      Function Call: texture2DProj(sE21;vf3; (lowp 4-component vector of float)
+0:122        'sExt' (uniform lowp samplerExternalOES)
+0:122        Construct vec3 (3-component vector of float)
+0:122          'f13' (invariant mediump float)
+0:123      Function Call: texture2DProj(sE21;vf4; (lowp 4-component vector of float)
+0:123        'sExt' (uniform lowp samplerExternalOES)
+0:123        direct index (smooth mediump 4-component vector of float)
+0:123          'v' (smooth in 3-element array of mediump 4-component vector of float)
+0:123          Constant:
+0:123            2 (const int)
+0:130  Function Definition: foo246( (void)
+0:130    Function Parameters: 
+0:132    Sequence
+0:132      Function Call: texture2D(sE21;vf2; (mediump 4-component vector of float)
+0:132        'mediumExt' (uniform mediump samplerExternalOES)
+0:132        Constant:
+0:132          0.200000
+0:132          0.200000
+0:133      Function Call: texture2DProj(sE21;vf4; (highp 4-component vector of float)
+0:133        'highExt' (uniform highp samplerExternalOES)
+0:133        direct index (smooth mediump 4-component vector of float)
+0:133          'v' (smooth in 3-element array of mediump 4-component vector of float)
+0:133          Constant:
+0:133            2 (const int)
+0:134      Constant:
+0:134        0.000000
+0:135      Constant:
+0:135        0.000000
 0:?   Linker Objects
 0:?     'a' (3-element array of mediump int)
 0:?     'uint' (mediump int)
@@ -200,4 +239,7 @@ ERROR: node is still EOpNull!
 0:?     'vary2D' (smooth in lowp sampler2D)
 0:?     's3D' (uniform mediump sampler3D)
 0:?     's3D2' (uniform highp sampler3D)
+0:?     'sExt' (uniform lowp samplerExternalOES)
+0:?     'mediumExt' (uniform mediump samplerExternalOES)
+0:?     'highExt' (uniform highp samplerExternalOES)
 
diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h
index 330df775951e9412f7204e1f9563b749c14f13cb..1a74a4ec68800e0b8c1afe1c0f756fb339d7c8ca 100644
--- a/glslang/Include/Types.h
+++ b/glslang/Include/Types.h
@@ -65,6 +65,7 @@ struct TSampler {
     bool     shadow : 1;
     bool         ms : 1;
     bool      image : 1;
+    bool   external : 1;  // GL_OES_EGL_image_external
 
     void clear()
     {
@@ -74,6 +75,7 @@ struct TSampler {
         shadow = false;
         ms = false;
         image = false;
+        external = false;
     }
 
     void set(TBasicType t, TSamplerDim d, bool a = false, bool s = false, bool m = false)
@@ -84,6 +86,7 @@ struct TSampler {
         shadow = s;
         ms = m;
         image = false;
+        external = false;
     }
 
     void setImage(TBasicType t, TSamplerDim d, bool a = false, bool s = false, bool m = false)
@@ -94,6 +97,7 @@ struct TSampler {
         shadow = s;
         ms = m;
         image = true;
+        external = false;
     }
 
     bool operator==(const TSampler& right) const
@@ -103,7 +107,8 @@ struct TSampler {
             arrayed == right.arrayed &&
              shadow == right.shadow &&
                  ms == right.ms &&
-              image == right.image;
+              image == right.image &&
+           external == right.external;
     }
 
     TString getString() const
@@ -120,6 +125,10 @@ struct TSampler {
             s.append("image");
         else
             s.append("sampler");
+        if (external) {
+            s.append("ExternalOES");
+            return s;
+        }
         switch (dim) {
         case Esd1D:      s.append("1D");     break;
         case Esd2D:      s.append("2D");     break;
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 6c600b2cd78a6ba37cf89cc17653c54482514624..be3726fc24998135456c53f304c5fca50b2454ce 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -686,6 +686,15 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "\n");
     }
 
+    if (profile == EEsProfile) {
+        // GL_OES_EGL_image_external, caught by keyword check
+        commonBuiltins.append(
+            "vec4 texture2D(samplerExternalOES, vec2 coord);"
+            "vec4 texture2DProj(samplerExternalOES, vec3);"
+            "vec4 texture2DProj(samplerExternalOES, vec4);"
+            "\n");
+    }
+
     //
     // Noise functions.
     //
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index e9dc7b1708703cf5779d2bdb2273c5325b093199..29c21129f77b87e1a250876b5bbb65f3ac7e0288 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -74,6 +74,9 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, bool pb,
         defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
         sampler.set(EbtFloat, EsdCube);
         defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
+        sampler.set(EbtFloat, Esd2D);
+        sampler.external = true;
+        defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow;
 
         switch (language) {
         case EShLangFragment:
@@ -1715,10 +1718,11 @@ void TParseContext::setDefaultPrecision(TSourceLoc loc, TPublicType& publicType,
 // correlates with the declaration of defaultSamplerPrecision[]
 int TParseContext::computeSamplerTypeIndex(TSampler& sampler)
 {
-    int arrayIndex = sampler.arrayed ? 1 : 0;
-    int shadowIndex = sampler.shadow ? 1 : 0;
+    int arrayIndex   = sampler.arrayed   ? 1 : 0;
+    int shadowIndex   = sampler.shadow   ? 1 : 0;
+    int externalIndex = sampler.external ? 1 : 0;
 
-    return EsdNumDims * (EbtNumTypes * (2 * arrayIndex + shadowIndex) + sampler.type) + sampler.dim;
+    return EsdNumDims * (EbtNumTypes * (2 * (2 * arrayIndex + shadowIndex) + externalIndex) + sampler.type) + sampler.dim;
 }
 
 TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType)
diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h
index 9ff76e77454ea2852ce9907b1a448fac4abd5292..c7680ba3310b7784d843e96aa6db3307b7c2f77e 100644
--- a/glslang/MachineIndependent/ParseHelper.h
+++ b/glslang/MachineIndependent/ParseHelper.h
@@ -238,7 +238,7 @@ protected:
     int numErrors;               // number of compile-time errors encountered
     bool parsingBuiltins;        // true if parsing built-in symbols/functions
     TMap<TString, TExtensionBehavior> extensionBehavior;    // for each extension string, what its current behavior is set to
-    static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex()
+    static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2 * 2)); // see computeSamplerTypeIndex()
     TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex];
     bool afterEOF;
     TQualifier globalBufferDefaults;
diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp
index c93099cd2c0c31f33f0465e155a8e91c14db62fd..2f6fd24f95f4533cebe7eb23ec6890c204626b68 100644
--- a/glslang/MachineIndependent/Scan.cpp
+++ b/glslang/MachineIndependent/Scan.cpp
@@ -424,6 +424,7 @@ void TScanContext::fillInKeywordMap()
     (*KeywordMap)["sampler2DRect"] =           SAMPLER2DRECT;
     (*KeywordMap)["sampler2DRectShadow"] =     SAMPLER2DRECTSHADOW;
     (*KeywordMap)["sampler1DArray"] =          SAMPLER1DARRAY;
+    (*KeywordMap)["samplerExternalOES"] =      SAMPLEREXTERNALOES; // GL_OES_EGL_image_external
     (*KeywordMap)["noperspective"] =           NOPERSPECTIVE;
     (*KeywordMap)["smooth"] =                  SMOOTH;
     (*KeywordMap)["flat"] =                    FLAT;
@@ -811,6 +812,12 @@ int TScanContext::tokenizeIdentifier()
             return identifierOrType();
         return keyword;
 
+    case SAMPLEREXTERNALOES:
+        afterType = true;
+        if (parseContext.symbolTable.atBuiltInLevel() || parseContext.extensionsTurnedOn(1, &GL_OES_EGL_image_external))
+            return keyword;
+        return identifierOrType();
+
     case NOPERSPECTIVE:
         return es30ReservedFromGLSL(130);
         
diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp
index e801a935a30a2a7094f25615bade92e0af237b34..a801193a3b3009246bd4b083d5a978bccff4a4e0 100644
--- a/glslang/MachineIndependent/SymbolTable.cpp
+++ b/glslang/MachineIndependent/SymbolTable.cpp
@@ -77,6 +77,8 @@ void TType::buildMangledName(TString& mangledName)
             mangledName += "A";
         if (sampler.shadow)
             mangledName += "S";
+        if (sampler.external)
+            mangledName += "E";
         switch (sampler.dim) {
         case Esd1D:       mangledName += "1";  break;
         case Esd2D:       mangledName += "2";  break;
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 4574c4e9fe6084a91388d37060387f973ab483fb..c86d4f3782e1cd6f77152289550ee4718f892509 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -152,6 +152,7 @@ void TParseContext::initializeExtensionBehavior()
     extensionBehavior[GL_OES_texture_3D]               = EBhDisable;
     extensionBehavior[GL_OES_standard_derivatives]     = EBhDisable;
     extensionBehavior[GL_EXT_frag_depth]               = EBhDisable;
+    extensionBehavior[GL_OES_EGL_image_external]       = EBhDisable;
 
     extensionBehavior[GL_ARB_texture_rectangle]        = EBhDisable;
     extensionBehavior[GL_3DL_array_objects]            = EBhDisable;
@@ -169,7 +170,8 @@ const char* TParseContext::getPreamble()
             "#define GL_ES 1\n"
             "#define GL_OES_texture_3D 1\n"
             "#define GL_OES_standard_derivatives 1\n"
-            "#define GL_EXT_frag_depth 1\n";
+            "#define GL_EXT_frag_depth 1\n"
+            "#define GL_OES_EGL_image_external 1\n";
     } else {
         return
             "#define GL_FRAGMENT_PRECISION_HIGH 1\n"
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index 8e2ffcc02a538f5f10aea04ff27f54519e5883ed..0580cc96826d50f4bacd50464bc7f24b6437f301 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -75,6 +75,7 @@ typedef enum {
 const char* const GL_OES_texture_3D               = "GL_OES_texture_3D";
 const char* const GL_OES_standard_derivatives     = "GL_OES_standard_derivatives";
 const char* const GL_EXT_frag_depth               = "GL_EXT_frag_depth";
+const char* const GL_OES_EGL_image_external       = "GL_OES_EGL_image_external";
 
 const char* const GL_ARB_texture_rectangle        = "GL_ARB_texture_rectangle";
 const char* const GL_3DL_array_objects            = "GL_3DL_array_objects";
diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y
index df91311ebf719e9c7ef40c48e33447295c9634dd..de5438b256e3df9c21bde1505aa69f9ad09a4ce5 100644
--- a/glslang/MachineIndependent/glslang.y
+++ b/glslang/MachineIndependent/glslang.y
@@ -139,6 +139,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
 %token <lex> ISAMPLERCUBEARRAY USAMPLERCUBEARRAY
 %token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
 %token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
+%token <lex> SAMPLEREXTERNALOES
 
 %token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
 %token <lex> UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D
@@ -1951,6 +1952,12 @@ type_specifier_nonarray
         $$.basicType = EbtSampler;
         $$.sampler.setImage(EbtUint, Esd2D, true, false, true);
     }
+    | SAMPLEREXTERNALOES {  // GL_OES_EGL_image_external
+        $$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
+        $$.basicType = EbtSampler;
+        $$.sampler.set(EbtFloat, Esd2D);
+        $$.sampler.external = true;
+    }
     | struct_specifier {
         $$ = $1;
         $$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;