| // 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, "<not-an-intrinsic>") \ |
| 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 "<unknown>"; |
| } |
| |
| 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 |