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   // The value ordering of this enumeration is part of the DXIL ABI. Elements
50   // can only be added to the end, and not removed.
51   enum class ComponentType : uint32_t {
52     Invalid = 0,
53     I1,
54     I16,
55     U16,
56     I32,
57     U32,
58     I64,
59     U64,
60     F16,
61     F32,
62     F64,
63     SNormF16,
64     UNormF16,
65     SNormF32,
66     UNormF32,
67     SNormF64,
68     UNormF64,
69     PackedS8x32,
70     PackedU8x32,
71     LastEntry
72   };
73 
74   static StringRef getComponentTypeName(ComponentType CompType);
75   static void printComponentType(Kinds Kind, ComponentType CompType,
76                                  unsigned Alignment, raw_ostream &OS);
77 
78 public:
79   struct ExtendedProperties {
80     std::optional<ComponentType> ElementType;
81 
82     // The value ordering of this enumeration is part of the DXIL ABI. Elements
83     // can only be added to the end, and not removed.
84     enum Tags : uint32_t {
85       TypedBufferElementType = 0,
86       StructuredBufferElementStride,
87       SamplerFeedbackKind,
88       Atomic64Use
89     };
90 
91     MDNode *write(LLVMContext &Ctx) const;
92   };
93 };
94 
95 class UAVResource : public ResourceBase {
96   ResourceBase::Kinds Shape;
97   bool GloballyCoherent;
98   bool HasCounter;
99   bool IsROV;
100   ResourceBase::ExtendedProperties ExtProps;
101 
102   void parseSourceType(StringRef S);
103 
104 public:
105   UAVResource(uint32_t I, hlsl::FrontendResource R);
106 
107   MDNode *write() const;
108   void print(raw_ostream &O) const;
109 };
110 
111 class ConstantBuffer : public ResourceBase {
112   uint32_t CBufferSizeInBytes = 0; // Cbuffer used size in bytes.
113 public:
114   ConstantBuffer(uint32_t I, hlsl::FrontendResource R);
115   void setSize(CBufferDataLayout &DL);
116   MDNode *write() const;
117   void print(raw_ostream &O) const;
118 };
119 
120 template <typename T> class ResourceTable {
121   StringRef MDName;
122 
123   llvm::SmallVector<T> Data;
124 
125 public:
126   ResourceTable(StringRef Name) : MDName(Name) {}
127   void collect(Module &M);
128   MDNode *write(Module &M) const;
129   void print(raw_ostream &O) const;
130 };
131 
132 // FIXME: Fully computing the resource structures requires analyzing the IR
133 // because some flags are set based on what operations are performed on the
134 // resource. This partial patch handles some of the leg work, but not all of it.
135 // See issue https://github.com/llvm/llvm-project/issues/57936.
136 class Resources {
137   ResourceTable<UAVResource> UAVs = {"hlsl.uavs"};
138   ResourceTable<ConstantBuffer> CBuffers = {"hlsl.cbufs"};
139 
140 public:
141   void collect(Module &M);
142   void write(Module &M) const;
143   void print(raw_ostream &O) const;
144   LLVM_DUMP_METHOD void dump() const;
145 };
146 
147 } // namespace dxil
148 } // namespace llvm
149 
150 #endif // LLVM_TARGET_DIRECTX_DXILRESOURCE_H
151