clang 24.0.0git
HLSLResource.h
Go to the documentation of this file.
1//===- HLSLResource.h - Routines for HLSL resources and bindings ----------===//
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// This file provides shared routines to help analyze HLSL resources and
10// theirs bindings during Sema and CodeGen.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_HLSLRESOURCE_H
15#define LLVM_CLANG_AST_HLSLRESOURCE_H
16
18#include "clang/AST/Attr.h"
19#include "clang/AST/DeclBase.h"
23#include "llvm/Frontend/HLSL/HLSLResource.h"
24#include "llvm/Support/raw_ostream.h"
25
26namespace clang {
27
28class HLSLResourceBindingAttr;
29
30namespace hlsl {
31
33 HLSLResourceBindingAttr *RegBinding;
34 HLSLVkBindingAttr *VkBinding;
35
37 RegBinding = D->getAttr<HLSLResourceBindingAttr>();
38 bool IsSpirv = D->getASTContext().getTargetInfo().getTriple().isSPIRV();
39 VkBinding = IsSpirv ? D->getAttr<HLSLVkBindingAttr>() : nullptr;
40 }
41
42 bool hasBinding() const { return RegBinding || VkBinding; }
43 bool isExplicit() const {
44 return (RegBinding && RegBinding->hasRegisterSlot()) || VkBinding;
45 }
46
47 unsigned getSlot() const {
48 assert(isExplicit() && "no explicit binding");
49 if (VkBinding)
50 return VkBinding->getBinding();
51 if (RegBinding && RegBinding->hasRegisterSlot())
52 return RegBinding->getSlotNumber();
53 llvm_unreachable("no explicit binding");
54 }
55
56 unsigned getSpace() const {
57 if (VkBinding)
58 return VkBinding->getSet();
59 if (RegBinding)
60 return RegBinding->getSpaceNumber();
61 return 0;
62 }
63
64 bool hasImplicitOrderID() const {
65 return RegBinding && RegBinding->hasImplicitBindingOrderID();
66 }
67
68 unsigned getImplicitOrderID() const {
69 assert(hasImplicitOrderID());
70 return RegBinding->getImplicitBindingOrderID();
71 }
72
73 void setImplicitOrderID(unsigned Value) const {
74 assert(hasBinding() && !isExplicit() && !hasImplicitOrderID());
75 RegBinding->setImplicitBindingOrderID(Value);
76 }
77 void setCounterImplicitOrderID(unsigned Value) const {
79 RegBinding->setImplicitCounterBindingOrderID(Value);
80 }
81
83 return RegBinding && RegBinding->hasImplicitCounterBindingOrderID();
84 }
85
86 unsigned getCounterImplicitOrderID() const {
88 return RegBinding->getImplicitCounterBindingOrderID();
89 }
90};
91
92inline uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim) {
93 switch (Dim) {
94 case llvm::dxil::ResourceDimension::Dim1D:
95 return 1;
96 break;
97 case llvm::dxil::ResourceDimension::Dim2D:
98 return 2;
99 break;
100 case llvm::dxil::ResourceDimension::Dim3D:
101 case llvm::dxil::ResourceDimension::Cube:
102 return 3;
103 break;
104 case llvm::dxil::ResourceDimension::Unknown:
105 llvm_unreachable(
106 "We cannot get the dimension of a resource with unknown dimension.");
107 }
108 llvm_unreachable("Unhandled llvm::dxil::ResourceDimension enum.");
109}
110
111// Returns true if sampling operations on a resource of this dimension take a
112// texel-space offset operand.
113inline bool hasResourceOffset(llvm::dxil::ResourceDimension Dim) {
114 return Dim != llvm::dxil::ResourceDimension::Cube;
115}
116
117// Returns true if the second field of the record is a counter resource handle
118inline bool hasCounterHandle(const CXXRecordDecl *RD) {
119 if (RD->field_empty())
120 return false;
121 auto It = std::next(RD->field_begin());
122 if (It == RD->field_end())
123 return false;
124 const FieldDecl *SecondField = *It;
125 if (const auto *ResTy =
126 SecondField->getType()->getAs<HLSLAttributedResourceType>()) {
127 return ResTy->getAttrs().IsCounter;
128 }
129 return false;
130}
131
132// Helper class for building a name of a global resource variable that
133// gets created for a resource embedded in a struct or class. This will
134// also be used from CodeGen to build a name that matches the resource
135// access with the corresponding declaration.
139
140 inline static constexpr std::string_view BaseClassDelim = "::";
141 inline static constexpr std::string_view FieldDelim = ".";
142 inline static constexpr std::string_view ArrayIndexDelim = FieldDelim;
143
144public:
145 EmbeddedResourceNameBuilder(llvm::StringRef BaseName) : Name(BaseName) {}
147
148 void pushName(llvm::StringRef N) { pushName(N, FieldDelim); }
149 void pushBaseName(llvm::StringRef N);
150 void pushArrayIndex(uint64_t Index);
151 void pushBaseNameHierarchy(CXXRecordDecl *DerivedRD, CXXRecordDecl *BaseRD);
152
153 void pop() {
154 assert(!Offsets.empty() && "no name to pop");
155 Name.resize(Offsets.pop_back_val());
156 }
157
159 return &AST.Idents.get(Name);
160 }
161
162 llvm::StringRef getName() const { return Name; }
163
164private:
165 void pushName(llvm::StringRef N, llvm::StringRef Delim);
166};
167
168} // namespace hlsl
169
170} // namespace clang
171
172#endif // LLVM_CLANG_AST_HLSLRESOURCE_H
Defines the clang::ASTContext interface.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:245
IdentifierTable & Idents
Definition ASTContext.h:852
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:971
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
T * getAttr() const
Definition DeclBase.h:582
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
Represents a member of a struct/union/class.
Definition Decl.h:3311
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
field_iterator field_end() const
Definition Decl.h:4682
bool field_empty() const
Definition Decl.h:4687
field_iterator field_begin() const
Definition Decl.cpp:5372
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9299
QualType getType() const
Definition Decl.h:725
EmbeddedResourceNameBuilder(llvm::StringRef BaseName)
void pushBaseNameHierarchy(CXXRecordDecl *DerivedRD, CXXRecordDecl *BaseRD)
IdentifierInfo * getNameAsIdentifier(ASTContext &AST) const
Defines the clang::TargetInfo interface.
uint32_t getResourceDimensions(llvm::dxil::ResourceDimension Dim)
bool hasResourceOffset(llvm::dxil::ResourceDimension Dim)
bool hasCounterHandle(const CXXRecordDecl *RD)
Top level wrappers for InstallAPI frontend operations.
void setCounterImplicitOrderID(unsigned Value) const
unsigned getCounterImplicitOrderID() const
HLSLResourceBindingAttr * RegBinding
void setImplicitOrderID(unsigned Value) const