Skip to content
Snippets Groups Projects
Commit a4ca22ff authored by John Kessenich's avatar John Kessenich
Browse files

Finish compile-time constant folding for multi-argument built-ins: ...

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
parent 0bd3ab69
No related branches found
No related tags found
No related merge requests found
......@@ -133,6 +133,16 @@ void foo324(void)
{
float p = pow(3.2, 4.6);
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
......
......@@ -463,6 +463,17 @@ public:
}
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; }
protected:
......
......@@ -303,7 +303,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// but not always.
int resultSize;
switch (op) {
// TODO: 3.0 functionality: constant folding: finish listing exceptions to size here
case EOpDeterminant:
case EOpAny:
case EOpAll:
......@@ -316,6 +315,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
// These don't actually fold
return 0;
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
resultSize = 1;
break;
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
case EOpUnpackHalf2x16:
resultSize = 2;
break;
default:
resultSize = getType().getObjectSize();
break;
......@@ -332,7 +343,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
{
double sum = 0;
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);
if (op == EOpLength)
newConstArray[0].setDConst(length);
......@@ -487,7 +498,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
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 EOpCosh:
......@@ -693,20 +704,74 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
} else {
// Non-componentwise...
switch (aggrNode->getOp()) {
// TODO: 3.0 Functionality: constant folding: the rest of the ops have to be fleshed out
int numComps = children[0]->getAsConstantUnion()->getType().getObjectSize();
double dot;
case EOpModf:
switch (aggrNode->getOp()) {
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:
newConstArray[0].setDConst(childConstUnions[0].dot(childConstUnions[1]));
break;
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:
// 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:
// 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:
{
// 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:
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:
return aggrNode;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment