[llvm-branch-commits] [DirectX] Add resource handling to the DXIL pretty printer (PR #104448)

Helena Kotas via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 15 11:18:06 PDT 2024


================
@@ -10,23 +10,235 @@
 #include "DXILResourceAnalysis.h"
 #include "DirectX.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/DXILResource.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
 
-static void prettyPrintResources(raw_ostream &OS,
+static constexpr StringRef getRCName(dxil::ResourceClass RC) {
+  switch (RC) {
+  case dxil::ResourceClass::SRV:
+    return "SRV";
+  case dxil::ResourceClass::UAV:
+    return "UAV";
+  case dxil::ResourceClass::CBuffer:
+    return "cbuffer";
+  case dxil::ResourceClass::Sampler:
+    return "sampler";
+  }
+  llvm_unreachable("covered switch");
+}
+
+static constexpr StringRef getRCPrefix(dxil::ResourceClass RC) {
+  switch (RC) {
+  case dxil::ResourceClass::SRV:
+    return "t";
+  case dxil::ResourceClass::UAV:
+    return "u";
+  case dxil::ResourceClass::CBuffer:
+    return "cb";
+  case dxil::ResourceClass::Sampler:
+    return "s";
+  }
+}
+
+static constexpr StringRef getFormatName(const dxil::ResourceInfo &RI) {
+  if (RI.isTyped()) {
+    switch (RI.getTyped().ElementTy) {
+    case dxil::ElementType::I1:
+      return "i1";
+    case dxil::ElementType::I16:
+      return "i16";
+    case dxil::ElementType::U16:
+      return "u16";
+    case dxil::ElementType::I32:
+      return "i32";
+    case dxil::ElementType::U32:
+      return "u32";
+    case dxil::ElementType::I64:
+      return "i64";
+    case dxil::ElementType::U64:
+      return "u64";
+    case dxil::ElementType::F16:
+      return "f16";
+    case dxil::ElementType::F32:
+      return "f32";
+    case dxil::ElementType::F64:
+      return "f64";
+    case dxil::ElementType::SNormF16:
+      return "snorm_f16";
+    case dxil::ElementType::UNormF16:
+      return "unorm_f16";
+    case dxil::ElementType::SNormF32:
+      return "snorm_f32";
+    case dxil::ElementType::UNormF32:
+      return "unorm_f32";
+    case dxil::ElementType::SNormF64:
+      return "snorm_f64";
+    case dxil::ElementType::UNormF64:
+      return "unorm_f64";
+    case dxil::ElementType::PackedS8x32:
+      return "p32i8";
+    case dxil::ElementType::PackedU8x32:
+      return "p32u8";
+    case dxil::ElementType::Invalid:
+      llvm_unreachable("Invalid ElementType");
+    }
+    llvm_unreachable("Unhandled ElementType");
+  } else if (RI.isStruct())
+    return "struct";
+  else if (RI.isCBuffer() || RI.isSampler())
+    return "NA";
+  return "byte";
+}
+
+static constexpr StringRef getTextureDimName(dxil::ResourceKind RK) {
+  switch (RK) {
+  case dxil::ResourceKind::Texture1D:
+    return "1d";
+  case dxil::ResourceKind::Texture2D:
+    return "2d";
+  case dxil::ResourceKind::Texture3D:
+    return "3d";
+  case dxil::ResourceKind::TextureCube:
+    return "cube";
+  case dxil::ResourceKind::Texture1DArray:
+    return "1darray";
+  case dxil::ResourceKind::Texture2DArray:
+    return "2darray";
+  case dxil::ResourceKind::TextureCubeArray:
+    return "cubearray";
+  case dxil::ResourceKind::TBuffer:
+    return "tbuffer";
+  case dxil::ResourceKind::FeedbackTexture2D:
+    return "fbtex2d";
+  case dxil::ResourceKind::FeedbackTexture2DArray:
+    return "fbtex2darray";
+  case dxil::ResourceKind::Texture2DMS:
+    return "2dMS";
+  case dxil::ResourceKind::Texture2DMSArray:
+    return "2darrayMS";
+  case dxil::ResourceKind::Invalid:
+  case dxil::ResourceKind::NumEntries:
+  case dxil::ResourceKind::CBuffer:
+  case dxil::ResourceKind::RawBuffer:
+  case dxil::ResourceKind::Sampler:
+  case dxil::ResourceKind::StructuredBuffer:
+  case dxil::ResourceKind::TypedBuffer:
+  case dxil::ResourceKind::RTAccelerationStructure:
+    llvm_unreachable("Invalid ResourceKind for texture");
+  }
+  llvm_unreachable("Unhandled ResourceKind");
+}
+
+namespace {
+struct FormatResourceDimension
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatResourceDimension(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    dxil::ResourceKind RK = Item.getResourceKind();
+    switch (RK) {
+    default: {
+      OS << getTextureDimName(RK);
+      if (Item.isMultiSample())
+        OS << Item.getMultiSample().Count;
+      break;;
+    }
+    case dxil::ResourceKind::RawBuffer:
+    case dxil::ResourceKind::StructuredBuffer:
+      if (!Item.isUAV())
+        OS << "r/o";
+      else if (Item.getUAV().HasCounter)
+        OS << "r/w+cnt";
+      else
+        OS << "r/w";
+      break;
+    case dxil::ResourceKind::TypedBuffer:
+      OS << "buf";
+      break;
+    case dxil::ResourceKind::RTAccelerationStructure:
+      // TODO: dxc would print "ras" here. Can/should this happen?
+      llvm_unreachable("RTAccelerationStructure printing is not implemented");
+    }
+  }
+};
+
+struct FormatBindingID
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingID(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    OS << getRCPrefix(Item.getResourceClass()).upper()
+       << Item.getBinding().RecordID;
+  }
+};
+
+struct FormatBindingLocation
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingLocation(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    const auto &Binding = Item.getBinding();
+    OS << getRCPrefix(Item.getResourceClass()) << Binding.LowerBound;
+    if (Binding.Space)
+      OS << ",space" << Binding.Space;
+  }
+};
+
+struct FormatBindingSize
+    : public llvm::FormatAdapter<const dxil::ResourceInfo &> {
+  explicit FormatBindingSize(const dxil::ResourceInfo &RI)
+      : llvm::FormatAdapter<const dxil::ResourceInfo &>(RI) {}
+
+  void format(llvm::raw_ostream &OS, StringRef Style) override {
+    uint32_t Size = Item.getBinding().Size;
+    if (Size == std::numeric_limits<uint32_t>::max())
+      OS << "unbounded";
+    else
+      OS << Size;
+  }
+};
+
+} // namespace
+
+static void prettyPrintResources(raw_ostream &OS, const DXILResourceMap &DRM,
                                  const dxil::Resources &MDResources) {
   // Column widths are arbitrary but match the widths DXC uses.
   OS << ";\n; Resource Bindings:\n;\n";
-  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,16}\n",
+  OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n",
                 "Name", "Type", "Format", "Dim", "ID", "HLSL Bind", "Count");
   OS << formatv(
-      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+16}\n", "",
+      "; {0,-+30} {1,-+10} {2,-+7} {3,-+11} {4,-+7} {5,-+14} {6,-+9}\n", "",
       "", "", "", "", "", "");
 
+  // TODO: Do we want to sort these by binding or something like that?
+  for (auto [_, RI] : DRM) {
+    dxil::ResourceClass RC = RI.getResourceClass();
+    assert((RC != dxil::ResourceClass::CBuffer || !MDResources.hasCBuffers()) &&
+           "Old and new cbuffer representations can't coexist");
+    assert((RC != dxil::ResourceClass::UAV || !MDResources.hasUAVs()) &&
+           "Old and new UAV representations can't coexist");
+
+    StringRef Name(RI.getName());
+    StringRef Type(getRCName(RC));
+    StringRef Format(getFormatName(RI));
+    FormatResourceDimension Dim(RI);
+    FormatBindingID ID(RI);
+    FormatBindingLocation Bind(RI);
+    FormatBindingSize Count(RI);
+    OS << formatv("; {0,-30} {1,10} {2,7} {3,11} {4,7} {5,14} {6,9}\n",
----------------
hekota wrote:

Neat use of the ` llvm::FormatAdapter`. Bit of a overkill for the simple cases but it looks elegant. ;).

https://github.com/llvm/llvm-project/pull/104448


More information about the llvm-branch-commits mailing list