//===- DXContainerYAML.cpp - DXContainer YAMLIO implementation ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for handling the YAML representation of
// DXContainerYAML.
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"
#include <cstdint>
#include <system_error>

namespace llvm {

// This assert is duplicated here to leave a breadcrumb of the places that need
// to be updated if flags grow past 64-bits.
static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit <= 1ull << 63,
              "Shader flag bits exceed enum size.");

DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  Val = (FlagData & (uint64_t)dxbc::FeatureFlags::Val) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

template <typename T>
static llvm::Error
readDescriptorRanges(DXContainerYAML::RootParameterHeaderYaml &Header,
                     DXContainerYAML::RootSignatureYamlDesc &RootSigDesc,
                     object::DirectX::DescriptorTableView *DTV) {

  llvm::Expected<object::DirectX::DescriptorTable<T>> TableOrErr =
      DTV->read<T>();
  if (Error E = TableOrErr.takeError())
    return E;
  auto Table = *TableOrErr;

  DXContainerYAML::RootParameterLocationYaml Location(Header);
  DXContainerYAML::DescriptorTableYaml &TableYaml =
      RootSigDesc.Parameters.getOrInsertTable(Location);
  RootSigDesc.Parameters.insertLocation(Location);

  TableYaml.NumRanges = Table.NumRanges;
  TableYaml.RangesOffset = Table.RangesOffset;

  for (const auto &R : Table.Ranges) {
    DXContainerYAML::DescriptorRangeYaml NewR;
    NewR.OffsetInDescriptorsFromTableStart =
        R.OffsetInDescriptorsFromTableStart;
    NewR.NumDescriptors = R.NumDescriptors;
    NewR.BaseShaderRegister = R.BaseShaderRegister;
    NewR.RegisterSpace = R.RegisterSpace;
    if (!dxbc::isValidRangeType(R.RangeType))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for descriptor range type");
    NewR.RangeType = dxil::ResourceClass(R.RangeType);
    if constexpr (std::is_same_v<T, dxbc::RTS0::v2::DescriptorRange>) {
      // Set all flag fields for v2
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  NewR.Enum =                                                                  \
      (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlags::Enum)) != 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
    }
    TableYaml.Ranges.push_back(NewR);
  }

  return Error::success();
}

llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
DXContainerYAML::RootSignatureYamlDesc::create(
    const object::DirectX::RootSignature &Data) {

  RootSignatureYamlDesc RootSigDesc;
  uint32_t Version = Data.getVersion();

  RootSigDesc.Version = Version;
  RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
  RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
  RootSigDesc.NumRootParameters = Data.getNumRootParameters();
  RootSigDesc.RootParametersOffset = Data.getRootParametersOffset();

  uint32_t Flags = Data.getFlags();
  for (const dxbc::RTS0::v1::RootParameterHeader &PH : Data.param_headers()) {

    if (!dxbc::isValidParameterType(PH.ParameterType))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for parameter type");

    RootParameterHeaderYaml Header(dxbc::RootParameterType(PH.ParameterType));
    Header.Offset = PH.ParameterOffset;

    if (!dxbc::isValidShaderVisibility(PH.ShaderVisibility))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for shader visibility");

    Header.Visibility = dxbc::ShaderVisibility(PH.ShaderVisibility);

    llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr =
        Data.getParameter(PH);
    if (Error E = ParamViewOrErr.takeError())
      return std::move(E);
    object::DirectX::RootParameterView ParamView = ParamViewOrErr.get();

    if (auto *RCV = dyn_cast<object::DirectX::RootConstantView>(&ParamView)) {
      llvm::Expected<dxbc::RTS0::v1::RootConstants> ConstantsOrErr =
          RCV->read();
      if (Error E = ConstantsOrErr.takeError())
        return std::move(E);

      auto Constants = *ConstantsOrErr;
      RootParameterLocationYaml Location(Header);
      RootConstantsYaml &ConstantYaml =
          RootSigDesc.Parameters.getOrInsertConstants(Location);
      RootSigDesc.Parameters.insertLocation(Location);
      ConstantYaml.Num32BitValues = Constants.Num32BitValues;
      ConstantYaml.ShaderRegister = Constants.ShaderRegister;
      ConstantYaml.RegisterSpace = Constants.RegisterSpace;

    } else if (auto *RDV =
                   dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
      llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
          RDV->read(Version);
      if (Error E = DescriptorOrErr.takeError())
        return std::move(E);
      auto Descriptor = *DescriptorOrErr;
      RootParameterLocationYaml Location(Header);
      RootDescriptorYaml &YamlDescriptor =
          RootSigDesc.Parameters.getOrInsertDescriptor(Location);
      RootSigDesc.Parameters.insertLocation(Location);

      YamlDescriptor.ShaderRegister = Descriptor.ShaderRegister;
      YamlDescriptor.RegisterSpace = Descriptor.RegisterSpace;
      if (Version > 1) {
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  YamlDescriptor.Enum =                                                        \
      (Descriptor.Flags &                                                      \
       llvm::to_underlying(dxbc::RootDescriptorFlags::Enum)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
      }
    } else if (auto *DTV =
                   dyn_cast<object::DirectX::DescriptorTableView>(&ParamView)) {
      if (Version == 1) {
        if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>(
                Header, RootSigDesc, DTV))
          return std::move(E);
      } else if (Version == 2 || Version == 3) {
        if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>(
                Header, RootSigDesc, DTV))
          return std::move(E);
      } else
        llvm_unreachable("Unknown version for DescriptorRanges");
    }
  }

  for (const auto &S : Data.samplers()) {
    if (!dxbc::isValidSamplerFilter(S.Filter))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler filter");

    if (!dxbc::isValidAddress(S.AddressU))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressU");

    if (!dxbc::isValidAddress(S.AddressV))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressV");

    if (!dxbc::isValidAddress(S.AddressW))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressW");

    if (!dxbc::isValidComparisonFunc(S.ComparisonFunc))
      return createStringError(
          std::errc::invalid_argument,
          "Invalid value for static sampler ComparisonFunc");

    if (!dxbc::isValidBorderColor(S.BorderColor))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler BorderColor");

    if (!dxbc::isValidShaderVisibility(S.ShaderVisibility))
      return createStringError(
          std::errc::invalid_argument,
          "Invalid value for static sampler ShaderVisibility");

    StaticSamplerYamlDesc NewS;
    NewS.Filter = dxbc::SamplerFilter(S.Filter);
    NewS.AddressU = dxbc::TextureAddressMode(S.AddressU);
    NewS.AddressV = dxbc::TextureAddressMode(S.AddressV);
    NewS.AddressW = dxbc::TextureAddressMode(S.AddressW);
    NewS.MipLODBias = S.MipLODBias;
    NewS.MaxAnisotropy = S.MaxAnisotropy;
    NewS.ComparisonFunc = dxbc::ComparisonFunc(S.ComparisonFunc);
    NewS.BorderColor = dxbc::StaticBorderColor(S.BorderColor);
    NewS.MinLOD = S.MinLOD;
    NewS.MaxLOD = S.MaxLOD;
    NewS.ShaderRegister = S.ShaderRegister;
    NewS.RegisterSpace = S.RegisterSpace;
    NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);

    if (Version > 2) {
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum));
#include "llvm/BinaryFormat/DXContainerConstants.def"
    }
    RootSigDesc.StaticSamplers.push_back(NewS);
  }

#define ROOT_SIGNATURE_FLAG(Num, Val)                                          \
  RootSigDesc.Val = (Flags & llvm::to_underlying(dxbc::RootFlags::Val)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return RootSigDesc;
}

uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
  uint64_t Flags = 0;
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::RootDescriptorFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
  uint64_t Flag = 0;
#define ROOT_SIGNATURE_FLAG(Num, Val)                                          \
  if (Val)                                                                     \
    Flag |= (uint32_t)dxbc::RootFlags::Val;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flag;
}

uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
  uint64_t Flags = 0;
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::DescriptorRangeFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint32_t DXContainerYAML::StaticSamplerYamlDesc::getEncodedFlags() const {
  uint64_t Flags = 0;
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::StaticSamplerFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
  uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  if (Val)                                                                     \
    Flag |= (uint64_t)dxbc::FeatureFlags::Val;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flag;
}

DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash &Data)
    : IncludesSource((Data.Flags & static_cast<uint32_t>(
                                       dxbc::HashFlags::IncludesSource)) != 0),
      Digest(16, 0) {
  memcpy(Digest.data(), &Data.Digest[0], 16);
}

DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
  memset(&Info, 0, sizeof(Info));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P,
                                  uint16_t Stage)
    : Version(0) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v0::RuntimeInfo));

  assert(Stage < std::numeric_limits<uint8_t>::max() &&
         "Stage should be a very small number");
  // We need to bring the stage in separately since it isn't part of the v1 data
  // structure.
  Info.ShaderStage = static_cast<uint8_t>(Stage);
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P)
    : Version(1) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v1::RuntimeInfo));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P)
    : Version(2) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v2::RuntimeInfo));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P,
                                  StringRef StringTable)
    : Version(3),
      EntryName(StringTable.substr(P->EntryNameOffset,
                                   StringTable.find('\0', P->EntryNameOffset) -
                                       P->EntryNameOffset)) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v3::RuntimeInfo));
}

namespace yaml {

void MappingTraits<DXContainerYAML::VersionTuple>::mapping(
    IO &IO, DXContainerYAML::VersionTuple &Version) {
  IO.mapRequired("Major", Version.Major);
  IO.mapRequired("Minor", Version.Minor);
}

void MappingTraits<DXContainerYAML::FileHeader>::mapping(
    IO &IO, DXContainerYAML::FileHeader &Header) {
  IO.mapRequired("Hash", Header.Hash);
  IO.mapRequired("Version", Header.Version);
  IO.mapOptional("FileSize", Header.FileSize);
  IO.mapRequired("PartCount", Header.PartCount);
  IO.mapOptional("PartOffsets", Header.PartOffsets);
}

void MappingTraits<DXContainerYAML::DXILProgram>::mapping(
    IO &IO, DXContainerYAML::DXILProgram &Program) {
  IO.mapRequired("MajorVersion", Program.MajorVersion);
  IO.mapRequired("MinorVersion", Program.MinorVersion);
  IO.mapRequired("ShaderKind", Program.ShaderKind);
  IO.mapOptional("Size", Program.Size);
  IO.mapRequired("DXILMajorVersion", Program.DXILMajorVersion);
  IO.mapRequired("DXILMinorVersion", Program.DXILMinorVersion);
  IO.mapOptional("DXILSize", Program.DXILSize);
  IO.mapOptional("DXIL", Program.DXIL);
}

void MappingTraits<DXContainerYAML::ShaderFeatureFlags>::mapping(
    IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags) {
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  IO.mapRequired(#Val, Flags.Val);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::ShaderHash>::mapping(
    IO &IO, DXContainerYAML::ShaderHash &Hash) {
  IO.mapRequired("IncludesSource", Hash.IncludesSource);
  IO.mapRequired("Digest", Hash.Digest);
}

void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
    IO &IO, DXContainerYAML::PSVInfo &PSV) {
  IO.mapRequired("Version", PSV.Version);

  // Store the PSV version in the YAML context.
  void *OldContext = IO.getContext();
  uint32_t Version = PSV.Version;
  IO.setContext(&Version);

  // Restore the YAML context on function exit.
  auto RestoreContext = make_scope_exit([&]() { IO.setContext(OldContext); });

  // Shader stage is only included in binaries for v1 and later, but we always
  // include it since it simplifies parsing and file construction.
  IO.mapRequired("ShaderStage", PSV.Info.ShaderStage);
  PSV.mapInfoForVersion(IO);

  IO.mapRequired("ResourceStride", PSV.ResourceStride);
  IO.mapRequired("Resources", PSV.Resources);
  if (PSV.Version == 0)
    return;
  IO.mapRequired("SigInputElements", PSV.SigInputElements);
  IO.mapRequired("SigOutputElements", PSV.SigOutputElements);
  IO.mapRequired("SigPatchOrPrimElements", PSV.SigPatchOrPrimElements);

  Triple::EnvironmentType Stage = dxbc::getShaderStage(PSV.Info.ShaderStage);
  if (PSV.Info.UsesViewID) {
    MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
        PSV.OutputVectorMasks);
    IO.mapRequired("OutputVectorMasks", MutableOutMasks);
    if (Stage == Triple::EnvironmentType::Hull)
      IO.mapRequired("PatchOrPrimMasks", PSV.PatchOrPrimMasks);
  }
  MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
      PSV.InputOutputMap);
  IO.mapRequired("InputOutputMap", MutableIOMap);

  if (Stage == Triple::EnvironmentType::Hull)
    IO.mapRequired("InputPatchMap", PSV.InputPatchMap);

  if (Stage == Triple::EnvironmentType::Domain)
    IO.mapRequired("PatchOutputMap", PSV.PatchOutputMap);
}

