فهرست منبع

Updated glslang.

Branimir Karadžić 7 سال پیش
والد
کامیت
f310352f11

+ 13 - 0
3rdparty/glslang/Test/110scope.vert

@@ -71,4 +71,17 @@ void main()
 
     int degrees;
     degrees(3.2);
+
+    {
+        S s;
+        s.x = 3;
+        struct S {   // okay, hides S
+            bool b;
+        };
+        S t;
+        t.b = true;
+        struct S {    // ERROR, redefinition of struct S
+            float f;
+        };
+    }
 }

+ 32 - 1
3rdparty/glslang/Test/baseResults/110scope.vert.out

@@ -2,7 +2,8 @@
 ERROR: 0:5: 'a' : redefinition 
 ERROR: 0:57: 'z' : undeclared identifier 
 ERROR: 0:57: 'z' : redefinition 
-ERROR: 3 compilation errors.  No code generated.
+ERROR: 0:83: 'S' : redefinition struct
+ERROR: 4 compilation errors.  No code generated.
 
 
 Shader version: 110
@@ -120,6 +121,21 @@ ERROR: node is still EOpNull!
 0:69            0 (const int)
 0:73      Constant:
 0:73        183.346494
+0:?       Sequence
+0:77        move second child to first child ( temp int)
+0:77          x: direct index for structure ( temp int)
+0:77            's' ( temp structure{ temp int x})
+0:77            Constant:
+0:77              0 (const int)
+0:77          Constant:
+0:77            3 (const int)
+0:82        move second child to first child ( temp bool)
+0:82          b: direct index for structure ( temp bool)
+0:82            't' ( temp structure{ temp bool b})
+0:82            Constant:
+0:82              0 (const int)
+0:82          Constant:
+0:82            true (const bool)
 0:?   Linker Objects
 0:?     'b' ( global bool)
 0:?     'c' ( global bool)
@@ -236,6 +252,21 @@ ERROR: node is still EOpNull!
 0:69            0 (const int)
 0:73      Constant:
 0:73        183.346494
+0:?       Sequence
+0:77        move second child to first child ( temp int)
+0:77          x: direct index for structure ( temp int)
+0:77            's' ( temp structure{ temp int x})
+0:77            Constant:
+0:77              0 (const int)
+0:77          Constant:
+0:77            3 (const int)
+0:82        move second child to first child ( temp bool)
+0:82          b: direct index for structure ( temp bool)
+0:82            't' ( temp structure{ temp bool b})
+0:82            Constant:
+0:82              0 (const int)
+0:82          Constant:
+0:82            true (const bool)
 0:?   Linker Objects
 0:?     'b' ( global bool)
 0:?     'c' ( global bool)

+ 6 - 3
3rdparty/glslang/glslang/MachineIndependent/Scan.cpp

@@ -778,7 +778,7 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token)
         case '?':                       return QUESTION;
         case '[':                       return LEFT_BRACKET;
         case ']':                       return RIGHT_BRACKET;
-        case '{':                       return LEFT_BRACE;
+        case '{':  afterStruct = false; return LEFT_BRACE;
         case '}':                       return RIGHT_BRACE;
         case '\\':
             parseContext.error(loc, "illegal use of escape character", "\\", "");
@@ -861,7 +861,6 @@ int TScanContext::tokenizeIdentifier()
     case IN:
     case OUT:
     case INOUT:
-    case STRUCT:
     case BREAK:
     case CONTINUE:
     case DO:
@@ -874,6 +873,10 @@ int TScanContext::tokenizeIdentifier()
     case CASE:
         return keyword;
 
+    case STRUCT:
+        afterStruct = true;
+        return keyword;
+
     case NONUNIFORM:
         if (parseContext.extensionTurnedOn(E_GL_EXT_nonuniform_qualifier))
             return keyword;
@@ -1537,7 +1540,7 @@ int TScanContext::identifierOrType()
         return IDENTIFIER;
 
     parserToken->sType.lex.symbol = parseContext.symbolTable.find(*parserToken->sType.lex.string);
