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;
|
TIntermTyped* result = base;
|
||||||
if ((base->isVector() || base->isScalar()) &&
|
if ((base->isVector() || base->isScalar()) &&
|
||||||
(base->isFloatingDomain() || base->isIntegerDomain() || base->getBasicType() == EbtBool)) {
|
(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()) {
|
if (base->isScalar()) {
|
||||||
const char* dotFeature = "scalar swizzle";
|
const char* dotFeature = "scalar swizzle";
|
||||||
requireProfile(loc, ~EEsProfile, dotFeature);
|
requireProfile(loc, ~EEsProfile, dotFeature);
|
||||||
@ -866,42 +913,6 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
|
|||||||
if (base->getType().getQualifier().isSpecConstant())
|
if (base->getType().getQualifier().isSpecConstant())
|
||||||
result->getWritableType().getQualifier().makeSpecConstant();
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -315,6 +315,7 @@ public:
|
|||||||
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
|
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* handleUnaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* childNode);
|
||||||
TIntermTyped* handleDotDereference(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
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);
|
void blockMemberExtensionCheck(const TSourceLoc&, const TIntermTyped* base, int member, const TString& memberName);
|
||||||
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
TFunction* handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user