diff options
Diffstat (limited to 'llvm/lib/Frontend/HLSL')
-rw-r--r-- | llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp | 136 |
3 files changed, 22 insertions, 194 deletions
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp index 78c20a6..574883e 100644 --- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp +++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp @@ -18,24 +18,6 @@ namespace hlsl { namespace rootsig { template <typename T> -static std::optional<StringRef> getEnumName(const T Value, - ArrayRef<EnumEntry<T>> Enums) { - for (const auto &EnumItem : Enums) - if (EnumItem.Value == Value) - return EnumItem.Name; - return std::nullopt; -} - -template <typename T> -static raw_ostream &printEnum(raw_ostream &OS, const T Value, - ArrayRef<EnumEntry<T>> Enums) { - auto MaybeName = getEnumName(Value, Enums); - if (MaybeName) - OS << *MaybeName; - return OS; -} - -template <typename T> static raw_ostream &printFlags(raw_ostream &OS, const T Value, ArrayRef<EnumEntry<T>> Flags) { bool FlagSet = false; @@ -46,9 +28,9 @@ static raw_ostream &printFlags(raw_ostream &OS, const T Value, if (FlagSet) OS << " | "; - auto MaybeFlag = getEnumName(T(Bit), Flags); - if (MaybeFlag) - OS << *MaybeFlag; + StringRef MaybeFlag = enumToStringRef(T(Bit), Flags); + if (!MaybeFlag.empty()) + OS << MaybeFlag; else OS << "invalid: " << Bit; @@ -70,57 +52,49 @@ static const EnumEntry<RegisterType> RegisterNames[] = { }; static raw_ostream &operator<<(raw_ostream &OS, const Register &Reg) { - printEnum(OS, Reg.ViewType, ArrayRef(RegisterNames)); - OS << Reg.Number; + OS << enumToStringRef(Reg.ViewType, ArrayRef(RegisterNames)) << Reg.Number; return OS; } static raw_ostream &operator<<(raw_ostream &OS, const llvm::dxbc::ShaderVisibility &Visibility) { - printEnum(OS, Visibility, dxbc::getShaderVisibility()); + OS << enumToStringRef(Visibility, dxbc::getShaderVisibility()); return OS; } static raw_ostream &operator<<(raw_ostream &OS, const llvm::dxbc::SamplerFilter &Filter) { - printEnum(OS, Filter, dxbc::getSamplerFilters()); + OS << enumToStringRef(Filter, dxbc::getSamplerFilters()); return OS; } static raw_ostream &operator<<(raw_ostream &OS, const dxbc::TextureAddressMode &Address) { - printEnum(OS, Address, dxbc::getTextureAddressModes()); + OS << enumToStringRef(Address, dxbc::getTextureAddressModes()); return OS; } static raw_ostream &operator<<(raw_ostream &OS, const dxbc::ComparisonFunc &CompFunc) { - printEnum(OS, CompFunc, dxbc::getComparisonFuncs()); + OS << enumToStringRef(CompFunc, dxbc::getComparisonFuncs()); return OS; } static raw_ostream &operator<<(raw_ostream &OS, const dxbc::StaticBorderColor &BorderColor) { - printEnum(OS, BorderColor, dxbc::getStaticBorderColors()); + OS << enumToStringRef(BorderColor, dxbc::getStaticBorderColors()); return OS; } -static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = { - {"CBV", dxil::ResourceClass::CBuffer}, - {"SRV", dxil::ResourceClass::SRV}, - {"UAV", dxil::ResourceClass::UAV}, - {"Sampler", dxil::ResourceClass::Sampler}, -}; - static raw_ostream &operator<<(raw_ostream &OS, const ClauseType &Type) { - printEnum(OS, dxil::ResourceClass(llvm::to_underlying(Type)), - ArrayRef(ResourceClassNames)); + OS << enumToStringRef(dxil::ResourceClass(llvm::to_underlying(Type)), + dxbc::getResourceClasses()); return OS; } diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 6d89fa7..1cda308 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -51,20 +51,6 @@ static std::optional<StringRef> extractMdStringValue(MDNode *Node, return NodeText->getString(); } -static const EnumEntry<dxil::ResourceClass> ResourceClassNames[] = { - {"CBV", dxil::ResourceClass::CBuffer}, - {"SRV", dxil::ResourceClass::SRV}, - {"UAV", dxil::ResourceClass::UAV}, - {"Sampler", dxil::ResourceClass::Sampler}, -}; - -static std::optional<StringRef> getResourceName(dxil::ResourceClass Class) { - for (const auto &ClassEnum : ResourceClassNames) - if (ClassEnum.Value == Class) - return ClassEnum.Name; - return std::nullopt; -} - namespace { // We use the OverloadVisit with std::visit to ensure the compiler catches if a @@ -133,10 +119,11 @@ MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) { MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) { IRBuilder<> Builder(Ctx); - std::optional<StringRef> ResName = - getResourceName(dxil::ResourceClass(to_underlying(Descriptor.Type))); - assert(ResName && "Provided an invalid Resource Class"); - SmallString<7> Name({"Root", *ResName}); + StringRef ResName = + enumToStringRef(dxil::ResourceClass(to_underlying(Descriptor.Type)), + dxbc::getResourceClasses()); + assert(!ResName.empty() && "Provided an invalid Resource Class"); + SmallString<7> Name({"Root", ResName}); Metadata *Operands[] = { MDString::get(Ctx, Name), ConstantAsMetadata::get( @@ -174,11 +161,12 @@ MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) { MDNode *MetadataBuilder::BuildDescriptorTableClause( const DescriptorTableClause &Clause) { IRBuilder<> Builder(Ctx); - std::optional<StringRef> ResName = - getResourceName(dxil::ResourceClass(to_underlying(Clause.Type))); - assert(ResName && "Provided an invalid Resource Class"); + StringRef ResName = + enumToStringRef(dxil::ResourceClass(to_underlying(Clause.Type)), + dxbc::getResourceClasses()); + assert(!ResName.empty() && "Provided an invalid Resource Class"); Metadata *Operands[] = { - MDString::get(Ctx, *ResName), + MDString::get(Ctx, ResName), ConstantAsMetadata::get(Builder.getInt32(Clause.NumDescriptors)), ConstantAsMetadata::get(Builder.getInt32(Clause.Reg.Number)), ConstantAsMetadata::get(Builder.getInt32(Clause.Space)), diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp index f11c7d2..72308a3d 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp @@ -29,7 +29,7 @@ bool verifyRegisterValue(uint32_t RegisterValue) { // This Range is reserverved, therefore invalid, according to the spec // https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#all-the-values-should-be-legal bool verifyRegisterSpace(uint32_t RegisterSpace) { - return !(RegisterSpace >= 0xFFFFFFF0 && RegisterSpace <= 0xFFFFFFFF); + return !(RegisterSpace >= 0xFFFFFFF0); } bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal) { @@ -180,140 +180,6 @@ bool verifyBorderColor(uint32_t BorderColor) { bool verifyLOD(float LOD) { return !std::isnan(LOD); } -std::optional<const RangeInfo *> -ResourceRange::getOverlapping(const RangeInfo &Info) const { - MapT::const_iterator Interval = Intervals.find(Info.LowerBound); - if (!Interval.valid() || Info.UpperBound < Interval.start()) - return std::nullopt; - return Interval.value(); -} - -const RangeInfo *ResourceRange::lookup(uint32_t X) const { - return Intervals.lookup(X, nullptr); -} - -void ResourceRange::clear() { return Intervals.clear(); } - -std::optional<const RangeInfo *> ResourceRange::insert(const RangeInfo &Info) { - uint32_t LowerBound = Info.LowerBound; - uint32_t UpperBound = Info.UpperBound; - - std::optional<const RangeInfo *> Res = std::nullopt; - MapT::iterator Interval = Intervals.begin(); - - while (true) { - if (UpperBound < LowerBound) - break; - - Interval.advanceTo(LowerBound); - if (!Interval.valid()) // No interval found - break; - - // Let Interval = [x;y] and [LowerBound;UpperBound] = [a;b] and note that - // a <= y implicitly from Intervals.find(LowerBound) - if (UpperBound < Interval.start()) - break; // found interval does not overlap with inserted one - - if (!Res.has_value()) // Update to be the first found intersection - Res = Interval.value(); - - if (Interval.start() <= LowerBound && UpperBound <= Interval.stop()) { - // x <= a <= b <= y implies that [a;b] is covered by [x;y] - // -> so we don't need to insert this, report an overlap - return Res; - } else if (LowerBound <= Interval.start() && - Interval.stop() <= UpperBound) { - // a <= x <= y <= b implies that [x;y] is covered by [a;b] - // -> so remove the existing interval that we will cover with the - // overwrite - Interval.erase(); - } else if (LowerBound < Interval.start() && UpperBound <= Interval.stop()) { - // a < x <= b <= y implies that [a; x] is not covered but [x;b] is - // -> so set b = x - 1 such that [a;x-1] is now the interval to insert - UpperBound = Interval.start() - 1; - } else if (Interval.start() <= LowerBound && Interval.stop() < UpperBound) { - // a < x <= b <= y implies that [y; b] is not covered but [a;y] is - // -> so set a = y + 1 such that [y+1;b] is now the interval to insert - LowerBound = Interval.stop() + 1; - } - } - - assert(LowerBound <= UpperBound && "Attempting to insert an empty interval"); - Intervals.insert(LowerBound, UpperBound, &Info); - return Res; -} - -llvm::SmallVector<OverlappingRanges> -findOverlappingRanges(ArrayRef<RangeInfo> Infos) { - // It is expected that Infos is filled with valid RangeInfos and that - // they are sorted with respect to the RangeInfo <operator - assert(llvm::is_sorted(Infos) && "Ranges must be sorted"); - - llvm::SmallVector<OverlappingRanges> Overlaps; - using GroupT = std::pair<dxil::ResourceClass, /*Space*/ uint32_t>; - - // First we will init our state to track: - if (Infos.size() == 0) - return Overlaps; // No ranges to overlap - GroupT CurGroup = {Infos[0].Class, Infos[0].Space}; - - // Create a ResourceRange for each Visibility - ResourceRange::MapT::Allocator Allocator; - std::array<ResourceRange, 8> Ranges = { - ResourceRange(Allocator), // All - ResourceRange(Allocator), // Vertex - ResourceRange(Allocator), // Hull - ResourceRange(Allocator), // Domain - ResourceRange(Allocator), // Geometry - ResourceRange(Allocator), // Pixel - ResourceRange(Allocator), // Amplification - ResourceRange(Allocator), // Mesh - }; - - // Reset the ResourceRanges for when we iterate through a new group - auto ClearRanges = [&Ranges]() { - for (ResourceRange &Range : Ranges) - Range.clear(); - }; - - // Iterate through collected RangeInfos - for (const RangeInfo &Info : Infos) { - GroupT InfoGroup = {Info.Class, Info.Space}; - // Reset our ResourceRanges when we enter a new group - if (CurGroup != InfoGroup) { - ClearRanges(); - CurGroup = InfoGroup; - } - - // Insert range info into corresponding Visibility ResourceRange - ResourceRange &VisRange = Ranges[llvm::to_underlying(Info.Visibility)]; - if (std::optional<const RangeInfo *> Overlapping = VisRange.insert(Info)) - Overlaps.push_back(OverlappingRanges(&Info, Overlapping.value())); - - // Check for overlap in all overlapping Visibility ResourceRanges - // - // If the range that we are inserting has ShaderVisiblity::All it needs to - // check for an overlap in all other visibility types as well. - // Otherwise, the range that is inserted needs to check that it does not - // overlap with ShaderVisibility::All. - // - // OverlapRanges will be an ArrayRef to all non-all visibility - // ResourceRanges in the former case and it will be an ArrayRef to just the - // all visiblity ResourceRange in the latter case. - ArrayRef<ResourceRange> OverlapRanges = - Info.Visibility == llvm::dxbc::ShaderVisibility::All - ? ArrayRef<ResourceRange>{Ranges}.drop_front() - : ArrayRef<ResourceRange>{Ranges}.take_front(); - - for (const ResourceRange &Range : OverlapRanges) - if (std::optional<const RangeInfo *> Overlapping = - Range.getOverlapping(Info)) - Overlaps.push_back(OverlappingRanges(&Info, Overlapping.value())); - } - - return Overlaps; -} - } // namespace rootsig } // namespace hlsl } // namespace llvm |