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
23namespace llvm {
24class Module;
25class GlobalVariable;
26
27namespace dxil {
28class CBufferDataLayout;
29
30class ResourceBase {
31protected:
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
53public:
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
70class 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
79public:
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
88class ConstantBuffer : public ResourceBase {
89  uint32_t CBufferSizeInBytes = 0; // Cbuffer used size in bytes.
90public:
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
97template <typename T> class ResourceTable {
98  StringRef MDName;
99
100  llvm::SmallVector<T> Data;
101
102public:
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.
113class Resources {
114  ResourceTable<UAVResource> UAVs = {"hlsl.uavs"};
115  ResourceTable<ConstantBuffer> CBuffers = {"hlsl.cbufs"};
116
117public:
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