1 //===- DXILResource.h - DXIL Resource helper objects ----------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file This file contains helper objects for working with DXIL Resources. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_TARGET_DIRECTX_DXILRESOURCE_H 14 #define LLVM_TARGET_DIRECTX_DXILRESOURCE_H 15 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/Frontend/HLSL/HLSLResource.h" 19 #include "llvm/IR/Metadata.h" 20 #include "llvm/Support/Compiler.h" 21 #include <cstdint> 22 23 namespace llvm { 24 class Module; 25 class GlobalVariable; 26 27 namespace dxil { 28 class CBufferDataLayout; 29 30 class ResourceBase { 31 protected: 32 uint32_t ID; 33 GlobalVariable *GV; 34 StringRef Name; 35 uint32_t Space; 36 uint32_t LowerBound; 37 uint32_t RangeSize; 38 ResourceBase(uint32_t I, hlsl::FrontendResource R); 39 40 void write(LLVMContext &Ctx, MutableArrayRef<Metadata *> Entries) const; 41 42 void print(raw_ostream &O, StringRef IDPrefix, StringRef BindingPrefix) const; 43 using Kinds = hlsl::ResourceKind; 44 static StringRef getKindName(Kinds Kind); 45 static void printKind(Kinds Kind, unsigned Alignment, raw_ostream &OS, 46 bool SRV = false, bool HasCounter = false, 47 uint32_t SampleCount = 0); 48 49 static StringRef getElementTypeName(hlsl::ElementType CompType); 50 static void printElementType(Kinds Kind, hlsl::ElementType CompType, 51 unsigned Alignment, raw_ostream &OS); 52 53 public: 54 struct ExtendedProperties { 55 std::optional<hlsl::ElementType> ElementType; 56 57 // The value ordering of this enumeration is part of the DXIL ABI. Elements 58 // can only be added to the end, and not removed. 59 enum Tags : uint32_t { 60 TypedBufferElementType = 0, 61 StructuredBufferElementStride, 62 SamplerFeedbackKind, 63 Atomic64Use 64 }; 65 66 MDNode *write(LLVMContext &Ctx) const; 67 }; 68 }; 69 70 class UAVResource : public ResourceBase { 71 ResourceBase::Kinds Shape; 72 bool GloballyCoherent; 73 bool HasCounter; 74 bool IsROV; 75 ResourceBase::ExtendedProperties ExtProps; 76 77 void parseSourceType(StringRef S); 78 79 public: 80 UAVResource(uint32_t I, hlsl::FrontendResource R) 81 : ResourceBase(I, R), Shape(R.getResourceKind()), GloballyCoherent(false), 82 HasCounter(false), IsROV(R.getIsROV()), ExtProps{R.getElementType()} {} 83 84 MDNode *write() const; 85 void print(raw_ostream &O) const; 86 }; 87 88 class ConstantBuffer : public ResourceBase { 89 uint32_t CBufferSizeInBytes = 0; // Cbuffer used size in bytes. 90 public: 91 ConstantBuffer(uint32_t I, hlsl::FrontendResource R); 92 void setSize(CBufferDataLayout &DL); 93 MDNode *write() const; 94 void print(raw_ostream &O) const; 95 }; 96 97 template <typename T> class ResourceTable { 98 StringRef MDName; 99 100 llvm::SmallVector<T> Data; 101 102 public: 103 ResourceTable(StringRef Name) : MDName(Name) {} 104 void collect(Module &M); 105 MDNode *write(Module &M) const; 106 void print(raw_ostream &O) const; 107 }; 108 109 // FIXME: Fully computing the resource structures requires analyzing the IR 110 // because some flags are set based on what operations are performed on the 111 // resource. This partial patch handles some of the leg work, but not all of it. 112 // See issue https://github.com/llvm/llvm-project/issues/57936. 113 class Resources { 114 ResourceTable<UAVResource> UAVs = {"hlsl.uavs"}; 115 ResourceTable<ConstantBuffer> CBuffers = {"hlsl.cbufs"}; 116 117 public: 118 void collect(Module &M); 119 void write(Module &M) const; 120 void print(raw_ostream &O) const; 121 LLVM_DUMP_METHOD void dump() const; 122 }; 123 124 } // namespace dxil 125 } // namespace llvm 126 127 #endif // LLVM_TARGET_DIRECTX_DXILRESOURCE_H 128