TIntermTyped* ir_add_vector_swizzle(TVectorFields& fields, TIntermTyped* arg, TSourceLoc lineDot, TSourceLoc lineIndex) { // swizzle on a constant -> fold it if (arg->getType().getQualifier() == EvqConst) { TIntermTyped* res = ir_add_const_vector_swizzle(fields, arg, lineIndex); if (res) return res; } TIntermTyped* res = NULL; if (fields.num == 1) { TIntermConstant* index = ir_add_constant(TType(EbtInt, EbpUndefined, EvqConst), lineIndex); index->setValue(fields.offsets[0]); res = ir_add_index(EOpIndexDirect, arg, index, lineDot); res->setType(TType(arg->getBasicType(), arg->getPrecision())); } else { TIntermTyped* index = ir_add_swizzle(fields, lineIndex); res = ir_add_index(EOpVectorSwizzle, arg, index, lineDot); res->setType(TType(arg->getBasicType(), arg->getPrecision(), EvqTemporary, 1, fields.num)); } return res; }
TIntermTyped *TIntermediate::addComma(TIntermTyped *left, TIntermTyped *right, const TSourceLoc &line, int shaderVersion) { TQualifier resultQualifier = EvqConst; // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression. if (shaderVersion >= 300 || left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) { resultQualifier = EvqTemporary; } TIntermTyped *commaNode = nullptr; if (!left->hasSideEffects()) { commaNode = right; } else { commaNode = growAggregate(left, right, line); commaNode->getAsAggregate()->setOp(EOpComma); commaNode->setType(right->getType()); } commaNode->getTypePointer()->setQualifier(resultQualifier); return commaNode; }
TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) { if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) { return right; } else { TIntermTyped *commaAggregate = growAggregate(left, right, line); commaAggregate->getAsAggregate()->setOp(EOpComma); commaAggregate->setType(right->getType()); commaAggregate->getTypePointer()->setQualifier(EvqTemporary); return commaAggregate; } }
TIntermTyped* ir_add_comma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line) { if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) { return right; } else { TIntermTyped *commaAggregate = ir_grow_aggregate(left, right, line); commaAggregate->getAsAggregate()->setOperator(EOpComma); commaAggregate->setType(right->getType()); commaAggregate->getTypePointer()->changeQualifier(EvqTemporary); return commaAggregate; } }
// // Make a constant vector node or constant scalar node, representing a given // constant vector and constant swizzle into it. // TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TVectorFields& fields, const TSourceLoc& loc) { const TConstUnionArray& unionArray = node->getAsConstantUnion()->getConstArray(); TConstUnionArray constArray(fields.num); for (int i = 0; i < fields.num; i++) constArray[i] = unionArray[fields.offsets[i]]; TIntermTyped* result = addConstantUnion(constArray, node->getType(), loc); if (result == 0) result = node; else result->setType(TType(node->getBasicType(), EvqConst, fields.num)); return result; }
// // Constant folding of a bracket (array-style) dereference or struct-like dot // dereference. Can handle any thing except a multi-character swizzle, though // all swizzles may go to foldSwizzle(). // TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc) { TType dereferencedType(node->getType(), index); dereferencedType.getQualifier().storage = EvqConst; TIntermTyped* result = 0; int size = dereferencedType.computeNumComponents(); int start; if (node->isStruct()) { start = 0; for (int i = 0; i < index; ++i) start += (*node->getType().getStruct())[i].type->computeNumComponents(); } else start = size * index; result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc); if (result == 0) result = node; else result->setType(dereferencedType); return result; }