From 50a8cabbbb8365b2d907d1bf42f96f39f5b4f48e Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 10 Jun 2013 07:37:49 +0000 Subject: [PATCH] Add constant folding for length(), normalize(), fwidth(), dFdx(), and dFdy(). git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@21918 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/constFold.frag | 4 +++ glslang/MachineIndependent/Constant.cpp | 48 +++++++++++++++++++------ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Test/constFold.frag b/Test/constFold.frag index 3b0d3607..e08dc846 100644 --- a/Test/constFold.frag +++ b/Test/constFold.frag @@ -8,8 +8,11 @@ const float e = float(d); // 2.0 const float f = e * float(c); // 6.0 const float g = f / float(d); // 3.0 +const vec2 pytho = vec2(3.0, 4.0); + in vec4 inv; out vec4 FragColor; +out vec2 out2; void main() { @@ -26,4 +29,5 @@ void main() vec4 arrayMax[int(max(float(array2.length()), float(array3.length())))]; vec4 arrayMin[int(min(float(array2.length()), float(array3.length())))]; FragColor = vec4(arrayMax.length(), arrayMin.length(), sin(3.14), cos(3.14)); // 3, 2, .00159, -.999 + out2 = length(pytho) + normalize(pytho) + dFdx(pytho) + dFdy(pytho) + fwidth(pytho); // 5+3/5, 5+4/5 } diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index e8c42a7f..f973cc1a 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -377,12 +377,35 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, case EOpDeterminant: case EOpAny: case EOpAll: + case EOpLength: newConstArray = new constUnion[1]; - break; + break; + default: newConstArray = new constUnion[objectSize]; } + // Process non-component-wise operations + switch (op) { + case EOpLength: + case EOpNormalize: + { + double sum = 0; + for (int i = 0; i < objectSize; i++) + sum += double(unionArray[i].getFConst()) * unionArray[i].getFConst(); + double length = sqrt(sum); + if (op == EOpLength) + newConstArray[0].setFConst(float(length)); + else { + for (int i = 0; i < objectSize; i++) + newConstArray[i].setFConst(float(unionArray[i].getFConst() / length)); + } + break; + } + default: + break; + } + // TODO: Functionality: constant folding: separate component-wise from non-component-wise for (int i = 0; i < objectSize; i++) { switch (op) { @@ -433,6 +456,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, newConstArray[i].setFConst(atan(unionArray[i].getFConst())); break; + case EOpLength: + case EOpNormalize: + // handled above as special case + break; + + case EOpDPdx: + case EOpDPdy: + case EOpFwidth: + // The derivatives are all mandated to create a constant 0. + newConstArray[i].setFConst(0.0f); + break; + // TODO: Functionality: constant folding: the rest of the ops have to be fleshed out case EOpExp: @@ -465,13 +500,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, case EOpPackHalf2x16: case EOpUnpackHalf2x16: - case EOpLength: - - case EOpDPdx: - case EOpDPdy: - case EOpFwidth: - // The derivatives are all mandated to create a constant 0. - case EOpDeterminant: case EOpMatrixInverse: case EOpTranspose: @@ -480,7 +508,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType, case EOpAll: default: - infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", getLine()); + infoSink.info.message(EPrefixInternalError, "missing operator for unary constant folding", getLine()); return 0; } } @@ -521,7 +549,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpMix: case EOpDistance: case EOpCross: - case EOpNormalize: objectSize = children[0]->getAsConstantUnion()->getType().getObjectSize(); break; case EOpDot: @@ -574,7 +601,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EOpDistance: case EOpDot: case EOpCross: - case EOpNormalize: case EOpFaceForward: case EOpReflect: case EOpRefract: