Skip to content

[HLSL] Adding support for Root Constants in LLVM Metadata #135085

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

Merged
merged 143 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from 141 commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
526b34a
adding rootsignature to obj2yaml
Jan 13, 2025
e84a8e1
adding test
Jan 13, 2025
f25fd64
removing old test
Jan 13, 2025
16552f0
remove useless includes
Jan 13, 2025
a6eb4c0
addressing comments
Jan 14, 2025
7d080b3
updating test
Jan 14, 2025
504527b
removing useless header
Jan 15, 2025
2425672
fix formating
Jan 15, 2025
08c17bb
renaming test
Jan 15, 2025
395a536
addressing pr comments
Jan 16, 2025
f93dff9
adding str to ROOT_ELEMENT_FLAG
Jan 16, 2025
1c1edb8
formating
Jan 17, 2025
5bef775
refactoring to follow llvm standards
Jan 18, 2025
628545a
addressing comments
Jan 27, 2025
c5c2ab6
clean up
Jan 27, 2025
b9db72c
remove version
Jan 30, 2025
f4af043
fix pr
Jan 30, 2025
496b922
adding dxil-dis test
Jan 31, 2025
422578f
adding compatibility test
Jan 31, 2025
b1423eb
addressing test concerns
Feb 3, 2025
b6262b6
clean up
Feb 3, 2025
16d0e8e
addressing comments
Feb 4, 2025
0a9e468
adding fail test
Feb 4, 2025
8295031
adding comment
Feb 4, 2025
c8e1e38
adding few more tests
Feb 4, 2025
434b862
format
Feb 4, 2025
2bfc5ad
cleanup
Feb 5, 2025
479422d
adding metadata extraction
Jan 15, 2025
f61ee77
moving root signature to it's own pass
Jan 16, 2025
499d879
formating
Jan 16, 2025
c4af535
removing useless imports
Jan 16, 2025
819fa0d
fixing pr changes
Jan 16, 2025
d347a87
adding some asserts
Jan 16, 2025
d8824ed
format
Jan 16, 2025
25c0384
fixing assert
Jan 18, 2025
5eb0ad2
cleaning
Jan 27, 2025
559427d
clean up
Jan 29, 2025
8ca5b2a
addressing comments
Jan 30, 2025
d52cd2c
removing version
Jan 30, 2025
5930dcb
fix test
Jan 30, 2025
fc72988
addressing PR Comments
Jan 31, 2025
2d1ee0d
fix test
Feb 3, 2025
92a85fe
filtering root signatures not associated with entry function
Feb 4, 2025
979ee91
separating parsing and validation
Feb 4, 2025
d089674
improve error handling
Feb 6, 2025
980e7d9
clean up
Feb 6, 2025
04667f3
clean up
Feb 6, 2025
8ec40aa
formating
Feb 6, 2025
b0ac6be
addressing comments and fix tests
Feb 7, 2025
6a36503
formating
Feb 7, 2025
f7d2c12
addressing pr comments
Feb 10, 2025
d6c98ed
addressing PR comments
Feb 11, 2025
36746f5
addressing pr comments
Feb 11, 2025
b5208e8
removing copies from root signature use in dx container globals
Feb 11, 2025
1fd6568
adding more tests
Feb 12, 2025
cde4634
maybe fix test?
Feb 12, 2025
4410e7b
try fix format
Feb 12, 2025
cbdb114
removing test
Feb 12, 2025
667ee17
adding llvm unreachable and testing test
Feb 12, 2025
d0dae8b
stopping compilation if root signature error were emitted
Feb 12, 2025
b1b28f8
making sure Error tests fail
Feb 12, 2025
0efd8cc
adding root constants
Feb 12, 2025
11256d8
refactoring root signature analysis to return a map instead
Feb 12, 2025
3c5046e
addressing pr comments
Feb 12, 2025
5d4505c
clean up
Feb 12, 2025
3117530
addressing pr comments
Feb 13, 2025
0af845c
implementing find interface for RootSignatureAnalysisWrapper
Feb 13, 2025
bf49a3a
adding test for null function
Feb 13, 2025
78826a5
fix root signature test error
Feb 14, 2025
4e689e9
fix other functions are checked
Feb 14, 2025
b0d0180
adding missing continue
Feb 14, 2025
3c6894f
adding few more tests
Feb 14, 2025
08f6ddc
adding yaml2obj support
Feb 15, 2025
b232967
adding support for obj2yaml and initial tests
Feb 18, 2025
1026a8e
multiple parameters support and more testing
Feb 19, 2025
00175bf
clean up
Feb 19, 2025
9ed2adc
fixing formating
Feb 19, 2025
e8252ba
reapply rebase fix
Feb 19, 2025
4de5c29
clean up
Feb 20, 2025
fe13b61
addressing pr comments
Feb 22, 2025
767b7d0
first working version
Feb 22, 2025
8434dc2
formating
Feb 22, 2025
d391727
moving the offset logic to it's own class
Feb 24, 2025
68c7513
refactoring to remove use of map and string
Feb 24, 2025
23069ab
addressing comments
Feb 25, 2025
d14471b
using buffer_ostream
Feb 25, 2025
216341c
remove getsize
Feb 25, 2025
85f012c
clean up
Feb 25, 2025
1e2bcf5
clean up
Feb 25, 2025
0e277d9
clean up
Feb 25, 2025
5cd0044
clean up
Feb 25, 2025
7a7c34d
addressing pr comments
Feb 25, 2025
d3fafab
clean up
Feb 25, 2025
15d1a8c
Merge branch 'refactor/improve-offset-calculation' into users/joaosaf…
Feb 25, 2025
7485640
clean up
Feb 26, 2025
17abc82
moving initializer arround
Feb 26, 2025
4b177e2
addressing pr comments
Feb 26, 2025
ec1dd87
addressing changes
Feb 26, 2025
eb9d7d3
Merge branch 'main' into users/joaosaffran/127840
Feb 26, 2025
f2a4f04
fix test
Feb 26, 2025
7c4236c
refactoring to change representations in binary format
Mar 1, 2025
2894f96
addressing pr comments
Mar 2, 2025
7b5e9d8
addressing comments and clean up
Mar 20, 2025
f0e6a46
moving RootSignatureValidations to out of BinaryFormat
Mar 24, 2025
4fe30df
addressing most pr comments
Mar 24, 2025
cbc334a
adding root parameter view
Mar 26, 2025
31bcd73
clean up
Mar 26, 2025
30098e1
addressing pr comments
Mar 29, 2025
1bf6408
wip: implementing comments
Mar 31, 2025
d1b32f3
removing old code
Apr 4, 2025
3b9bf27
address errors
Apr 4, 2025
89632a4
removing validations from obj2yaml
Apr 7, 2025
67da709
ac
Apr 8, 2025
3991c5d
address comments
Apr 8, 2025
cfc6bfb
clean up
Apr 8, 2025
82a31fa
removing param_header_begin and param_header_end
Apr 9, 2025
9b59d01
adding support for root constants in metadata generation
Apr 9, 2025
efc5e52
add test
Apr 9, 2025
e6865a7
Revert "clean up"
Apr 9, 2025
021976d
Reapply "clean up"
Apr 9, 2025
102ff4b
removing unnecessary parameters
Apr 10, 2025
39d4b08
addressing pr comments
Apr 10, 2025
7343d95
adding more tests
Apr 11, 2025
6986945
adding more tests and addressing comments
Apr 11, 2025
c0ac522
adding tests and changing parameter type
Apr 14, 2025
cadc296
Merge branch 'obj2yaml/root-constants' into metadata/root-constants
Apr 14, 2025
c4b78d8
address comments
Apr 14, 2025
8bdc206
address comments
Apr 14, 2025
1e5eee5
addressing pr comments
Apr 14, 2025
a968d81
Revert "addressing pr comments"
Apr 14, 2025
8511fa9
address comments
Apr 14, 2025
330369a
changing back enums to enum class
Apr 15, 2025
d747bcc
addressing PR comments and adding more tests
Apr 16, 2025
6cef567
adding tests and fixing code
Apr 16, 2025
246d5d3
addressing comments
Apr 16, 2025
bb6c0cf
clean up
Apr 16, 2025
2203885
Merge branch 'obj2yaml/root-constants' into metadata/root-constants
Apr 16, 2025
7aed7d1
fixing bugs
Apr 16, 2025
7885eed
addressing nits
Apr 17, 2025
f315bb4
Merge branch 'obj2yaml/root-constants' into metadata/root-constants
Apr 17, 2025
193a80b
Merge branch 'main' into metadata/root-constants
Apr 17, 2025
578faea
addressing pr comments
Apr 24, 2025
860fddd
addressing comments
Apr 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/MC/DXContainerRootSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct RootSignatureDesc {

uint32_t Version = 2U;
uint32_t Flags = 0U;
uint32_t RootParameterOffset = 0U;
uint32_t RootParameterOffset = 24U;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a comment as to why it should be 24

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clang emits the root signature data in dxcontainer following a specific sequence, first the header, then the root parameters, the header is always 24 bytes long, so this is why we have 24 here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good thanks. Can we add this to the code as well so it doesn't get lost

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the root parameter offset doesn't actually have to be 24 it feels awkward to set it like it's a constant here. I think it's more logical to leave this as zero and fill it in when we create these from the metadata, much like we'll have to do for StaticSamplersOffset

uint32_t StaticSamplersOffset = 0u;
uint32_t NumStaticSamplers = 0u;
SmallVector<mcdxbc::RootParameter> Parameters;
Expand Down
138 changes: 129 additions & 9 deletions llvm/lib/Target/DirectX/DXILRootSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,64 @@ static bool reportError(LLVMContext *Ctx, Twine Message,
return true;
}

static bool reportValueError(LLVMContext *Ctx, Twine ParamName, uint32_t Value,
DiagnosticSeverity Severity = DS_Error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the function is called reportValueError it seems weird for there to be a Severity parameter. We should either drop that parameter or rename this.

Ctx->diagnose(DiagnosticInfoGeneric(
"Invalid value for " + ParamName + ": " + Twine(Value), Severity));
return true;
}

static bool extractMdIntValue(uint32_t &Value, MDNode *Node,
unsigned int OpId) {
auto *CI = mdconst::dyn_extract<ConstantInt>(Node->getOperand(OpId).get());
if (CI == nullptr)
return true;

Value = CI->getZExtValue();
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does end up being slightly more verbose, but I think it's slightly clearer to use std::optional here rather than a boolean return value and an out parameter, like

static std::optional<uint32_t> extractMdIntValue(MDNode *Node,
                                                 unsigned int OpId) {
  if (auto *CI =
          mdconst::dyn_extract<ConstantInt>(Node->getOperand(OpId).get()))
    return CI->getZExtValue();
  return std::nullopt;
}

then:

  if (std::optional<uint32_t> Val = extractMdIntValue(RootConstantNode, 1))
    NewParameter.Header.ShaderVisibility = *Val;
  else
    return reportError(Ctx, "Invalid value for ShaderVisibility");


static bool parseRootFlags(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
MDNode *RootFlagNode) {

if (RootFlagNode->getNumOperands() != 2)
return reportError(Ctx, "Invalid format for RootFlag Element");

auto *Flag = mdconst::extract<ConstantInt>(RootFlagNode->getOperand(1));
RSD.Flags = Flag->getZExtValue();
if (extractMdIntValue(RSD.Flags, RootFlagNode, 1))
return reportError(Ctx, "Invalid value for RootFlag");

return false;
}

static bool parseRootConstants(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
MDNode *RootConstantNode) {

if (RootConstantNode->getNumOperands() != 5)
return reportError(Ctx, "Invalid format for RootConstants Element");

mcdxbc::RootParameter NewParameter;
NewParameter.Header.ParameterType =
llvm::to_underlying(dxbc::RootParameterType::Constants32Bit);

uint32_t SV;
if (extractMdIntValue(SV, RootConstantNode, 1))
return reportError(Ctx, "Invalid value for ShaderVisibility");

NewParameter.Header.ShaderVisibility = SV;

if (extractMdIntValue(NewParameter.Constants.ShaderRegister, RootConstantNode,
2))
return reportError(Ctx, "Invalid value for ShaderRegister");

if (extractMdIntValue(NewParameter.Constants.RegisterSpace, RootConstantNode,
3))
return reportError(Ctx, "Invalid value for RegisterSpace");

if (extractMdIntValue(NewParameter.Constants.Num32BitValues, RootConstantNode,
4))
return reportError(Ctx, "Invalid value for Num32BitValues");

RSD.Parameters.push_back(NewParameter);

return false;
}
Expand All @@ -62,12 +112,16 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
RootSignatureElementKind ElementKind =
StringSwitch<RootSignatureElementKind>(ElementText->getString())
.Case("RootFlags", RootSignatureElementKind::RootFlags)
.Case("RootConstants", RootSignatureElementKind::RootConstants)
.Default(RootSignatureElementKind::Error);

switch (ElementKind) {

case RootSignatureElementKind::RootFlags:
return parseRootFlags(Ctx, RSD, Element);
case RootSignatureElementKind::RootConstants:
return parseRootConstants(Ctx, RSD, Element);
break;
case RootSignatureElementKind::Error:
return reportError(Ctx, "Invalid Root Signature Element: " +
ElementText->getString());
Expand All @@ -94,10 +148,55 @@ static bool parse(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,

static bool verifyRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; }

static bool verifyShaderVisibility(uint32_t Flags) {
switch (Flags) {

case llvm::to_underlying(dxbc::ShaderVisibility::All):
case llvm::to_underlying(dxbc::ShaderVisibility::Vertex):
case llvm::to_underlying(dxbc::ShaderVisibility::Hull):
case llvm::to_underlying(dxbc::ShaderVisibility::Domain):
case llvm::to_underlying(dxbc::ShaderVisibility::Geometry):
case llvm::to_underlying(dxbc::ShaderVisibility::Pixel):
case llvm::to_underlying(dxbc::ShaderVisibility::Amplification):
case llvm::to_underlying(dxbc::ShaderVisibility::Mesh):
return true;
}

return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this just dxbc::isValidShaderVisibility()?


static bool verifyParameterType(uint32_t Type) {
switch (Type) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
return true;
}

return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


static bool verifyVersion(uint32_t Version) {
return (Version == 1 || Version == 2);
}

static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {

if (!verifyVersion(RSD.Version)) {
return reportValueError(Ctx, "Version", RSD.Version);
}

if (!verifyRootFlag(RSD.Flags)) {
return reportError(Ctx, "Invalid Root Signature flag value");
return reportValueError(Ctx, "RootFlags", RSD.Flags);
}

for (const auto &P : RSD.Parameters) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (const auto &P : RSD.Parameters) {
for (const RootParameter &P : RSD.Parameters) {

if (!verifyShaderVisibility(P.Header.ShaderVisibility))
return reportValueError(Ctx, "ShaderVisibility",
(uint32_t)P.Header.ShaderVisibility);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.Header.ShaderVisibility is already uint32_t. What's this cast for?


assert(verifyParameterType(P.Header.ParameterType) &&
"Invalid value for ParameterType");
}

return false;
}

Expand Down Expand Up @@ -205,14 +304,35 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,

// start root signature header
Space++;
OS << indent(Space) << "Flags: " << format_hex(RS.Flags, 8) << ":\n";
OS << indent(Space) << "Version: " << RS.Version << ":\n";
OS << indent(Space) << "NumParameters: " << RS.Parameters.size() << ":\n";
OS << indent(Space) << "RootParametersOffset: " << RSHSize << ":\n";
OS << indent(Space) << "NumStaticSamplers: " << 0 << ":\n";
OS << indent(Space) << "Flags: " << format_hex(RS.Flags, 8) << "\n";
OS << indent(Space) << "Version: " << RS.Version << "\n";
OS << indent(Space) << "NumParameters: " << RS.Parameters.size() << "\n";
OS << indent(Space) << "RootParametersOffset: " << RSHSize << "\n";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically a pre-existing bug, but this needs to print RS.RootParametersOffset, not RSHSize

OS << indent(Space) << "NumStaticSamplers: " << 0 << "\n";
OS << indent(Space)
<< "StaticSamplersOffset: " << RSHSize + RS.Parameters.size_in_bytes()
<< ":\n";
<< "\n";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be some kind of header to indicate that we're printing the root parameters here, or at least an empty line? The way this reads currently it looks almost like these are associated with the static samplers since that's what printed right before.

We could also consider printing these jinline near the parts about root parameters. Something like

Definition for 'main':
  Flags: 0x000001
  Version: 2
  RootParametersOffset: 24
  NumParameters: 2
    - Parameter Type: 1
      Shader Visibility: 0
      Register Space: 2
      Shader Register: 1
      Num 32 Bit Values: 3
    - Parameter Type: ...
      ...
  NumStaticSamplers: 0
  StaticSamplersOffset: 48

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you took pieces of both of my suggestions. I think we should either:

  • Put the list of parameters inline after the num parameters / offset fields
  • Print out a header that says "Root Parameters:" before the list of parameters

As it is now, we print the parameters immediately after the "static samplers offset", and it isn't clear that it's a list of parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry, I missed the first point indeed, will fix it.


Space++;
for (auto const &P : RS.Parameters) {
OS << indent(Space)
<< "Parameter Type: " << (uint32_t)P.Header.ParameterType << "\n";
OS << indent(Space)
<< "Shader Visibility: " << (uint32_t)P.Header.ShaderVisibility
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more superfluous casts.

<< "\n";
switch (P.Header.ParameterType) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
OS << indent(Space) << "Register Space: " << P.Constants.RegisterSpace
<< "\n";
OS << indent(Space) << "Shader Register: " << P.Constants.ShaderRegister
<< "\n";
OS << indent(Space)
<< "Num 32 Bit Values: " << P.Constants.Num32BitValues << "\n";
break;
}
}
Space--;

Space--;
// end root signature header
}
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/DirectX/DXILRootSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@
namespace llvm {
namespace dxil {

enum class RootSignatureElementKind { Error = 0, RootFlags = 1 };
enum class RootSignatureElementKind {
Error = 0,
RootFlags = 1,
RootConstants = 2
};
class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
friend AnalysisInfoMixin<RootSignatureAnalysis>;
static AnalysisKey Key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
; DXC-NEXT: RootSignature:
; DXC-NEXT: Version: 2
; DXC-NEXT: NumRootParameters: 0
; DXC-NEXT: RootParametersOffset: 0
; DXC-NEXT: RootParametersOffset: 24
; DXC-NEXT: NumStaticSamplers: 0
; DXC-NEXT: StaticSamplersOffset: 0
; DXC-NEXT: Parameters: []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

; CHECK: error: Invalid value for ShaderVisibility: 255
; CHECK-NOT: Root Signature Definitions

target triple = "dxil-unknown-shadermodel6.0-compute"


define void @main() #0 {
entry:
ret void
}

attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootConstants", i32 255, i32 1, i32 2, i32 3 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
; RUN: opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"


define void @main() #0 {
entry:
ret void
}

attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !4, !5 } ; list of root signature elements
!4 = !{ !"RootFlags", i32 1 } ; 1 = allow_input_assembler_input_layout
!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, i32 3 }

; CHECK-LABEL: Definition for 'main':
; CHECK-NEXT: Flags: 0x000001
; CHECK-NEXT: Version: 2
; CHECK-NEXT: NumParameters: 1
; CHECK-NEXT: RootParametersOffset: 24
; CHECK-NEXT: NumStaticSamplers: 0
; CHECK-NEXT: StaticSamplersOffset: 48
; CHECK-NEXT: Parameter Type: 1
; CHECK-NEXT: Shader Visibility: 0
; CHECK-NEXT: Register Space: 2
; CHECK-NEXT: Shader Register: 1
; CHECK-NEXT: Num 32 Bit Values: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"

; CHECK: error: Invalid value for Num32BitValues
; CHECK-NOT: Root Signature Definitions

define void @main() {
entry:
ret void
}

!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, !"Invalid" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"

; CHECK: error: Invalid value for RegisterSpace
; CHECK-NOT: Root Signature Definitions

define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootConstants", i32 0, i32 1, !"Invalid", i32 3 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

target triple = "dxil-unknown-shadermodel6.0-compute"

; CHECK: error: Invalid value for ShaderRegister
; CHECK-NOT: Root Signature Definitions

define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootConstants", i32 0, !"Invalid", i32 2, i32 3 }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test name implies that we are only testing root constants. Can we either change the name or remove root flags

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC

target triple = "dxil-unknown-shadermodel6.0-compute"

; CHECK: @dx.rts0 = private constant [48 x i8] c"{{.*}}", section "RTS0", align 4

define void @main() #0 {
entry:
ret void
}
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }


!dx.rootsignatures = !{!2} ; list of function/root signature pairs
!2 = !{ ptr @main, !3 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"RootConstants", i32 0, i32 1, i32 2, i32 3 }

; DXC: - Name: RTS0
; DXC-NEXT: Size: 48
; DXC-NEXT: RootSignature:
; DXC-NEXT: Version: 2
; DXC-NEXT: NumRootParameters: 1
; DXC-NEXT: RootParametersOffset: 24
; DXC-NEXT: NumStaticSamplers: 0
; DXC-NEXT: StaticSamplersOffset: 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a different value from the test above (0 vs 48). Presumably they should be the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference comes to the fact that obj2yaml has no support for static samplers yet. So those tools are not dealing with this value consistently. This will be fixed when adding the support is added to obj2yaml

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RootSignatureAnalysis also doesn't have support for static samplers yet, and the 48 comes from the fact that it prints RSHSize + RS.Parameters.size_in_bytes() rather than StaticSamplersOffset, which is arguably a bug. That will all need to be fixed as part of the implementation for static samplers though.

; DXC-NEXT: Parameters:
; DXC-NEXT: - ParameterType: 1
; DXC-NEXT: ShaderVisibility: 0
; DXC-NEXT: Constants:
; DXC-NEXT: Num32BitValues: 3
; DXC-NEXT: RegisterSpace: 2
; DXC-NEXT: ShaderRegister: 1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s

; CHECK: error: Invalid Root Signature flag value
; CHECK: error: Invalid value for RootFlags: 2147487744
; CHECK-NOT: Root Signature Definitions

target triple = "dxil-unknown-shadermodel6.0-compute"
Expand Down
Loading