-    if (afterType == false && parserToken->sType.lex.symbol) {
+    if ((afterType == false && afterStruct == false) && parserToken->sType.lex.symbol != nullptr) {
         if (const TVariable* variable = parserToken->sType.lex.symbol->getAsVariable()) {
             if (variable->isUserType()) {
                 afterType = true;

+ 5 - 1
3rdparty/glslang/glslang/MachineIndependent/ScanContext.h

@@ -50,7 +50,10 @@ class TParserToken;
 
 class TScanContext {
 public:
-    explicit TScanContext(TParseContextBase& pc) : parseContext(pc), afterType(false), field(false) { }
+    explicit TScanContext(TParseContextBase& pc) :
+        parseContext(pc),
+        afterType(false), afterStruct(false),
+        field(false) { }
     virtual ~TScanContext() { }
 
     static void fillInKeywordMap();
@@ -76,6 +79,7 @@ protected:
 
     TParseContextBase& parseContext;
     bool afterType;           // true if we've recognized a type, so can only be looking for an identifier
+    bool afterStruct;         // true if we've recognized the STRUCT keyword, so can only be looking for an identifier
     bool field;               // true if we're on a field, right after a '.'
     TSourceLoc loc;
     TParserToken* parserToken;

+ 26 - 19
3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp

@@ -383,29 +383,34 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
         return !(at != slots[set].end() && *at == slot);
     }
 
-    int reserveSlot(int set, int slot)
+    int reserveSlot(int set, int slot, int size = 1)
     {
         TSlotSet::iterator at = findSlot(set, slot);
 
         // tolerate aliasing, by not double-recording aliases
         // (policy about appropriateness of the alias is higher up)
-        if (at == slots[set].end() || *at != slot)
-            slots[set].insert(at, slot);
+        for (int i = 0; i < size; i++) {
+                if (at == slots[set].end() || *at != slot + i)
+                        at = slots[set].insert(at, slot + i);
+                ++at;
+        }
 
         return slot;
     }
 
-    int getFreeSlot(int set, int base)
+    int getFreeSlot(int set, int base, int size = 1)
     {
         TSlotSet::iterator at = findSlot(set, base);
         if (at == slots[set].end())
-            return reserveSlot(set, base);
+            return reserveSlot(set, base, size);
 
-        // look in locksteps, if they not match, then there is a free slot
-        for (; at != slots[set].end(); ++at, ++base)
-            if (*at != base)
+        // look for a big enough gap
+        for (; at != slots[set].end(); ++at) {
+            if (*at - base >= size)
                 break;
-        return reserveSlot(set, base);
+            base = *at + 1;
+        }
+        return reserveSlot(set, base, size);
     }
 
     virtual bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override = 0;
@@ -561,40 +566,42 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
     int resolveBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool is_live) override
     {
         const int set = getLayoutSet(type);
+        // On OpenGL arrays of opaque types take a seperate binding for each element
+        int numBindings = intermediate.getSpv().openGl != 0 && type.isSizedArray() ? type.getCumulativeArraySize() : 1;
 
         if (type.getQualifier().hasBinding()) {
             if (isImageType(type))
-                return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding);
+                return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding, numBindings);
 
             if (isTextureType(type))
-                return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
+                return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding, numBindings);
 
             if (isSsboType(type))
-                return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding);
+                return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding, numBindings);
 
             if (isSamplerType(type))
-                return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
+                return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding, numBindings);
 
             if (isUboType(type))
-                return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
+                return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding, numBindings);
         } else if (is_live && doAutoBindingMapping()) {
             // find free slot, the caller did make sure it passes all vars with binding
             // first and now all are passed that do not have a binding and needs one
 
             if (isImageType(type))
-                return getFreeSlot(set, getBaseBinding(EResImage, set));
+                return getFreeSlot(set, getBaseBinding(EResImage, set), numBindings);
 
             if (isTextureType(type))
-                return getFreeSlot(set, getBaseBinding(EResTexture, set));
+                return getFreeSlot(set, getBaseBinding(EResTexture, set), numBindings);
 
             if (isSsboType(type))
-                return getFreeSlot(set, getBaseBinding(EResSsbo, set));
+                return getFreeSlot(set, getBaseBinding(EResSsbo, set), numBindings);
 
             if (isSamplerType(type))
-                return getFreeSlot(set, getBaseBinding(EResSampler, set));
+                return getFreeSlot(set, getBaseBinding(EResSampler, set), numBindings);
 
             if (isUboType(type))
-                return getFreeSlot(set, getBaseBinding(EResUbo, set));
+                return getFreeSlot(set, getBaseBinding(EResUbo, set), numBindings);
         }
 
         return -1;