// Copyright 2020 The Tint Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "src/semantic/intrinsic.h" TINT_INSTANTIATE_TYPEINFO(tint::semantic::Intrinsic); namespace tint { namespace semantic { std::ostream& operator<<(std::ostream& out, IntrinsicType i) { out << str(i); return out; } const char* Intrinsic::str() const { return semantic::str(type_); } /// Name matches the spelling in the WGSL spec including case. #define INTRINSIC_LIST() \ INTRINSIC(IntrinsicType::kNone, "") \ INTRINSIC(IntrinsicType::kAbs, "abs") \ INTRINSIC(IntrinsicType::kAcos, "acos") \ INTRINSIC(IntrinsicType::kAll, "all") \ INTRINSIC(IntrinsicType::kAny, "any") \ INTRINSIC(IntrinsicType::kArrayLength, "arrayLength") \ INTRINSIC(IntrinsicType::kAsin, "asin") \ INTRINSIC(IntrinsicType::kAtan, "atan") \ INTRINSIC(IntrinsicType::kAtan2, "atan2") \ INTRINSIC(IntrinsicType::kCeil, "ceil") \ INTRINSIC(IntrinsicType::kClamp, "clamp") \ INTRINSIC(IntrinsicType::kCos, "cos") \ INTRINSIC(IntrinsicType::kCosh, "cosh") \ INTRINSIC(IntrinsicType::kCountOneBits, "countOneBits") \ INTRINSIC(IntrinsicType::kCross, "cross") \ INTRINSIC(IntrinsicType::kDeterminant, "determinant") \ INTRINSIC(IntrinsicType::kDistance, "distance") \ INTRINSIC(IntrinsicType::kDot, "dot") \ INTRINSIC(IntrinsicType::kDpdx, "dpdx") \ INTRINSIC(IntrinsicType::kDpdxCoarse, "dpdxCoarse") \ INTRINSIC(IntrinsicType::kDpdxFine, "dpdxFine") \ INTRINSIC(IntrinsicType::kDpdy, "dpdy") \ INTRINSIC(IntrinsicType::kDpdyCoarse, "dpdyCoarse") \ INTRINSIC(IntrinsicType::kDpdyFine, "dpdyFine") \ INTRINSIC(IntrinsicType::kExp, "exp") \ INTRINSIC(IntrinsicType::kExp2, "exp2") \ INTRINSIC(IntrinsicType::kFaceForward, "faceForward") \ INTRINSIC(IntrinsicType::kFloor, "floor") \ INTRINSIC(IntrinsicType::kFma, "fma") \ INTRINSIC(IntrinsicType::kFract, "fract") \ INTRINSIC(IntrinsicType::kFrexp, "frexp") \ INTRINSIC(IntrinsicType::kFwidth, "fwidth") \ INTRINSIC(IntrinsicType::kFwidthCoarse, "fwidthCoarse") \ INTRINSIC(IntrinsicType::kFwidthFine, "fwidthFine") \ INTRINSIC(IntrinsicType::kInverseSqrt, "inverseSqrt") \ INTRINSIC(IntrinsicType::kIsFinite, "isFinite") \ INTRINSIC(IntrinsicType::kIsInf, "isInf") \ INTRINSIC(IntrinsicType::kIsNan, "isNan") \ INTRINSIC(IntrinsicType::kIsNormal, "isNormal") \ INTRINSIC(IntrinsicType::kLdexp, "ldexp") \ INTRINSIC(IntrinsicType::kLength, "length") \ INTRINSIC(IntrinsicType::kLog, "log") \ INTRINSIC(IntrinsicType::kLog2, "log2") \ INTRINSIC(IntrinsicType::kMax, "max") \ INTRINSIC(IntrinsicType::kMin, "min") \ INTRINSIC(IntrinsicType::kMix, "mix") \ INTRINSIC(IntrinsicType::kModf, "modf") \ INTRINSIC(IntrinsicType::kNormalize, "normalize") \ INTRINSIC(IntrinsicType::kPack4x8Snorm, "pack4x8snorm") \ INTRINSIC(IntrinsicType::kPack4x8Unorm, "pack4x8unorm") \ INTRINSIC(IntrinsicType::kPack2x16Snorm, "pack2x16snorm") \ INTRINSIC(IntrinsicType::kPack2x16Unorm, "pack2x16unorm") \ INTRINSIC(IntrinsicType::kPack2x16Float, "pack2x16float") \ INTRINSIC(IntrinsicType::kPow, "pow") \ INTRINSIC(IntrinsicType::kReflect, "reflect") \ INTRINSIC(IntrinsicType::kReverseBits, "reverseBits") \ INTRINSIC(IntrinsicType::kRound, "round") \ INTRINSIC(IntrinsicType::kSelect, "select") \ INTRINSIC(IntrinsicType::kSign, "sign") \ INTRINSIC(IntrinsicType::kSin, "sin") \ INTRINSIC(IntrinsicType::kSinh, "sinh") \ INTRINSIC(IntrinsicType::kSmoothStep, "smoothStep") \ INTRINSIC(IntrinsicType::kSqrt, "sqrt") \ INTRINSIC(IntrinsicType::kStep, "step") \ INTRINSIC(IntrinsicType::kStorageBarrier, "storageBarrier") \ INTRINSIC(IntrinsicType::kTan, "tan") \ INTRINSIC(IntrinsicType::kTanh, "tanh") \ INTRINSIC(IntrinsicType::kTextureDimensions, "textureDimensions") \ INTRINSIC(IntrinsicType::kTextureLoad, "textureLoad") \ INTRINSIC(IntrinsicType::kTextureNumLayers, "textureNumLayers") \ INTRINSIC(IntrinsicType::kTextureNumLevels, "textureNumLevels") \ INTRINSIC(IntrinsicType::kTextureNumSamples, "textureNumSamples") \ INTRINSIC(IntrinsicType::kTextureSample, "textureSample") \ INTRINSIC(IntrinsicType::kTextureSampleBias, "textureSampleBias") \ INTRINSIC(IntrinsicType::kTextureSampleCompare, "textureSampleCompare") \ INTRINSIC(IntrinsicType::kTextureSampleGrad, "textureSampleGrad") \ INTRINSIC(IntrinsicType::kTextureSampleLevel, "textureSampleLevel") \ INTRINSIC(IntrinsicType::kTextureStore, "textureStore") \ INTRINSIC(IntrinsicType::kTrunc, "trunc") \ INTRINSIC(IntrinsicType::kUnpack2x16Float, "unpack2x16float") \ INTRINSIC(IntrinsicType::kUnpack2x16Snorm, "unpack2x16snorm") \ INTRINSIC(IntrinsicType::kUnpack2x16Unorm, "unpack2x16unorm") \ INTRINSIC(IntrinsicType::kUnpack4x8Snorm, "unpack4x8snorm") \ INTRINSIC(IntrinsicType::kUnpack4x8Unorm, "unpack4x8unorm") \ INTRINSIC(IntrinsicType::kWorkgroupBarrier, "workgroupBarrier") IntrinsicType ParseIntrinsicType(const std::string& name) { #define INTRINSIC(ENUM, NAME) \ if (name == NAME) { \ return ENUM; \ } INTRINSIC_LIST() #undef INTRINSIC return IntrinsicType::kNone; } const char* str(IntrinsicType i) { #define INTRINSIC(ENUM, NAME) \ case ENUM: \ return NAME; switch (i) { INTRINSIC_LIST() } #undef INTRINSIC return ""; } bool IsCoarseDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdxCoarse || i == IntrinsicType::kDpdyCoarse || i == IntrinsicType::kFwidthCoarse; } bool IsFineDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdxFine || i == IntrinsicType::kDpdyFine || i == IntrinsicType::kFwidthFine; } bool IsDerivativeIntrinsic(IntrinsicType i) { return i == IntrinsicType::kDpdx || i == IntrinsicType::kDpdy || i == IntrinsicType::kFwidth || IsCoarseDerivativeIntrinsic(i) || IsFineDerivativeIntrinsic(i); } bool IsFloatClassificationIntrinsic(IntrinsicType i) { return i == IntrinsicType::kIsFinite || i == IntrinsicType::kIsInf || i == IntrinsicType::kIsNan || i == IntrinsicType::kIsNormal; } bool IsTextureIntrinsic(IntrinsicType i) { return IsImageQueryIntrinsic(i) || i == IntrinsicType::kTextureLoad || i == IntrinsicType::kTextureSample || i == IntrinsicType::kTextureSampleLevel || i == IntrinsicType::kTextureSampleBias || i == IntrinsicType::kTextureSampleCompare || i == IntrinsicType::kTextureSampleGrad || i == IntrinsicType::kTextureStore; } bool IsImageQueryIntrinsic(IntrinsicType i) { return i == IntrinsicType::kTextureDimensions || i == IntrinsicType::kTextureNumLayers || i == IntrinsicType::kTextureNumLevels || i == IntrinsicType::kTextureNumSamples; } bool IsDataPackingIntrinsic(IntrinsicType i) { return i == IntrinsicType::kPack4x8Snorm || i == IntrinsicType::kPack4x8Unorm || i == IntrinsicType::kPack2x16Snorm || i == IntrinsicType::kPack2x16Unorm || i == IntrinsicType::kPack2x16Float; } bool IsDataUnpackingIntrinsic(IntrinsicType i) { return i == IntrinsicType::kUnpack4x8Snorm || i == IntrinsicType::kUnpack4x8Unorm || i == IntrinsicType::kUnpack2x16Snorm || i == IntrinsicType::kUnpack2x16Unorm || i == IntrinsicType::kUnpack2x16Float; } bool IsBarrierIntrinsic(IntrinsicType i) { return i == IntrinsicType::kWorkgroupBarrier || i == IntrinsicType::kStorageBarrier; } Intrinsic::Intrinsic(IntrinsicType type, type::Type* return_type, const ParameterList& parameters) : Base(return_type, parameters), type_(type) {} Intrinsic::~Intrinsic() = default; bool Intrinsic::IsCoarseDerivative() const { return IsCoarseDerivativeIntrinsic(type_); } bool Intrinsic::IsFineDerivative() const { return IsFineDerivativeIntrinsic(type_); } bool Intrinsic::IsDerivative() const { return IsDerivativeIntrinsic(type_); } bool Intrinsic::IsFloatClassification() const { return IsFloatClassificationIntrinsic(type_); } bool Intrinsic::IsTexture() const { return IsTextureIntrinsic(type_); } bool Intrinsic::IsImageQuery() const { return IsImageQueryIntrinsic(type_); } bool Intrinsic::IsDataPacking() const { return IsDataPackingIntrinsic(type_); } bool Intrinsic::IsDataUnpacking() const { return IsDataUnpackingIntrinsic(type_); } bool Intrinsic::IsBarrier() const { return IsBarrierIntrinsic(type_); } } // namespace semantic } // namespace tint