Skip to content

[DirectX] Add static sampler support to root signature #143422

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 85 commits into from
Jun 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
0abacfc
adding support for Root Descriptors
Apr 24, 2025
8b8c02a
clean up
Apr 24, 2025
7ac9641
addressing comments
Apr 25, 2025
c105458
formating
Apr 26, 2025
efe76aa
try fix test
Apr 26, 2025
a928e9d
addressing comments
Apr 26, 2025
a38f10b
refactoring mcdxbc struct to store root parameters out of order
Apr 25, 2025
9a7c359
changing name
Apr 28, 2025
d6c2b55
changing variant to host pointers
Apr 28, 2025
93e4cf2
clean up
Apr 28, 2025
b45b1b6
fix
Apr 28, 2025
f804a23
fix
Apr 28, 2025
15eb6f5
fix naming
May 5, 2025
b9d7f07
fix naming
May 5, 2025
46cc8c1
addressing comments
May 8, 2025
1b3e10a
addressing comments
May 8, 2025
1f31957
addressing comments
May 8, 2025
e8fbfce
clean up
May 8, 2025
a31e5a5
removing v parameter
May 9, 2025
a394ad0
Merge branch 'obj2yaml/root-descriptors' into refactoring/remove-union
May 9, 2025
ad415a7
clean up
May 9, 2025
8ff4845
Merge branch 'main' into refactoring/remove-union
May 9, 2025
f875555
adding support for root descriptors
May 13, 2025
4f7f998
removing none as a flag option
May 13, 2025
3eb5e10
adding tests
May 13, 2025
58e1789
clean up and add more tests
May 13, 2025
81915ad
addressing comments
May 30, 2025
a515e28
Merge branch 'main' into metadata/root-descriptors
Jun 2, 2025
0d54162
clean
Jun 2, 2025
7f70dc5
cleanup
Jun 2, 2025
3e6b07e
add parsing
Jun 2, 2025
bb1a61f
add tests
Jun 2, 2025
8979ab7
adding support on analysis printer
Jun 2, 2025
be60d51
adding support on analysis printer
Jun 2, 2025
0c570c8
adding requested comment
Jun 2, 2025
c3d24b6
clean up
Jun 3, 2025
d1ca37d
addressing PR comments
Jun 3, 2025
cb0780b
formating
Jun 3, 2025
eeffded
addressing PR comments
Jun 3, 2025
3cbe0cf
formating
Jun 3, 2025
92b766b
formating
Jun 3, 2025
0259cf7
adding test
Jun 3, 2025
8732594
adding test
Jun 3, 2025
fdb8b98
clean up
Jun 3, 2025
8b61ffd
Merge branch 'metadata/root-descriptors' into metadata/descriptor-table
Jun 3, 2025
0b3e16b
format
Jun 3, 2025
750a6d5
Merge branch 'main' into metadata/descriptor-table
Jun 4, 2025
72b8dbc
addressing comments
Jun 6, 2025
8f069c7
fix
Jun 6, 2025
440566c
addressing comments
Jun 9, 2025
72ca44b
address coments
Jun 9, 2025
90f7403
remove diff
Jun 9, 2025
7a4382e
address comments
Jun 9, 2025
1c608f4
address comments
Jun 11, 2025
3b8b2e1
Merge branch 'bugfix/wrong-values-root-descriptor-flags' into metadat…
Jun 11, 2025
e0bc5e3
fix
Jun 11, 2025
35a2e0b
fix other values
Jun 11, 2025
655b3b4
Merge branch 'bugfix/wrong-values-root-descriptor-flags' into metadat…
Jun 11, 2025
91346a7
adding more tests
Jun 11, 2025
e8066df
address comments
Jun 12, 2025
9f51858
adding metadata support for static samplers
Jun 4, 2025
fb9c7c4
add validations
Jun 5, 2025
611f0bb
adding tests
Jun 6, 2025
42beb33
addressing comments
Jun 6, 2025
0995050
fix
Jun 9, 2025
24f38bd
rebase
Jun 12, 2025
15f4f49
Merge branch 'main' into metadata/descriptor-table
Jun 17, 2025
638d961
remove empty file
Jun 18, 2025
8b831f8
adding check for mutually exclusive descriptor flags
Jun 18, 2025
5c677a5
format
Jun 18, 2025
bce790c
address comments
Jun 18, 2025
fefe820
remove value
Jun 18, 2025
e577503
adding support to version in metadata
Jun 19, 2025
746c54a
fix tests
Jun 19, 2025
c5a1009
Merge branch 'metadata/add-versioning-support' into metadata/descript…
Jun 19, 2025
a66e6a3
add test
Jun 19, 2025
351eee2
Merge branch 'main' into metadata/descriptor-table
Jun 20, 2025
4a0a955
fix merge and test issues
Jun 20, 2025
4e655da
addressing comments
Jun 20, 2025
c31af32
Merge branch 'metadata/descriptor-table' into metadata/static-samplers
Jun 20, 2025
2507ea3
address comment
Jun 20, 2025
cf11ce0
Merge branch 'main' into metadata/static-samplers
Jun 20, 2025
91cb708
Merge branch 'main' into metadata/static-samplers
Jun 24, 2025
7040af7
improve validation
Jun 24, 2025
e2eee99
clean
Jun 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
41 changes: 24 additions & 17 deletions llvm/lib/MC/DXContainerRootSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,16 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
BOS.reserveExtraSpace(getSize());

const uint32_t NumParameters = ParametersContainer.size();

const uint32_t NumSamplers = StaticSamplers.size();
support::endian::write(BOS, Version, llvm::endianness::little);
support::endian::write(BOS, NumParameters, llvm::endianness::little);
support::endian::write(BOS, RootParameterOffset, llvm::endianness::little);
support::endian::write(BOS, NumStaticSamplers, llvm::endianness::little);
support::endian::write(BOS, StaticSamplersOffset, llvm::endianness::little);
support::endian::write(BOS, NumSamplers, llvm::endianness::little);
uint32_t SSO = StaticSamplersOffset;
if (NumSamplers > 0)
SSO = writePlaceholder(BOS);
else
support::endian::write(BOS, SSO, llvm::endianness::little);
support::endian::write(BOS, Flags, llvm::endianness::little);

SmallVector<uint32_t> ParamsOffsets;
Expand Down Expand Up @@ -142,20 +146,23 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
}
}
}
for (const auto &S : StaticSamplers) {
support::endian::write(BOS, S.Filter, llvm::endianness::little);
support::endian::write(BOS, S.AddressU, llvm::endianness::little);
support::endian::write(BOS, S.AddressV, llvm::endianness::little);
support::endian::write(BOS, S.AddressW, llvm::endianness::little);
support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);
support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);
support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);
support::endian::write(BOS, S.BorderColor, llvm::endianness::little);
support::endian::write(BOS, S.MinLOD, llvm::endianness::little);
support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);
support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);
if (NumSamplers > 0) {
rewriteOffsetToCurrentByte(BOS, SSO);
Copy link
Contributor

Choose a reason for hiding this comment

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

So when NumSampler == 0 is required to be 0 right? Or is it just ignored? Or do we set it 0 to match DXC?

Just want to double-check that is defined and correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I set it to zero just to make sure we are not jumping into a random file location by mistake. I don't think DXC forces it to be zero. But if you have no ranges, the offset should be ignored.

Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW DXC writes the value where samplers would be unconditionally, so there might be some argument to match that just so that we're binary identical.

That said, you are correct that this offset should be ignored when there aren't any samplers, and I think that explicitly zeroing it makes that clearer, so I kind of like it as is.

for (const auto &S : StaticSamplers) {
support::endian::write(BOS, S.Filter, llvm::endianness::little);
support::endian::write(BOS, S.AddressU, llvm::endianness::little);
support::endian::write(BOS, S.AddressV, llvm::endianness::little);
support::endian::write(BOS, S.AddressW, llvm::endianness::little);
support::endian::write(BOS, S.MipLODBias, llvm::endianness::little);
support::endian::write(BOS, S.MaxAnisotropy, llvm::endianness::little);
support::endian::write(BOS, S.ComparisonFunc, llvm::endianness::little);
support::endian::write(BOS, S.BorderColor, llvm::endianness::little);
support::endian::write(BOS, S.MinLOD, llvm::endianness::little);
support::endian::write(BOS, S.MaxLOD, llvm::endianness::little);
support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);
}
}
assert(Storage.size() == getSize());
OS.write(Storage.data(), Storage.size());
Expand Down
183 changes: 183 additions & 0 deletions llvm/lib/Target/DirectX/DXILRootSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cmath>
#include <cstdint>
#include <optional>
#include <utility>
Expand Down Expand Up @@ -55,6 +56,13 @@ static std::optional<uint32_t> extractMdIntValue(MDNode *Node,
return std::nullopt;
}

