Add GL_OES_texture_3D extension. Also, minor tweaks to extension adding infrastructure.
authorJohn Kessenich <cepheus@frii.com>
Mon, 11 Nov 2013 18:50:06 +0000 (18:50 +0000)
committerJohn Kessenich <cepheus@frii.com>
Mon, 11 Nov 2013 18:50:06 +0000 (18:50 +0000)
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24001 e7fa87d3-cd2b-0410-9028-fcbf551c1848

Test/100.frag
Test/baseResults/100.frag.out
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/ParseHelper.h
glslang/MachineIndependent/Scan.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h

index 4250ab7..08dc51b 100644 (file)
@@ -76,3 +76,16 @@ struct sp {
     uniform float h;        // ERROR\r
     invariant float i;      // ERROR\r
 };\r
+\r
+uniform sampler3D s3D;      // ERROR\r
+\r
+#extension GL_OES_texture_3D : enable\r
+\r
+precision highp sampler3D;\r
+uniform sampler3D s3D2;\r
+\r
+void foo234()\r
+{\r
+    texture3D(s3D2, vec3(0.2), 0.2);\r
+    texture3DProj(s3D2, v[1], 0.4);\r
+}\r
index 8c7b64f..d9a755a 100644 (file)
@@ -40,7 +40,9 @@ ERROR: 0:71: 'sampler2D' : sampler/image types can only be used in uniform varia
 ERROR: 0:75: 'g' : cannot use storage or interpolation qualifiers on structure members \r
 ERROR: 0:76: 'h' : cannot use storage or interpolation qualifiers on structure members \r
 ERROR: 0:77: 'i' : cannot use invariant qualifier on structure members \r
-ERROR: 35 compilation errors.  No code generated.\r
+ERROR: 0:80: 'sampler3D' : Reserved word. \r
+ERROR: 0:80: 'sampler/image' : type requires declaration of default precision qualifier \r
+ERROR: 37 compilation errors.  No code generated.\r
 \r
 ERROR: node is still EOpNull!\r
 0:3  Sequence\r
