[llvm] [HLSL][RootSignature] Implement serialization of remaining Root Elements (PR #143198)
Finn Plummer via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 17 14:34:25 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/143198
>From aaa46bc4c02ecddf3797c1ccb06f03a54479ce39 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Mon, 16 Jun 2025 21:17:12 +0000
Subject: [PATCH] implement serialization of remaining root elements
---
.../Frontend/HLSL/HLSLRootSignatureUtils.h | 6 +
.../Frontend/HLSL/HLSLRootSignatureUtils.cpp | 142 ++++++++++++++++++
.../Frontend/HLSLRootSignatureDumpTest.cpp | 121 +++++++++++++++
3 files changed, 269 insertions(+)
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
index 6d959ad5bdc7f..69922348a0083 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
@@ -32,6 +32,12 @@ LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const DescriptorTable &Table);
+LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
+ const RootDescriptor &Descriptor);
+
+LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
+ const StaticSampler &StaticSampler);
+
LLVM_ABI void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements);
class MetadataBuilder {
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
index 7d744781da04f..9fbe6924bb5c8 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
@@ -98,6 +98,109 @@ static raw_ostream &operator<<(raw_ostream &OS,
return OS;
}
+static const EnumEntry<SamplerFilter> SamplerFilterNames[] = {
+ {"MinMagMipPoint", SamplerFilter::MinMagMipPoint},
+ {"MinMagPointMipLinear", SamplerFilter::MinMagPointMipLinear},
+ {"MinPointMagLinearMipPoint", SamplerFilter::MinPointMagLinearMipPoint},
+ {"MinPointMagMipLinear", SamplerFilter::MinPointMagMipLinear},
+ {"MinLinearMagMipPoint", SamplerFilter::MinLinearMagMipPoint},
+ {"MinLinearMagPointMipLinear", SamplerFilter::MinLinearMagPointMipLinear},
+ {"MinMagLinearMipPoint", SamplerFilter::MinMagLinearMipPoint},
+ {"MinMagMipLinear", SamplerFilter::MinMagMipLinear},
+ {"Anisotropic", SamplerFilter::Anisotropic},
+ {"ComparisonMinMagMipPoint", SamplerFilter::ComparisonMinMagMipPoint},
+ {"ComparisonMinMagPointMipLinear",
+ SamplerFilter::ComparisonMinMagPointMipLinear},
+ {"ComparisonMinPointMagLinearMipPoint",
+ SamplerFilter::ComparisonMinPointMagLinearMipPoint},
+ {"ComparisonMinPointMagMipLinear",
+ SamplerFilter::ComparisonMinPointMagMipLinear},
+ {"ComparisonMinLinearMagMipPoint",
+ SamplerFilter::ComparisonMinLinearMagMipPoint},
+ {"ComparisonMinLinearMagPointMipLinear",
+ SamplerFilter::ComparisonMinLinearMagPointMipLinear},
+ {"ComparisonMinMagLinearMipPoint",
+ SamplerFilter::ComparisonMinMagLinearMipPoint},
+ {"ComparisonMinMagMipLinear", SamplerFilter::ComparisonMinMagMipLinear},
+ {"ComparisonAnisotropic", SamplerFilter::ComparisonAnisotropic},
+ {"MinimumMinMagMipPoint", SamplerFilter::MinimumMinMagMipPoint},
+ {"MinimumMinMagPointMipLinear", SamplerFilter::MinimumMinMagPointMipLinear},
+ {"MinimumMinPointMagLinearMipPoint",
+ SamplerFilter::MinimumMinPointMagLinearMipPoint},
+ {"MinimumMinPointMagMipLinear", SamplerFilter::MinimumMinPointMagMipLinear},
+ {"MinimumMinLinearMagMipPoint", SamplerFilter::MinimumMinLinearMagMipPoint},
+ {"MinimumMinLinearMagPointMipLinear",
+ SamplerFilter::MinimumMinLinearMagPointMipLinear},
+ {"MinimumMinMagLinearMipPoint", SamplerFilter::MinimumMinMagLinearMipPoint},
+ {"MinimumMinMagMipLinear", SamplerFilter::MinimumMinMagMipLinear},
+ {"MinimumAnisotropic", SamplerFilter::MinimumAnisotropic},
+ {"MaximumMinMagMipPoint", SamplerFilter::MaximumMinMagMipPoint},
+ {"MaximumMinMagPointMipLinear", SamplerFilter::MaximumMinMagPointMipLinear},
+ {"MaximumMinPointMagLinearMipPoint",
+ SamplerFilter::MaximumMinPointMagLinearMipPoint},
+ {"MaximumMinPointMagMipLinear", SamplerFilter::MaximumMinPointMagMipLinear},
+ {"MaximumMinLinearMagMipPoint", SamplerFilter::MaximumMinLinearMagMipPoint},
+ {"MaximumMinLinearMagPointMipLinear",
+ SamplerFilter::MaximumMinLinearMagPointMipLinear},
+ {"MaximumMinMagLinearMipPoint", SamplerFilter::MaximumMinMagLinearMipPoint},
+ {"MaximumMinMagMipLinear", SamplerFilter::MaximumMinMagMipLinear},
+ {"MaximumAnisotropic", SamplerFilter::MaximumAnisotropic},
+};
+
+static raw_ostream &operator<<(raw_ostream &OS, const SamplerFilter &Filter) {
+ printEnum(OS, Filter, ArrayRef(SamplerFilterNames));
+
+ return OS;
+}
+
+static const EnumEntry<TextureAddressMode> TextureAddressModeNames[] = {
+ {"Wrap", TextureAddressMode::Wrap},
+ {"Mirror", TextureAddressMode::Mirror},
+ {"Clamp", TextureAddressMode::Clamp},
+ {"Border", TextureAddressMode::Border},
+ {"MirrorOnce", TextureAddressMode::MirrorOnce},
+};
+
+static raw_ostream &operator<<(raw_ostream &OS,
+ const TextureAddressMode &Address) {
+ printEnum(OS, Address, ArrayRef(TextureAddressModeNames));
+
+ return OS;
+}
+
+static const EnumEntry<ComparisonFunc> ComparisonFuncNames[] = {
+ {"Never", ComparisonFunc::Never},
+ {"Less", ComparisonFunc::Less},
+ {"Equal", ComparisonFunc::Equal},
+ {"LessEqual", ComparisonFunc::LessEqual},
+ {"Greater", ComparisonFunc::Greater},
+ {"NotEqual", ComparisonFunc::NotEqual},
+ {"GreaterEqual", ComparisonFunc::GreaterEqual},
+ {"Always", ComparisonFunc::Always},
+};
+
+static raw_ostream &operator<<(raw_ostream &OS,
+ const ComparisonFunc &CompFunc) {
+ printEnum(OS, CompFunc, ArrayRef(ComparisonFuncNames));
+
+ return OS;
+}
+
+static const EnumEntry<StaticBorderColor> StaticBorderColorNames[] = {
+ {"TransparentBlack", StaticBorderColor::TransparentBlack},
+ {"OpaqueBlack", StaticBorderColor::OpaqueBlack},
+ {"OpaqueWhite", StaticBorderColor::OpaqueWhite},
+ {"OpaqueBlackUint", StaticBorderColor::OpaqueBlackUint},
+ {"OpaqueWhiteUint", StaticBorderColor::OpaqueWhiteUint},
+};
+
+static raw_ostream &operator<<(raw_ostream &OS,
+ const StaticBorderColor &BorderColor) {
+ printEnum(OS, BorderColor, ArrayRef(StaticBorderColorNames));
+
+ return OS;
+}
+
static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = {
{"CBV", dxil::ResourceClass::CBuffer},
{"SRV", dxil::ResourceClass::SRV},
@@ -112,6 +215,20 @@ static raw_ostream &operator<<(raw_ostream &OS, const ClauseType &Type) {
return OS;
}
+static const EnumEntry<RootDescriptorFlags> RootDescriptorFlagNames[] = {
+ {"DataVolatile", RootDescriptorFlags::DataVolatile},
+ {"DataStaticWhileSetAtExecute",
+ RootDescriptorFlags::DataStaticWhileSetAtExecute},
+ {"DataStatic", RootDescriptorFlags::DataStatic},
+};
+
+static raw_ostream &operator<<(raw_ostream &OS,
+ const RootDescriptorFlags &Flags) {
+ printFlags(OS, Flags, ArrayRef(RootDescriptorFlagNames));
+
+ return OS;
+}
+
static const EnumEntry<DescriptorRangeFlags> DescriptorRangeFlagNames[] = {
{"DescriptorsVolatile", DescriptorRangeFlags::DescriptorsVolatile},
{"DataVolatile", DescriptorRangeFlags::DataVolatile},
@@ -149,6 +266,31 @@ raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause) {
return OS;
}
+raw_ostream &operator<<(raw_ostream &OS, const RootDescriptor &Descriptor) {
+ ClauseType Type = ClauseType(llvm::to_underlying(Descriptor.Type));
+ OS << "Root" << Type << "(" << Descriptor.Reg
+ << ", space = " << Descriptor.Space
+ << ", visibility = " << Descriptor.Visibility
+ << ", flags = " << Descriptor.Flags << ")";
+
+ return OS;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const StaticSampler &Sampler) {
+ OS << "StaticSampler(" << Sampler.Reg << ", filter = " << Sampler.Filter
+ << ", addressU = " << Sampler.AddressU
+ << ", addressV = " << Sampler.AddressV
+ << ", addressW = " << Sampler.AddressW
+ << ", mipLODBias = " << Sampler.MipLODBias
+ << ", maxAnisotropy = " << Sampler.MaxAnisotropy
+ << ", comparisonFunc = " << Sampler.CompFunc
+ << ", borderColor = " << Sampler.BorderColor
+ << ", minLOD = " << Sampler.MinLOD << ", maxLOD = " << Sampler.MaxLOD
+ << ", space = " << Sampler.Space << ", visibility = " << Sampler.Visibility
+ << ")";
+ return OS;
+}
+
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) {
OS << "RootElements{";
bool First = true;
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index 90e6cd0a80d6b..29c487a85b3db 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -108,4 +108,125 @@ TEST(HLSLRootSignatureTest, DescriptorTableDump) {
EXPECT_EQ(Out, Expected);
}
+TEST(HLSLRootSignatureTest, RootCBVDump) {
+ RootDescriptor Descriptor;
+ Descriptor.Type = DescriptorType::CBuffer;
+ Descriptor.Reg = {RegisterType::BReg, 0};
+ Descriptor.setDefaultFlags();
+
+ std::string Out;
+ llvm::raw_string_ostream OS(Out);
+ OS << Descriptor;
+ OS.flush();
+
+ std::string Expected = "RootCBV(b0, space = 0, "
+ "visibility = All, "
+ "flags = DataStaticWhileSetAtExecute)";
+ EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, RootSRVDump) {
+ RootDescriptor Descriptor;
+ Descriptor.Type = DescriptorType::SRV;
+ Descriptor.Reg = {RegisterType::TReg, 0};
+ Descriptor.Space = 42;
+ Descriptor.Visibility = ShaderVisibility::Geometry;
+ Descriptor.Flags = RootDescriptorFlags::None;
+
+ std::string Out;
+ llvm::raw_string_ostream OS(Out);
+ OS << Descriptor;
+ OS.flush();
+
+ std::string Expected =
+ "RootSRV(t0, space = 42, visibility = Geometry, flags = None)";
+ EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, RootUAVDump) {
+ RootDescriptor Descriptor;
+ Descriptor.Type = DescriptorType::UAV;
+ Descriptor.Reg = {RegisterType::UReg, 92374};
+ Descriptor.Space = 932847;
+ Descriptor.Visibility = ShaderVisibility::Hull;
+ Descriptor.Flags = RootDescriptorFlags::ValidFlags;
+
+ std::string Out;
+ llvm::raw_string_ostream OS(Out);
+ OS << Descriptor;
+ OS.flush();
+
+ std::string Expected =
+ "RootUAV(u92374, space = 932847, visibility = Hull, flags = "
+ "DataVolatile | "
+ "DataStaticWhileSetAtExecute | "
+ "DataStatic)";
+ EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, DefaultStaticSamplerDump) {
+ StaticSampler Sampler;
+ Sampler.Reg = {RegisterType::SReg, 0};
+
+ std::string Out;
+ llvm::raw_string_ostream OS(Out);
+ OS << Sampler;
+ OS.flush();
+
+ std::string Expected = "StaticSampler(s0, "
+ "filter = Anisotropic, "
+ "addressU = Wrap, "
+ "addressV = Wrap, "
+ "addressW = Wrap, "
+ "mipLODBias = 0.000000e+00, "
+ "maxAnisotropy = 16, "
+ "comparisonFunc = LessEqual, "
+ "borderColor = OpaqueWhite, "
+ "minLOD = 0.000000e+00, "
+ "maxLOD = 3.402823e+38, "
+ "space = 0, "
+ "visibility = All"
+ ")";
+ EXPECT_EQ(Out, Expected);
+}
+
+TEST(HLSLRootSignatureTest, DefinedStaticSamplerDump) {
+ StaticSampler Sampler;
+ Sampler.Reg = {RegisterType::SReg, 0};
+
+ Sampler.Filter = SamplerFilter::ComparisonMinMagLinearMipPoint;
+ Sampler.AddressU = TextureAddressMode::Mirror;
+ Sampler.AddressV = TextureAddressMode::Border;
+ Sampler.AddressW = TextureAddressMode::Clamp;
+ Sampler.MipLODBias = 4.8f;
+ Sampler.MaxAnisotropy = 32;
+ Sampler.CompFunc = ComparisonFunc::NotEqual;
+ Sampler.BorderColor = StaticBorderColor::OpaqueBlack;
+ Sampler.MinLOD = 1.0f;
+ Sampler.MaxLOD = 32.0f;
+ Sampler.Space = 7;
+ Sampler.Visibility = ShaderVisibility::Domain;
+
+ std::string Out;
+ llvm::raw_string_ostream OS(Out);
+ OS << Sampler;
+ OS.flush();
+
+ std::string Expected = "StaticSampler(s0, "
+ "filter = ComparisonMinMagLinearMipPoint, "
+ "addressU = Mirror, "
+ "addressV = Border, "
+ "addressW = Clamp, "
+ "mipLODBias = 4.800000e+00, "
+ "maxAnisotropy = 32, "
+ "comparisonFunc = NotEqual, "
+ "borderColor = OpaqueBlack, "
+ "minLOD = 1.000000e+00, "
+ "maxLOD = 3.200000e+01, "
+ "space = 7, "
+ "visibility = Domain"
+ ")";
+ EXPECT_EQ(Out, Expected);
+}
+
} // namespace
More information about the llvm-commits
mailing list