[clang] [llvm] [HLSL][RootSignature] Add parsing of address params in StaticSampler (PR #140293)
Finn Plummer via cfe-commits
cfe-commits at lists.llvm.org
Thu May 29 15:03:39 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/140293
>From 1eabfe2fe30eaed793bdcf03f0e58d1e0c14548f Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 16 May 2025 16:38:33 +0000
Subject: [PATCH 1/4] pre-req: add keywords
---
.../clang/Lex/HLSLRootSignatureTokenKinds.def | 14 ++++++++++++++
clang/unittests/Lex/LexHLSLRootSignatureTest.cpp | 9 ++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index 7ca131349fed4..9b47ec57f541b 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -53,6 +53,9 @@
#ifndef SHADER_VISIBILITY_ENUM
#define SHADER_VISIBILITY_ENUM(NAME, LIT) ENUM(NAME, LIT)
#endif
+#ifndef TEXTURE_ADDRESS_MODE_ENUM
+#define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
// General Tokens:
TOK(invalid, "invalid identifier")
@@ -102,6 +105,9 @@ KEYWORD(offset)
// StaticSampler Keywords:
KEYWORD(mipLODBias)
+KEYWORD(addressU)
+KEYWORD(addressV)
+KEYWORD(addressW)
KEYWORD(maxAnisotropy)
KEYWORD(minLOD)
KEYWORD(maxLOD)
@@ -148,6 +154,14 @@ SHADER_VISIBILITY_ENUM(Pixel, "SHADER_VISIBILITY_PIXEL")
SHADER_VISIBILITY_ENUM(Amplification, "SHADER_VISIBILITY_AMPLIFICATION")
SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
+// Texture Address Mode Enums:
+TEXTURE_ADDRESS_MODE_ENUM(Wrap, "TEXTURE_ADDRESS_WRAP")
+TEXTURE_ADDRESS_MODE_ENUM(Mirror, "TEXTURE_ADDRESS_MIRROR")
+TEXTURE_ADDRESS_MODE_ENUM(Clamp, "TEXTURE_ADDRESS_CLAMP")
+TEXTURE_ADDRESS_MODE_ENUM(Border, "TEXTURE_ADDRESS_BORDER")
+TEXTURE_ADDRESS_MODE_ENUM(MirrorOnce, "TEXTURE_ADDRESS_MIRRORONCE")
+
+#undef TEXTURE_ADDRESS_MODE_ENUM
#undef SHADER_VISIBILITY_ENUM
#undef DESCRIPTOR_RANGE_FLAG_ENUM
#undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 575a97e75a05d..f0f22ccc29e9f 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -136,7 +136,8 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
space visibility flags
numDescriptors offset
- mipLODBias maxAnisotropy minLOD maxLOD
+ mipLODBias addressU addressV addressW
+ maxAnisotropy minLOD maxLOD
unbounded
DESCRIPTOR_RANGE_OFFSET_APPEND
@@ -168,6 +169,12 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
shader_visibility_pixel
shader_visibility_amplification
shader_visibility_mesh
+
+ TEXTURE_ADDRESS_WRAP
+ TEXTURE_ADDRESS_MIRROR
+ TEXTURE_ADDRESS_CLAMP
+ TEXTURE_ADDRESS_BORDER
+ TEXTURE_ADDRESS_MIRRORONCE
)cc";
auto TokLoc = SourceLocation();
hlsl::RootSignatureLexer Lexer(Source, TokLoc);
>From 4f85c5b4a685eb11973a39d12ed10c7e74bdd1a1 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 16 May 2025 16:48:32 +0000
Subject: [PATCH 2/4] add parsing of TextureAddressMode for addressU
---
.../clang/Parse/ParseHLSLRootSignature.h | 3 ++
clang/lib/Parse/ParseHLSLRootSignature.cpp | 46 +++++++++++++++++++
.../Parse/ParseHLSLRootSignatureTest.cpp | 5 +-
.../llvm/Frontend/HLSL/HLSLRootSignature.h | 9 ++++
4 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 859ea7866cd04..ef27198b58f3e 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -112,6 +112,7 @@ class RootSignatureParser {
struct ParsedStaticSamplerParams {
std::optional<llvm::hlsl::rootsig::Register> Reg;
std::optional<float> MipLODBias;
+ std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressU;
std::optional<uint32_t> MaxAnisotropy;
std::optional<float> MinLOD;
std::optional<float> MaxLOD;
@@ -125,6 +126,8 @@ class RootSignatureParser {
/// Parsing methods of various enums
std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
+ std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+ parseTextureAddressMode();
std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
parseRootDescriptorFlags();
std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 23e64e8cb165d..660bd7dd147ba 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -377,6 +377,9 @@ std::optional<StaticSampler> RootSignatureParser::parseStaticSampler() {
Sampler.Reg = Params->Reg.value();
// Fill in optional values
+ if (Params->AddressU.has_value())
+ Sampler.AddressU = Params->AddressU.value();
+
if (Params->MipLODBias.has_value())
Sampler.MipLODBias = Params->MipLODBias.value();
@@ -675,6 +678,23 @@ RootSignatureParser::parseStaticSamplerParams() {
Params.Reg = Reg;
}
+ // `addressU` `=` TEXTURE_ADDRESS
+ if (tryConsumeExpectedToken(TokenKind::kw_addressU)) {
+ if (Params.AddressU.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ auto AddressU = parseTextureAddressMode();
+ if (!AddressU.has_value())
+ return std::nullopt;
+ Params.AddressU = AddressU;
+ }
+
// `mipLODBias` `=` NUMBER
if (tryConsumeExpectedToken(TokenKind::kw_mipLODBias)) {
if (Params.MipLODBias.has_value()) {
@@ -849,6 +869,32 @@ RootSignatureParser::parseShaderVisibility() {
return std::nullopt;
}
+std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+RootSignatureParser::parseTextureAddressMode() {
+ assert(CurToken.TokKind == TokenKind::pu_equal &&
+ "Expects to only be invoked starting at given keyword");
+
+ TokenKind Expected[] = {
+#define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ };
+
+ if (!tryConsumeExpectedToken(Expected))
+ return std::nullopt;
+
+ switch (CurToken.TokKind) {
+#define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT) \
+ case TokenKind::en_##NAME: \
+ return TextureAddressMode::NAME; \
+ break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ default:
+ llvm_unreachable("Switch for consumed enum token was not provided");
+ }
+
+ return std::nullopt;
+}
+
std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
RootSignatureParser::parseRootDescriptorFlags() {
assert(CurToken.TokKind == TokenKind::pu_equal &&
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index b3703c21b5ee1..7636171004e70 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -228,7 +228,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
StaticSampler(s0),
StaticSampler(s0, maxAnisotropy = 3,
minLOD = 4.2f, mipLODBias = 0.23e+3,
- maxLOD = 9000,
+ maxLOD = 9000, addressU = TEXTURE_ADDRESS_MIRROR
)
)cc";
@@ -252,6 +252,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU, TextureAddressMode::Wrap);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 16u);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 0.f);
@@ -262,6 +264,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU, TextureAddressMode::Mirror);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 230.f);
ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 3u);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 4.2f);
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 940d6d0bd8d44..ed3f20ded585b 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -76,6 +76,14 @@ enum class ShaderVisibility {
Mesh = 7,
};
+enum class TextureAddressMode {
+ Wrap = 1,
+ Mirror = 2,
+ Clamp = 3,
+ Border = 4,
+ MirrorOnce = 5
+};
+
// Definitions of the in-memory data layout structures
// Models the different registers: bReg | tReg | uReg | sReg
@@ -157,6 +165,7 @@ raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause);
struct StaticSampler {
Register Reg;
+ TextureAddressMode AddressU = TextureAddressMode::Wrap;
float MipLODBias = 0.f;
uint32_t MaxAnisotropy = 16;
float MinLOD = 0.f;
>From 9eb02ce5fa54651a3e34b1399108c940a3fc1f16 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 16 May 2025 17:18:45 +0000
Subject: [PATCH 3/4] add parsing of addressV and addressW
---
.../clang/Parse/ParseHLSLRootSignature.h | 2 +
clang/lib/Parse/ParseHLSLRootSignature.cpp | 40 +++++++++++++++++++
.../Parse/ParseHLSLRootSignatureTest.cpp | 6 +++
.../llvm/Frontend/HLSL/HLSLRootSignature.h | 2 +
4 files changed, 50 insertions(+)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index ef27198b58f3e..d436265b8b37a 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -113,6 +113,8 @@ class RootSignatureParser {
std::optional<llvm::hlsl::rootsig::Register> Reg;
std::optional<float> MipLODBias;
std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressU;
+ std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressV;
+ std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressW;
std::optional<uint32_t> MaxAnisotropy;
std::optional<float> MinLOD;
std::optional<float> MaxLOD;
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 660bd7dd147ba..e9373f9a82beb 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -380,6 +380,12 @@ std::optional<StaticSampler> RootSignatureParser::parseStaticSampler() {
if (Params->AddressU.has_value())
Sampler.AddressU = Params->AddressU.value();
+ if (Params->AddressV.has_value())
+ Sampler.AddressV = Params->AddressV.value();
+
+ if (Params->AddressW.has_value())
+ Sampler.AddressW = Params->AddressW.value();
+
if (Params->MipLODBias.has_value())
Sampler.MipLODBias = Params->MipLODBias.value();
@@ -695,6 +701,40 @@ RootSignatureParser::parseStaticSamplerParams() {
Params.AddressU = AddressU;
}
+ // `addressV` `=` TEXTURE_ADDRESS
+ if (tryConsumeExpectedToken(TokenKind::kw_addressV)) {
+ if (Params.AddressV.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ auto AddressV = parseTextureAddressMode();
+ if (!AddressV.has_value())
+ return std::nullopt;
+ Params.AddressV = AddressV;
+ }
+
+ // `addressW` `=` TEXTURE_ADDRESS
+ if (tryConsumeExpectedToken(TokenKind::kw_addressW)) {
+ if (Params.AddressW.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ auto AddressW = parseTextureAddressMode();
+ if (!AddressW.has_value())
+ return std::nullopt;
+ Params.AddressW = AddressW;
+ }
+
// `mipLODBias` `=` NUMBER
if (tryConsumeExpectedToken(TokenKind::kw_mipLODBias)) {
if (Params.MipLODBias.has_value()) {
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 7636171004e70..06c8a3d05312f 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -228,6 +228,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
StaticSampler(s0),
StaticSampler(s0, maxAnisotropy = 3,
minLOD = 4.2f, mipLODBias = 0.23e+3,
+ addressW = TEXTURE_ADDRESS_CLAMP,
+ addressV = TEXTURE_ADDRESS_BORDER,
maxLOD = 9000, addressU = TEXTURE_ADDRESS_MIRROR
)
)cc";
@@ -253,6 +255,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU, TextureAddressMode::Wrap);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressV, TextureAddressMode::Wrap);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressW, TextureAddressMode::Wrap);
ASSERT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 16u);
@@ -265,6 +269,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU, TextureAddressMode::Mirror);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressV, TextureAddressMode::Border);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).AddressW, TextureAddressMode::Clamp);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 230.f);
ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 3u);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 4.2f);
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index ed3f20ded585b..bb0a0d158a980 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -166,6 +166,8 @@ raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause);
struct StaticSampler {
Register Reg;
TextureAddressMode AddressU = TextureAddressMode::Wrap;
+ TextureAddressMode AddressV = TextureAddressMode::Wrap;
+ TextureAddressMode AddressW = TextureAddressMode::Wrap;
float MipLODBias = 0.f;
uint32_t MaxAnisotropy = 16;
float MinLOD = 0.f;
>From 654e8c42f83e9d23aa1cf18e92bec2f89d76c2d4 Mon Sep 17 00:00:00 2001
From: Finn Plummer <finn.c.plum at gmail.com>
Date: Thu, 29 May 2025 15:03:30 -0700
Subject: [PATCH 4/4] self-review: fix typo
---
clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 06c8a3d05312f..6477b25550c4d 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -257,7 +257,6 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_EQ(std::get<StaticSampler>(Elem).AddressU, TextureAddressMode::Wrap);
ASSERT_EQ(std::get<StaticSampler>(Elem).AddressV, TextureAddressMode::Wrap);
ASSERT_EQ(std::get<StaticSampler>(Elem).AddressW, TextureAddressMode::Wrap);
- ASSERT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MipLODBias, 0.f);
ASSERT_EQ(std::get<StaticSampler>(Elem).MaxAnisotropy, 16u);
ASSERT_FLOAT_EQ(std::get<StaticSampler>(Elem).MinLOD, 0.f);
More information about the cfe-commits
mailing list