[llvm] b5d5708 - [HLSL] Add descriptor table metadata parsing (#142492)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 20 12:12:05 PDT 2025
Author: joaosaffran
Date: 2025-06-20T12:12:02-07:00
New Revision: b5d5708128e99f69add50c322bfbed5f4905c23d
URL: https://github.com/llvm/llvm-project/commit/b5d5708128e99f69add50c322bfbed5f4905c23d
DIFF: https://github.com/llvm/llvm-project/commit/b5d5708128e99f69add50c322bfbed5f4905c23d.diff
LOG: [HLSL] Add descriptor table metadata parsing (#142492)
Implements descriptor table parsing from root signature metadata. This
is required to support root signatures in hlsl.
Closes: #[126640](https://github.com/llvm/llvm-project/issues/126640)
---------
Co-authored-by: joaosaffran <joao.saffran at microsoft.com>
Added:
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinations.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-Flag.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RangeType.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RegisterSpace.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
Modified:
llvm/include/llvm/BinaryFormat/DXContainer.h
llvm/include/llvm/BinaryFormat/DXContainerConstants.def
llvm/lib/Target/DirectX/DXILRootSignature.cpp
llvm/lib/Target/DirectX/DXILRootSignature.h
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 6d625dad5853f..56c9e53308674 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -13,6 +13,7 @@
#ifndef LLVM_BINARYFORMAT_DXCONTAINER_H
#define LLVM_BINARYFORMAT_DXCONTAINER_H
+#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Error.h"
@@ -40,6 +41,8 @@ template <typename T> struct EnumEntry;
namespace dxbc {
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
inline Triple::EnvironmentType getShaderStage(uint32_t Kind) {
assert(Kind <= Triple::Amplification - Triple::Pixel &&
"Shader kind out of expected range.");
@@ -167,6 +170,8 @@ enum class RootDescriptorFlag : uint32_t {
#define DESCRIPTOR_RANGE_FLAG(Num, Val) Val = Num,
enum class DescriptorRangeFlag : uint32_t {
#include "DXContainerConstants.def"
+
+ LLVM_MARK_AS_BITMASK_ENUM(DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS)
};
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 18e79e6fa65a5..a281256a44ae0 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -99,6 +99,16 @@ DESCRIPTOR_RANGE_FLAG(0x10000, DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS)
#undef DESCRIPTOR_RANGE_FLAG
#endif // DESCRIPTOR_RANGE_FLAG
+// DESCRIPTOR_RANGE(value, name).
+#ifdef DESCRIPTOR_RANGE
+
+DESCRIPTOR_RANGE(0, SRV)
+DESCRIPTOR_RANGE(1, UAV)
+DESCRIPTOR_RANGE(2, CBV)
+DESCRIPTOR_RANGE(3, Sampler)
+#undef DESCRIPTOR_RANGE
+#endif // DESCRIPTOR_RANGE
+
#ifdef ROOT_PARAMETER
ROOT_PARAMETER(0, DescriptorTable)
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.cpp b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
index 88914a31f46e1..1f175fd4ecd99 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.cpp
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.cpp
@@ -174,6 +174,93 @@ static bool parseRootDescriptors(LLVMContext *Ctx,
return false;
}
+static bool parseDescriptorRange(LLVMContext *Ctx,
+ mcdxbc::DescriptorTable &Table,
+ MDNode *RangeDescriptorNode) {
+
+ if (RangeDescriptorNode->getNumOperands() != 6)
+ return reportError(Ctx, "Invalid format for Descriptor Range");
+
+ dxbc::RTS0::v2::DescriptorRange Range;
+
+ std::optional<StringRef> ElementText =
+ extractMdStringValue(RangeDescriptorNode, 0);
+
+ if (!ElementText.has_value())
+ return reportError(Ctx, "Descriptor Range, first element is not a string.");
+
+ Range.RangeType =
+ StringSwitch<uint32_t>(*ElementText)
+ .Case("CBV", llvm::to_underlying(dxbc::DescriptorRangeType::CBV))
+ .Case("SRV", llvm::to_underlying(dxbc::DescriptorRangeType::SRV))
+ .Case("UAV", llvm::to_underlying(dxbc::DescriptorRangeType::UAV))
+ .Case("Sampler",
+ llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
+ .Default(~0U);
+
+ if (Range.RangeType == ~0U)
+ return reportError(Ctx, "Invalid Descriptor Range type: " + *ElementText);
+
+ if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))
+ Range.NumDescriptors = *Val;
+ else
+ return reportError(Ctx, "Invalid value for Number of Descriptor in Range");
+
+ if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 2))
+ Range.BaseShaderRegister = *Val;
+ else
+ return reportError(Ctx, "Invalid value for BaseShaderRegister");
+
+ if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 3))
+ Range.RegisterSpace = *Val;
+ else
+ return reportError(Ctx, "Invalid value for RegisterSpace");
+
+ if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 4))
+ Range.OffsetInDescriptorsFromTableStart = *Val;
+ else
+ return reportError(Ctx,
+ "Invalid value for OffsetInDescriptorsFromTableStart");
+
+ if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 5))
+ Range.Flags = *Val;
+ else
+ return reportError(Ctx, "Invalid value for Descriptor Range Flags");
+
+ Table.Ranges.push_back(Range);
+ return false;
+}
+
+static bool parseDescriptorTable(LLVMContext *Ctx,
+ mcdxbc::RootSignatureDesc &RSD,
+ MDNode *DescriptorTableNode) {
+ const unsigned int NumOperands = DescriptorTableNode->getNumOperands();
+ if (NumOperands < 2)
+ return reportError(Ctx, "Invalid format for Descriptor Table");
+
+ dxbc::RTS0::v1::RootParameterHeader Header;
+ if (std::optional<uint32_t> Val = extractMdIntValue(DescriptorTableNode, 1))
+ Header.ShaderVisibility = *Val;
+ else
+ return reportError(Ctx, "Invalid value for ShaderVisibility");
+
+ mcdxbc::DescriptorTable Table;
+ Header.ParameterType =
+ llvm::to_underlying(dxbc::RootParameterType::DescriptorTable);
+
+ for (unsigned int I = 2; I < NumOperands; I++) {
+ MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));
+ if (Element == nullptr)
+ return reportError(Ctx, "Missing Root Element Metadata Node.");
+
+ if (parseDescriptorRange(Ctx, Table, Element))
+ return true;
+ }
+
+ RSD.ParametersContainer.addParameter(Header, Table);
+ return false;
+}
+
static bool parseRootSignatureElement(LLVMContext *Ctx,
mcdxbc::RootSignatureDesc &RSD,
MDNode *Element) {
@@ -188,6 +275,7 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
.Case("RootCBV", RootSignatureElementKind::CBV)
.Case("RootSRV", RootSignatureElementKind::SRV)
.Case("RootUAV", RootSignatureElementKind::UAV)
+ .Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)
.Default(RootSignatureElementKind::Error);
switch (ElementKind) {
@@ -200,6 +288,8 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
case RootSignatureElementKind::SRV:
case RootSignatureElementKind::UAV:
return parseRootDescriptors(Ctx, RSD, Element, ElementKind);
+ case RootSignatureElementKind::DescriptorTable:
+ return parseDescriptorTable(Ctx, RSD, Element);
case RootSignatureElementKind::Error:
return reportError(Ctx, "Invalid Root Signature Element: " + *ElementText);
}
@@ -241,6 +331,81 @@ static bool verifyRegisterSpace(uint32_t RegisterSpace) {
static bool verifyDescriptorFlag(uint32_t Flags) { return (Flags & ~0xE) == 0; }
+static bool verifyRangeType(uint32_t Type) {
+ switch (Type) {
+ case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
+ case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
+ case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
+ case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler):
+ return true;
+ };
+
+ return false;
+}
+
+static bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
+ uint32_t FlagsVal) {
+ using FlagT = dxbc::DescriptorRangeFlag;
+ FlagT Flags = FlagT(FlagsVal);
+
+ const bool IsSampler =
+ (Type == llvm::to_underlying(dxbc::DescriptorRangeType::Sampler));
+
+ if (Version == 1) {
+ // Since the metadata is unversioned, we expect to explicitly see the values
+ // that map to the version 1 behaviour here.
+ if (IsSampler)
+ return Flags == FlagT::DESCRIPTORS_VOLATILE;
+ return Flags == (FlagT::DATA_VOLATILE | FlagT::DESCRIPTORS_VOLATILE);
+ }
+
+ // The data-specific flags are mutually exclusive.
+ FlagT DataFlags = FlagT::DATA_VOLATILE | FlagT::DATA_STATIC |
+ FlagT::DATA_STATIC_WHILE_SET_AT_EXECUTE;
+
+ if (popcount(llvm::to_underlying(Flags & DataFlags)) > 1)
+ return false;
+
+ // The descriptor-specific flags are mutually exclusive.
+ FlagT DescriptorFlags =
+ FlagT::DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS |
+ FlagT::DESCRIPTORS_VOLATILE;
+ if (popcount(llvm::to_underlying(Flags & DescriptorFlags)) > 1)
+ return false;
+
+ // For volatile descriptors, DATA_STATIC is never valid.
+ if ((Flags & FlagT::DESCRIPTORS_VOLATILE) == FlagT::DESCRIPTORS_VOLATILE) {
+ FlagT Mask = FlagT::DESCRIPTORS_VOLATILE;
+ if (!IsSampler) {
+ Mask |= FlagT::DATA_VOLATILE;
+ Mask |= FlagT::DATA_STATIC_WHILE_SET_AT_EXECUTE;
+ }
+ return (Flags & ~Mask) == FlagT::NONE;
+ }
+
+ // For "STATIC_KEEPING_BUFFER_BOUNDS_CHECKS" descriptors,
+ // the other data-specific flags may all be set.
+ if ((Flags & FlagT::DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS) ==
+ FlagT::DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS) {
+ FlagT Mask = FlagT::DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS;
+ if (!IsSampler) {
+ Mask |= FlagT::DATA_VOLATILE;
+ Mask |= FlagT::DATA_STATIC;
+ Mask |= FlagT::DATA_STATIC_WHILE_SET_AT_EXECUTE;
+ }
+ return (Flags & ~Mask) == FlagT::NONE;
+ }
+
+ // When no descriptor flag is set, any data flag is allowed.
+ FlagT Mask = FlagT::NONE;
+ if (!IsSampler) {
+ Mask |= FlagT::DATA_VOLATILE;
+ Mask |= FlagT::DATA_STATIC;
+ Mask |= FlagT::DATA_STATIC_WHILE_SET_AT_EXECUTE;
+ }
+ return (Flags & ~Mask) == FlagT::NONE;
+}
+
static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
if (!verifyVersion(RSD.Version)) {
@@ -275,7 +440,23 @@ static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
if (RSD.Version > 1) {
if (!verifyDescriptorFlag(Descriptor.Flags))
- return reportValueError(Ctx, "DescriptorFlag", Descriptor.Flags);
+ return reportValueError(Ctx, "DescriptorRangeFlag", Descriptor.Flags);
+ }
+ break;
+ }
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+ const mcdxbc::DescriptorTable &Table =
+ RSD.ParametersContainer.getDescriptorTable(Info.Location);
+ for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) {
+ if (!verifyRangeType(Range.RangeType))
+ return reportValueError(Ctx, "RangeType", Range.RangeType);
+
+ if (!verifyRegisterSpace(Range.RegisterSpace))
+ return reportValueError(Ctx, "RegisterSpace", Range.RegisterSpace);
+
+ if (!verifyDescriptorRangeFlag(RSD.Version, Range.RangeType,
+ Range.Flags))
+ return reportValueError(Ctx, "DescriptorFlag", Range.Flags);
}
break;
}
@@ -388,43 +569,33 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
OS << "Root Signature Definitions"
<< "\n";
- uint8_t Space = 0;
for (const Function &F : M) {
auto It = RSDMap.find(&F);
if (It == RSDMap.end())
continue;
const auto &RS = It->second;
OS << "Definition for '" << F.getName() << "':\n";
-
// 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) << "RootParametersOffset: " << RS.RootParameterOffset
- << "\n";
- OS << indent(Space) << "NumParameters: " << RS.ParametersContainer.size()
- << "\n";
- Space++;
+ OS << "Flags: " << format_hex(RS.Flags, 8) << "\n"
+ << "Version: " << RS.Version << "\n"
+ << "RootParametersOffset: " << RS.RootParameterOffset << "\n"
+ << "NumParameters: " << RS.ParametersContainer.size() << "\n";
for (size_t I = 0; I < RS.ParametersContainer.size(); I++) {
const auto &[Type, Loc] =
RS.ParametersContainer.getTypeAndLocForParameter(I);
const dxbc::RTS0::v1::RootParameterHeader Header =
RS.ParametersContainer.getHeader(I);
- OS << indent(Space) << "- Parameter Type: " << Type << "\n";
- OS << indent(Space + 2)
- << "Shader Visibility: " << Header.ShaderVisibility << "\n";
+ OS << "- Parameter Type: " << Type << "\n"
+ << " Shader Visibility: " << Header.ShaderVisibility << "\n";
switch (Type) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit): {
const dxbc::RTS0::v1::RootConstants &Constants =
RS.ParametersContainer.getConstant(Loc);
- OS << indent(Space + 2) << "Register Space: " << Constants.RegisterSpace
- << "\n";
- OS << indent(Space + 2)
- << "Shader Register: " << Constants.ShaderRegister << "\n";
- OS << indent(Space + 2)
- << "Num 32 Bit Values: " << Constants.Num32BitValues << "\n";
+ OS << " Register Space: " << Constants.RegisterSpace << "\n"
+ << " Shader Register: " << Constants.ShaderRegister << "\n"
+ << " Num 32 Bit Values: " << Constants.Num32BitValues << "\n";
break;
}
case llvm::to_underlying(dxbc::RootParameterType::CBV):
@@ -432,23 +603,33 @@ PreservedAnalyses RootSignatureAnalysisPrinter::run(Module &M,
case llvm::to_underlying(dxbc::RootParameterType::SRV): {
const dxbc::RTS0::v2::RootDescriptor &Descriptor =
RS.ParametersContainer.getRootDescriptor(Loc);
- OS << indent(Space + 2)
- << "Register Space: " << Descriptor.RegisterSpace << "\n";
- OS << indent(Space + 2)
- << "Shader Register: " << Descriptor.ShaderRegister << "\n";
+ OS << " Register Space: " << Descriptor.RegisterSpace << "\n"
+ << " Shader Register: " << Descriptor.ShaderRegister << "\n";
if (RS.Version > 1)
- OS << indent(Space + 2) << "Flags: " << Descriptor.Flags << "\n";
+ OS << " Flags: " << Descriptor.Flags << "\n";
+ break;
+ }
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+ const mcdxbc::DescriptorTable &Table =
+ RS.ParametersContainer.getDescriptorTable(Loc);
+ OS << " NumRanges: " << Table.Ranges.size() << "\n";
+
+ for (const dxbc::RTS0::v2::DescriptorRange Range : Table) {
+ OS << " - Range Type: " << Range.RangeType << "\n"
+ << " Register Space: " << Range.RegisterSpace << "\n"
+ << " Base Shader Register: " << Range.BaseShaderRegister << "\n"
+ << " Num Descriptors: " << Range.NumDescriptors << "\n"
+ << " Offset In Descriptors From Table Start: "
+ << Range.OffsetInDescriptorsFromTableStart << "\n";
+ if (RS.Version > 1)
+ OS << " Flags: " << Range.Flags << "\n";
+ }
break;
}
}
- Space--;
}
- OS << indent(Space) << "NumStaticSamplers: " << 0 << "\n";
- OS << indent(Space) << "StaticSamplersOffset: " << RS.StaticSamplersOffset
- << "\n";
-
- Space--;
- // end root signature header
+ OS << "NumStaticSamplers: " << 0 << "\n";
+ OS << "StaticSamplersOffset: " << RS.StaticSamplersOffset << "\n";
}
return PreservedAnalyses::all();
}
diff --git a/llvm/lib/Target/DirectX/DXILRootSignature.h b/llvm/lib/Target/DirectX/DXILRootSignature.h
index 3f25551b2b5ef..b45cebc15fd39 100644
--- a/llvm/lib/Target/DirectX/DXILRootSignature.h
+++ b/llvm/lib/Target/DirectX/DXILRootSignature.h
@@ -31,6 +31,7 @@ enum class RootSignatureElementKind {
SRV = 3,
UAV = 4,
CBV = 5,
+ DescriptorTable = 6,
};
class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
friend AnalysisInfoMixin<RootSignatureAnalysis>;
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinations.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinations.ll
new file mode 100644
index 0000000000000..8eb7f90c6b757
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinations.ll
@@ -0,0 +1,157 @@
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+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, i32 2 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"DescriptorTable", i32 0, !6, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20 }
+
+; typedef enum D3D12_DESCRIPTOR_RANGE_FLAGS {
+; NONE = 0,
+; DESCRIPTORS_VOLATILE = 0x1,
+; DATA_VOLATILE = 0x2,
+; DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
+; DATA_STATIC = 0x8,
+; DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS = 0x10000
+; } ;
+
+;0
+!6 = !{ !"Sampler", i32 1, i32 0, i32 1, i32 -1, i32 0 }
+;DESCRIPTORS_VOLATILE
+!8 = !{ !"Sampler", i32 1, i32 0, i32 3, i32 -1, i32 1 }
+;DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS
+!9 = !{ !"Sampler", i32 1, i32 0, i32 4, i32 -1, i32 65536 }
+;0
+!10 = !{ !"SRV", i32 1, i32 0, i32 5, i32 -1, i32 1 }
+;DESCRIPTORS_VOLATILE
+!11 = !{ !"UAV", i32 5, i32 1, i32 6, i32 5, i32 1 }
+;DATA_VOLATILE
+!12 = !{ !"CBV", i32 5, i32 1, i32 7, i32 5, i32 2 }
+;DATA_STATIC
+!13 = !{ !"SRV", i32 5, i32 1, i32 8, i32 5, i32 8 }
+;DATA_STATIC_WHILE_SET_AT_EXECUTE
+!14 = !{ !"UAV", i32 5, i32 1, i32 9, i32 5, i32 4 }
+;DESCRIPTORS_VOLATILE | DATA_VOLATILE
+!15 = !{ !"CBV", i32 5, i32 1, i32 10, i32 5, i32 3 }
+;DESCRIPTORS_VOLATILE | DATA_STATIC_WHILE_SET_AT_EXECUTE
+!16 = !{ !"SRV", i32 5, i32 1, i32 11, i32 5, i32 5 }
+;DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS
+!17 = !{ !"UAV", i32 5, i32 1, i32 12, i32 5, i32 65536 }
+;DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS | DATA_VOLATILE
+!18 = !{ !"CBV", i32 5, i32 1, i32 13, i32 5, i32 65538 }
+;DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS | DATA_STATIC
+!19 = !{ !"SRV", i32 5, i32 1, i32 14, i32 5, i32 65544 }
+;DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS | DATA_STATIC_WHILE_SET_AT_EXECUTE
+!20 = !{ !"UAV", i32 5, i32 1, i32 15, i32 5, i32 65540 }
+
+;DXC:- Name: RTS0
+;DXC-NEXT: Size: 380
+;DXC-NEXT: RootSignature:
+;DXC-NEXT: Version: 2
+;DXC-NEXT: NumRootParameters: 1
+;DXC-NEXT: RootParametersOffset: 24
+;DXC-NEXT: NumStaticSamplers: 0
+;DXC-NEXT: StaticSamplersOffset: 0
+;DXC-NEXT: Parameters:
+;DXC-NEXT: - ParameterType: 0
+;DXC-NEXT: ShaderVisibility: 0
+;DXC-NEXT: Table:
+;DXC-NEXT: NumRanges: 14
+;DXC-NEXT: RangesOffset: 44
+;DXC-NEXT: Ranges:
+;DXC-NEXT: - RangeType: 3
+;DXC-NEXT: NumDescriptors: 1
+;DXC-NEXT: BaseShaderRegister: 0
+;DXC-NEXT: RegisterSpace: 1
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+;DXC-NEXT: - RangeType: 3
+;DXC-NEXT: NumDescriptors: 1
+;DXC-NEXT: BaseShaderRegister: 0
+;DXC-NEXT: RegisterSpace: 3
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+;DXC-NEXT: DESCRIPTORS_VOLATILE: true
+;DXC-NEXT: - RangeType: 3
+;DXC-NEXT: NumDescriptors: 1
+;DXC-NEXT: BaseShaderRegister: 0
+;DXC-NEXT: RegisterSpace: 4
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+;DXC-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+;DXC-NEXT: - RangeType: 0
+;DXC-NEXT: NumDescriptors: 1
+;DXC-NEXT: BaseShaderRegister: 0
+;DXC-NEXT: RegisterSpace: 5
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+;DXC-NEXT: DESCRIPTORS_VOLATILE: true
+;DXC-NEXT: - RangeType: 1
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 6
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DESCRIPTORS_VOLATILE: true
+;DXC-NEXT: - RangeType: 2
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 7
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_VOLATILE: true
+;DXC-NEXT: - RangeType: 0
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 8
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_STATIC: true
+;DXC-NEXT: - RangeType: 1
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 9
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+;DXC-NEXT: - RangeType: 2
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 10
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DESCRIPTORS_VOLATILE: true
+;DXC-NEXT: DATA_VOLATILE: true
+;DXC-NEXT: - RangeType: 0
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 11
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DESCRIPTORS_VOLATILE: true
+;DXC-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+;DXC-NEXT: - RangeType: 1
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 12
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+;DXC-NEXT: - RangeType: 2
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 13
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_VOLATILE: true
+;DXC-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+;DXC-NEXT: - RangeType: 0
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 14
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_STATIC: true
+;DXC-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+;DXC-NEXT: - RangeType: 1
+;DXC-NEXT: NumDescriptors: 5
+;DXC-NEXT: BaseShaderRegister: 1
+;DXC-NEXT: RegisterSpace: 15
+;DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+;DXC-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+;DXC-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
new file mode 100644
index 0000000000000..9d89dbdd9107b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-AllValidFlagCombinationsV1.ll
@@ -0,0 +1,44 @@
+; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+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, i32 1 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
+!6 = !{ !"Sampler", i32 0, i32 1, i32 0, i32 -1, i32 1 }
+!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 3 }
+
+
+; DXC: - Name: RTS0
+; DXC-NEXT: Size: 84
+; DXC-NEXT: RootSignature:
+; DXC-NEXT: Version: 1
+; DXC-NEXT: NumRootParameters: 1
+; DXC-NEXT: RootParametersOffset: 24
+; DXC-NEXT: NumStaticSamplers: 0
+; DXC-NEXT: StaticSamplersOffset: 0
+; DXC-NEXT: Parameters:
+; DXC-NEXT: - ParameterType: 0
+; DXC-NEXT: ShaderVisibility: 0
+; DXC-NEXT: Table:
+; DXC-NEXT: NumRanges: 2
+; DXC-NEXT: RangesOffset: 44
+; DXC-NEXT: Ranges:
+; DXC-NEXT: - RangeType: 3
+; DXC-NEXT: NumDescriptors: 0
+; DXC-NEXT: BaseShaderRegister: 1
+; DXC-NEXT: RegisterSpace: 0
+; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+; DXC-NEXT: - RangeType: 1
+; DXC-NEXT: NumDescriptors: 5
+; DXC-NEXT: BaseShaderRegister: 1
+; DXC-NEXT: RegisterSpace: 10
+; DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-Flag.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-Flag.ll
new file mode 100644
index 0000000000000..41101c1f1fe8e
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-Flag.ll
@@ -0,0 +1,20 @@
+; 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 DescriptorFlag: 22
+; 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 = !{ !"DescriptorTable", i32 0, !6, !7 }
+!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 22 }
+!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RangeType.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RangeType.ll
new file mode 100644
index 0000000000000..b7e99ae7cd27b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RangeType.ll
@@ -0,0 +1,20 @@
+; 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 Descriptor Range type: Invalid
+; 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 = !{ !"DescriptorTable", i32 0, !6, !7 }
+!6 = !{ !"Invalid", i32 0, i32 0, i32 -1, i32 -1, i32 4 }
+!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RegisterSpace.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RegisterSpace.ll
new file mode 100644
index 0000000000000..4cef5d86a980b
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable-Invalid-RegisterSpace.ll
@@ -0,0 +1,20 @@
+; 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: 4294967280
+; 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 = !{ !"DescriptorTable", i32 0, !6, !7 }
+!6 = !{ !"SRV", i32 0, i32 0, i32 10, i32 -1, i32 4 }
+!7 = !{ !"UAV", i32 5, i32 1, i32 4294967280, i32 5, i32 2 }
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
new file mode 100644
index 0000000000000..b516d66180247
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-DescriptorTable.ll
@@ -0,0 +1,48 @@
+; 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 [92 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, i32 2 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"DescriptorTable", i32 0, !6, !7 }
+!6 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 }
+!7 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
+
+; DXC: - Name: RTS0
+; DXC-NEXT: Size: 92
+; DXC-NEXT: RootSignature:
+; DXC-NEXT: Version: 2
+; DXC-NEXT: NumRootParameters: 1
+; DXC-NEXT: RootParametersOffset: 24
+; DXC-NEXT: NumStaticSamplers: 0
+; DXC-NEXT: StaticSamplersOffset: 0
+; DXC-NEXT: Parameters:
+; DXC-NEXT: - ParameterType: 0
+; DXC-NEXT: ShaderVisibility: 0
+; DXC-NEXT: Table:
+; DXC-NEXT: NumRanges: 2
+; DXC-NEXT: RangesOffset: 44
+; DXC-NEXT: Ranges:
+; DXC-NEXT: - RangeType: 0
+; DXC-NEXT: NumDescriptors: 0
+; DXC-NEXT: BaseShaderRegister: 1
+; DXC-NEXT: RegisterSpace: 0
+; DXC-NEXT: OffsetInDescriptorsFromTableStart: 4294967295
+; DXC-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+; DXC-NEXT: - RangeType: 1
+; DXC-NEXT: NumDescriptors: 5
+; DXC-NEXT: BaseShaderRegister: 1
+; DXC-NEXT: RegisterSpace: 10
+; DXC-NEXT: OffsetInDescriptorsFromTableStart: 5
+; DXC-NEXT: DATA_VOLATILE: true
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
index 80aa757d7e10a..d0a58bc34ffa4 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Parameters.ll
@@ -12,16 +12,19 @@ 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 = !{ !4, !5, !6 } ; list of root signature elements
+!3 = !{ !4, !5, !6, !7 } ; 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 }
!6 = !{ !"RootSRV", i32 1, i32 4, i32 5, i32 6 }
+!7 = !{ !"DescriptorTable", i32 0, !8, !9 }
+!8 = !{ !"SRV", i32 0, i32 1, i32 0, i32 -1, i32 4 }
+!9 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 }
;CHECK-LABEL: Definition for 'main':
;CHECK-NEXT: Flags: 0x000001
;CHECK-NEXT: Version: 2
;CHECK-NEXT: RootParametersOffset: 24
-;CHECK-NEXT: NumParameters: 2
+;CHECK-NEXT: NumParameters: 3
;CHECK-NEXT: - Parameter Type: 1
;CHECK-NEXT: Shader Visibility: 0
;CHECK-NEXT: Register Space: 2
@@ -32,5 +35,20 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
;CHECK-NEXT: Register Space: 5
;CHECK-NEXT: Shader Register: 4
;CHECK-NEXT: Flags: 6
+;CHECK-NEXT: - Parameter Type: 0
+;CHECK-NEXT: Shader Visibility: 0
+;CHECK-NEXT: NumRanges: 2
+;CHECK-NEXT: - Range Type: 0
+;CHECK-NEXT: Register Space: 0
+;CHECK-NEXT: Base Shader Register: 1
+;CHECK-NEXT: Num Descriptors: 0
+;CHECK-NEXT: Offset In Descriptors From Table Start: 4294967295
+;CHECK-NEXT: Flags: 4
+;CHECK-NEXT: - Range Type: 1
+;CHECK-NEXT: Register Space: 10
+;CHECK-NEXT: Base Shader Register: 1
+;CHECK-NEXT: Num Descriptors: 5
+;CHECK-NEXT: Offset In Descriptors From Table Start: 5
+;CHECK-NEXT: Flags: 2
;CHECK-NEXT: NumStaticSamplers: 0
;CHECK-NEXT: StaticSamplersOffset: 0
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags.ll
index 6c90bcb09b64b..7ee04710be0ae 100644
--- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags.ll
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-RootDescriptor-Invalid-Flags.ll
@@ -3,7 +3,7 @@
target triple = "dxil-unknown-shadermodel6.0-compute"
-; CHECK: error: Invalid value for DescriptorFlag: 3
+; CHECK: error: Invalid value for DescriptorRangeFlag: 3
; CHECK-NOT: Root Signature Definitions
define void @main() #0 {
entry:
More information about the llvm-commits
mailing list