| // 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/sem/intrinsic.h" |
| |
| TINT_INSTANTIATE_TYPEINFO(tint::sem::Intrinsic); |
| |
| namespace tint { |
| namespace sem { |
| |
| std::ostream& operator<<(std::ostream& out, IntrinsicType i) { |
| out << str(i); |
| return out; |
| } |
| |
| const char* Intrinsic::str() const { |
| return sem::str(type_); |
| } |
| |
| 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::kTextureSampleCompareLevel || |
| 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; |
| } |
| |
| bool IsAtomicIntrinsic(IntrinsicType i) { |
| return i == sem::IntrinsicType::kAtomicLoad || |
| i == sem::IntrinsicType::kAtomicStore || |
| i == sem::IntrinsicType::kAtomicAdd || |
| i == sem::IntrinsicType::kAtomicMax || |
| i == sem::IntrinsicType::kAtomicMin || |
| i == sem::IntrinsicType::kAtomicAnd || |
| i == sem::IntrinsicType::kAtomicOr || |
| i == sem::IntrinsicType::kAtomicXor || |
| i == sem::IntrinsicType::kAtomicExchange || |
| i == sem::IntrinsicType::kAtomicCompareExchangeWeak; |
| } |
| |
| Intrinsic::Intrinsic(IntrinsicType type, |
| sem::Type* return_type, |
| const ParameterList& parameters, |
| PipelineStageSet supported_stages, |
| bool is_deprecated) |
| : Base(return_type, parameters), |
| type_(type), |
| supported_stages_(supported_stages), |
| is_deprecated_(is_deprecated) {} |
| |
| Intrinsic::Intrinsic(const Intrinsic&) = default; |
| |
| 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_); |
| } |
| |
| bool Intrinsic::IsAtomic() const { |
| return IsAtomicIntrinsic(type_); |
| } |
| |
| bool operator==(const Intrinsic& a, const Intrinsic& b) { |
| static_assert(sizeof(Intrinsic(IntrinsicType::kNone, nullptr, ParameterList{}, |
| PipelineStageSet{}, false)) > 0, |
| "don't forget to update the comparison below if you change the " |
| "constructor of Intrinsic!"); |
| |
| if (a.Type() != b.Type() || a.SupportedStages() != b.SupportedStages() || |
| a.ReturnType() != b.ReturnType() || |
| a.IsDeprecated() != b.IsDeprecated() || |
| a.Parameters().size() != b.Parameters().size()) { |
| return false; |
| } |
| for (size_t i = 0; i < a.Parameters().size(); i++) { |
| if (a.Parameters()[i] != b.Parameters()[i]) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| } // namespace sem |
| } // namespace tint |