//===- llvm/MC/DXContainerRootSignature.cpp - RootSignature -*- C++ -*-=======//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/DXContainerRootSignature.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/EndianStream.h"

using namespace llvm;
using namespace llvm::mcdxbc;

static uint32_t writePlaceholder(raw_svector_ostream &Stream) {
  const uint32_t DummyValue = std::numeric_limits<uint32_t>::max();
  uint32_t Offset = Stream.tell();
  support::endian::write(Stream, DummyValue, llvm::endianness::little);
  return Offset;
}

static uint32_t rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,
                                           uint32_t Offset) {
  uint32_t ByteOffset = Stream.tell();
  uint32_t Value = support::endian::byte_swap<uint32_t>(
      ByteOffset, llvm::endianness::little);
  Stream.pwrite(reinterpret_cast<const char *>(&Value), sizeof(Value), Offset);
  return ByteOffset;
}

size_t RootSignatureDesc::getSize() const {
  uint32_t StaticSamplersOffset = computeStaticSamplersOffset();
  size_t StaticSamplersSize = sizeof(dxbc::RTS0::v1::StaticSampler);
  if (Version > 2)
    StaticSamplersSize = sizeof(dxbc::RTS0::v3::StaticSampler);

  return size_t(StaticSamplersOffset) +
         (StaticSamplersSize * StaticSamplers.size());
}

uint32_t RootSignatureDesc::computeRootParametersOffset() const {
  return sizeof(dxbc::RTS0::v1::RootSignatureHeader);
}

uint32_t RootSignatureDesc::computeStaticSamplersOffset() const {
  uint32_t Offset = computeRootParametersOffset();

  for (const RootParameterInfo &I : ParametersContainer) {
    Offset += sizeof(dxbc::RTS0::v1::RootParameterHeader);
    switch (I.Type) {
    case dxbc::RootParameterType::Constants32Bit:
      Offset += sizeof(dxbc::RTS0::v1::RootConstants);
      break;
    case dxbc::RootParameterType::CBV:
    case dxbc::RootParameterType::SRV:
    case dxbc::RootParameterType::UAV:
      if (Version == 1)
        Offset += sizeof(dxbc::RTS0::v1::RootDescriptor);
      else
        Offset += sizeof(dxbc::RTS0::v2::RootDescriptor);

      break;
    case dxbc::RootParameterType::DescriptorTable:
      const DescriptorTable &Table =
          ParametersContainer.getDescriptorTable(I.Location);

      // 4 bytes for the number of ranges in table and
      // 4 bytes for the ranges offset
      Offset += 2 * sizeof(uint32_t);
      if (Version == 1)
        Offset += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();
      else
        Offset += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();
      break;
    }
  }

  return Offset;
}

void RootSignatureDesc::write(raw_ostream &OS) const {
  SmallString<256> Storage;
  raw_svector_ostream BOS(Storage);
  BOS.reserveExtraSpace(getSize());

  const uint32_t NumParameters = ParametersContainer.size();
  const uint32_t NumSamplers = StaticSamplers.size();
  support::endian::write(BOS, Version, llvm::endianness::little);
  support::endian::write(BOS, NumParameters, llvm::endianness::little);
  support::endian::write(BOS, RootParameterOffset, llvm::endianness::little);
  support::endian::write(BOS, NumSamplers, llvm::endianness::little);
  uint32_t SSO = writePlaceholder(BOS);
  support::endian::write(BOS, Flags, llvm::endianness::little);

  SmallVector<uint32_t> ParamsOffsets;
  for (const RootParameterInfo &I : ParametersContainer) {
    support::endian::write(BOS, I.Type, llvm::endianness::little);
    support::endian::write(BOS, I.Visibility, llvm::endianness::little);

    ParamsOffsets.push_back(writePlaceholder(BOS));
  }

  assert(NumParameters == ParamsOffsets.size());
  for (size_t I = 0; I < NumParameters; ++I) {
    rewriteOffsetToCurrentByte(BOS, ParamsOffsets[I]);
    const RootParameterInfo &Info = ParametersContainer.getInfo(I);
    switch (Info.Type) {
    case dxbc::RootParameterType::Constants32Bit: {
      const mcdxbc::RootConstants &Constants =
          ParametersContainer.getConstant(Info.Location);
      support::endian::write(BOS, Constants.ShaderRegister,
                             llvm::endianness::little);
      support::endian::write(BOS, Constants.RegisterSpace,
                             llvm::endianness::little);
      support::endian::write(BOS, Constants.Num32BitValues,
                             llvm::endianness::little);
      break;
    }
    case dxbc::RootParameterType::CBV:
    case dxbc::RootParameterType::SRV:
    case dxbc::RootParameterType::UAV: {
      const mcdxbc::RootDescriptor &Descriptor =
          ParametersContainer.getRootDescriptor(Info.Location);

      support::endian::write(BOS, Descriptor.ShaderRegister,
                             llvm::endianness::little);
      support::endian::write(BOS, Descriptor.RegisterSpace,
                             llvm::endianness::little);
      if (Version > 1)
        support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);
      break;
    }
    case dxbc::RootParameterType::DescriptorTable: {
      const DescriptorTable &Table =
          ParametersContainer.getDescriptorTable(Info.Location);
      support::endian::write(BOS, (uint32_t)Table.Ranges.size(),
                             llvm::endianness::little);
      rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));
      for (const auto &Range : Table) {
        support::endian::write(BOS, static_cast<uint32_t>(Range.RangeType),
                               llvm::endianness::little);
        support::endian::write(BOS, Range.NumDescriptors,
                               llvm::endianness::little);
        support::endian::write(BOS, Range.BaseShaderRegister,
                               llvm::endianness::little);
        support::endian::write(BOS, Range.RegisterSpace,
                               llvm::endianness::little);
        if (Version > 1)
          support::endian::write(BOS, Range.Flags, llvm::endianness::little);
        support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,
                               llvm::endianness::little);
      }
      break;
    }
    }
  }
  [[maybe_unused]] uint32_t Offset = rewriteOffsetToCurrentByte(BOS, SSO);
  assert(Offset == computeStaticSamplersOffset() &&
         "Computed offset does not match written offset");
  for (const auto &S : StaticSamplers) {
    support::endian::write(BOS, S.Filter, llvm::endianness::little);
    support::endian::write(BOS, S.AddressU, llvm::endianness::little);
    support::endian::write(BOS, S.AddressV, llvm::endianness::little);
    support::endian::write(BOS, S.AddressW, llvm::endianness::little);
    support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);
    support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);
    support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);
    support::endian::write(BOS, S.BorderColor, llvm::endianness::little);
    support::endian::write(BOS, S.MinLOD, llvm::endianness::little);
    support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);
    support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
    support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
    support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);

    if (Version > 2)
      support::endian::write(BOS, S.Flags, llvm::endianness::little);
  }
  assert(Storage.size() == getSize());
  OS.write(Storage.data(), Storage.size());
}
