// Copyright 2017 The NXT 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 "backend/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[](nxt::BindingType type) {
            switch (type) {
                case nxt::BindingType::UniformBuffer:
                    return mMap[0];
                case nxt::BindingType::Sampler:
                    return mMap[1];
                case nxt::BindingType::SampledTexture:
                    return mMap[2];
                case nxt::BindingType::StorageBuffer:
                    return mMap[3];
                default:
                    NXT_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
