brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.5 KiB · 9da3bdb Raw
304 lines · cpp
1//===- DXILPrettyPrinter.cpp - Print resources for textual DXIL -----------===//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#include "DXILPrettyPrinter.h"10#include "DirectX.h"11#include "llvm/ADT/StringRef.h"12#include "llvm/Analysis/DXILResource.h"13#include "llvm/IR/PassManager.h"14#include "llvm/InitializePasses.h"15#include "llvm/Pass.h"16#include "llvm/Support/FormatAdapters.h"17#include "llvm/Support/FormatVariadic.h"18#include "llvm/Support/raw_ostream.h"19 20using namespace llvm;21 22static StringRef getRCName(dxil::ResourceClass RC) {23  switch (RC) {24  case dxil::ResourceClass::SRV:25    return "texture";26  case dxil::ResourceClass::UAV:27    return "UAV";28  case dxil::ResourceClass::CBuffer:29    return "cbuffer";30  case dxil::ResourceClass::Sampler:31    return "sampler";32  }33  llvm_unreachable("covered switch");34}35 36static StringRef getRCPrefix(dxil::ResourceClass RC) {37  switch (RC) {38  case dxil::ResourceClass::SRV:39    return "t";40  case dxil::ResourceClass::UAV:41    return "u";42  case dxil::ResourceClass::CBuffer:43    return "cb";44  case dxil::ResourceClass::Sampler:45    return "s";46  }47  llvm_unreachable("covered switch");48}49 50static StringRef getFormatName(const dxil::ResourceTypeInfo &RI) {51  if (RI.isTyped()) {52    switch (RI.getTyped().DXILStorageTy) {53    case dxil::ElementType::I1:54      return "i1";55    case dxil::ElementType::I16:56      return "i16";57    case dxil::ElementType::U16:58      return "u16";59    case dxil::ElementType::I32:60      return "i32";61    case dxil::ElementType::U32:62      return "u32";63    case dxil::ElementType::I64:64      return "i64";65    case dxil::ElementType::U64:66      return "u64";67    case dxil::ElementType::F16:68      return "f16";69    case dxil::ElementType::F32:70      return "f32";71    case dxil::ElementType::F64:72      return "f64";73    case dxil::ElementType::SNormF16:74      return "snorm_f16";75    case dxil::ElementType::UNormF16:76      return "unorm_f16";77    case dxil::ElementType::SNormF32:78      return "snorm_f32";79    case dxil::ElementType::UNormF32:80      return "unorm_f32";81    case dxil::ElementType::SNormF64:82      return "snorm_f64";83    case dxil::ElementType::UNormF64:84      return "unorm_f64";85    case dxil::ElementType::PackedS8x32:86      return "p32i8";87    case dxil::ElementType::PackedU8x32:88      return "p32u8";89    case dxil::ElementType::Invalid:90      llvm_unreachable("Invalid ElementType");91    }92    llvm_unreachable("Unhandled ElementType");93  } else if (RI.isStruct())94    return "struct";95  else if (RI.isCBuffer() || RI.isSampler())96    return "NA";97  return "byte";98}99 100static StringRef getTextureDimName(dxil::ResourceKind RK) {101  switch (RK) {102  case dxil::ResourceKind::Texture1D:103    return "1d";104  case dxil::ResourceKind::Texture2D:105    return "2d";106  case dxil::ResourceKind::Texture3D:107    return "3d";108  case dxil::ResourceKind::TextureCube:109    return "cube";110  case dxil::ResourceKind::Texture1DArray:111    return "1darray";112  case dxil::ResourceKind::Texture2DArray:113    return "2darray";114  case dxil::ResourceKind::TextureCubeArray:115    return "cubearray";116  case dxil::ResourceKind::TBuffer:117    return "tbuffer";118  case dxil::ResourceKind::FeedbackTexture2D:119    return "fbtex2d";120  case dxil::ResourceKind::FeedbackTexture2DArray:121    return "fbtex2darray";122  case dxil::ResourceKind::Texture2DMS:123    return "2dMS";124  case dxil::ResourceKind::Texture2DMSArray:125    return "2darrayMS";126  case dxil::ResourceKind::Invalid:127  case dxil::ResourceKind::NumEntries:128  case dxil::ResourceKind::CBuffer:129  case dxil::ResourceKind::RawBuffer:130  case dxil::ResourceKind::Sampler:131  case dxil::ResourceKind::StructuredBuffer:132  case dxil::ResourceKind::TypedBuffer:133  case dxil::ResourceKind::RTAccelerationStructure:134    llvm_unreachable("Invalid ResourceKind for texture");135  }136  llvm_unreachable("Unhandled ResourceKind");137}138 139namespace {140struct FormatResourceDimension141    : public llvm::FormatAdapter<const dxil::ResourceTypeInfo &> {142  FormatResourceDimension(const dxil::ResourceTypeInfo &RI, bool HasCounter)143      : llvm::FormatAdapter<const dxil::ResourceTypeInfo &>(RI),144        HasCounter(HasCounter) {}145 146  bool HasCounter;147 148  void format(llvm::raw_ostream &OS, StringRef Style) override {149    dxil::ResourceKind RK = Item.getResourceKind();150    switch (RK) {151    default: {152      OS << getTextureDimName(RK);153      if (Item.isMultiSample())154        OS << Item.getMultiSampleCount();155      break;156    }157    case dxil::ResourceKind::RawBuffer:158    case dxil::ResourceKind::StructuredBuffer:159      if (!Item.isUAV())160        OS << "r/o";161      else if (HasCounter)162        OS << "r/w+cnt";163      else164        OS << "r/w";165      break;166    case dxil::ResourceKind::TypedBuffer:167      OS << "buf";168      break;169    case dxil::ResourceKind::CBuffer:170      OS << "NA";171      break;172    case dxil::ResourceKind::RTAccelerationStructure:173      // TODO: dxc would print "ras" here. Can/should this happen?174      llvm_unreachable("RTAccelerationStructure printing is not implemented");175    }176  }177};178 179struct FormatBindingID180    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {181  dxil::ResourceClass RC;182 183  explicit FormatBindingID(const dxil::ResourceInfo &RI,184                           const dxil::ResourceTypeInfo &RTI)185      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),186        RC(RTI.getResourceClass()) {}187 188  void format(llvm::raw_ostream &OS, StringRef Style) override {189    OS << getRCPrefix(RC).upper() << Item.getBinding().RecordID;190  }191};192 193struct FormatBindingLocation194    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {195  dxil::ResourceClass RC;196 197  explicit FormatBindingLocation(const dxil::ResourceInfo &RI,198                                 const dxil::ResourceTypeInfo &RTI)199      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI),200        RC(RTI.getResourceClass()) {}201 202  void format(llvm::raw_ostream &OS, StringRef Style) override {203    const auto &Binding = Item.getBinding();204    OS << getRCPrefix(RC) << Binding.LowerBound;205    if (Binding.Space)206      OS << ",space" << Binding.Space;207  }208};209 210struct FormatBindingSize211    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {212  explicit FormatBindingSize(const dxil::ResourceInfo &RI)213      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}214 215  void format(llvm::raw_ostream &OS, StringRef Style) override {216    uint32_t Size = Item.getBinding().Size;217    if (Size == std::numeric_limits<uint32_t>::max())218      OS << "unbounded";219    else220      OS << Size;221  }222};223 224} // namespace225 226static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,227                                 DXILResourceTypeMap &DRTM) {228  // Column widths are arbitrary but match the widths DXC uses.229  OS << ";\n; Resource Bindings:\n;\n";230  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", "Name",231                "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");232  OS << formatv(233      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "", "",234      "", "", "", "", "");235 236  // TODO: Do we want to sort these by binding or something like that?237  for (const dxil::ResourceInfo &RI : DRM) {238    const dxil::ResourceTypeInfo &RTI = DRTM[RI.getHandleTy()];239 240    dxil::ResourceClass RC = RTI.getResourceClass();241    StringRef Name(RI.getName());242    StringRef Type(getRCName(RC));243    StringRef Format(getFormatName(RTI));244    FormatResourceDimension Dim(RTI, RI.hasCounter());245    FormatBindingID ID(RI, RTI);246    FormatBindingLocation Bind(RI, RTI);247    FormatBindingSize Count(RI);248    OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n", Name,249                  Type, Format, Dim, ID, Bind, Count);250  }251  OS << ";\n";252}253 254PreservedAnalyses DXILPrettyPrinterPass::run(Module &M,255                                             ModuleAnalysisManager &MAM) {256  const DXILResourceMap &DRM = MAM.getResult<DXILResourceAnalysis>(M);257  DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M);258  prettyPrintResources(OS, DRM, DRTM);259  return PreservedAnalyses::all();260}261 262namespace {263class DXILPrettyPrinterLegacy : public llvm::ModulePass {264  raw_ostream &OS; // raw_ostream to print to.265 266public:267  static char ID;268 269  explicit DXILPrettyPrinterLegacy(raw_ostream &O) : ModulePass(ID), OS(O) {}270 271  StringRef getPassName() const override {272    return "DXIL Metadata Pretty Printer";273  }274 275  bool runOnModule(Module &M) override;276  void getAnalysisUsage(AnalysisUsage &AU) const override {277    AU.setPreservesAll();278    AU.addRequired<DXILResourceTypeWrapperPass>();279    AU.addRequired<DXILResourceWrapperPass>();280  }281};282} // namespace283 284char DXILPrettyPrinterLegacy::ID = 0;285INITIALIZE_PASS_BEGIN(DXILPrettyPrinterLegacy, "dxil-pretty-printer",286                      "DXIL Metadata Pretty Printer", true, true)287INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass)288INITIALIZE_PASS_DEPENDENCY(DXILResourceWrapperPass)289INITIALIZE_PASS_END(DXILPrettyPrinterLegacy, "dxil-pretty-printer",290                    "DXIL Metadata Pretty Printer", true, true)291 292bool DXILPrettyPrinterLegacy::runOnModule(Module &M) {293  const DXILResourceMap &DRM =294      getAnalysis<DXILResourceWrapperPass>().getResourceMap();295  DXILResourceTypeMap &DRTM =296      getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();297  prettyPrintResources(OS, DRM, DRTM);298  return false;299}300 301ModulePass *llvm::createDXILPrettyPrinterLegacyPass(raw_ostream &OS) {302  return new DXILPrettyPrinterLegacy(OS);303}304