[clang] [llvm] [DirectX] Validate registers are bound to root signature (PR #146785)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 10 11:03:38 PDT 2025
================
@@ -14,10 +14,129 @@
#ifndef LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
#define LLVM_LIB_TARGET_DIRECTX_DXILPOSTOPTIMIZATIONVALIDATION_H
+#include "DXILRootSignature.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+static uint64_t combineUint32ToUint64(uint32_t High, uint32_t Low) {
+ return (static_cast<uint64_t>(High) << 32) | Low;
+}
+
+class RootSignatureBindingValidation {
+ using MapT =
+ llvm::IntervalMap<uint64_t, dxil::ResourceInfo::ResourceBinding,
+ sizeof(llvm::dxil::ResourceInfo::ResourceBinding),
+ llvm::IntervalMapInfo<uint64_t>>;
+
+private:
+ MapT::Allocator Allocator;
+ MapT CRegBindingsMap;
+ MapT TRegBindingsMap;
+ MapT URegBindingsMap;
+ MapT SamplersBindingsMap;
+
+ void addRange(const dxbc::RTS0::v2::RootDescriptor &Desc, uint32_t Type) {
+ assert((Type == llvm::to_underlying(dxbc::RootParameterType::CBV) ||
+ Type == llvm::to_underlying(dxbc::RootParameterType::SRV) ||
+ Type == llvm::to_underlying(dxbc::RootParameterType::UAV)) &&
+ "Invalid Type in add Range Method");
+
+ llvm::dxil::ResourceInfo::ResourceBinding Binding;
+ Binding.LowerBound = Desc.ShaderRegister;
+ Binding.Space = Desc.RegisterSpace;
+ Binding.Size = 1;
+
+ uint64_t LowRange =
+ combineUint32ToUint64(Binding.Space, Binding.LowerBound);
+ uint64_t HighRange = combineUint32ToUint64(
+ Binding.Space, Binding.LowerBound + Binding.Size - 1);
+
+ assert(LowRange <= HighRange && "Invalid range configuration");
+
+ switch (Type) {
+
+ case llvm::to_underlying(dxbc::RootParameterType::CBV):
+ CRegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::SRV):
+ TRegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::UAV):
+ URegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ }
+ }
+
+ void addRange(const dxbc::RTS0::v2::DescriptorRange &Range) {
+
+ llvm::dxil::ResourceInfo::ResourceBinding Binding;
+ Binding.LowerBound = Range.BaseShaderRegister;
+ Binding.Space = Range.RegisterSpace;
+ Binding.Size = Range.NumDescriptors;
+
+ uint64_t LowRange =
+ combineUint32ToUint64(Binding.Space, Binding.LowerBound);
+ uint64_t HighRange = combineUint32ToUint64(
+ Binding.Space, Binding.LowerBound + Binding.Size - 1);
+
+ assert(LowRange <= HighRange && "Invalid range configuration");
+
+ switch (Range.RangeType) {
+ case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
+ CRegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
+ TRegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
+ URegBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler):
+ SamplersBindingsMap.insert(LowRange, HighRange, Binding);
+ break;
+ }
+ }
+
+public:
+ RootSignatureBindingValidation()
+ : Allocator(), CRegBindingsMap(Allocator), TRegBindingsMap(Allocator),
+ URegBindingsMap(Allocator), SamplersBindingsMap(Allocator) {}
+
+ void addRsBindingInfo(mcdxbc::RootSignatureDesc &RSD,
+ dxbc::ShaderVisibility Visibility);
+
+ bool checkCRegBinding(dxil::ResourceInfo::ResourceBinding Binding) {
+ return CRegBindingsMap.overlaps(
----------------
joaosaffran wrote:
Not always, the user can assign any register inside the range defined in the root signature, here is an example: https://hlsl.godbolt.org/z/qYox19jex
https://github.com/llvm/llvm-project/pull/146785
More information about the cfe-commits
mailing list