static TOperator getMatrixConstructOp(const TIntermTyped& intermediate) { switch (intermediate.getColsCount()) { case 2: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat2x2; case 3: return EOpConstructMat2x3; case 4: return EOpConstructMat2x4; } break; case 3: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat3x2; case 3: return EOpConstructMat3x3; case 4: return EOpConstructMat3x4; } break; case 4: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat4x2; case 3: return EOpConstructMat4x3; case 4: return EOpConstructMat4x4; } break; } assert(false); return EOpNull; }
static TOperator getMatrixConstructOp(const TIntermTyped& intermediate, TParseContext& ctx) { // before GLSL 1.20, only square matrices if (ctx.targetVersion < ETargetGLSL_120) { const int c = intermediate.getColsCount(); const int r = intermediate.getRowsCount(); if (c == 2 && r == 2) return EOpConstructMat2x2FromMat; if (c == 3 && r == 3) return EOpConstructMat3x3FromMat; if (c == 4 && r == 4) return EOpConstructMat4x4; ctx.error(intermediate.getLine(), " non-square matrices not supported", "", "(%ix%i)", r, c); return EOpNull; } switch (intermediate.getColsCount()) { case 2: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat2x2; case 3: return EOpConstructMat2x3; case 4: return EOpConstructMat2x4; } break; case 3: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat3x2; case 3: return EOpConstructMat3x3; case 4: return EOpConstructMat3x4; } break; case 4: switch (intermediate.getRowsCount()) { case 2: return EOpConstructMat4x2; case 3: return EOpConstructMat4x3; case 4: return EOpConstructMat4x4; } break; } assert(false); return EOpNull; }
// Add one node as the parent of another that it operates on. TIntermTyped* ir_add_unary_math(TOperator op, TIntermNode* childNode, TSourceLoc line, TParseContext& ctx) { TIntermUnary* node; TIntermTyped* child = childNode->getAsTyped(); if (child == 0) { ctx.infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line); return 0; } switch (op) { case EOpLogicalNot: if (!child->isScalar()) return 0; break; case EOpPostIncrement: case EOpPreIncrement: case EOpPostDecrement: case EOpPreDecrement: case EOpNegative: if (child->getType().getBasicType() == EbtStruct || child->getType().isArray()) return 0; default: break; } // // Do we need to promote the operand? // // Note: Implicit promotions were removed from the language. // TBasicType newType = EbtVoid; switch (op) { case EOpConstructInt: newType = EbtInt; break; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; case EOpLogicalNot: newType = EbtBool; break; default: break; } if (newType != EbtVoid) { child = ir_add_conversion(op, TType(newType, child->getPrecision(), EvqTemporary, child->getColsCount(), child->getRowsCount(), child->isMatrix(), child->isArray()), child, ctx.infoSink); if (child == 0) return 0; } // // For constructors, we are now done, it's all in the conversion. // switch (op) { case EOpConstructInt: case EOpConstructBool: case EOpConstructFloat: return child; default: break; } TIntermConstant* childConst = child->getAsConstant(); // // Make a new node for the operator. // node = new TIntermUnary(op); if (line.line == 0) line = child->getLine(); node->setLine(line); node->setOperand(child); if (! node->promote(ctx)) return 0; // // See if we can fold constants if (childConst) { TIntermConstant* FoldUnaryConstantExpression(TOperator op, TIntermConstant* node); TIntermConstant* res = FoldUnaryConstantExpression(node->getOp(), childConst); if (res) { delete node; return res; } } return node; }