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

#include "common/Assert.h"

#include <spirv-cross/spirv_hlsl.hpp>

namespace backend { namespace d3d12 {

    // TODO(kainino@chromium.org): Consider replacing this with a generic enum_map.
    template <typename T>
    class BindingTypeMap {
      public:
        T& operator[](dawn::BindingType type) {
            switch (type) {
                case dawn::BindingType::UniformBuffer:
                    return mMap[0];
                case dawn::BindingType::Sampler:
                    return mMap[1];
                case dawn::BindingType::SampledTexture:
                    return mMap[2];
                case dawn::BindingType::StorageBuffer:
                    return mMap[3];
                default:
                    DAWN_UNREACHABLE();
            }
        }

      private:
        static constexpr int kNumBindingTypes = 4;
        std::array<T, kNumBindingTypes> mMap{};
    };

    ShaderModule::ShaderModule(Device* device, ShaderModuleBuilder* builder)
        : ShaderModuleBase(builder), mDevice(device) {
        spirv_cross::CompilerHLSL compiler(builder->AcquireSpirv());

        spirv_cross::CompilerGLSL::Options options_glsl;
        options_glsl.vertex.fixup_clipspace = true;
        options_glsl.vertex.flip_vert_y = true;
        compiler.spirv_cross::CompilerGLSL::set_options(options_glsl);

        spirv_cross::CompilerHLSL::Options options_hlsl;
        options_hlsl.shader_model = 51;
        compiler.spirv_cross::CompilerHLSL::set_options(options_hlsl);

        ExtractSpirvInfo(compiler);

        // rename bindings so that each register type c/u/t/s starts at 0 and then offset by
        // kMaxBindingsPerGroup * bindGroupIndex
        const auto& moduleBindingInfo = GetBindingInfo();
        for (uint32_t group = 0; group < moduleBindingInfo.size(); ++group) {
            const auto& groupBindingInfo = moduleBindingInfo[group];

            BindingTypeMap<uint32_t> baseRegisters{};
            for (const auto& bindingInfo : groupBindingInfo) {
                if (bindingInfo.used) {
                    uint32_t& baseRegister = baseRegisters[bindingInfo.type];
                    uint32_t bindGroupOffset = group * kMaxBindingsPerGroup;
                    compiler.set_decoration(bindingInfo.id, spv::DecorationBinding,
                                            bindGroupOffset + baseRegister++);
                }
            }
        }

        mHlslSource = compiler.compile();
    }

    const std::string& ShaderModule::GetHLSLSource() const {
        return mHlslSource;
    }

}}  // namespace backend::d3d12