@@ -121,6 +123,25 @@ ERROR: node is still EOpNull!
 0:67  Function Definition: f11(s21; (void)\r
 0:67    Function Parameters: \r
 0:67      'p2d' (in lowp sampler2D)\r
+0:87  Function Definition: foo234( (void)\r
+0:87    Function Parameters: \r
+0:89    Sequence\r
+0:89      Function Call: texture3D(s31;vf3;f1; (highp 4-component vector of float)\r
+0:89        's3D2' (uniform highp sampler3D)\r
+0:89        Constant:\r
+0:89          0.200000\r
+0:89          0.200000\r
+0:89          0.200000\r
+0:89        Constant:\r
+0:89          0.200000\r
+0:90      Function Call: texture3DProj(s31;vf4;f1; (highp 4-component vector of float)\r
+0:90        's3D2' (uniform highp sampler3D)\r
+0:90        direct index (smooth mediump 4-component vector of float)\r
+0:90          'v' (smooth in 3-element array of mediump 4-component vector of float)\r
+0:90          Constant:\r
+0:90            1 (const int)\r
+0:90        Constant:\r
+0:90          0.400000\r
 0:?   Linker Objects\r
 0:?     'a' (3-element array of mediump int)\r
 0:?     'uint' (mediump int)\r
@@ -135,4 +156,6 @@ ERROR: node is still EOpNull!
 0:?     'uv3' (invariant uniform mediump 3-component vector of float)\r
 0:?     'glob2D' (lowp sampler2D)\r
 0:?     'vary2D' (smooth in lowp sampler2D)\r
+0:?     's3D' (uniform mediump sampler3D)\r
+0:?     's3D2' (uniform highp sampler3D)\r
 \r
index b9d0a76..a6b6404 100644 (file)
@@ -659,6 +659,9 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture2DProj(sampler2D, vec3);"
             "vec4 texture2DProj(sampler2D, vec4);"
 
+            "vec4 texture3D(sampler3D, vec3);"     // OES_texture_3D, but caught by keyword check
+            "vec4 texture3DProj(sampler3D, vec4);" // OES_texture_3D, but caught by keyword check
+
             "vec4 textureCube(samplerCube, vec3);"
             
             "\n");
@@ -673,9 +676,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture1DProj(sampler1D, vec2);"
             "vec4 texture1DProj(sampler1D, vec4);"
                      
-            "vec4 texture3D(sampler3D, vec3);"
-            "vec4 texture3DProj(sampler3D, vec4);"
-                     
             "vec4 shadow1D(sampler1DShadow, vec3);"
             "vec4 shadow2D(sampler2DShadow, vec3);"
             "vec4 shadow1DProj(sampler1DShadow, vec4);"
@@ -742,6 +742,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture2DLod(sampler2D, vec2, float);"
             "vec4 texture2DProjLod(sampler2D, vec3, float);"
             "vec4 texture2DProjLod(sampler2D, vec4, float);"
+            "vec4 texture3DLod(sampler3D, vec3, float);"         // OES_texture_3D, but caught by keyword check
+            "vec4 texture3DProjLod(sampler3D, vec4, float);"     // OES_texture_3D, but caught by keyword check
             "vec4 textureCubeLod(samplerCube, vec3, float);"
             
             "\n");
@@ -753,8 +755,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture1DLod(sampler1D, float, float);"
             "vec4 texture1DProjLod(sampler1D, vec2, float);"
             "vec4 texture1DProjLod(sampler1D, vec4, float);"
-            "vec4 texture3DLod(sampler3D, vec3, float);"
-            "vec4 texture3DProjLod(sampler3D, vec4, float);"
             "vec4 shadow1DLod(sampler1DShadow, vec3, float);"
             "vec4 shadow2DLod(sampler2DShadow, vec3, float);"
             "vec4 shadow1DProjLod(sampler1DShadow, vec4, float);"
@@ -828,6 +828,8 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture2D(sampler2D, vec2, float);"
             "vec4 texture2DProj(sampler2D, vec3, float);"
             "vec4 texture2DProj(sampler2D, vec4, float);"
+            "vec4 texture3D(sampler3D, vec3, float);"        // OES_texture_3D
+            "vec4 texture3DProj(sampler3D, vec4, float);"    // OES_texture_3D
             "vec4 textureCube(samplerCube, vec3, float);"
             
             "\n");
@@ -837,8 +839,6 @@ void TBuiltIns::initialize(int version, EProfile profile)
             "vec4 texture1D(sampler1D, float, float);"
             "vec4 texture1DProj(sampler1D, vec2, float);"
             "vec4 texture1DProj(sampler1D, vec4, float);"
-            "vec4 texture3D(sampler3D, vec3, float);"
-            "vec4 texture3DProj(sampler3D, vec4, float);"
             "vec4 shadow1D(sampler1DShadow, vec3, float);"
             "vec4 shadow2D(sampler2DShadow, vec3, float);"
             "vec4 shadow1DProj(sampler1DShadow, vec4, float);"
index 0af66b2..557981f 100644 (file)
@@ -974,7 +974,7 @@ void TParseContext::nonOpBuiltInCheck(TSourceLoc loc, const TFunction& fnCandida
     if (fnCandidate.getName().compare(0, 13, "textureGather") == 0) {
         const char* feature = "texture gather function";
         requireProfile(loc, ~EEsProfile, feature);
-        profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature);
+        profileRequires(loc, ~EEsProfile, 400, GL_ARB_texture_gather, feature); // TODO: GL_ARB_gpu_shader5
         int lastArgIndex = fnCandidate.getParamCount() - 1;
         if (fnCandidate[lastArgIndex].type->getBasicType() == EbtInt && fnCandidate[lastArgIndex].type->isScalar()) {
             // the last integral argument to a texture gather must be a constant int between 0 and 3
index 8b31037..7c5b8ab 100644 (file)
@@ -77,7 +77,6 @@ public:
     bool reservedErrorCheck(TSourceLoc, const TString&);
     bool builtInName(const TString&);
 
-    void updateExtensionBehavior(const char* extName, const char* behavior);
     void handlePragma(const char **tokens, int numTokens);
     TIntermTyped* handleVariable(TSourceLoc, TSymbol* symbol, TString* string);
     TIntermTyped* handleBracketDereference(TSourceLoc, TIntermTyped* base, TIntermTyped* index);
@@ -180,12 +179,15 @@ public:
     // The following are implemented in Versions.cpp to localize version/profile/stage/extensions control
     void initializeExtensionBehavior();
     void requireProfile(TSourceLoc, int queryProfiles, const char *featureDesc);
-    void profileRequires(TSourceLoc, int queryProfiles, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc);
-    void profileRequires(TSourceLoc, int queryProfiles, int minVersion, const char* extension, const char *featureDesc);
+    void profileRequires(TSourceLoc, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char *featureDesc);
+    void profileRequires(TSourceLoc, int queryProfiles, int minVersion, const char* const extension, const char *featureDesc);
     void requireStage(TSourceLoc, EShLanguageMask, const char *featureDesc);
     void requireStage(TSourceLoc, EShLanguage, const char *featureDesc);
     void checkDeprecated(TSourceLoc, int queryProfiles, int depVersion, const char *featureDesc);
     void requireNotRemoved(TSourceLoc, int queryProfiles, int removedVersion, const char *featureDesc);
+    TExtensionBehavior getExtensionBehavior(const char*);
+    bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
+    void updateExtensionBehavior(const char* const extension, const char* behavior);
     void fullIntegerCheck(TSourceLoc, const char* op);
     void doubleCheck(TSourceLoc, const char* op);
 
index 39774a9..c93099c 100644 (file)
@@ -781,6 +781,13 @@ int TScanContext::tokenizeIdentifier()
         return keyword;
 
     case SAMPLER3D:
+        afterType = true;
+        if (parseContext.profile == EEsProfile && parseContext.version < 300) {
+            if (! parseContext.extensionsTurnedOn(1, &GL_OES_texture_3D))
+                reservedWord();
+        }
+        return keyword;
+
     case SAMPLER2DSHADOW:
         afterType = true;
         if (parseContext.profile == EEsProfile && parseContext.version < 300)
@@ -883,9 +890,13 @@ int TScanContext::identifierOrType()
     return IDENTIFIER;
 }
 
+// Give an error for use of a reserved symbol.
+// However, allow built-in declarations to use reserved words, to allow
+// extension support before the extension is enabled.
 int TScanContext::reservedWord()
 {
-    parseContext.error(loc, "Reserved word.", tokenText, "", "");
+    if (! parseContext.symbolTable.atBuiltInLevel())
+        parseContext.error(loc, "Reserved word.", tokenText, "", "");
 
     return 0;
 }
index 8b9680f..93e3c03 100644 (file)
@@ -65,7 +65,7 @@
 //    implements Feature F, and will log the proper error/warning messages.  Parsing 
 //    will then always continue as if the tested feature was enabled.
 //    
-//    There is typically no if-testing or conditional parsing, just insertion of requirements.
+//    There is typically no if-testing or conditional parsing, just insertion of the calls above.
 //    However, if symbols specific to the extension are added (step 5), they will
 //    only be added under tests that the minimum version and profile are present.
 //
 //        // following the requireProfile() call...
 //        profileRequires(loc, 
 //                        ECoreProfile | ECompatibilityProfile,
-//                        420, // 0 if no version incorporated the feature into the core spec.
+//                        420,             // 0 if no version incorporated the feature into the core spec.
 //                        XXX_extension_X, // can be a list of extensions that all add the feature
-//                        "Feature F");
+//                        "Feature F Description");
 // 
 //    This allows the feature if either A) one of the extensions is enabled or
 //    B) the version is high enough.  If no version yet incorporates the feature
@@ -144,6 +144,8 @@ namespace glslang {
 //
 void TParseContext::initializeExtensionBehavior()
 {
+    extensionBehavior[GL_OES_texture_3D]               = EBhDisable;
+
     extensionBehavior[GL_ARB_texture_rectangle]        = EBhDisable;
     extensionBehavior[GL_3DL_array_objects]            = EBhDisable;
     extensionBehavior[GL_ARB_shading_language_420pack] = EBhDisable;
@@ -156,7 +158,8 @@ void TParseContext::initializeExtensionBehavior()
 const char* TParseContext::getPreamble()
 {
     if (profile == EEsProfile) {
-        return 
+        return
+            "#define GL_OES_texture_3D 1\n"
             "#define GL_ES 1\n";
     } else {
         return
@@ -185,7 +188,7 @@ const char* ProfileName(EProfile profile)
 //
 // When to use requireProfile():
 //
-//     If only some profiles support a feature.  However, if within a profile the feature 
+//     Use if only some profiles support a feature.  However, if within a profile the feature 
 //     is version or extension specific, follow this call with calls to profileRequires().
 //
 // Operation:  If the current profile is not one of the profileMask,
@@ -230,15 +233,14 @@ const char* StageName(EShLanguage stage)
 //
 
 // entry point that takes multiple extensions
-void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVersion, int numExtensions, const char* extensions[], const char *featureDesc)
+void TParseContext::profileRequires(TSourceLoc loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char *featureDesc)
 {
     if (profile & profileMask) {
         bool okay = false;
         if (minVersion > 0 && version >= minVersion)
             okay = true;
         for (int i = 0; i < numExtensions; ++i) {
-            TExtensionBehavior behavior = extensionBehavior[extensions[i]];
-            switch (behavior) {
+            switch (getExtensionBehavior(extensions[i])) {
             case EBhWarn:
                 infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
                 // fall through
@@ -314,10 +316,34 @@ void TParseContext::requireNotRemoved(TSourceLoc loc, int profileMask, int remov
     }
 }
 
+TExtensionBehavior TParseContext::getExtensionBehavior(const char* extension)
+{
+    TMap<TString, TExtensionBehavior>::iterator iter = extensionBehavior.find(TString(extension));
+    if (iter == extensionBehavior.end())
+        return EBhMissing;
+    else
+        return iter->second;
+}
+
+// See if any of the extensions are set to enable, require, or warn.
+bool TParseContext::extensionsTurnedOn(int numExtensions, const char* const extensions[])
+{
+    for (int i = 0; i < numExtensions; ++i) {
+        switch (getExtensionBehavior(extensions[i])) {
+        case EBhEnable:
+        case EBhRequire:
+        case EBhWarn:
+            return true;
+        }
+    }
+
+    return false;
+}
+
 //
 // Change the current state of an extension's behavior.
 //
-void TParseContext::updateExtensionBehavior(const char* extName, const char* behaviorString)
+void TParseContext::updateExtensionBehavior(const char* extension, const char* behaviorString)
 {
     // Translate from text string of extension's behavior to an enum.
     TExtensionBehavior behavior = EBhDisable;
@@ -334,7 +360,7 @@ void TParseContext::updateExtensionBehavior(const char* extName, const char* beh
 
     // Update the current behavior
     TMap<TString, TExtensionBehavior>::iterator iter;
-    if (! strcmp(extName, "all")) {
+    if (! strcmp(extension, "all")) {
         // special case for the 'all' extension; apply it to every extension present
         if (behavior == EBhRequire || behavior == EBhEnable) {
             error(getCurrentLoc(), "extension 'all' cannot have 'require' or 'enable' behavior", "#extension", "");
@@ -345,16 +371,16 @@ void TParseContext::updateExtensionBehavior(const char* extName, const char* beh
         }
     } else {
         // Do the update for this single extension
-        iter = extensionBehavior.find(TString(extName));
+        iter = extensionBehavior.find(TString(extension));
         if (iter == extensionBehavior.end()) {
             switch (behavior) {
             case EBhRequire:
-                error(getCurrentLoc(), "extension not supported", "#extension", extName);
+                error(getCurrentLoc(), "extension not supported", "#extension", extension);
                 break;
             case EBhEnable:
             case EBhWarn:
             case EBhDisable:
-                warn(getCurrentLoc(), "extension not supported", "#extension", extName);
+                warn(getCurrentLoc(), "extension not supported", "#extension", extension);
                 break;
             default:
                 assert(0 && "unexpected behavior");
index bd0a5d0..66622a8 100644 (file)
@@ -61,6 +61,7 @@ namespace glslang {
 // The behaviors from the GLSL "#extension extension_name : behavior"
 //
 typedef enum {
+    EBhMissing = 0,
     EBhRequire,
     EBhEnable,
     EBhWarn,
@@ -71,6 +72,9 @@ typedef enum {
 // Symbolic names for extensions.  Strings may be directly used when calling the
 // functions, but better to have the compiler do spelling checks.
 //
+const char* const GL_OES_texture_3D               = "GL_OES_texture_3D";
+
+
 const char* const GL_ARB_texture_rectangle        = "GL_ARB_texture_rectangle";
 const char* const GL_3DL_array_objects            = "GL_3DL_array_objects";
 const char* const GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack";