-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Open
Labels
HLSLHLSL Language SupportHLSL Language Support
Description
The Matrix type doesn'1 have support for constant matrix expression evaluation. We need something like this:
class MatrixExprEvaluator
: public ExprEvaluatorBase<MatrixExprEvaluator> {
APValue &Result;
public:
MatrixExprEvaluator(EvalInfo &info, APValue &Result)
: ExprEvaluatorBaseTy(info), Result(Result) {}
bool Success(ArrayRef<APValue> V, const Expr *E) {
assert(V.size() == E->getType()->castAs<ConstantMatrixType>()->getNumElementsFlattened());
// FIXME: remove this APValue copy.
Result = APValue(V.data(), V.size());
return true;
}
bool Success(const APValue &M, const Expr *E) {
assert(M.isMatrix());
Result = M;
return true;
}
bool VisitCastExpr(const CastExpr* E);
};
static bool EvaluateMatrix(const Expr* E, APValue& Result, EvalInfo &Info) {
assert(E->isPRValue() && E->getType()->isConstantMatrixType() &&
"not a matrix prvalue");
return MatrixExprEvaluator(Info, Result).Visit(E);
}
and at least support VisitCastExpr.
We also need to add a new enum Matrix to APValue::ValueKind .
And then the following helpers
bool isMatrix() const { return Kind == Matrix; }
APValue &getMatrixElt(unsigned RowIdx, unsigned ColIdx) {
assert(isMatrix() && "Invalid accessor");
assert(RowIdx < getRowLength() && "Row Index out of range");
assert(ColIdx < getColumnLength() && "Column Index out of range");
// combine Row/Col index into a single Index
// figure out if I will be Row or Column major some how to do the calculation right
unsigned I = ...;
return ((Mat *)(char *)&Data)->Elts[I];
}
APValue &getFlatMatrixElt(unsigned Idx) {
assert(isMatrix() && "Invalid accessor");
assert(Idx < getRowLength() * getColumnLength() && "Index out of range");
return ((Mat *)(char *)&Data)->Elts[I];
}
unsigned getRowLength() const {
assert(isMatrix() && "Invalid accessor");
return ((const Mat *)(const void *)&Data)->RowSize;
}
unsigned getColumnLength() const {
assert(isMatrix() && "Invalid accessor");
return ((const Mat *)(const void *)&Data)->ColumnSize;
}
void MakeMatrix() {
assert(isAbsent() && "Bad state change");
new ((void *)(char *)&Data) Mat();
Kind = Matrix;
}
struct Mat {
APValue *Elts = nullptr;
unsigned RowSize = 0;
unsigned ColumnSize = 0;
Mat() = default;
Mat(const Mat &) = delete;
Mat &operator=(const Vec &) = delete;
~Mat() { delete[] Elts; }
};The usages in should look like this
case CK_HLSLMatrixTruncation: {
APValue Val;
SmallVector<APValue, 4> Elements;
if (!EvaluateMatrix(SE, Val, Info))
return Error(E);
for (unsigned I= 0; I < Elts; I++)
Elements.push_back(Val.getFlatMatrixElt(I));
return Success(Elements, E);
}
...
case CK_HLSLMatrixTruncation: {
APValue Val;
if (!EvaluateMatrix(SubExpr, Val, Info))
return Error(E);
return Success(Val.getMatrixElt(0,0), E);
}
...
case CK_HLSLVectorTruncation: {
APValue Val;
if (!EvaluateMatrix(SubExpr, Val, Info))
return Error(E);
return Success(Val.getMatrixElt(0,0), E);
}Metadata
Metadata
Assignees
Labels
HLSLHLSL Language SupportHLSL Language Support
Type
Projects
Status
Planning