Finish compile-time constant folding for multi-argument built-ins: distance(), dot(), cross(), faceforward(), reflect(), refract(), and outerProduct().

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24272 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-12-03 01:18:06 +00:00
parent 0bd3ab69e2
commit a4ca22ff1d
3 changed files with 95 additions and 9 deletions

View file

@ -133,6 +133,16 @@ void foo324(void)
{ {
float p = pow(3.2, 4.6); float p = pow(3.2, 4.6);
p += sin(0.4); p += sin(0.4);
p += distance(vec2(10.0, 11.0), vec2(13.0, 15.0)); // 5
p += dot(vec3(2,3,5), vec3(-2,-1,4)); // 13
vec3 c3 = cross(vec3(3,-3,1), vec3(4,9,2)); // (-15, -2, 39)
c3 += faceforward(vec3(1,2,3), vec3(2,3,5), vec3(-2,-1,4)); // (-1,-2,-3)
c3 += faceforward(vec3(1,2,3), vec3(-2,-3,-5), vec3(-2,-1,4)); // (1,2,3)
vec2 c2 = reflect(vec2(1,3), vec2(0,1)); // (1,-3)
c2 += refract(vec2(1,3), vec2(0,1), 1.0); // (1,-3)
c2 += refract(vec2(1,3), vec2(0,1), 3.0);
c2 += refract(vec2(1,0.1), vec2(0,1), 5.0); // (0,0)
mat3x2 m32 = outerProduct(vec2(2,3), vec3(5,7,11));// rows: (10, 14, 22), (15, 21, 33)
} }
float imageBuffer; // ERROR, reserved float imageBuffer; // ERROR, reserved

View file

@ -463,6 +463,17 @@ public:
} }
bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); } bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
double dot(const TConstUnionArray& rhs)
{
assert(rhs.unionArray->size() == unionArray->size());
double sum = 0.0;
for (size_t comp = 0; comp < unionArray->size(); ++comp)
sum += (*this)[comp].getDConst() * rhs[comp].getDConst();
return sum;
}
bool empty() const { return unionArray == 0; } bool empty() const { return unionArray == 0; }
protected: protected:

View file

@ -303,7 +303,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// but not always. // but not always.
int resultSize; int resultSize;
switch (op) { switch (op) {
// TODO: 3.0 functionality: constant folding: finish listing exceptions to size here
case EOpDeterminant: case EOpDeterminant:
case EOpAny: case EOpAny:
case EOpAll: case EOpAll:
@ -316,6 +315,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// These don't actually fold // These don't actually fold
return 0; return 0;
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
resultSize = 1;
break;
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
case EOpUnpackHalf2x16:
resultSize = 2;
break;
default: default:
resultSize = getType().getObjectSize(); resultSize = getType().getObjectSize();
break; break;
@ -332,7 +343,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
{ {
double sum = 0; double sum = 0;
for (int i = 0; i < objectSize; i++) for (int i = 0; i < objectSize; i++)
sum += double(unionArray[i].getDConst()) * unionArray[i].getDConst(); sum += unionArray[i].getDConst() * unionArray[i].getDConst();
double length = sqrt(sum); double length = sqrt(sum);
if (op == EOpLength) if (op == EOpLength)
newConstArray[0].setDConst(length); newConstArray[0].setDConst(length);
@ -487,7 +498,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
break; break;
} }
// TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
case EOpSinh: case EOpSinh:
case EOpCosh: case EOpCosh:
@ -693,20 +704,74 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
} else { } else {
// Non-componentwise... // Non-componentwise...
int numComps = children[0]->getAsConstantUnion()->getType().getObjectSize();
double dot;
switch (aggrNode->getOp()) { switch (aggrNode->getOp()) {
// TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
case EOpModf:
case EOpDistance: case EOpDistance:
{
double sum = 0.0;
for (int comp = 0; comp < numComps; ++comp) {
double diff = childConstUnions[1][comp].getDConst() - childConstUnions[0][comp].getDConst();
sum += diff * diff;
}
newConstArray[0].setDConst(sqrt(sum));
break;
}
case EOpDot: case EOpDot:
newConstArray[0].setDConst(childConstUnions[0].dot(childConstUnions[1]));
break;
case EOpCross: case EOpCross:
newConstArray[0] = childConstUnions[0][1] * childConstUnions[1][2] - childConstUnions[0][2] * childConstUnions[1][1];
newConstArray[1] = childConstUnions[0][2] * childConstUnions[1][0] - childConstUnions[0][0] * childConstUnions[1][2];
newConstArray[2] = childConstUnions[0][0] * childConstUnions[1][1] - childConstUnions[0][1] * childConstUnions[1][0];
break;
case EOpFaceForward: case EOpFaceForward:
// If dot(Nref, I) < 0 return N, otherwise return N: Arguments are (N, I, Nref).
dot = childConstUnions[1].dot(childConstUnions[2]);
for (int comp = 0; comp < numComps; ++comp) {
if (dot < 0.0)
newConstArray[comp] = childConstUnions[0][comp];
else
newConstArray[comp].setDConst(-childConstUnions[0][comp].getDConst());
}
break;
case EOpReflect: case EOpReflect:
// I 2 * dot(N, I) * N: Arguments are (I, N).
dot = childConstUnions[0].dot(childConstUnions[1]);
dot *= 2.0;
for (int comp = 0; comp < numComps; ++comp)
newConstArray[comp].setDConst(childConstUnions[0][comp].getDConst() - dot * childConstUnions[1][comp].getDConst());
break;
case EOpRefract: case EOpRefract:
{
// Arguments are (I, N, eta).
// k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
// if (k < 0.0)
// return dvec(0.0)
// else
// return eta * I - (eta * dot(N, I) + sqrt(k)) * N
dot = childConstUnions[0].dot(childConstUnions[1]);
double eta = childConstUnions[2][0].getDConst();
double k = 1.0 - eta * eta * (1.0 - dot * dot);
if (k < 0.0) {
for (int comp = 0; comp < numComps; ++comp)
newConstArray[comp].setDConst(0.0);
} else {
for (int comp = 0; comp < numComps; ++comp)
newConstArray[comp].setDConst(eta * childConstUnions[0][comp].getDConst() - (eta * dot + sqrt(k)) * childConstUnions[1][comp].getDConst());
}
break;
}
case EOpOuterProduct: case EOpOuterProduct:
return aggrNode; {
int numRows = numComps;
int numCols = children[1]->getAsConstantUnion()->getType().getObjectSize();
for (int row = 0; row < numRows; ++row)
for (int col = 0; col < numCols; ++col)
newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col];
break;
}
default: default:
return aggrNode; return aggrNode;
} }