// 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 <cmath>

#include "dawn/native/Device.h"
#include "dawn/native/ObjectContentHasher.h"
#include "dawn/native/ValidationUtils_autogen.h"

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
