Function for constructor implementation. Calls addUnaryMath with appropriate EOp value for the parameter to the constructor (passed to this function). Essentially, it converts the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a float, then float is converted to int. Returns nullptr for an error or the constructed node.
| 9947 | // Returns nullptr for an error or the constructed node. |
| 9948 | // |
| 9949 | TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, TIntermTyped* node, const TSourceLoc& loc, |
| 9950 | bool subset) |
| 9951 | { |
| 9952 | // If we are changing a matrix in both domain of basic type and to a non matrix, |
| 9953 | // do the shape change first (by default, below, basic type is changed before shape). |
| 9954 | // This avoids requesting a matrix of a new type that is going to be discarded anyway. |
| 9955 | // TODO: This could be generalized to more type combinations, but that would require |
| 9956 | // more extensive testing and full algorithm rework. For now, the need to do two changes makes |
| 9957 | // the recursive call work, and avoids the most egregious case of creating integer matrices. |
| 9958 | if (node->getType().isMatrix() && (type.isScalar() || type.isVector()) && |
| 9959 | type.isFloatingDomain() != node->getType().isFloatingDomain()) { |
| 9960 | TType transitionType(node->getBasicType(), glslang::EvqTemporary, type.getVectorSize(), 0, 0, node->isVector()); |
| 9961 | TOperator transitionOp = intermediate.mapTypeToConstructorOp(transitionType); |
| 9962 | node = constructBuiltIn(transitionType, transitionOp, node, loc, false); |
| 9963 | } |
| 9964 | |
| 9965 | TIntermTyped* newNode; |
| 9966 | TOperator basicOp; |
| 9967 | |
| 9968 | // |
| 9969 | // First, convert types as needed. |
| 9970 | // |
| 9971 | switch (op) { |
| 9972 | case EOpConstructVec2: |
| 9973 | case EOpConstructVec3: |
| 9974 | case EOpConstructVec4: |
| 9975 | case EOpConstructMat2x2: |
| 9976 | case EOpConstructMat2x3: |
| 9977 | case EOpConstructMat2x4: |
| 9978 | case EOpConstructMat3x2: |
| 9979 | case EOpConstructMat3x3: |
| 9980 | case EOpConstructMat3x4: |
| 9981 | case EOpConstructMat4x2: |
| 9982 | case EOpConstructMat4x3: |
| 9983 | case EOpConstructMat4x4: |
| 9984 | case EOpConstructFloat: |
| 9985 | basicOp = EOpConstructFloat; |
| 9986 | break; |
| 9987 | |
| 9988 | case EOpConstructIVec2: |
| 9989 | case EOpConstructIVec3: |
| 9990 | case EOpConstructIVec4: |
| 9991 | case EOpConstructInt: |
| 9992 | basicOp = EOpConstructInt; |
| 9993 | break; |
| 9994 | |
| 9995 | case EOpConstructUVec2: |
| 9996 | if (node->getType().getBasicType() == EbtReference) { |
| 9997 | requireExtensions(loc, 1, &E_GL_EXT_buffer_reference_uvec2, "reference conversion to uvec2"); |
| 9998 | TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node, |
| 9999 | type); |
| 10000 | return newNode; |
| 10001 | } else if (node->getType().getBasicType() == EbtSampler) { |
| 10002 | requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "sampler conversion to uvec2"); |
| 10003 | // force the basic type of the constructor param to uvec2, otherwise spv builder will |
| 10004 | // report some errors |
| 10005 | TIntermTyped* newSrcNode = intermediate.createConversion(EbtUint, node); |
| 10006 | newSrcNode->getAsTyped()->getWritableType().setVectorSize(2); |
nothing calls this directly
no test coverage detected