GLSL: Separate out swizzle handling (potentially fixing bugs).
Noticed this when looking at swizzles. It's at least better structure, removing hard-to-see early returns, which might be contributing to bugs.
This commit is contained in:
parent
bfaf88ee6a
commit
2ac3c5b6d6
@ -822,6 +822,53 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
||||
TIntermTyped* result = base;
|
||||
if ((base->isVector() || base->isScalar()) &&
|
||||
(base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
|
||||
result = handleDotSwizzle(loc, base, field);
|
||||
} else if (base->isStruct() || base->isReference()) {
|
||||
const TTypeList* fields = base->isReference() ?
|
||||
base->getType().getReferentType()->getStruct() :
|
||||
base->getType().getStruct();
|
||||
bool fieldFound = false;
|
||||
int member;
|
||||
for (member = 0; member < (int)fields->size(); ++member) {
|
||||
if ((*fields)[member].type->getFieldName() == field) {
|
||||
fieldFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fieldFound) {
|
||||
if (base->getType().getQualifier().isFrontEndConstant())
|
||||
result = intermediate.foldDereference(base, member, loc);
|
||||
else {
|
||||
blockMemberExtensionCheck(loc, base, member, field);
|
||||
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
|
||||
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
|
||||
result->setType(*(*fields)[member].type);
|
||||
if ((*fields)[member].type->getQualifier().isIo())
|
||||
intermediate.addIoAccessed(field);
|
||||
}
|
||||
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
|
||||
} else
|
||||
error(loc, "no such field in structure", field.c_str(), "");
|
||||
} else
|
||||
error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
|
||||
|
||||
// Propagate noContraction up the dereference chain
|
||||
if (base->getQualifier().isNoContraction())
|
||||
result->getWritableType().getQualifier().setNoContraction();
|
||||
|
||||
// Propagate nonuniform
|
||||
if (base->getQualifier().isNonUniform())
|
||||
result->getWritableType().getQualifier().nonUniform = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing a base.swizzle, a subset of base.identifier in the grammar.
|
||||
//
|
||||
TIntermTyped* TParseContext::handleDotSwizzle(const TSourceLoc& loc, TIntermTyped* base, const TString& field)
|
||||
{
|
||||
TIntermTyped* result = base;
|
||||
if (base->isScalar()) {
|
||||
const char* dotFeature = "scalar swizzle";
|
||||
requireProfile(loc, ~EEsProfile, dotFeature);
|
||||
@ -866,42 +913,6 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
||||
if (base->getType().getQualifier().isSpecConstant())
|
||||
result->getWritableType().getQualifier().makeSpecConstant();
|
||||
}
|
||||
} else if (base->isStruct() || base->isReference()) {
|
||||
const TTypeList* fields = base->isReference() ?
|
||||
base->getType().getReferentType()->getStruct() :
|
||||
base->getType().getStruct();
|
||||
bool fieldFound = false;
|
||||
int member;
|
||||
for (member = 0; member < (int)fields->size(); ++member) {
|
||||
if ((*fields)[member].type->getFieldName() == field) {
|
||||
fieldFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fieldFound) {
|
||||
if (base->getType().getQualifier().isFrontEndConstant())
|
||||
result = intermediate.foldDereference(base, member, loc);
|
||||
else {
|
||||
blockMemberExtensionCheck(loc, base, member, field);
|
||||
TIntermTyped* index = intermediate.addConstantUnion(member, loc);
|
||||
result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc);
|
||||
result->setType(*(*fields)[member].type);
|
||||
if ((*fields)[member].type->getQualifier().isIo())
|
||||
intermediate.addIoAccessed(field);
|
||||
}
|
||||
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
|
||||
} else
|
||||
error(loc, "no such field in structure", field.c_str(), "");
|
||||
} else
|
||||
error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str());
|
||||
|
||||
// Propagate noContraction up the dereference chain
|
||||
if (base->getQualifier().isNoContraction())
|
||||
result->getWritableType().getQualifier().setNoContraction();
|
||||
|
||||
// Propagate nonuniform
|
||||
if (base->getQualifier().isNonUniform())
|
||||
result->getWritableType().getQualifier().nonUniform = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -315,6 +315,7 @@ public:
|
||||
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
||||
TIntermTyped* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||
TIntermTyped* handleDotSwizzle(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||
|
Loading…
x
Reference in New Issue
Block a user