Skip to content

[DirectX] Add shader flags for heap resources - #216461

Merged
hekota merged 14 commits into
llvm:mainfrom
hekota:dyn-res-shader-flags
Aug 25, 2026
Merged

[DirectX] Add shader flags for heap resources#216461
hekota merged 14 commits into
llvm:mainfrom
hekota:dyn-res-shader-flags

Conversation

@hekota

@hekota hekota commented Aug 15, 2026

Copy link
Copy Markdown
Member

Descriptor-heap usage must be recorded in the shader feature flags. The DXILShaderFlags pass inspects each llvm.dx.resource.handlefromheap call and sets the SamplerDescriptorHeapIndexing shader flag when IsSamplerHeap is true, or ResourceDescriptorHeapIndexing flag when it is false.

Fixes #213825

hekota added 3 commits August 14, 2026 21:45
- `DXILResourceMap` now handles a new `llvm.dx.resource.handlefromheap` intrisics
  and adds the heap resources to the resource map.

- A new member `HeapResourceID` has been added to `ResourceInfo` to distinguish
  between heap resource instances created from different indices. The `HeapResourceID`
  is unique for each heap index `Value*`, so multiple handle creation calls using
  the same index `Value*` resolve to the same resource.

- Heap resources do not have register bindings, so the `Binding` member
  on `ResourceInfo` is now optional.

- All places that were always expecting binding are updated to handle
  heap resources. In most cases that means skipping them, such as when
  generating DXIL resource metadata, creating PSV resource entries or
  pretty-printing the resource table comment for the module disassembly
  output.

- Diagnostics of conflicting increment and decrement operations now works on heap
  resources.
@hekota hekota linked an issue Aug 17, 2026 that may be closed by this pull request
@hekota
hekota marked this pull request as ready for review August 17, 2026 06:47
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-directx

Author: Helena Kotas (hekota)

Changes

Descriptor-heap usage must be recorded in the shader feature flags. The DXILShaderFlags pass inspects each llvm.dx.resource.handlefromheap call and sets the SamplerDescriptorHeapIndexing shader flag when IsSamplerHeap is true, or ResourceDescriptorHeapIndexing flag when it is false.

Fixes #213825

Depends on #216454


Full diff: https://github.com/llvm/llvm-project/pull/216461.diff

2 Files Affected:

  • (modified) llvm/lib/Target/DirectX/DXILShaderFlags.cpp (+11-1)
  • (added) llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll (+42)
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 64d8dc33e3e60..b7c296b2bde6d 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -274,6 +274,16 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
       }
       break;
     }
+    case Intrinsic::dx_resource_handlefromheap: {
+      if (auto *ConstInt = dyn_cast<ConstantInt>(II->getArgOperand(1))) {
+        bool IsSamplerHeap = ConstInt->getValue().getBoolValue();
+        if (IsSamplerHeap)
+          CSF.SamplerDescriptorHeapIndexing = true;
+        else
+          CSF.ResourceDescriptorHeapIndexing = true;
+      }
+      break;
+    }
     case Intrinsic::dx_resource_load_typedbuffer: {
       dxil::ResourceTypeInfo &RTI =
           DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
@@ -342,7 +352,7 @@ ModuleShaderFlags::gatherGlobalModuleFlags(const Module &M,
     if (MMDI.ValidatorVersion < VersionTuple(1, 6)) {
       NumUAVs++;
     } else { // MMDI.ValidatorVersion >= VersionTuple(1, 6)
-      uint32_t Size = UAV.getBinding().Size;
+      uint32_t Size = UAV.getSize();
       uint32_t NewNum = NumUAVs + (Size == 0 ? ~0U : Size);
       if (NewNum < NumUAVs)
         NewNum = ~0U;
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll
new file mode 100644
index 0000000000000..d7e15a65aea3a
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+; RUN: llc %s -disable-dxil-remove-unused-resources --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC
+
+; This test makes sure that the shader flags 'Resource descriptor heap indexing'
+; is set when the shader uses CreateHandleFromHeap instruction on a resource
+; descriptor heap.
+
+target triple = "dxil-pc-shadermodel6.6-library"
+
+; CHECK:      Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0xc0000000
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK:        Resource descriptor heap indexing
+; CHECK:        Sampler descriptor heap indexing
+;
+; CHECK: Function test_1 : 0x40000000
+define void @test_1() "hlsl.export" {
+  ; RWBuffer<float4> Buf = ResourceDescriptorHeap[3]
+  %typed = call target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
+              @llvm.dx.resource.handlefromheap.tdx.TypedBuffer_v4f32_1_0_0(i32 3, i1 false)
+  ret void
+}
+
+; CHECK: Function test_2 : 0x80000000
+define void @test_2() "hlsl.export" {
+  ; SamplerState Samp = ResourceDescriptorHeap[100];
+  %samp = call target("dx.Sampler", 0)
+              @llvm.dx.resource.handlefromheap.tdx.Sampler_0(i32 100, i1 true)
+  ret void
+}
+
+!dx.valver = !{!0}
+!0 = !{i32 1, i32 8}
+
+; DXC: - Name:            SFI0
+; DXC-NEXT:     Size:            8
+; DXC-NEXT:     Flags:
+; DXC:             ResourceDescriptorHeapIndexing: true
+; DXC:             SamplerDescriptorHeapIndexing: true
+; DXC:       NextUnusedBit:   false
+

@hekota
hekota requested review from Icohedron and bob80905 August 18, 2026 17:32

@bob80905 bob80905 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, just some nits. Also, random curiosity, we expect a diagnostic / a validation failure if the operand (the index) is not a constant? Has that been previously validated by the point of the code you've written?

Comment thread llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll Outdated
Comment thread llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll Outdated
@hekota

hekota commented Aug 18, 2026

Copy link
Copy Markdown
Member Author

looks good, just some nits. Also, random curiosity, we expect a diagnostic / a validation failure if the operand (the index) is not a constant? Has that been previously validated by the point of the code you've written?

The Index operand is allowed to be non-constant so the resources can be indexed dynamically. The second isSamplerHeap is supposed to be constant and can add validation for that to the lowering PR (#216459).

Comment thread llvm/lib/Target/DirectX/DXILShaderFlags.cpp
Comment thread llvm/lib/Target/DirectX/DXILShaderFlags.cpp Outdated
Comment thread llvm/lib/Target/DirectX/DXILShaderFlags.cpp Outdated
Comment thread llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll Outdated
Comment thread llvm/test/CodeGen/DirectX/ShaderFlags/heap-resources.ll Outdated
Comment thread llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@hekota hekota linked an issue Aug 21, 2026 that may be closed by this pull request
3 tasks
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

✅ With the latest revision this PR passed the C/C++ code formatter.

@hekota
hekota changed the base branch from users/hekota/pr216454-dyn-red-heap-index-id to main August 22, 2026 03:11
@hekota
hekota merged commit d75923d into llvm:main Aug 25, 2026
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[DirectX] Set shader flags for dynamic resources [DirectX] Add handling of llvm.dx.handle.fromHeap to DXIL resource passes

4 participants