242 lines
11 KiB
C++
242 lines
11 KiB
C++
// 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
|