static std::optional<float> extractMdFloatValue(MDNode *Node,
unsigned int OpId) {
if (auto *CI = mdconst::dyn_extract<ConstantFP>(Node->getOperand(OpId).get()))
return CI->getValueAPF().convertToFloat();
return std::nullopt;
}

static std::optional<StringRef> extractMdStringValue(MDNode *Node,
unsigned int OpId) {
MDString *NodeText = dyn_cast<MDString>(Node->getOperand(OpId));
Expand Down Expand Up @@ -261,6 +269,81 @@ static bool parseDescriptorTable(LLVMContext *Ctx,
return false;
}

static bool parseStaticSampler(LLVMContext *Ctx, mcdxbc::RootSignatureDesc &RSD,
MDNode *StaticSamplerNode) {
if (StaticSamplerNode->getNumOperands() != 14)
return reportError(Ctx, "Invalid format for Static Sampler");

dxbc::RTS0::v1::StaticSampler Sampler;
if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 1))
Sampler.Filter = *Val;
else
return reportError(Ctx, "Invalid value for Filter");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 2))
Sampler.AddressU = *Val;
else
return reportError(Ctx, "Invalid value for AddressU");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 3))
Sampler.AddressV = *Val;
else
return reportError(Ctx, "Invalid value for AddressV");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 4))
Sampler.AddressW = *Val;
else
return reportError(Ctx, "Invalid value for AddressW");

if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 5))
Sampler.MipLODBias = *Val;
else
return reportError(Ctx, "Invalid value for MipLODBias");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 6))
Sampler.MaxAnisotropy = *Val;
else
return reportError(Ctx, "Invalid value for MaxAnisotropy");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 7))
Sampler.ComparisonFunc = *Val;
else
return reportError(Ctx, "Invalid value for ComparisonFunc ");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 8))
Sampler.BorderColor = *Val;
else
return reportError(Ctx, "Invalid value for ComparisonFunc ");

if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 9))
Sampler.MinLOD = *Val;
else
return reportError(Ctx, "Invalid value for MinLOD");

if (std::optional<float> Val = extractMdFloatValue(StaticSamplerNode, 10))
Sampler.MaxLOD = *Val;
else
return reportError(Ctx, "Invalid value for MaxLOD");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 11))
Sampler.ShaderRegister = *Val;
else
return reportError(Ctx, "Invalid value for ShaderRegister");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 12))
Sampler.RegisterSpace = *Val;
else
return reportError(Ctx, "Invalid value for RegisterSpace");

if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 13))
Sampler.ShaderVisibility = *Val;
else
return reportError(Ctx, "Invalid value for ShaderVisibility");

RSD.StaticSamplers.push_back(Sampler);
return false;
}

static bool parseRootSignatureElement(LLVMContext *Ctx,
mcdxbc::RootSignatureDesc &RSD,
MDNode *Element) {
Expand All @@ -276,6 +359,7 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
.Case("RootSRV", RootSignatureElementKind::SRV)
.Case("RootUAV", RootSignatureElementKind::UAV)
.Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)
.Case("StaticSampler", RootSignatureElementKind::StaticSamplers)
.Default(RootSignatureElementKind::Error);

switch (ElementKind) {
Expand All @@ -290,6 +374,8 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
return parseRootDescriptors(Ctx, RSD, Element, ElementKind);
case RootSignatureElementKind::DescriptorTable:
return parseDescriptorTable(Ctx, RSD, Element);
case RootSignatureElementKind::StaticSamplers:
return parseStaticSampler(Ctx, RSD, Element);
case RootSignatureElementKind::Error:
return reportError(Ctx, "Invalid Root Signature Element: " + *ElementText);
}
Expand Down Expand Up @@ -406,6 +492,58 @@ static bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
return (Flags & ~Mask) == FlagT::NONE;
}

