Commit a8b364b7 by Alexis Hetu Committed by Alexis Hétu

Adding Struct related types

Added TField, TFieldListCollection, TStructure and TInterfaceBlock for structures and uniform blocks. In the TType class, changed structure's type from TTypeList to TStructure and made related changes in other files to reflect this change. Change-Id: Ided4c535651a566952c3314c8c4f31c2d0ccdcca Reviewed-on: https://swiftshader-review.googlesource.com/3451Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 5f4ee797
......@@ -399,19 +399,17 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS
//
// Depth range in window coordinates
//
TTypeList *members = NewPoolTTypeList();
TTypeLine near = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
TTypeLine far = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
TTypeLine diff = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0};
near.type->setFieldName("near");
far.type->setFieldName("far");
diff.type->setFieldName("diff");
members->push_back(near);
members->push_back(far);
members->push_back(diff);
TVariable *depthRangeParameters = new TVariable(NewPoolTString("gl_DepthRangeParameters"), TType(members, "gl_DepthRangeParameters"), true);
TFieldList *fields = NewPoolTFieldList();
TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("near"), 0);
TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("far"), 0);
TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString("diff"), 0);
fields->push_back(near);
fields->push_back(far);
fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(members, "gl_DepthRangeParameters"));
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform);
symbolTable.insert(COMMON_BUILTINS, *depthRange);
......
......@@ -993,16 +993,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
const TTypeList* fields = leftNodeType.getStruct();
const TFieldList& fields = leftNodeType.getStruct()->fields();
size_t structSize = fields->size();
size_t structSize = fields.size();
int index = 0;
for (size_t j = 0; j < structSize; j++) {
int size = (*fields)[j].type->getObjectSize();
int size = fields[j]->type()->getObjectSize();
for (int i = 0; i < size; i++) {
if ((*fields)[j].type->getBasicType() == EbtStruct) {
if (!CompareStructure(*(*fields)[j].type, &rightUnionArray[index], &leftUnionArray[index]))
if (fields[j]->type()->getBasicType() == EbtStruct) {
if (!CompareStructure(*(fields[j]->type()), &rightUnionArray[index], &leftUnionArray[index]))
return false;
} else {
if (leftUnionArray[index] != rightUnionArray[index])
......
......@@ -326,20 +326,13 @@ namespace glsl
{
ASSERT(leftType.isStruct());
const TTypeList *structure = leftType.getStruct();
const TString &fieldName = rightType.getFieldName();
const TFieldList& fields = leftType.getStruct()->fields();
int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
for(size_t i = 0; i < structure->size(); i++)
for(int i = 0; i < index; i++)
{
const TType &fieldType = *(*structure)[i].type;
if(fieldType.getFieldName() == fieldName)
{
break;
}
fieldOffset += fieldType.totalRegisterCount();
fieldOffset += fields[i]->type()->totalRegisterCount();
}
copy(result, left, fieldOffset);
......@@ -1439,12 +1432,12 @@ namespace glsl
if(type.isStruct())
{
TTypeList *structure = type.getStruct();
const TFieldList& fields = type.getStruct()->fields();
int elements = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
{
const TType &fieldType = *field->type;
const TType &fieldType = *((*field)->type());
if(fieldType.totalRegisterCount() <= registers)
{
......@@ -1472,7 +1465,7 @@ namespace glsl
{
if(type.isStruct())
{
return registerSize(*type.getStruct()->begin()->type, 0);
return registerSize(*((*(type.getStruct()->fields().begin()))->type()), 0);
}
return type.isMatrix() ? type.getSecondarySize() : type.getNominalSize();
......@@ -1487,12 +1480,12 @@ namespace glsl
if(type.isStruct())
{
TTypeList *structure = type.getStruct();
const TFieldList& fields = type.getStruct()->fields();
int elements = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)
for(TFieldList::const_iterator field = fields.begin(); field != fields.end(); field++)
{
const TType &fieldType = *field->type;
const TType &fieldType = *((*field)->type());
if(fieldType.totalRegisterCount() <= registers)
{
......@@ -1520,7 +1513,6 @@ namespace glsl
{
TIntermTyped *arg = argument->getAsTyped();
const TType &type = arg->getType();
const TTypeList *structure = type.getStruct();
index = (index >= arg->totalRegisterCount()) ? arg->totalRegisterCount() - 1 : index;
int size = registerSize(type, index);
......@@ -1771,23 +1763,20 @@ namespace glsl
break;
case EOpIndexDirectStruct:
{
const TTypeList *structure = left->getType().getStruct();
const TString &fieldName = right->getType().getFieldName();
const TFieldList& fields = left->getType().getStruct()->fields();
int index = right->getAsConstantUnion()->getIConst(0);
int fieldOffset = 0;
int offset = 0;
for(TTypeList::const_iterator field = structure->begin(); field != structure->end(); field++)
for(int i = 0; i < index; i++)
{
if(field->type->getFieldName() == fieldName)
{
dst.type = registerType(left);
dst.index += offset;
dst.mask = writeMask(right);
return 0xE4;
}
offset += field->type->totalRegisterCount();
fieldOffset += fields[i]->type()->totalRegisterCount();
}
dst.type = registerType(left);
dst.index += fieldOffset;
dst.mask = writeMask(right);
return 0xE4;
}
break;
case EOpVectorSwizzle:
......@@ -2354,7 +2343,7 @@ namespace glsl
void OutputASM::declareUniform(const TType &type, const TString &name, int index)
{
const TTypeList *structure = type.getStruct();
const TStructure *structure = type.getStruct();
ActiveUniforms &activeUniforms = shaderObject->activeUniforms;
if(!structure)
......@@ -2371,16 +2360,17 @@ namespace glsl
}
else
{
const TFieldList& fields = structure->fields();
if(type.isArray())
{
int elementIndex = index;
for(int i = 0; i < type.getArraySize(); i++)
{
for(size_t j = 0; j < structure->size(); j++)
for(size_t j = 0; j < fields.size(); j++)
{
const TType &fieldType = *(*structure)[j].type;
const TString &fieldName = fieldType.getFieldName();
const TType &fieldType = *(fields[j]->type());
const TString &fieldName = fields[j]->name();
const TString uniformName = name + "[" + str(i) + "]." + fieldName;
declareUniform(fieldType, uniformName, elementIndex);
......@@ -2392,10 +2382,10 @@ namespace glsl
{
int fieldIndex = index;
for(size_t i = 0; i < structure->size(); i++)
for(size_t i = 0; i < fields.size(); i++)
{
const TType &fieldType = *(*structure)[i].type;
const TString &fieldName = fieldType.getFieldName();
const TType &fieldType = *(fields[i]->type());
const TString &fieldName = fields[i]->name();
const TString uniformName = name + "." + fieldName;
declareUniform(fieldType, uniformName, fieldIndex);
......
......@@ -522,7 +522,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
return true;
}
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->fields().size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
return true;
}
......@@ -682,9 +682,9 @@ bool TParseContext::containsSampler(TType& type)
return true;
if (type.getBasicType() == EbtStruct) {
TTypeList& structure = *type.getStruct();
for (unsigned int i = 0; i < structure.size(); ++i) {
if (containsSampler(*structure[i].type))
const TFieldList& fields = type.getStruct()->fields();
for(unsigned int i = 0; i < fields.size(); ++i) {
if (containsSampler(*fields[i]->type()))
return true;
}
}
......@@ -1232,12 +1232,12 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* arguments, const TType*
if(op == EOpConstructStruct)
{
TTypeList &fields = *type->getStruct();
const TFieldList &fields = type->getStruct()->fields();
TIntermSequence &args = aggregateArguments->getSequence();
for(size_t i = 0; i < fields.size(); i++)
{
if(args[i]->getAsTyped()->getType() != *fields[i].type)
if(args[i]->getAsTyped()->getType() != *fields[i]->type())
{
error(line, "Structure constructor arguments do not match structure fields", "Error");
recover();
......@@ -1405,17 +1405,17 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
//
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{
const TTypeList* fields = node->getType().getStruct();
const TFieldList &fields = node->getType().getStruct()->fields();
TIntermTyped *typedNode;
int instanceSize = 0;
unsigned int index = 0;
TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
for ( index = 0; index < fields->size(); ++index) {
if ((*fields)[index].type->getFieldName() == identifier) {
for ( index = 0; index < fields.size(); ++index) {
if (fields[index]->name() == identifier) {
break;
} else {
instanceSize += (*fields)[index].type->getObjectSize();
instanceSize += fields[index]->type()->getObjectSize();
}
}
......
......@@ -26,12 +26,11 @@ int TSymbolTableLevel::uniqueId = 0;
TType::TType(const TPublicType &p) :
type(p.type), precision(p.precision), primarySize(p.primarySize), secondarySize(p.secondarySize), qualifier(p.qualifier), array(p.array), arraySize(p.arraySize),
maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
maxArraySize(0), arrayInformationType(0), structure(0), deepestStructNesting(0), mangled(0)
{
if (p.userDef)
{
structure = p.userDef->getStruct();
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
computeDeepestStructNesting();
}
}
......@@ -52,19 +51,23 @@ void TType::buildMangledName(TString& mangledName)
case EbtUInt: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break;
case EbtSampler2D: mangledName += "s2"; break;
case EbtSamplerCube: mangledName += "sC"; break;
case EbtSamplerExternalOES: mangledName += "sE"; break;
case EbtSampler3D: mangledName += "s3"; break;
case EbtStruct:
mangledName += "struct-";
if (typeName)
mangledName += *typeName;
{// support MSVC++6.0
for (unsigned int i = 0; i < structure->size(); ++i) {
mangledName += '-';
(*structure)[i].type->buildMangledName(mangledName);
}
}
case EbtSamplerCube: mangledName += "sC"; break;
case EbtSampler2DArray: mangledName += "s2a"; break;
case EbtSamplerExternalOES: mangledName += "sext"; break;
case EbtISampler2D: mangledName += "is2"; break;
case EbtISampler3D: mangledName += "is3"; break;
case EbtISamplerCube: mangledName += "isC"; break;
case EbtISampler2DArray: mangledName += "is2a"; break;
case EbtUSampler2D: mangledName += "us2"; break;
case EbtUSampler3D: mangledName += "us3"; break;
case EbtUSamplerCube: mangledName += "usC"; break;
case EbtUSampler2DArray: mangledName += "us2a"; break;
case EbtSampler2DShadow: mangledName += "s2s"; break;
case EbtSamplerCubeShadow: mangledName += "sCs"; break;
case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
case EbtStruct: mangledName += structure->mangledName(); break;
case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
default:
break;
}
......@@ -89,46 +92,68 @@ int TType::getStructSize() const
return 0;
}
if (structureSize == 0)
for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
structureSize += ((*tl).type)->getObjectSize();
return structureSize;
return getStruct()->objectSize();
}
void TType::computeDeepestStructNesting()
{
if (!structure)
{
return;
}
deepestStructNesting = structure ? structure->deepestNesting() : 0;
}
int maxNesting = 0;
for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++)
{
maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
}
bool TStructure::containsArrays() const
{
for(size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if(fieldType->isArray() || fieldType->isStructureContainingArrays())
return true;
}
return false;
}
deepestStructNesting = 1 + maxNesting;
bool TStructure::containsSamplers() const
{
for(size_t i = 0; i < mFields->size(); ++i)
{
const TType *fieldType = (*mFields)[i]->type();
if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
return true;
}
return false;
}
bool TType::isStructureContainingArrays() const
TString TFieldListCollection::buildMangledName() const
{
if (!structure)
{
return false;
}
TString mangledName(mangledNamePrefix());
mangledName += *mName;
for(size_t i = 0; i < mFields->size(); ++i)
{
mangledName += '-';
mangledName += (*mFields)[i]->type()->getMangledName();
}
return mangledName;
}
for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
{
if (member->type->isArray() ||
member->type->isStructureContainingArrays())
{
return true;
}
}
size_t TFieldListCollection::calculateObjectSize() const
{
size_t size = 0;
for(size_t i = 0; i < mFields->size(); ++i)
{
size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
if(fieldSize > INT_MAX - size)
size = INT_MAX;
else
size += fieldSize;
}
return size;
}
return false;
int TStructure::calculateDeepestNesting() const
{
int maxNesting = 0;
for(size_t i = 0; i < mFields->size(); ++i)
maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
return 1 + maxNesting;
}
//
......
......@@ -75,8 +75,8 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
TTypeList* typeList;
TField* field;
TFieldList* fieldList;
};
} interm;
}
......@@ -176,8 +176,8 @@ extern void yyerror(TParseContext* context, const char* reason);
%type <interm.type> type_qualifier fully_specified_type type_specifier storage_qualifier interpolation_qualifier
%type <interm.type> type_specifier_no_prec type_specifier_nonarray
%type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.field> struct_declarator
%type <interm.fieldList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
......@@ -316,7 +316,7 @@ postfix_expression
$$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConstExpr), $2.line);
} else if ($1->isArray()) {
if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
$$->setType(TType($1->getType().getStruct()));
else
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->getSecondarySize()));
......@@ -391,15 +391,16 @@ postfix_expression
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
const TStructure* structure = $1->getType().getStruct();
if (structure == 0) {
context->error($2.line, "structure has no fields", "Internal Error");
context->recover();
$$ = $1;
} else {
unsigned int i;
for (i = 0; i < fields->size(); ++i) {
if ((*fields)[i].type->getFieldName() == *$3.string) {
const TFieldList& fields = structure->fields();
for (i = 0; i < fields.size(); ++i) {
if (fields[i]->name() == *$3.string) {
fieldFound = true;
break;
}
......@@ -412,7 +413,7 @@ postfix_expression
$$ = $1;
}
else {
$$->setType(*(*fields)[i].type);
$$->setType(*fields[i]->type());
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
$$->getTypePointer()->setQualifier(EvqConstExpr);
......@@ -420,9 +421,9 @@ postfix_expression
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(fields[i]->type()), $3.line);
$$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
$$->setType(*(*fields)[i].type);
$$->setType(*fields[i]->type());
}
} else {
context->error($2.line, " no such field in structure", $3.string->c_str());
......@@ -2007,7 +2008,7 @@ struct_specifier
if (context->reservedErrorCheck($2.line, *$2.string))
context->recover();
TType* structure = new TType($5, *$2.string);
TType* structure = new TType(new TStructure($2.string, $5));
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
if (! context->symbolTable.declare(*userTypeDef)) {
context->error($2.line, "redefinition", $2.string->c_str(), "struct");
......@@ -2018,7 +2019,8 @@ struct_specifier
context->exitStructDeclaration();
}
| STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, TString(""));
TString emptyName("");
TType* structure = new TType(new TStructure(&emptyName, $4));
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
context->exitStructDeclaration();
......@@ -2032,9 +2034,10 @@ struct_declaration_list
| struct_declaration_list struct_declaration {
$$ = $1;
for (unsigned int i = 0; i < $2->size(); ++i) {
TField* field = (*$2)[i];
for (unsigned int j = 0; j < $$->size(); ++j) {
if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
if ((*$$)[j]->name() == field->name()) {
context->error((*$2)[i]->line(), "duplicate field name in structure:", "struct", field->name().c_str());
context->recover();
}
}
......@@ -2047,14 +2050,14 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON {
$$ = $2;
if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
if (context->voidErrorCheck($1.line, (*$2)[0]->name(), $1)) {
context->recover();
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
// Careful not to replace already known aspects of type, like array-ness
//
TType* type = (*$$)[i].type;
TType* type = (*$$)[i]->type();
type->setBasicType($1.type);
type->setNominalSize($1.primarySize);
type->setSecondarySize($1.secondarySize);
......@@ -2069,7 +2072,6 @@ struct_declaration
type->setArraySize($1.arraySize);
if ($1.userDef) {
type->setStruct($1.userDef->getStruct());
type->setTypeName($1.userDef->getTypeName());
}
}
}
......@@ -2077,7 +2079,7 @@ struct_declaration
struct_declarator_list
: struct_declarator {
$$ = NewPoolTTypeList();
$$ = NewPoolTFieldList();
$$->push_back($1);
}
| struct_declarator_list COMMA struct_declarator {
......@@ -2090,22 +2092,20 @@ struct_declarator
if (context->reservedErrorCheck($1.line, *$1.string))
context->recover();
$$.type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
TType* type = new TType(EbtVoid, EbpUndefined);
$$ = new TField(type, $1.string, $1.line);
}
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
if (context->reservedErrorCheck($1.line, *$1.string))
context->recover();
$$.type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
TType* type = new TType(EbtVoid, EbpUndefined);
int size;
if (context->arraySizeErrorCheck($2.line, $3, size))
if (context->arraySizeErrorCheck($3->getLine(), $3, size))
context->recover();
$$.type->setArraySize(size);
type->setArraySize(size);
$$ = new TField(type, $1.string, $1.line);
}
;
......
......@@ -201,8 +201,8 @@ typedef union YYSTYPE
TQualifier qualifier;
TFunction* function;
TParameter param;
TTypeLine typeLine;
TTypeList* typeList;
TField* field;
TFieldList* fieldList;
};
} interm;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment