Updated glslang.

This commit is contained in:
Branimir Karadžić
2018-06-17 15:44:40 -07:00
parent aaf0465b18
commit f310352f11
5 changed files with 82 additions and 24 deletions

13
3rdparty/glslang/Test/110scope.vert vendored Normal file → Executable file
View File

@@ -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;
};
}
}

View File

@@ -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)

View File

@@ -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;

6
3rdparty/glslang/glslang/MachineIndependent/ScanContext.h vendored Normal file → Executable file
View File

@@ -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;

View File

@@ -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;