// 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/d3d12/SamplerD3D12.h"

#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/UtilsD3D12.h"

namespace dawn_native::d3d12 {

    namespace {
        D3D12_TEXTURE_ADDRESS_MODE AddressMode(wgpu::AddressMode mode) {
            switch (mode) {
                case wgpu::AddressMode::Repeat:
                    return D3D12_TEXTURE_ADDRESS_MODE_WRAP;
                case wgpu::AddressMode::MirrorRepeat:
                    return D3D12_TEXTURE_ADDRESS_MODE_MIRROR;
                case wgpu::AddressMode::ClampToEdge:
                    return D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
            }
        }
    }  // namespace

    // static
    Ref<Sampler> Sampler::Create(Device* device, const SamplerDescriptor* descriptor) {
        return AcquireRef(new Sampler(device, descriptor));
    }

    Sampler::Sampler(Device* device, const SamplerDescriptor* descriptor)
        : SamplerBase(device, descriptor) {
        D3D12_FILTER_TYPE minFilter;
        switch (descriptor->minFilter) {
            case wgpu::FilterMode::Nearest:
                minFilter = D3D12_FILTER_TYPE_POINT;
                break;
            case wgpu::FilterMode::Linear:
                minFilter = D3D12_FILTER_TYPE_LINEAR;
                break;
        }

        D3D12_FILTER_TYPE magFilter;
        switch (descriptor->magFilter) {
            case wgpu::FilterMode::Nearest:
                magFilter = D3D12_FILTER_TYPE_POINT;
                break;
            case wgpu::FilterMode::Linear:
                magFilter = D3D12_FILTER_TYPE_LINEAR;
                break;
        }

        D3D12_FILTER_TYPE mipmapFilter;
        switch (descriptor->mipmapFilter) {
            case wgpu::FilterMode::Nearest:
                mipmapFilter = D3D12_FILTER_TYPE_POINT;
                break;
            case wgpu::FilterMode::Linear:
                mipmapFilter = D3D12_FILTER_TYPE_LINEAR;
                break;
        }

        D3D12_FILTER_REDUCTION_TYPE reduction =
            descriptor->compare == wgpu::CompareFunction::Undefined
                ? D3D12_FILTER_REDUCTION_TYPE_STANDARD
                : D3D12_FILTER_REDUCTION_TYPE_COMPARISON;

        // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_sampler_desc
        mSamplerDesc.MaxAnisotropy = std::min<uint16_t>(GetMaxAnisotropy(), 16u);

        if (mSamplerDesc.MaxAnisotropy > 1) {
            mSamplerDesc.Filter = D3D12_ENCODE_ANISOTROPIC_FILTER(reduction);
        } else {
            mSamplerDesc.Filter =
                D3D12_ENCODE_BASIC_FILTER(minFilter, magFilter, mipmapFilter, reduction);
        }

        mSamplerDesc.AddressU = AddressMode(descriptor->addressModeU);
        mSamplerDesc.AddressV = AddressMode(descriptor->addressModeV);
        mSamplerDesc.AddressW = AddressMode(descriptor->addressModeW);
        mSamplerDesc.MipLODBias = 0.f;

        if (descriptor->compare != wgpu::CompareFunction::Undefined) {
            mSamplerDesc.ComparisonFunc = ToD3D12ComparisonFunc(descriptor->compare);
        } else {
            // Still set the function so it's not garbage.
            mSamplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
        }
        mSamplerDesc.MinLOD = descriptor->lodMinClamp;
        mSamplerDesc.MaxLOD = descriptor->lodMaxClamp;
    }

    const D3D12_SAMPLER_DESC& Sampler::GetSamplerDescriptor() const {
        return mSamplerDesc;
    }

}  // namespace dawn_native::d3d12