static bool verifySamplerFilter(uint32_t Value) {
switch (Value) {
#define STATIC_SAMPLER_FILTER(Num, Val) \
case llvm::to_underlying(dxbc::StaticSamplerFilter::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}

// Values allowed here:
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_texture_address_mode#syntax
static bool verifyAddress(uint32_t Address) {
switch (Address) {
#define TEXTURE_ADDRESS_MODE(Num, Val) \
case llvm::to_underlying(dxbc::TextureAddressMode::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}

static bool verifyMipLODBias(float MipLODBias) {
return MipLODBias >= -16.f && MipLODBias <= 15.99f;
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this matches what DXC's validator does so it's probably "correct", but 15.99 isn't actually representable in float and this literal is subject to rounding.

}

static bool verifyMaxAnisotropy(uint32_t MaxAnisotropy) {
return MaxAnisotropy <= 16u;
}

static bool verifyComparisonFunc(uint32_t ComparisonFunc) {
switch (ComparisonFunc) {
#define COMPARISON_FUNCTION(Num, Val) \
case llvm::to_underlying(dxbc::SamplersComparisonFunction::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}

static bool verifyBorderColor(uint32_t BorderColor) {
switch (BorderColor) {
#define STATIC_BORDER_COLOR(Num, Val) \
case llvm::to_underlying(dxbc::SamplersBorderColor::Val):
#include "llvm/BinaryFormat/DXContainerConstants.def"
return true;
}
return false;
}

static bool verifyLOD(float LOD) { return !std::isnan(LOD); }

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

if (!verifyVersion(RSD.Version)) {
Expand Down Expand Up @@ -463,6 +601,48 @@ static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
}
}

for (const dxbc::RTS0::v1::StaticSampler &Sampler : RSD.StaticSamplers) {
if (!verifySamplerFilter(Sampler.Filter))
return reportValueError(Ctx, "Filter", Sampler.Filter);

if (!verifyAddress(Sampler.AddressU))
Copy link
Contributor

Choose a reason for hiding this comment

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

One thought that just came up. I don't think it is required for us to early exit on all these verifications.

Maybe we can report all invalid errors in one go rather than exiting on the first one? Can you provide an argument for why or why not?

I would assume reporting all errors (so long as they aren't too verbose) reduces the number of compile cycles for the user to correct their input.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've created a follow-up PR with this: #144465

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll take a look at the other PR and think about it there, but FWIW we don't expect to be getting here from a user's input per se - I would expect we only really get here from a root signature read from a binary format or from a frontend that's presumably already attempted to validate the input.

return reportValueError(Ctx, "AddressU", Sampler.AddressU);

if (!verifyAddress(Sampler.AddressV))
return reportValueError(Ctx, "AddressV", Sampler.AddressV);

if (!verifyAddress(Sampler.AddressW))
return reportValueError(Ctx, "AddressW", Sampler.AddressW);

if (!verifyMipLODBias(Sampler.MipLODBias))
return reportValueError(Ctx, "MipLODBias", Sampler.MipLODBias);

if (!verifyMaxAnisotropy(Sampler.MaxAnisotropy))
return reportValueError(Ctx, "MaxAnisotropy", Sampler.MaxAnisotropy);

if (!verifyComparisonFunc(Sampler.ComparisonFunc))
return reportValueError(Ctx, "ComparisonFunc", Sampler.ComparisonFunc);

if (!verifyBorderColor(Sampler.BorderColor))
return reportValueError(Ctx, "BorderColor", Sampler.BorderColor);

if (!verifyLOD(Sampler.MinLOD))
return reportValueError(Ctx, "MinLOD", Sampler.MinLOD);

if (!verifyLOD(Sampler.MaxLOD))
return reportValueError(Ctx, "MaxLOD", Sampler.MaxLOD);

if (!verifyRegisterValue(Sampler.ShaderRegister))
return reportValueError(Ctx, "ShaderRegister", Sampler.ShaderRegister);

if (!verifyRegisterSpace(Sampler.RegisterSpace))
return reportValueError(Ctx, "RegisterSpace", Sampler.RegisterSpace);

if (!dxbc::isValidShaderVisibility(Sampler.ShaderVisibility))
return reportValueError(Ctx, "ShaderVisibility",
Sampler.ShaderVisibility);
}

return false;
}

Expand Down Expand Up @@ -542,6 +722,9 @@ analyzeModule(Module &M) {
// offset will always equal to the header size.
RSD.RootParameterOffset = sizeof(dxbc::RTS0::v1::RootSignatureHeader);

// static sampler offset is calculated when writting dxcontainer.
RSD.StaticSamplersOffset = 0u;

if (parse(Ctx, RSD, RootElementListNode) || validate(Ctx, RSD)) {
return RSDMap;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXILRootSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enum class RootSignatureElementKind {
UAV = 4,
CBV = 5,
DescriptorTable = 6,
StaticSamplers = 7
};
class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
friend AnalysisInfoMixin<RootSignatureAnalysis>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; 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 AddressU: 666
; 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, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; 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 AddressV: 666
; 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, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"StaticSampler", i32 4, i32 2, i32 666, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; 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 AddressW: 666
; 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, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 666, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
; 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 BorderColor: 666
; 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, i32 2 } ; function, root signature
!3 = !{ !5 } ; list of root signature elements
!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 666, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 }
Loading