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 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 ElementText = + extractMdStringValue(RangeDescriptorNode, 0); + + if (!ElementText.has_value()) + return reportError(Ctx, "Descriptor Range, first element is not a string."); + + Range.RangeType = + StringSwitch(*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 Val = extractMdIntValue(RangeDescriptorNode, 1)) + Range.NumDescriptors = *Val; + else + return reportError(Ctx, "Invalid value for Number of Descriptor in Range"); + + if (std::optional Val = extractMdIntValue(RangeDescriptorNode, 2)) + Range.BaseShaderRegister = *Val; + else + return reportError(Ctx, "Invalid value for BaseShaderRegister"); + + if (std::optional Val = extractMdIntValue(RangeDescriptorNode, 3)) + Range.RegisterSpace = *Val; + else + return reportError(Ctx, "Invalid value for RegisterSpace"); + + if (std::optional Val = extractMdIntValue(RangeDescriptorNode, 4)) + Range.OffsetInDescriptorsFromTableStart = *Val; + else + return reportError(Ctx, + "Invalid value for OffsetInDescriptorsFromTableStart"); + + if (std::optional 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 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(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 { friend AnalysisInfoMixin; 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' %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' %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' %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: