From 61c47a951bc73b50509a91257980bcb09f7661eb Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 14 Dec 2015 18:21:19 -0700 Subject: [PATCH] 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. --- SPIRV/GlslangToSpv.cpp | 2 +- Test/baseResults/constFold.frag.out | 50 ++++++++++++++++++ Test/constFold.frag | 8 +++ glslang/Include/revision.h | 4 +- glslang/MachineIndependent/Constant.cpp | 89 +++++++++++++++++---------------- 5 files changed, 106 insertions(+), 47 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index e1babc1..a2e8a9e 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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: diff --git a/Test/baseResults/constFold.frag.out b/Test/baseResults/constFold.frag.out index bd6e040..c03d865 100644 --- a/Test/baseResults/constFold.frag.out +++ b/Test/baseResults/constFold.frag.out @@ -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 diff --git a/Test/constFold.frag b/Test/constFold.frag index ae0817a..81c718c 100644 --- a/Test/constFold.frag +++ b/Test/constFold.frag @@ -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; +} diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 542f8f3..4ad7772 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -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" diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 6a797f0..a0bb8de 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -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; -- 2.7.4