mirror of
https://github.com/RPCS3/glslang.git
synced 2024-11-25 12:19:49 +00:00
Block/structure fixes: Merge qualifiers with multiple declarators, handle arrays of blocks, more semantic checks for what's allowed.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21883 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ceb0623823
commit
0fbb0c4930
38
Test/300block.frag
Normal file
38
Test/300block.frag
Normal file
@ -0,0 +1,38 @@
|
||||
#version 300 es
|
||||
|
||||
struct S {
|
||||
vec4 u;
|
||||
uvec4 v;
|
||||
isampler3D sampler;
|
||||
vec3 w;
|
||||
struct T1 { // ERROR
|
||||
int a;
|
||||
} t;
|
||||
};
|
||||
|
||||
uniform S s;
|
||||
|
||||
uniform fooBlock {
|
||||
uvec4 bv;
|
||||
mat2 bm2;
|
||||
isampler2D sampler; // ERROR
|
||||
struct T2 { // ERROR
|
||||
int a;
|
||||
} t;
|
||||
S fbs;
|
||||
};
|
||||
|
||||
uniform barBlock {
|
||||
uvec4 nbv;
|
||||
int ni;
|
||||
} inst;
|
||||
|
||||
uniform barBlockArray {
|
||||
uvec4 nbv;
|
||||
int ni;
|
||||
} insts[4];
|
||||
|
||||
void main()
|
||||
{
|
||||
texture(s.sampler, vec3(inst.ni, bv.y, insts[2].nbv.z));
|
||||
}
|
@ -27,6 +27,7 @@ comment.frag
|
||||
300layout.vert
|
||||
300layout.frag
|
||||
300operations.frag
|
||||
300block.frag
|
||||
330.frag
|
||||
330comp.frag
|
||||
constErrors.frag
|
||||
|
@ -392,7 +392,7 @@ typedef std::map<TTypeList*, TTypeList*>::const_iterator TStructureMapIterator;
|
||||
class TType {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
|
||||
TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
||||
explicit TType(TBasicType t, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0) :
|
||||
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), arraySizes(0),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0),
|
||||
fieldName(0), mangled(0), typeName(0)
|
||||
@ -416,7 +416,10 @@ public:
|
||||
basicType(p.basicType), vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), arraySizes(p.arraySizes),
|
||||
structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
|
||||
{
|
||||
sampler = p.sampler;
|
||||
if (basicType == EbtSampler)
|
||||
sampler = p.sampler;
|
||||
else
|
||||
sampler.clear();
|
||||
qualifier = p.qualifier;
|
||||
if (p.userDef) {
|
||||
structure = p.userDef->getStruct();
|
||||
@ -494,6 +497,21 @@ public:
|
||||
arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
|
||||
}
|
||||
|
||||
// Merge type from parent, where a parentType is at the beginning of a declaration,
|
||||
// establishing some charastics for all subsequent names, while this type
|
||||
// is on the individual names.
|
||||
void mergeType(const TPublicType& parentType)
|
||||
{
|
||||
// arrayness is currently the only child aspect that has to be preserved
|
||||
setElementType(parentType.basicType, parentType.vectorSize, parentType.matrixCols, parentType.matrixRows, parentType.userDef);
|
||||
qualifier = parentType.qualifier;
|
||||
sampler = parentType.sampler;
|
||||
if (parentType.arraySizes)
|
||||
setArraySizes(parentType.arraySizes);
|
||||
if (parentType.userDef)
|
||||
setTypeName(parentType.userDef->getTypeName());
|
||||
}
|
||||
|
||||
TType* clone(const TStructureMap& remapper)
|
||||
{
|
||||
TType *newType = new TType();
|
||||
|
@ -676,7 +676,7 @@ bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualif
|
||||
break;
|
||||
}
|
||||
|
||||
// Do non in/out error checks
|
||||
// Do non-in/out error checks
|
||||
|
||||
if (qualifier.storage != EvqUniform && samplerErrorCheck(line, publicType, "samplers and images must be uniform"))
|
||||
return true;
|
||||
@ -1517,7 +1517,7 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
||||
return;
|
||||
}
|
||||
|
||||
// check for qualifiers that don't belong within a block
|
||||
// check for qualifiers and types that don't belong within a block
|
||||
for (unsigned int member = 0; member < typeList.size(); ++member) {
|
||||
TQualifier memberQualifier = typeList[member].type->getQualifier();
|
||||
if (memberQualifier.storage != EvqTemporary && memberQualifier.storage != EvqGlobal &&
|
||||
@ -1531,6 +1531,12 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
||||
recover();
|
||||
}
|
||||
}
|
||||
|
||||
TBasicType basicType = typeList[member].type->getBasicType();
|
||||
if (basicType == EbtSampler) {
|
||||
error(line, "member of block cannot be a sampler type", typeList[member].type->getFieldName().c_str(), "");
|
||||
recover();
|
||||
}
|
||||
}
|
||||
|
||||
// Make default block qualification, and adjust the member qualifications
|
||||
@ -1546,6 +1552,8 @@ void TParseContext::addBlock(int line, TPublicType& publicType, const TString& b
|
||||
// Build and add the interface block as a new type named blockName
|
||||
|
||||
TType blockType(&typeList, blockName, publicType.qualifier.storage);
|
||||
if (arraySizes)
|
||||
blockType.setArraySizes(arraySizes);
|
||||
blockType.getQualifier().layoutPacking = defaultQualification.layoutPacking;
|
||||
TVariable* userTypeDef = new TVariable(&blockName, blockType, true);
|
||||
if (! symbolTable.insert(*userTypeDef)) {
|
||||
|
@ -1600,11 +1600,11 @@ fully_specified_type
|
||||
parseContext.recover();
|
||||
$2.arraySizes = 0;
|
||||
}
|
||||
|
||||
if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
|
||||
parseContext.recover();
|
||||
|
||||
$$ = $2;
|
||||
$$.qualifier = $1.qualifier;
|
||||
if ($$.qualifier.precision == EpqNone)
|
||||
$$.qualifier.precision = $2.qualifier.precision;
|
||||
|
||||
if (! $$.qualifier.isInterpolation() && parseContext.language == EShLangFragment)
|
||||
$$.qualifier.smooth = true;
|
||||
@ -2560,6 +2560,10 @@ precision_qualifier
|
||||
struct_specifier
|
||||
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
|
||||
// TODO: semantics: check for qualifiers that don't belong in a struct
|
||||
|
||||
// TODO: semantics: check that this is not nested inside a block or structure
|
||||
// parseContext.error($1.line, "cannot nest a block or structure definitions", $1.userDef->getTypeName().c_str(), "");
|
||||
|
||||
TType* structure = new TType($4, *$2.string);
|
||||
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
|
||||
if (! parseContext.symbolTable.insert(*userTypeDef)) {
|
||||
@ -2608,17 +2612,8 @@ struct_declaration
|
||||
if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
|
||||
parseContext.recover();
|
||||
}
|
||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||
//
|
||||
// Careful not to replace already know aspects of type, like array-ness
|
||||
//
|
||||
(*$$)[i].type->setElementType($1.basicType, $1.vectorSize, $1.matrixCols, $1.matrixRows, $1.userDef);
|
||||
|
||||
if ($1.arraySizes)
|
||||
(*$$)[i].type->setArraySizes($1.arraySizes);
|
||||
if ($1.userDef)
|
||||
(*$$)[i].type->setTypeName($1.userDef->getTypeName());
|
||||
}
|
||||
for (unsigned int i = 0; i < $$->size(); ++i)
|
||||
(*$$)[i].type->mergeType($1);
|
||||
}
|
||||
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
|
||||
if ($2.arraySizes) {
|
||||
@ -2632,17 +2627,8 @@ struct_declaration
|
||||
parseContext.recover();
|
||||
if (parseContext.mergeQualifiersErrorCheck($2.line, $2, $1, true))
|
||||
parseContext.recover();
|
||||
for (unsigned int i = 0; i < $$->size(); ++i) {
|
||||
//
|
||||
// Careful not to replace already know aspects of type, like array-ness
|
||||
//
|
||||
(*$$)[i].type->setElementType($2.basicType, $2.vectorSize, $2.matrixCols, $2.matrixRows, $2.userDef);
|
||||
(*$$)[i].type->getQualifier() = $2.qualifier;
|
||||
if ($2.arraySizes)
|
||||
(*$$)[i].type->setArraySizes($2.arraySizes);
|
||||
if ($2.userDef)
|
||||
(*$$)[i].type->setTypeName($2.userDef->getTypeName());
|
||||
}
|
||||
for (unsigned int i = 0; i < $$->size(); ++i)
|
||||
(*$$)[i].type->mergeType($2);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -982,7 +982,7 @@ static int macro_scan(InputSrc *inInput, yystypepp * yylvalpp)
|
||||
// return a zero, for scanning a macro that was never defined
|
||||
static int zero_scan(InputSrc *inInput, yystypepp * yylvalpp)
|
||||
{
|
||||
MacroInputSrc* in = (MacroInputSrc*)inInput; //?? need to free this?
|
||||
MacroInputSrc* in = (MacroInputSrc*)inInput;
|
||||
|
||||
strcpy(yylvalpp->symbol_name, "0");
|
||||
yylvalpp->sc_int = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user