// 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. // Doxygen seems to trip over this file for some unknown reason. Disable. //! @cond Doxygen_Suppress #include "src/tint/sem/builtin.h" #include #include #include "src/tint/utils/transform.h" TINT_INSTANTIATE_TYPEINFO(tint::sem::Builtin); namespace tint::sem { namespace { utils::VectorRef SetOwner(utils::VectorRef parameters, const tint::sem::CallTarget* owner) { for (auto* parameter : parameters) { parameter->SetOwner(owner); } return parameters; } } // namespace const char* Builtin::str() const { return sem::str(type_); } bool IsCoarseDerivativeBuiltin(BuiltinType i) { return i == BuiltinType::kDpdxCoarse || i == BuiltinType::kDpdyCoarse || i == BuiltinType::kFwidthCoarse; } bool IsFineDerivativeBuiltin(BuiltinType i) { return i == BuiltinType::kDpdxFine || i == BuiltinType::kDpdyFine || i == BuiltinType::kFwidthFine; } bool IsDerivativeBuiltin(BuiltinType i) { return i == BuiltinType::kDpdx || i == BuiltinType::kDpdy || i == BuiltinType::kFwidth || IsCoarseDerivativeBuiltin(i) || IsFineDerivativeBuiltin(i); } bool IsTextureBuiltin(BuiltinType i) { return IsImageQueryBuiltin(i) || i == BuiltinType::kTextureLoad || i == BuiltinType::kTextureGather || i == BuiltinType::kTextureGatherCompare || i == BuiltinType::kTextureSample || i == BuiltinType::kTextureSampleLevel || i == BuiltinType::kTextureSampleBias || i == BuiltinType::kTextureSampleCompare || i == BuiltinType::kTextureSampleCompareLevel || i == BuiltinType::kTextureSampleGrad || i == BuiltinType::kTextureStore; } bool IsImageQueryBuiltin(BuiltinType i) { return i == BuiltinType::kTextureDimensions || i == BuiltinType::kTextureNumLayers || i == BuiltinType::kTextureNumLevels || i == BuiltinType::kTextureNumSamples; } bool IsDataPackingBuiltin(BuiltinType i) { return i == BuiltinType::kPack4x8snorm || i == BuiltinType::kPack4x8unorm || i == BuiltinType::kPack2x16snorm || i == BuiltinType::kPack2x16unorm || i == BuiltinType::kPack2x16float; } bool IsDataUnpackingBuiltin(BuiltinType i) { return i == BuiltinType::kUnpack4x8snorm || i == BuiltinType::kUnpack4x8unorm || i == BuiltinType::kUnpack2x16snorm || i == BuiltinType::kUnpack2x16unorm || i == BuiltinType::kUnpack2x16float; } bool IsBarrierBuiltin(BuiltinType i) { return i == BuiltinType::kWorkgroupBarrier || i == BuiltinType::kStorageBarrier; } bool IsAtomicBuiltin(BuiltinType i) { return i == sem::BuiltinType::kAtomicLoad || i == sem::BuiltinType::kAtomicStore || i == sem::BuiltinType::kAtomicAdd || i == sem::BuiltinType::kAtomicSub || i == sem::BuiltinType::kAtomicMax || i == sem::BuiltinType::kAtomicMin || i == sem::BuiltinType::kAtomicAnd || i == sem::BuiltinType::kAtomicOr || i == sem::BuiltinType::kAtomicXor || i == sem::BuiltinType::kAtomicExchange || i == sem::BuiltinType::kAtomicCompareExchangeWeak; } bool IsDP4aBuiltin(BuiltinType i) { return i == sem::BuiltinType::kDot4I8Packed || i == sem::BuiltinType::kDot4U8Packed; } Builtin::Builtin(BuiltinType type, const sem::Type* return_type, utils::VectorRef parameters, EvaluationStage eval_stage, PipelineStageSet supported_stages, bool is_deprecated) : Base(return_type, SetOwner(std::move(parameters), this), eval_stage), type_(type), supported_stages_(supported_stages), is_deprecated_(is_deprecated) {} Builtin::~Builtin() = default; bool Builtin::IsCoarseDerivative() const { return IsCoarseDerivativeBuiltin(type_); } bool Builtin::IsFineDerivative() const { return IsFineDerivativeBuiltin(type_); } bool Builtin::IsDerivative() const { return IsDerivativeBuiltin(type_); } bool Builtin::IsTexture() const { return IsTextureBuiltin(type_); } bool Builtin::IsImageQuery() const { return IsImageQueryBuiltin(type_); } bool Builtin::IsDataPacking() const { return IsDataPackingBuiltin(type_); } bool Builtin::IsDataUnpacking() const { return IsDataUnpackingBuiltin(type_); } bool Builtin::IsBarrier() const { return IsBarrierBuiltin(type_); } bool Builtin::IsAtomic() const { return IsAtomicBuiltin(type_); } bool Builtin::IsDP4a() const { return IsDP4aBuiltin(type_); } bool Builtin::HasSideEffects() const { switch (type_) { case sem::BuiltinType::kAtomicAdd: case sem::BuiltinType::kAtomicAnd: case sem::BuiltinType::kAtomicCompareExchangeWeak: case sem::BuiltinType::kAtomicExchange: case sem::BuiltinType::kAtomicMax: case sem::BuiltinType::kAtomicMin: case sem::BuiltinType::kAtomicOr: case sem::BuiltinType::kAtomicStore: case sem::BuiltinType::kAtomicSub: case sem::BuiltinType::kAtomicXor: case sem::BuiltinType::kTextureStore: return true; default: break; } return false; } ast::Extension Builtin::RequiredExtension() const { if (IsDP4a()) { return ast::Extension::kChromiumExperimentalDp4A; } return ast::Extension::kInvalid; } } // namespace tint::sem //! @endcond