brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 2b33e56 Raw
225 lines · cpp
1//===- HLSLRootSignature.cpp - HLSL Root Signature helpers ----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file This file contains helpers for working with HLSL Root Signatures.10///11//===----------------------------------------------------------------------===//12 13#include "llvm/Frontend/HLSL/HLSLRootSignature.h"14#include "llvm/Support/DXILABI.h"15#include "llvm/Support/ScopedPrinter.h"16 17namespace llvm {18namespace hlsl {19namespace rootsig {20 21template <typename T>22static raw_ostream &printFlags(raw_ostream &OS, const T Value,23                               ArrayRef<EnumEntry<T>> Flags) {24  bool FlagSet = false;25  unsigned Remaining = llvm::to_underlying(Value);26  while (Remaining) {27    unsigned Bit = 1u << llvm::countr_zero(Remaining);28    if (Remaining & Bit) {29      if (FlagSet)30        OS << " | ";31 32      StringRef MaybeFlag = enumToStringRef(T(Bit), Flags);33      if (!MaybeFlag.empty())34        OS << MaybeFlag;35      else36        OS << "invalid: " << Bit;37 38      FlagSet = true;39    }40    Remaining &= ~Bit;41  }42 43  if (!FlagSet)44    OS << "None";45  return OS;46}47 48static const EnumEntry<RegisterType> RegisterNames[] = {49    {"b", RegisterType::BReg},50    {"t", RegisterType::TReg},51    {"u", RegisterType::UReg},52    {"s", RegisterType::SReg},53};54 55static raw_ostream &operator<<(raw_ostream &OS, const Register &Reg) {56  OS << enumToStringRef(Reg.ViewType, ArrayRef(RegisterNames)) << Reg.Number;57 58  return OS;59}60 61static raw_ostream &operator<<(raw_ostream &OS,62                               const llvm::dxbc::ShaderVisibility &Visibility) {63  OS << enumToStringRef(Visibility, dxbc::getShaderVisibility());64 65  return OS;66}67 68static raw_ostream &operator<<(raw_ostream &OS,69                               const llvm::dxbc::SamplerFilter &Filter) {70  OS << enumToStringRef(Filter, dxbc::getSamplerFilters());71 72  return OS;73}74 75static raw_ostream &operator<<(raw_ostream &OS,76                               const dxbc::TextureAddressMode &Address) {77  OS << enumToStringRef(Address, dxbc::getTextureAddressModes());78 79  return OS;80}81 82static raw_ostream &operator<<(raw_ostream &OS,83                               const dxbc::ComparisonFunc &CompFunc) {84  OS << enumToStringRef(CompFunc, dxbc::getComparisonFuncs());85 86  return OS;87}88 89static raw_ostream &operator<<(raw_ostream &OS,90                               const dxbc::StaticBorderColor &BorderColor) {91  OS << enumToStringRef(BorderColor, dxbc::getStaticBorderColors());92 93  return OS;94}95 96static raw_ostream &operator<<(raw_ostream &OS,97                               const dxil::ResourceClass &Type) {98  OS << dxil::getResourceClassName(Type);99  return OS;100}101 102static raw_ostream &operator<<(raw_ostream &OS,103                               const dxbc::RootDescriptorFlags &Flags) {104  printFlags(OS, Flags, dxbc::getRootDescriptorFlags());105 106  return OS;107}108 109static raw_ostream &operator<<(raw_ostream &OS,110                               const llvm::dxbc::DescriptorRangeFlags &Flags) {111  printFlags(OS, Flags, dxbc::getDescriptorRangeFlags());112 113  return OS;114}115 116static raw_ostream &operator<<(raw_ostream &OS,117                               const llvm::dxbc::StaticSamplerFlags &Flags) {118  printFlags(OS, Flags, dxbc::getStaticSamplerFlags());119 120  return OS;121}122 123raw_ostream &operator<<(raw_ostream &OS, const dxbc::RootFlags &Flags) {124  OS << "RootFlags(";125  printFlags(OS, Flags, dxbc::getRootFlags());126  OS << ")";127 128  return OS;129}130 131raw_ostream &operator<<(raw_ostream &OS, const RootConstants &Constants) {132  OS << "RootConstants(num32BitConstants = " << Constants.Num32BitConstants133     << ", " << Constants.Reg << ", space = " << Constants.Space134     << ", visibility = " << Constants.Visibility << ")";135 136  return OS;137}138 139raw_ostream &operator<<(raw_ostream &OS, const DescriptorTable &Table) {140  OS << "DescriptorTable(numClauses = " << Table.NumClauses141     << ", visibility = " << Table.Visibility << ")";142 143  return OS;144}145 146raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause) {147  OS << Clause.Type << "(" << Clause.Reg << ", numDescriptors = ";148  if (Clause.NumDescriptors == NumDescriptorsUnbounded)149    OS << "unbounded";150  else151    OS << Clause.NumDescriptors;152  OS << ", space = " << Clause.Space << ", offset = ";153  if (Clause.Offset == DescriptorTableOffsetAppend)154    OS << "DescriptorTableOffsetAppend";155  else156    OS << Clause.Offset;157  OS << ", flags = " << Clause.Flags << ")";158 159  return OS;160}161 162raw_ostream &operator<<(raw_ostream &OS, const RootDescriptor &Descriptor) {163  OS << "Root" << Descriptor.Type << "(" << Descriptor.Reg164     << ", space = " << Descriptor.Space165     << ", visibility = " << Descriptor.Visibility166     << ", flags = " << Descriptor.Flags << ")";167 168  return OS;169}170 171raw_ostream &operator<<(raw_ostream &OS, const StaticSampler &Sampler) {172  OS << "StaticSampler(" << Sampler.Reg << ", filter = " << Sampler.Filter173     << ", addressU = " << Sampler.AddressU174     << ", addressV = " << Sampler.AddressV175     << ", addressW = " << Sampler.AddressW176     << ", mipLODBias = " << Sampler.MipLODBias177     << ", maxAnisotropy = " << Sampler.MaxAnisotropy178     << ", comparisonFunc = " << Sampler.CompFunc179     << ", borderColor = " << Sampler.BorderColor180     << ", minLOD = " << Sampler.MinLOD << ", maxLOD = " << Sampler.MaxLOD181     << ", space = " << Sampler.Space << ", visibility = " << Sampler.Visibility182     << ", flags = " << Sampler.Flags << ")";183  return OS;184}185 186namespace {187 188// We use the OverloadVisit with std::visit to ensure the compiler catches if a189// new RootElement variant type is added but it's operator<< isn't handled.190template <class... Ts> struct OverloadedVisit : Ts... {191  using Ts::operator()...;192};193template <class... Ts> OverloadedVisit(Ts...) -> OverloadedVisit<Ts...>;194 195} // namespace196 197raw_ostream &operator<<(raw_ostream &OS, const RootElement &Element) {198  const auto Visitor = OverloadedVisit{199      [&OS](const dxbc::RootFlags &Flags) { OS << Flags; },200      [&OS](const RootConstants &Constants) { OS << Constants; },201      [&OS](const RootDescriptor &Descriptor) { OS << Descriptor; },202      [&OS](const DescriptorTableClause &Clause) { OS << Clause; },203      [&OS](const DescriptorTable &Table) { OS << Table; },204      [&OS](const StaticSampler &Sampler) { OS << Sampler; },205  };206  std::visit(Visitor, Element);207  return OS;208}209 210void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) {211  OS << " RootElements{";212  bool First = true;213  for (const RootElement &Element : Elements) {214    if (!First)215      OS << ",";216    OS << " " << Element;217    First = false;218  }219  OS << "}";220}221 222} // namespace rootsig223} // namespace hlsl224} // namespace llvm225