// Copyright 2017 The Dawn 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 "dawn_native/Sampler.h"

#include "dawn_native/Device.h"
#include "dawn_native/ObjectContentHasher.h"
#include "dawn_native/ValidationUtils_autogen.h"

#include <cmath>

namespace dawn_native {

    MaybeError ValidateSamplerDescriptor(DeviceBase*, const SamplerDescriptor* descriptor) {
        DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr");

        DAWN_INVALID_IF(std::isnan(descriptor->lodMinClamp) || std::isnan(descriptor->lodMaxClamp),
                        "LOD clamp bounds [%f, %f] contain a NaN.", descriptor->lodMinClamp,
                        descriptor->lodMaxClamp);

        DAWN_INVALID_IF(descriptor->lodMinClamp < 0 || descriptor->lodMaxClamp < 0,
                        "LOD clamp bounds [%f, %f] contain contain a negative number.",
                        descriptor->lodMinClamp, descriptor->lodMaxClamp);

        DAWN_INVALID_IF(descriptor->lodMinClamp > descriptor->lodMaxClamp,
                        "LOD min clamp (%f) is larger than the max clamp (%f).",
                        descriptor->lodMinClamp, descriptor->lodMaxClamp);

        if (descriptor->maxAnisotropy > 1) {
            DAWN_INVALID_IF(descriptor->minFilter != wgpu::FilterMode::Linear ||
                                descriptor->magFilter != wgpu::FilterMode::Linear ||
                                descriptor->mipmapFilter != wgpu::FilterMode::Linear,
                            "One of minFilter (%s), magFilter (%s) or mipmapFilter (%s) is not %s "
                            "while using anisotropic filter (maxAnisotropy is %f)",
                            descriptor->magFilter, descriptor->minFilter, descriptor->mipmapFilter,
                            wgpu::FilterMode::Linear, descriptor->maxAnisotropy);
        } else if (descriptor->maxAnisotropy == 0u) {
            return DAWN_FORMAT_VALIDATION_ERROR("Max anisotropy (%f) is less than 1.",
                                                descriptor->maxAnisotropy);
        }

        DAWN_TRY(ValidateFilterMode(descriptor->minFilter));
        DAWN_TRY(ValidateFilterMode(descriptor->magFilter));
        DAWN_TRY(ValidateFilterMode(descriptor->mipmapFilter));
        DAWN_TRY(ValidateAddressMode(descriptor->addressModeU));
        DAWN_TRY(ValidateAddressMode(descriptor->addressModeV));
        DAWN_TRY(ValidateAddressMode(descriptor->addressModeW));

        // CompareFunction::Undefined is tagged as invalid because it can't be used, except for the
        // SamplerDescriptor where it is a special value that means the sampler is not a
        // comparison-sampler.
        if (descriptor->compare != wgpu::CompareFunction::Undefined) {
            DAWN_TRY(ValidateCompareFunction(descriptor->compare));
        }

        return {};
    }

    // SamplerBase

    SamplerBase::SamplerBase(DeviceBase* device,
                             const SamplerDescriptor* descriptor,
                             ApiObjectBase::UntrackedByDeviceTag tag)
        : ApiObjectBase(device, descriptor->label),
          mAddressModeU(descriptor->addressModeU),
          mAddressModeV(descriptor->addressModeV),
          mAddressModeW(descriptor->addressModeW),
          mMagFilter(descriptor->magFilter),
          mMinFilter(descriptor->minFilter),
          mMipmapFilter(descriptor->mipmapFilter),
          mLodMinClamp(descriptor->lodMinClamp),
          mLodMaxClamp(descriptor->lodMaxClamp),
          mCompareFunction(descriptor->compare),
          mMaxAnisotropy(descriptor->maxAnisotropy) {
    }

    SamplerBase::SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor)
        : SamplerBase(device, descriptor, kUntrackedByDevice) {
        TrackInDevice();
    }

    SamplerBase::SamplerBase(DeviceBase* device) : ApiObjectBase(device, kLabelNotImplemented) {
        TrackInDevice();
    }

    SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag)
        : ApiObjectBase(device, tag) {
    }

    SamplerBase::~SamplerBase() = default;

    void SamplerBase::DestroyImpl() {
        if (IsCachedReference()) {
            // Do not uncache the actual cached object if we are a blueprint.
            GetDevice()->UncacheSampler(this);
        }
    }

    // static
    SamplerBase* SamplerBase::MakeError(DeviceBase* device) {
        return new SamplerBase(device, ObjectBase::kError);
    }

    ObjectType SamplerBase::GetType() const {
        return ObjectType::Sampler;
    }

    bool SamplerBase::IsComparison() const {
        return mCompareFunction != wgpu::CompareFunction::Undefined;
    }

    bool SamplerBase::IsFiltering() const {
        return mMinFilter == wgpu::FilterMode::Linear || mMagFilter == wgpu::FilterMode::Linear ||
               mMipmapFilter == wgpu::FilterMode::Linear;
    }

    size_t SamplerBase::ComputeContentHash() {
        ObjectContentHasher recorder;
        recorder.Record(mAddressModeU, mAddressModeV, mAddressModeW, mMagFilter, mMinFilter,
                        mMipmapFilter, mLodMinClamp, mLodMaxClamp, mCompareFunction,
                        mMaxAnisotropy);
        return recorder.GetContentHash();
    }

    bool SamplerBase::EqualityFunc::operator()(const SamplerBase* a, const SamplerBase* b) const {
        if (a == b) {
            return true;
        }

        ASSERT(!std::isnan(a->mLodMinClamp));
        ASSERT(!std::isnan(b->mLodMinClamp));
        ASSERT(!std::isnan(a->mLodMaxClamp));
        ASSERT(!std::isnan(b->mLodMaxClamp));

        return a->mAddressModeU == b->mAddressModeU && a->mAddressModeV == b->mAddressModeV &&
               a->mAddressModeW == b->mAddressModeW && a->mMagFilter == b->mMagFilter &&
               a->mMinFilter == b->mMinFilter && a->mMipmapFilter == b->mMipmapFilter &&
               a->mLodMinClamp == b->mLodMinClamp && a->mLodMaxClamp == b->mLodMaxClamp &&
               a->mCompareFunction == b->mCompareFunction && a->mMaxAnisotropy == b->mMaxAnisotropy;
    }

}  // namespace dawn_native