void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
    IO &IO, DXContainerYAML::SignatureParameter &S) {
  IO.mapRequired("Stream", S.Stream);
  IO.mapRequired("Name", S.Name);
  IO.mapRequired("Index", S.Index);
  IO.mapRequired("SystemValue", S.SystemValue);
  IO.mapRequired("CompType", S.CompType);
  IO.mapRequired("Register", S.Register);
  IO.mapRequired("Mask", S.Mask);
  IO.mapRequired("ExclusiveMask", S.ExclusiveMask);
  IO.mapRequired("MinPrecision", S.MinPrecision);
}

void MappingTraits<DXContainerYAML::Signature>::mapping(
    IO &IO, DXContainerYAML::Signature &S) {
  IO.mapRequired("Parameters", S.Parameters);
}

void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
    IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
  IO.mapRequired("Version", S.Version);
  IO.mapRequired("NumRootParameters", S.NumRootParameters);
  IO.mapOptional("RootParametersOffset", S.RootParametersOffset, std::nullopt);
  IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers);
  IO.mapOptional("StaticSamplersOffset", S.StaticSamplersOffset, std::nullopt);
  IO.mapRequired("Parameters", S.Parameters.Locations, S);
  IO.mapOptional("Samplers", S.StaticSamplers);
#define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
  IO.mapRequired("RangeType", R.RangeType);
  // handling the edge case where NumDescriptors might be -1
  if (IO.outputting()) {
    if (R.NumDescriptors == UINT_MAX) {
      int32_t NegOne = -1;
      IO.mapRequired("NumDescriptors", NegOne);
    } else
      IO.mapRequired("NumDescriptors", R.NumDescriptors);
  } else {
    int32_t TmpNumDesc = 0;
    IO.mapRequired("NumDescriptors", TmpNumDesc);
    R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
  }

  IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister);
  IO.mapRequired("RegisterSpace", R.RegisterSpace);
  IO.mapRequired("OffsetInDescriptorsFromTableStart",
                 R.OffsetInDescriptorsFromTableStart);
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  IO.mapOptional(#Flag, R.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
  IO.mapRequired("NumRanges", T.NumRanges);
  IO.mapOptional("RangesOffset", T.RangesOffset);
  IO.mapRequired("Ranges", T.Ranges);
}

void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
                          DXContainerYAML::RootSignatureYamlDesc>::
    mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
            DXContainerYAML::RootSignatureYamlDesc &S) {
  IO.mapRequired("ParameterType", L.Header.Type);
  IO.mapRequired("ShaderVisibility", L.Header.Visibility);

  switch (L.Header.Type) {
  case dxbc::RootParameterType::Constants32Bit: {
    DXContainerYAML::RootConstantsYaml &Constants =
        S.Parameters.getOrInsertConstants(L);
    IO.mapRequired("Constants", Constants);
    break;
  }
  case dxbc::RootParameterType::CBV:
  case dxbc::RootParameterType::SRV:
  case dxbc::RootParameterType::UAV: {
    DXContainerYAML::RootDescriptorYaml &Descriptor =
        S.Parameters.getOrInsertDescriptor(L);
    IO.mapRequired("Descriptor", Descriptor);
    break;
  }
  case dxbc::RootParameterType::DescriptorTable: {
    DXContainerYAML::DescriptorTableYaml &Table =
        S.Parameters.getOrInsertTable(L);
    IO.mapRequired("Table", Table);
    break;
  }
  }
}

void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
  IO.mapRequired("Num32BitValues", C.Num32BitValues);
  IO.mapRequired("RegisterSpace", C.RegisterSpace);
  IO.mapRequired("ShaderRegister", C.ShaderRegister);
}

