// 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 <utility>
#include <vector>

#include "src/tint/utils/transform.h"

TINT_INSTANTIATE_TYPEINFO(tint::sem::Builtin);

namespace tint::sem {
namespace {

utils::VectorRef<const Parameter*> SetOwner(utils::VectorRef<Parameter*> 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<Parameter*> 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 {
    if (IsAtomic() && type_ != sem::BuiltinType::kAtomicLoad) {
        return true;
    }
    if (type_ == sem::BuiltinType::kTextureStore) {
        return true;
    }
    return false;
}

ast::Extension Builtin::RequiredExtension() const {
    if (IsDP4a()) {
        return ast::Extension::kChromiumExperimentalDp4A;
    }
    return ast::Extension::kInvalid;
}

}  // namespace tint::sem

//! @endcond
