diff --git a/Test/300.frag b/Test/300.frag index 6fa7e336f453649858a8c769fe43389de550a86d..dea0c4e72ddbe18acfd9e461240b27d1ab7a914e 100644 --- a/Test/300.frag +++ b/Test/300.frag @@ -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 diff --git a/glslang/Include/ConstantUnion.h b/glslang/Include/ConstantUnion.h index c19502e8ade6c924b5c06ee7dbad47e26c5381e4..5de0d77409f36712f81391efc7d93043d1bc1156 100644 --- a/glslang/Include/ConstantUnion.h +++ b/glslang/Include/ConstantUnion.h @@ -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: diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 9837761a7929d2a344b1971c76f950e248bef5e0..48be7d37608eb1ba2124d4e4cbce32f4c3e41034 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -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; }