void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
  IO.mapRequired("RegisterSpace", D.RegisterSpace);
  IO.mapRequired("ShaderRegister", D.ShaderRegister);
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  IO.mapOptional(#Flag, D.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
    IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {

  IO.mapOptional("Filter", S.Filter);
  IO.mapOptional("AddressU", S.AddressU);
  IO.mapOptional("AddressV", S.AddressV);
  IO.mapOptional("AddressW", S.AddressW);
  IO.mapOptional("MipLODBias", S.MipLODBias);
  IO.mapOptional("MaxAnisotropy", S.MaxAnisotropy);
  IO.mapOptional("ComparisonFunc", S.ComparisonFunc);
  IO.mapOptional("BorderColor", S.BorderColor);
  IO.mapOptional("MinLOD", S.MinLOD);
  IO.mapOptional("MaxLOD", S.MaxLOD);
  IO.mapRequired("ShaderRegister", S.ShaderRegister);
  IO.mapRequired("RegisterSpace", S.RegisterSpace);
  IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  IO.mapOptional(#Flag, S.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
                                                   DXContainerYAML::Part &P) {
  IO.mapRequired("Name", P.Name);
  IO.mapRequired("Size", P.Size);
  IO.mapOptional("Program", P.Program);
  IO.mapOptional("Flags", P.Flags);
  IO.mapOptional("Hash", P.Hash);
  IO.mapOptional("PSVInfo", P.Info);
  IO.mapOptional("Signature", P.Signature);
  IO.mapOptional("RootSignature", P.RootSignature);
}

void MappingTraits<DXContainerYAML::Object>::mapping(
    IO &IO, DXContainerYAML::Object &Obj) {
  IO.mapTag("!dxcontainer", true);
  IO.mapRequired("Header", Obj.Header);
  IO.mapRequired("Parts", Obj.Parts);
}

void MappingTraits<DXContainerYAML::ResourceFlags>::mapping(
    IO &IO, DXContainerYAML::ResourceFlags &Flags) {
#define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
    IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
  IO.mapRequired("Type", Res.Type);
  IO.mapRequired("Space", Res.Space);
  IO.mapRequired("LowerBound", Res.LowerBound);
  IO.mapRequired("UpperBound", Res.UpperBound);

  const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
  if (*PSVVersion < 2)
    return;

  IO.mapRequired("Kind", Res.Kind);
  IO.mapRequired("Flags", Res.Flags);
}

void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
    IO &IO, DXContainerYAML::SignatureElement &El) {
  IO.mapRequired("Name", El.Name);
  IO.mapRequired("Indices", El.Indices);
  IO.mapRequired("StartRow", El.StartRow);
  IO.mapRequired("Cols", El.Cols);
  IO.mapRequired("StartCol", El.StartCol);
  IO.mapRequired("Allocated", El.Allocated);
  IO.mapRequired("Kind", El.Kind);
  IO.mapRequired("ComponentType", El.Type);
  IO.mapRequired("Interpolation", El.Mode);
  IO.mapRequired("DynamicMask", El.DynamicMask);
  IO.mapRequired("Stream", El.Stream);
}

void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
    IO &IO, dxbc::PSV::SemanticKind &Value) {
  for (const auto &E : dxbc::PSV::getSemanticKinds())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
    IO &IO, dxbc::PSV::ComponentType &Value) {
  for (const auto &E : dxbc::PSV::getComponentTypes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
    IO &IO, dxbc::PSV::InterpolationMode &Value) {
  for (const auto &E : dxbc::PSV::getInterpolationModes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
    IO &IO, dxbc::PSV::ResourceType &Value) {
  for (const auto &E : dxbc::PSV::getResourceTypes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
    IO &IO, dxbc::PSV::ResourceKind &Value) {
  for (const auto &E : dxbc::PSV::getResourceKinds())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
    IO &IO, dxbc::D3DSystemValue &Value) {
  for (const auto &E : dxbc::getD3DSystemValues())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
    IO &IO, dxbc::SigMinPrecision &Value) {
  for (const auto &E : dxbc::getSigMinPrecisions())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
    IO &IO, dxbc::SigComponentType &Value) {
  for (const auto &E : dxbc::getSigComponentTypes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::RootParameterType>::enumeration(
    IO &IO, dxbc::RootParameterType &Value) {
  for (const auto &E : dxbc::getRootParameterTypes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxil::ResourceClass>::enumeration(
    IO &IO, dxil::ResourceClass &Value) {
  const EnumEntry<dxil::ResourceClass> ResourceClasses[] = {
      {"CBuffer", dxil::ResourceClass::CBuffer},
      {"SRV", dxil::ResourceClass::SRV},
      {"UAV", dxil::ResourceClass::UAV},
      {"Sampler", dxil::ResourceClass::Sampler},
  };

  for (const auto &E : ResourceClasses)
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::SamplerFilter>::enumeration(
    IO &IO, dxbc::SamplerFilter &Value) {
  for (const auto &E : dxbc::getSamplerFilters())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::StaticBorderColor>::enumeration(
    IO &IO, dxbc::StaticBorderColor &Value) {
  for (const auto &E : dxbc::getStaticBorderColors())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::TextureAddressMode>::enumeration(
    IO &IO, dxbc::TextureAddressMode &Value) {
  for (const auto &E : dxbc::getTextureAddressModes())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::ShaderVisibility>::enumeration(
    IO &IO, dxbc::ShaderVisibility &Value) {
  for (const auto &E : dxbc::getShaderVisibility())
    IO.enumCase(Value, E.Name, E.Value);
}

void ScalarEnumerationTraits<dxbc::ComparisonFunc>::enumeration(
    IO &IO, dxbc::ComparisonFunc &Value) {
  for (const auto &E : dxbc::getComparisonFuncs())
    IO.enumCase(Value, E.Name, E.Value);
}

} // namespace yaml

void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
  dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
  Triple::EnvironmentType Stage = dxbc::getShaderStage(Info.ShaderStage);

  switch (Stage) {
  case Triple::EnvironmentType::Pixel:
    IO.mapRequired("DepthOutput", StageInfo.PS.DepthOutput);
    IO.mapRequired("SampleFrequency", StageInfo.PS.SampleFrequency);
    break;
  case Triple::EnvironmentType::Vertex:
    IO.mapRequired("OutputPositionPresent", StageInfo.VS.OutputPositionPresent);
    break;
  case Triple::EnvironmentType::Geometry:
    IO.mapRequired("InputPrimitive", StageInfo.GS.InputPrimitive);
    IO.mapRequired("OutputTopology", StageInfo.GS.OutputTopology);
    IO.mapRequired("OutputStreamMask", StageInfo.GS.OutputStreamMask);
    IO.mapRequired("OutputPositionPresent", StageInfo.GS.OutputPositionPresent);
    break;
  case Triple::EnvironmentType::Hull:
    IO.mapRequired("InputControlPointCount",
                   StageInfo.HS.InputControlPointCount);
    IO.mapRequired("OutputControlPointCount",
                   StageInfo.HS.OutputControlPointCount);
    IO.mapRequired("TessellatorDomain", StageInfo.HS.TessellatorDomain);
    IO.mapRequired("TessellatorOutputPrimitive",
                   StageInfo.HS.TessellatorOutputPrimitive);
    break;
  case Triple::EnvironmentType::Domain:
    IO.mapRequired("InputControlPointCount",
                   StageInfo.DS.InputControlPointCount);
    IO.mapRequired("OutputPositionPresent", StageInfo.DS.OutputPositionPresent);
    IO.mapRequired("TessellatorDomain", StageInfo.DS.TessellatorDomain);
    break;
  case Triple::EnvironmentType::Mesh:
    IO.mapRequired("GroupSharedBytesUsed", StageInfo.MS.GroupSharedBytesUsed);
    IO.mapRequired("GroupSharedBytesDependentOnViewID",
                   StageInfo.MS.GroupSharedBytesDependentOnViewID);
    IO.mapRequired("PayloadSizeInBytes", StageInfo.MS.PayloadSizeInBytes);
    IO.mapRequired("MaxOutputVertices", StageInfo.MS.MaxOutputVertices);
    IO.mapRequired("MaxOutputPrimitives", StageInfo.MS.MaxOutputPrimitives);
    break;
  case Triple::EnvironmentType::Amplification:
    IO.mapRequired("PayloadSizeInBytes", StageInfo.AS.PayloadSizeInBytes);
    break;
  default:
    break;
  }

  IO.mapRequired("MinimumWaveLaneCount", Info.MinimumWaveLaneCount);
  IO.mapRequired("MaximumWaveLaneCount", Info.MaximumWaveLaneCount);

  if (Version == 0)
    return;

  IO.mapRequired("UsesViewID", Info.UsesViewID);

  switch (Stage) {
  case Triple::EnvironmentType::Geometry:
    IO.mapRequired("MaxVertexCount", Info.GeomData.MaxVertexCount);
    break;
  case Triple::EnvironmentType::Hull:
  case Triple::EnvironmentType::Domain:
    IO.mapRequired("SigPatchConstOrPrimVectors",
                   Info.GeomData.SigPatchConstOrPrimVectors);
    break;
  case Triple::EnvironmentType::Mesh:
    IO.mapRequired("SigPrimVectors", Info.GeomData.MeshInfo.SigPrimVectors);
    IO.mapRequired("MeshOutputTopology",
                   Info.GeomData.MeshInfo.MeshOutputTopology);
    break;
  default:
    break;
  }

  IO.mapRequired("SigInputVectors", Info.SigInputVectors);
  MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
  IO.mapRequired("SigOutputVectors", Vec);

  if (Version == 1)
    return;

  IO.mapRequired("NumThreadsX", Info.NumThreadsX);
  IO.mapRequired("NumThreadsY", Info.NumThreadsY);
  IO.mapRequired("NumThreadsZ", Info.NumThreadsZ);

  if (Version == 2)
    return;

  IO.mapRequired("EntryName", EntryName);
}

} // namespace llvm
