-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[HLSL][RootSignature] Add metadata generation for descriptor tables #139633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
135e6c9
e1693cc
76e3b5e
bdbf47c
a931947
5ccbf46
0ed0c09
9e1e530
b613e2e
3da3df5
be9173c
dfe18c0
496ab5d
3f5eb15
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -o - %s | FileCheck %s | ||
|
||
// CHECK: !dx.rootsignatures = !{![[#FIRST_ENTRY:]], ![[#SECOND_ENTRY:]]} | ||
|
||
// CHECK: ![[#FIRST_ENTRY]] = !{ptr @FirstEntry, ![[#EMPTY:]]} | ||
// CHECK: ![[#EMPTY]] = !{} | ||
|
||
[shader("compute"), RootSignature("")] | ||
[numthreads(1,1,1)] | ||
void FirstEntry() {} | ||
|
||
// CHECK: ![[#SECOND_ENTRY]] = !{ptr @SecondEntry, ![[#SECOND_RS:]]} | ||
// CHECK: ![[#SECOND_RS]] = !{![[#TABLE:]]} | ||
// CHECK: ![[#TABLE]] = !{!"DescriptorTable", i32 0, ![[#CBV:]], ![[#SRV:]]} | ||
// CHECK: ![[#CBV]] = !{!"CBV", i32 1, i32 0, i32 0, i32 -1, i32 4} | ||
// CHECK: ![[#SRV]] = !{!"SRV", i32 4, i32 42, i32 3, i32 32, i32 0} | ||
|
||
#define SampleDescriptorTable \ | ||
"DescriptorTable( " \ | ||
" CBV(b0), " \ | ||
" SRV(t42, space = 3, offset = 32, numDescriptors = 4, flags = 0) " \ | ||
")" | ||
[shader("compute"), RootSignature(SampleDescriptorTable)] | ||
[numthreads(1,1,1)] | ||
void SecondEntry() {} | ||
|
||
// Sanity test to ensure no root is added for this function as there is only | ||
// two entries in !dx.roosignatures | ||
[shader("compute")] | ||
[numthreads(1,1,1)] | ||
void ThirdEntry() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,9 @@ | |
|
||
#include "llvm/Frontend/HLSL/HLSLRootSignature.h" | ||
#include "llvm/ADT/bit.h" | ||
#include "llvm/IR/IRBuilder.h" | ||
#include "llvm/IR/Metadata.h" | ||
#include "llvm/IR/Module.h" | ||
|
||
namespace llvm { | ||
namespace hlsl { | ||
|
@@ -160,6 +163,75 @@ void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) { | |
OS << "}"; | ||
} | ||
|
||
static MDString *ClauseTypeToName(LLVMContext &Ctx, ClauseType Type) { | ||
inbelic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
StringRef Name; | ||
switch (Type) { | ||
case ClauseType::CBuffer: | ||
Name = "CBV"; | ||
break; | ||
case ClauseType::SRV: | ||
Name = "SRV"; | ||
break; | ||
case ClauseType::UAV: | ||
Name = "UAV"; | ||
break; | ||
case ClauseType::Sampler: | ||
Name = "Sampler"; | ||
break; | ||
} | ||
return MDString::get(Ctx, Name); | ||
} | ||
|
||
MDNode *MetadataBuilder::BuildRootSignature() { | ||
for (const RootElement &Element : Elements) { | ||
MDNode *ElementMD = nullptr; | ||
if (const auto &Clause = std::get_if<DescriptorTableClause>(&Element)) | ||
ElementMD = BuildDescriptorTableClause(*Clause); | ||
if (const auto &Table = std::get_if<DescriptorTable>(&Element)) | ||
ElementMD = BuildDescriptorTable(*Table); | ||
GeneratedMetadata.push_back(ElementMD); | ||
} | ||
|
||
return MDNode::get(Ctx, GeneratedMetadata); | ||
} | ||
|
||
MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) { | ||
IRBuilder<> B(Ctx); | ||
inbelic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
SmallVector<Metadata *> TableOperands; | ||
// Set the mandatory arguments | ||
TableOperands.push_back(MDString::get(Ctx, "DescriptorTable")); | ||
TableOperands.push_back(ConstantAsMetadata::get( | ||
B.getInt32(llvm::to_underlying(Table.Visibility)))); | ||
|
||
// Remaining operands are references to the table's clauses. The in-memory | ||
// representation of the Root Elements created from parsing will ensure that | ||
// the previous N elements are the clauses for this table. | ||
assert(Table.NumClauses <= GeneratedMetadata.size() && | ||
"Table expected all owned clauses to be generated already"); | ||
Comment on lines
+196
to
+197
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if that assert would really help, since it could easily be mislead by the generation of other parameters. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was added as a (hopefully) better error message rather than the error that would be generated if Do you have a suggestion for how it could be better worded, or, a better assert? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure how complex/useful this is, we could check how many uint Count = 0;
// I think this should be the Element parameter, from BuildRootSignature
auto It = Element;
while (std::holds_alternative<DescriptorTableClause>(*It)){
Count ++;
Element --;
}
assert(Table.NumClauses == Count); Not sure this code is correct/useful, but that is the idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the idea and toyed around with it a bit. It unfortunately is a bit a unwieldly to implement. I think it introduces more complexity then it reduces |
||
// So, add a refence to each clause to our operands | ||
TableOperands.append(GeneratedMetadata.end() - Table.NumClauses, | ||
GeneratedMetadata.end()); | ||
joaosaffran marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Then, remove those clauses from the general list of Root Elements | ||
GeneratedMetadata.pop_back_n(Table.NumClauses); | ||
|
||
return MDNode::get(Ctx, TableOperands); | ||
} | ||
|
||
MDNode *MetadataBuilder::BuildDescriptorTableClause( | ||
const DescriptorTableClause &Clause) { | ||
IRBuilder<> B(Ctx); | ||
return MDNode::get( | ||
Ctx, { | ||
ClauseTypeToName(Ctx, Clause.Type), | ||
ConstantAsMetadata::get(B.getInt32(Clause.NumDescriptors)), | ||
ConstantAsMetadata::get(B.getInt32(Clause.Reg.Number)), | ||
ConstantAsMetadata::get(B.getInt32(Clause.Space)), | ||
ConstantAsMetadata::get(B.getInt32(Clause.Offset)), | ||
ConstantAsMetadata::get( | ||
B.getInt32(llvm::to_underlying(Clause.Flags))), | ||
}); | ||
} | ||
|
||
} // namespace rootsig | ||
} // namespace hlsl | ||
} // namespace llvm |
Uh oh!
There was an error while loading. Please reload this page.