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

Constant folding: Correct result type of non-square matrix folding.

This also made the function easier to read by identifying
left and right operands more clearly.
parent ea0cb2eb
No related branches found
No related tags found
No related merge requests found
......@@ -229,7 +229,7 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
{
switch (type.getQualifier().precision) {
case glslang::EpqLow: return spv::DecorationRelaxedPrecision; // TODO: Map instead to 16-bit types?
case glslang::EpqLow: return spv::DecorationRelaxedPrecision;
case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
case glslang::EpqHigh: return spv::NoPrecision;
default:
......
......@@ -257,6 +257,19 @@ ERROR: node is still EOpNull!
0:120 1.000000
0:120 Constant:
0:120 3 (const int)
0:126 Function Definition: foo3( (global void)
0:126 Function Parameters:
0:128 Sequence
0:128 Sequence
0:128 move second child to first child (temp 3X2 matrix of float)
0:128 'r32' (temp 3X2 matrix of float)
0:128 Constant:
0:128 43.000000
0:128 64.000000
0:128 51.000000
0:128 76.000000
0:128 59.000000
0:128 88.000000
0:? Linker Objects
0:? 'a' (const int)
0:? 1 (const int)
......@@ -331,6 +344,18 @@ ERROR: node is still EOpNull!
0:? 4.000000
0:? 5.000000
0:? 'a4' (global 2-element array of float)
0:? 'mm2' (const 2X2 matrix of float)
0:? 1.000000
0:? 2.000000
0:? 3.000000
0:? 4.000000
0:? 'mm32' (const 3X2 matrix of float)
0:? 10.000000
0:? 11.000000
0:? 12.000000
0:? 13.000000
0:? 14.000000
0:? 15.000000
Linked fragment stage:
......@@ -584,6 +609,19 @@ ERROR: node is still EOpNull!
0:120 1.000000
0:120 Constant:
0:120 3 (const int)
0:126 Function Definition: foo3( (global void)
0:126 Function Parameters:
0:128 Sequence
0:128 Sequence
0:128 move second child to first child (temp 3X2 matrix of float)
0:128 'r32' (temp 3X2 matrix of float)
0:128 Constant:
0:128 43.000000
0:128 64.000000
0:128 51.000000
0:128 76.000000
0:128 59.000000
0:128 88.000000
0:? Linker Objects
0:? 'a' (const int)
0:? 1 (const int)
......@@ -658,4 +696,16 @@ ERROR: node is still EOpNull!
0:? 4.000000
0:? 5.000000
0:? 'a4' (global 2-element array of float)
0:? 'mm2' (const 2X2 matrix of float)
0:? 1.000000
0:? 2.000000
0:? 3.000000
0:? 4.000000
0:? 'mm32' (const 3X2 matrix of float)
0:? 10.000000
0:? 11.000000
0:? 12.000000
0:? 13.000000
0:? 14.000000
0:? 15.000000
......@@ -119,3 +119,11 @@ void foo2()
float f = vec4(7.8 < 2.4 ? -1.333 : 1.444).a;
f = vec4(inv.x < 2.4 ? -1.0 : 1.0).a; // not folded, ensuring no propagation
}
const mat2 mm2 = mat2(1.0, 2.0, 3.0, 4.0);
const mat3x2 mm32 = mat3x2(10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
void foo3()
{
mat3x2 r32 = mm2 * mm32;
}
......@@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "SPIRV99.845"
#define GLSLANG_DATE "13-Dec-2015"
#define GLSLANG_REVISION "SPIRV99.849"
#define GLSLANG_DATE "16-Dec-2015"
......@@ -81,11 +81,12 @@ namespace glslang {
//
//
// Do folding between a pair of nodes
// Do folding between a pair of nodes.
// 'this' is the left-hand operand and 'rightConstantNode' is the right-hand operand.
//
// Returns a new node representing the result.
//
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* constantNode) const
TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* rightConstantNode) const
{
// For most cases, the return type matches the argument type, so set that
// up and just code to exceptions below.
......@@ -96,37 +97,37 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
// A pair of nodes is to be folded together
//
const TIntermConstantUnion *node = constantNode->getAsConstantUnion();
TConstUnionArray unionArray = getConstArray();
TConstUnionArray rightUnionArray = node->getConstArray();
const TIntermConstantUnion *rightNode = rightConstantNode->getAsConstantUnion();
TConstUnionArray leftUnionArray = getConstArray();
TConstUnionArray rightUnionArray = rightNode->getConstArray();
// Figure out the size of the result
int newComps;
int constComps;
switch(op) {
case EOpMatrixTimesMatrix:
newComps = getMatrixRows() * node->getMatrixCols();
newComps = rightNode->getMatrixCols() * getMatrixRows();
break;
case EOpMatrixTimesVector:
newComps = getMatrixRows();
break;
case EOpVectorTimesMatrix:
newComps = node->getMatrixCols();
newComps = rightNode->getMatrixCols();
break;
default:
newComps = getType().computeNumComponents();
constComps = constantNode->getType().computeNumComponents();
constComps = rightConstantNode->getType().computeNumComponents();
if (constComps == 1 && newComps > 1) {
// for a case like vec4 f = vec4(2,3,4,5) + 1.2;
TConstUnionArray smearedArray(newComps, node->getConstArray()[0]);
TConstUnionArray smearedArray(newComps, rightNode->getConstArray()[0]);
rightUnionArray = smearedArray;
} else if (constComps > 1 && newComps == 1) {
// for a case like vec4 f = 1.2 + vec4(2,3,4,5);
newComps = constComps;
rightUnionArray = node->getConstArray();
rightUnionArray = rightNode->getConstArray();
TConstUnionArray smearedArray(newComps, getConstArray()[0]);
unionArray = smearedArray;
returnType.shallowCopy(node->getType());
leftUnionArray = smearedArray;
returnType.shallowCopy(rightNode->getType());
}
break;
}
......@@ -137,52 +138,52 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
switch(op) {
case EOpAdd:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] + rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] + rightUnionArray[i];
break;
case EOpSub:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] - rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] - rightUnionArray[i];
break;
case EOpMul:
case EOpVectorTimesScalar:
case EOpMatrixTimesScalar:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] * rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] * rightUnionArray[i];
break;
case EOpMatrixTimesMatrix:
for (int row = 0; row < getMatrixRows(); row++) {
for (int column = 0; column < node->getMatrixCols(); column++) {
for (int column = 0; column < rightNode->getMatrixCols(); column++) {
double sum = 0.0f;
for (int i = 0; i < node->getMatrixRows(); i++)
sum += unionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * node->getMatrixRows() + i].getDConst();
for (int i = 0; i < rightNode->getMatrixRows(); i++)
sum += leftUnionArray[i * getMatrixRows() + row].getDConst() * rightUnionArray[column * rightNode->getMatrixRows() + i].getDConst();
newConstArray[column * getMatrixRows() + row].setDConst(sum);
}
}
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, getMatrixRows(), node->getMatrixCols()));
returnType.shallowCopy(TType(getType().getBasicType(), EvqConst, 0, rightNode->getMatrixCols(), getMatrixRows()));
break;
case EOpDiv:
for (int i = 0; i < newComps; i++) {
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat:
newConstArray[i].setDConst(unionArray[i].getDConst() / rightUnionArray[i].getDConst());
newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
break;
case EbtInt:
if (rightUnionArray[i] == 0)
newConstArray[i].setIConst(0x7FFFFFFF);
else if (rightUnionArray[i].getIConst() == -1 && unionArray[i].getIConst() == 0x80000000)
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == 0x80000000)
newConstArray[i].setIConst(0x80000000);
else
newConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
break;
case EbtUint:
if (rightUnionArray[i] == 0) {
newConstArray[i].setUConst(0xFFFFFFFF);
} else
newConstArray[i].setUConst(unionArray[i].getUConst() / rightUnionArray[i].getUConst());
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
default:
return 0;
......@@ -193,8 +194,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
case EOpMatrixTimesVector:
for (int i = 0; i < getMatrixRows(); i++) {
double sum = 0.0f;
for (int j = 0; j < node->getVectorSize(); j++) {
sum += unionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
for (int j = 0; j < rightNode->getVectorSize(); j++) {
sum += leftUnionArray[j*getMatrixRows() + i].getDConst() * rightUnionArray[j].getDConst();
}
newConstArray[i].setDConst(sum);
}
......@@ -203,89 +204,89 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* const
break;
case EOpVectorTimesMatrix:
for (int i = 0; i < node->getMatrixCols(); i++) {
for (int i = 0; i < rightNode->getMatrixCols(); i++) {
double sum = 0.0f;
for (int j = 0; j < getVectorSize(); j++)
sum += unionArray[j].getDConst() * rightUnionArray[i*node->getMatrixRows() + j].getDConst();
sum += leftUnionArray[j].getDConst() * rightUnionArray[i*rightNode->getMatrixRows() + j].getDConst();
newConstArray[i].setDConst(sum);
}
returnType.shallowCopy(TType(getBasicType(), EvqConst, node->getMatrixCols()));
returnType.shallowCopy(TType(getBasicType(), EvqConst, rightNode->getMatrixCols()));
break;
case EOpMod:
for (int i = 0; i < newComps; i++) {
if (rightUnionArray[i] == 0)
newConstArray[i] = unionArray[i];
newConstArray[i] = leftUnionArray[i];
else
newConstArray[i] = unionArray[i] % rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
}
break;
case EOpRightShift:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] >> rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] >> rightUnionArray[i];
break;
case EOpLeftShift:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] << rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] << rightUnionArray[i];
break;
case EOpAnd:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] & rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] & rightUnionArray[i];
break;
case EOpInclusiveOr:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] | rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] | rightUnionArray[i];
break;
case EOpExclusiveOr:
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] ^ rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] ^ rightUnionArray[i];
break;
case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] && rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] && rightUnionArray[i];
break;
case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
for (int i = 0; i < newComps; i++)
newConstArray[i] = unionArray[i] || rightUnionArray[i];
newConstArray[i] = leftUnionArray[i] || rightUnionArray[i];
break;
case EOpLogicalXor:
for (int i = 0; i < newComps; i++) {
switch (getType().getBasicType()) {
case EbtBool: newConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
case EbtBool: newConstArray[i].setBConst((leftUnionArray[i] == rightUnionArray[i]) ? false : true); break;
default: assert(false && "Default missing");
}
}
break;
case EOpLessThan:
newConstArray[0].setBConst(unionArray[0] < rightUnionArray[0]);
newConstArray[0].setBConst(leftUnionArray[0] < rightUnionArray[0]);
returnType.shallowCopy(constBool);
break;
case EOpGreaterThan:
newConstArray[0].setBConst(unionArray[0] > rightUnionArray[0]);
newConstArray[0].setBConst(leftUnionArray[0] > rightUnionArray[0]);
returnType.shallowCopy(constBool);
break;
case EOpLessThanEqual:
newConstArray[0].setBConst(! (unionArray[0] > rightUnionArray[0]));
newConstArray[0].setBConst(! (leftUnionArray[0] > rightUnionArray[0]));
returnType.shallowCopy(constBool);
break;
case EOpGreaterThanEqual:
newConstArray[0].setBConst(! (unionArray[0] < rightUnionArray[0]));
newConstArray[0].setBConst(! (leftUnionArray[0] < rightUnionArray[0]));
returnType.shallowCopy(constBool);
break;
case EOpEqual:
newConstArray[0].setBConst(node->getConstArray() == unionArray);
newConstArray[0].setBConst(rightNode->getConstArray() == leftUnionArray);
returnType.shallowCopy(constBool);
break;
case EOpNotEqual:
newConstArray[0].setBConst(node->getConstArray() != unionArray);
newConstArray[0].setBConst(rightNode->getConstArray() != leftUnionArray);
returnType.shallowCopy(constBool);
break;
......
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