================ @@ -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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits